fivocell 1.0.4 → 2.0.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.
- package/README.md +697 -505
- package/bin/cell.js +2 -2
- package/dist/behavior-intelligence.d.ts +90 -0
- package/dist/behavior-intelligence.d.ts.map +1 -0
- package/dist/behavior-intelligence.js +595 -0
- package/dist/behavior-intelligence.js.map +1 -0
- package/dist/cli.d.ts +6 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2191 -1
- package/dist/cli.js.map +1 -1
- package/dist/cloud-sync.d.ts +66 -0
- package/dist/cloud-sync.d.ts.map +1 -0
- package/dist/cloud-sync.js +328 -0
- package/dist/cloud-sync.js.map +1 -0
- package/dist/community-intelligence.d.ts +42 -0
- package/dist/community-intelligence.d.ts.map +1 -0
- package/dist/community-intelligence.js +160 -0
- package/dist/community-intelligence.js.map +1 -0
- package/dist/community-v2.d.ts +106 -0
- package/dist/community-v2.d.ts.map +1 -0
- package/dist/community-v2.js +378 -0
- package/dist/community-v2.js.map +1 -0
- package/dist/core/__tests__/chapter8-hostile.test.js +1 -1
- package/dist/core/__tests__/chapter8-hostile.test.js.map +1 -1
- package/dist/core/__tests__/chapter9-hostile.test.js +1 -1
- package/dist/core/__tests__/chapter9-hostile.test.js.map +1 -1
- package/dist/core/__tests__/complexity-analyzer.test.js +15 -15
- package/dist/core/__tests__/team-composer.test.js +2 -1
- package/dist/core/__tests__/team-composer.test.js.map +1 -1
- package/dist/core/convention-detector.d.ts.map +1 -1
- package/dist/core/convention-detector.js +11 -23
- package/dist/core/convention-detector.js.map +1 -1
- package/dist/core/cost-optimizer.d.ts.map +1 -1
- package/dist/core/cost-optimizer.js +13 -25
- package/dist/core/cost-optimizer.js.map +1 -1
- package/dist/core/database.d.ts +28 -0
- package/dist/core/database.d.ts.map +1 -0
- package/dist/core/database.js +587 -0
- package/dist/core/database.js.map +1 -0
- package/dist/core/knowledge-graph.d.ts.map +1 -1
- package/dist/core/knowledge-graph.js +9 -24
- package/dist/core/knowledge-graph.js.map +1 -1
- package/dist/core/logger.d.ts +9 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +26 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/playbook-generator.js +48 -48
- package/dist/core/privacy-manager.d.ts.map +1 -1
- package/dist/core/privacy-manager.js +5 -0
- package/dist/core/privacy-manager.js.map +1 -1
- package/dist/core/project-dna.d.ts.map +1 -1
- package/dist/core/project-dna.js +6 -19
- package/dist/core/project-dna.js.map +1 -1
- package/dist/core/prompt-builder.d.ts +18 -0
- package/dist/core/prompt-builder.d.ts.map +1 -0
- package/dist/core/prompt-builder.js +325 -0
- package/dist/core/prompt-builder.js.map +1 -0
- package/dist/core/session-memory.d.ts +90 -0
- package/dist/core/session-memory.d.ts.map +1 -0
- package/dist/core/session-memory.js +229 -0
- package/dist/core/session-memory.js.map +1 -0
- package/dist/core/signal-capture.d.ts +5 -0
- package/dist/core/signal-capture.d.ts.map +1 -1
- package/dist/core/signal-capture.js +67 -0
- package/dist/core/signal-capture.js.map +1 -1
- package/dist/core/team-composer.d.ts.map +1 -1
- package/dist/core/team-composer.js +16 -6
- package/dist/core/team-composer.js.map +1 -1
- package/dist/cross-model-memory.d.ts +95 -0
- package/dist/cross-model-memory.d.ts.map +1 -0
- package/dist/cross-model-memory.js +229 -0
- package/dist/cross-model-memory.js.map +1 -0
- package/dist/daemon/lifecycle.d.ts +18 -0
- package/dist/daemon/lifecycle.d.ts.map +1 -1
- package/dist/daemon/lifecycle.js +182 -5
- package/dist/daemon/lifecycle.js.map +1 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +269 -6
- package/dist/daemon/server.js.map +1 -1
- package/dist/first-run.d.ts +8 -0
- package/dist/first-run.d.ts.map +1 -0
- package/dist/first-run.js +182 -0
- package/dist/first-run.js.map +1 -0
- package/dist/focus-report.d.ts +32 -0
- package/dist/focus-report.d.ts.map +1 -0
- package/dist/focus-report.js +293 -0
- package/dist/focus-report.js.map +1 -0
- package/dist/ide-intelligence.d.ts +118 -0
- package/dist/ide-intelligence.d.ts.map +1 -0
- package/dist/ide-intelligence.js +284 -0
- package/dist/ide-intelligence.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +119 -2
- package/dist/index.js.map +1 -1
- package/dist/insight-generator.d.ts +58 -0
- package/dist/insight-generator.d.ts.map +1 -0
- package/dist/insight-generator.js +314 -0
- package/dist/insight-generator.js.map +1 -0
- package/dist/journey-memory.d.ts +75 -0
- package/dist/journey-memory.d.ts.map +1 -0
- package/dist/journey-memory.js +360 -0
- package/dist/journey-memory.js.map +1 -0
- package/dist/mcp-server.d.ts +2054 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +1120 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/onboarding-scan.d.ts +174 -0
- package/dist/onboarding-scan.d.ts.map +1 -0
- package/dist/onboarding-scan.js +1039 -0
- package/dist/onboarding-scan.js.map +1 -0
- package/dist/personal-intelligence.d.ts +97 -0
- package/dist/personal-intelligence.d.ts.map +1 -0
- package/dist/personal-intelligence.js +408 -0
- package/dist/personal-intelligence.js.map +1 -0
- package/dist/predictive-intelligence.d.ts +95 -0
- package/dist/predictive-intelligence.d.ts.map +1 -0
- package/dist/predictive-intelligence.js +544 -0
- package/dist/predictive-intelligence.js.map +1 -0
- package/dist/production.d.ts +67 -0
- package/dist/production.d.ts.map +1 -0
- package/dist/production.js +333 -0
- package/dist/production.js.map +1 -0
- package/dist/senior-features.d.ts +63 -0
- package/dist/senior-features.d.ts.map +1 -0
- package/dist/senior-features.js +325 -0
- package/dist/senior-features.js.map +1 -0
- package/dist/style-pull.d.ts +40 -0
- package/dist/style-pull.d.ts.map +1 -0
- package/dist/style-pull.js +385 -0
- package/dist/style-pull.js.map +1 -0
- package/dist/team-collaboration.d.ts +116 -0
- package/dist/team-collaboration.d.ts.map +1 -0
- package/dist/team-collaboration.js +375 -0
- package/dist/team-collaboration.js.map +1 -0
- package/dist/team-intelligence.d.ts +64 -0
- package/dist/team-intelligence.d.ts.map +1 -0
- package/dist/team-intelligence.js +289 -0
- package/dist/team-intelligence.js.map +1 -0
- package/dist/test-watch.d.ts +2 -0
- package/dist/test-watch.d.ts.map +1 -0
- package/dist/test-watch.js +8 -0
- package/dist/test-watch.js.map +1 -0
- package/dist/user-intelligence.d.ts +69 -0
- package/dist/user-intelligence.d.ts.map +1 -0
- package/dist/user-intelligence.js +553 -0
- package/dist/user-intelligence.js.map +1 -0
- package/dist/work-style.d.ts +49 -0
- package/dist/work-style.d.ts.map +1 -0
- package/dist/work-style.js +247 -0
- package/dist/work-style.js.map +1 -0
- package/package.json +3 -2
package/dist/cli.js
CHANGED
|
@@ -37,6 +37,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
38
|
};
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.runConnect = runConnect;
|
|
40
41
|
const commander_1 = require("commander");
|
|
41
42
|
const path = __importStar(require("path"));
|
|
42
43
|
const fs = __importStar(require("fs"));
|
|
@@ -1443,6 +1444,791 @@ daemonCmd
|
|
|
1443
1444
|
console.log(` Stale PID found: ${status.pid}`);
|
|
1444
1445
|
}
|
|
1445
1446
|
});
|
|
1447
|
+
daemonCmd
|
|
1448
|
+
.command('install-service')
|
|
1449
|
+
.description('Install as Windows scheduled task (auto-start at logon, auto-restart on crash)')
|
|
1450
|
+
.action(async () => {
|
|
1451
|
+
const { installService } = await Promise.resolve().then(() => __importStar(require('./daemon/lifecycle')));
|
|
1452
|
+
const r = installService();
|
|
1453
|
+
console.log(r.success ? `✅ ${r.message}` : `❌ ${r.message}`);
|
|
1454
|
+
});
|
|
1455
|
+
program
|
|
1456
|
+
.command('rescan')
|
|
1457
|
+
.description('Re-scan codebase and refresh pattern library')
|
|
1458
|
+
.option('--all', 'Scan all sub-projects (capped at 20,000 files)')
|
|
1459
|
+
.action(async (opts) => {
|
|
1460
|
+
const { scanCodebase, saveOnboarding } = await Promise.resolve().then(() => __importStar(require('./onboarding-scan')));
|
|
1461
|
+
const startDir = process.cwd();
|
|
1462
|
+
const scanAll = opts.all || false;
|
|
1463
|
+
console.log(C.primary(scanAll ? ' 🔄 Re-scanning ALL projects...' : ' 🔄 Re-scanning codebase...'));
|
|
1464
|
+
const result = scanCodebase(startDir, {
|
|
1465
|
+
timeBudgetMs: scanAll ? 30000 : 15000,
|
|
1466
|
+
maxFiles: scanAll ? 20000 : 2000,
|
|
1467
|
+
detectAllStacks: scanAll,
|
|
1468
|
+
});
|
|
1469
|
+
saveOnboarding(result);
|
|
1470
|
+
const onboardingMarker = path.join(os.homedir(), '.fivo', 'cell', '.onboarding-done');
|
|
1471
|
+
try {
|
|
1472
|
+
fs.writeFileSync(onboardingMarker, new Date().toISOString(), 'utf-8');
|
|
1473
|
+
}
|
|
1474
|
+
catch { }
|
|
1475
|
+
console.log(C.success(` ✅ Scanned ${result.filesScanned.toLocaleString()} files · ${result.totalLines.toLocaleString()} lines · ${result.patterns.length.toLocaleString()} patterns`));
|
|
1476
|
+
if (result.stack.length > 0) {
|
|
1477
|
+
console.log(C.dim(` Stack: ${result.stack.slice(0, 6).map(s => s.name).join(', ')}`));
|
|
1478
|
+
}
|
|
1479
|
+
console.log(C.dim(` Patterns merged into your taste profile.`));
|
|
1480
|
+
});
|
|
1481
|
+
program
|
|
1482
|
+
.command('profile')
|
|
1483
|
+
.description('Build YOUR user profile: products, stack fingerprint, common features, missing features')
|
|
1484
|
+
.option('--root <dir>', 'Root directory to scan (defaults to parent of CWD)', process.cwd())
|
|
1485
|
+
.action(async (opts) => {
|
|
1486
|
+
const { buildUserProfile, saveUserProfile, loadUserProfile } = await Promise.resolve().then(() => __importStar(require('./user-intelligence')));
|
|
1487
|
+
const startDir = opts.root || process.cwd();
|
|
1488
|
+
console.log(C.primary(' 🧠 Building your USER profile (not AI style)...'));
|
|
1489
|
+
const profile = buildUserProfile(startDir);
|
|
1490
|
+
saveUserProfile(profile);
|
|
1491
|
+
console.log(C.success(` ✅ Found ${profile.products.length} products across ${profile.products.reduce((a, p) => a + p.projects.length, 0)} projects`));
|
|
1492
|
+
console.log();
|
|
1493
|
+
for (const prod of profile.products) {
|
|
1494
|
+
console.log(C.bold(` 📦 ${prod.name.toUpperCase()}`) + C.dim(` (${prod.projects.length} projects · latest ${prod.latestVersion})`));
|
|
1495
|
+
if (prod.description)
|
|
1496
|
+
console.log(C.dim(` ${prod.description}`));
|
|
1497
|
+
console.log(C.dim(` ${prod.projects.join(' · ')}`));
|
|
1498
|
+
if (prod.commonFeatures.length > 0) {
|
|
1499
|
+
console.log(C.dim(` Features: ${prod.commonFeatures.join(', ')}`));
|
|
1500
|
+
}
|
|
1501
|
+
console.log();
|
|
1502
|
+
}
|
|
1503
|
+
if (profile.goToStack.length > 0) {
|
|
1504
|
+
console.log(C.bold(' 📦 Your go-to stack:'));
|
|
1505
|
+
for (const s of profile.goToStack.slice(0, 8)) {
|
|
1506
|
+
console.log(` • ${s.name} — ${s.reason}`);
|
|
1507
|
+
}
|
|
1508
|
+
console.log();
|
|
1509
|
+
}
|
|
1510
|
+
if (profile.missingFeatures.length > 0) {
|
|
1511
|
+
console.log(C.bold(' 💡 You might want to add:'));
|
|
1512
|
+
for (const m of profile.missingFeatures.slice(0, 5)) {
|
|
1513
|
+
console.log(C.dim(` ❌ ${m.name} — ${m.suggestion}`));
|
|
1514
|
+
}
|
|
1515
|
+
console.log();
|
|
1516
|
+
}
|
|
1517
|
+
console.log(C.dim(` Saved to: ~/.fivo/cell/user-profile.json + user-profile.md`));
|
|
1518
|
+
});
|
|
1519
|
+
program
|
|
1520
|
+
.command('taste')
|
|
1521
|
+
.description('See your saved user profile in human-readable form')
|
|
1522
|
+
.action(async () => {
|
|
1523
|
+
const { loadUserProfile } = await Promise.resolve().then(() => __importStar(require('./user-intelligence')));
|
|
1524
|
+
const profile = loadUserProfile();
|
|
1525
|
+
if (!profile) {
|
|
1526
|
+
console.log(C.dim(' No profile yet. Run `cell profile` to build one.'));
|
|
1527
|
+
return;
|
|
1528
|
+
}
|
|
1529
|
+
console.log(C.bold(' 🧠 Your User Profile'));
|
|
1530
|
+
console.log(C.dim(' ─────────────────────────────────────────'));
|
|
1531
|
+
console.log();
|
|
1532
|
+
console.log(C.bold(` 🏷️ ${profile.products.length} products you build:`));
|
|
1533
|
+
for (const prod of profile.products) {
|
|
1534
|
+
console.log();
|
|
1535
|
+
console.log(` 📦 ${prod.name.toUpperCase()} (${prod.projects.length} projects · latest ${prod.latestVersion})`);
|
|
1536
|
+
if (prod.description)
|
|
1537
|
+
console.log(C.dim(` ${prod.description}`));
|
|
1538
|
+
if (prod.commonStack.length > 0) {
|
|
1539
|
+
console.log(C.dim(` Stack: ${prod.commonStack.slice(0, 5).map(s => s.name).join(', ')}`));
|
|
1540
|
+
}
|
|
1541
|
+
if (prod.commonFeatures.length > 0) {
|
|
1542
|
+
console.log(C.dim(` Features: ${prod.commonFeatures.join(', ')}`));
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
console.log();
|
|
1546
|
+
console.log(C.bold(' 📦 Your go-to stack (across all products):'));
|
|
1547
|
+
for (const s of profile.goToStack.slice(0, 10)) {
|
|
1548
|
+
console.log(` • ${s.name} — ${s.reason} (${Math.round(s.confidence * 100)}%)`);
|
|
1549
|
+
}
|
|
1550
|
+
console.log();
|
|
1551
|
+
console.log(C.bold(' ✅ Features you build in every project:'));
|
|
1552
|
+
for (const f of profile.commonFeatures) {
|
|
1553
|
+
console.log(` • ${f.name} — ${f.projectCount}/${14} projects`);
|
|
1554
|
+
}
|
|
1555
|
+
console.log();
|
|
1556
|
+
if (profile.missingFeatures.length > 0) {
|
|
1557
|
+
console.log(C.bold(' 💡 Features you might want to add:'));
|
|
1558
|
+
for (const m of profile.missingFeatures) {
|
|
1559
|
+
console.log();
|
|
1560
|
+
console.log(` ❌ ${m.name}`);
|
|
1561
|
+
console.log(C.dim(` ${m.reason}`));
|
|
1562
|
+
console.log(C.dim(` → ${m.suggestion}`));
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
console.log();
|
|
1566
|
+
console.log(C.dim(` Full markdown: ~/.fivo/cell/user-profile.md`));
|
|
1567
|
+
});
|
|
1568
|
+
program
|
|
1569
|
+
.command('taste-interview')
|
|
1570
|
+
.description('Tell Cell about YOU directly (5 quick questions) — complements auto-scan')
|
|
1571
|
+
.action(async () => {
|
|
1572
|
+
const C2 = C;
|
|
1573
|
+
const { loadUserProfile, saveUserProfile } = await Promise.resolve().then(() => __importStar(require('./user-intelligence')));
|
|
1574
|
+
const profile = loadUserProfile() || {
|
|
1575
|
+
name: '',
|
|
1576
|
+
products: [],
|
|
1577
|
+
goToStack: [],
|
|
1578
|
+
commonFeatures: [],
|
|
1579
|
+
missingFeatures: [],
|
|
1580
|
+
workStyle: { isSolo: true, doesRAndD: false, shipsVersions: false, buildsCloud: false, buildsWeb: false },
|
|
1581
|
+
generatedAt: new Date().toISOString(),
|
|
1582
|
+
};
|
|
1583
|
+
console.log();
|
|
1584
|
+
console.log(C2.primary.bold(' 🎤 FIVO Cell — Taste Interview'));
|
|
1585
|
+
console.log(C2.dim(' ─────────────────────────────────────────'));
|
|
1586
|
+
console.log(C2.dim(' Cell ne tujhe samjha liya, ab tu bhi bata:'));
|
|
1587
|
+
console.log();
|
|
1588
|
+
const prompts = [
|
|
1589
|
+
{ key: 'name', q: 'Tera naam kya hai? (Cell tujhe isse bula kare)' },
|
|
1590
|
+
{ key: 'mainProduct', q: 'Tera MAIN product kya hai?', options: ['Fivo', 'PULSE', 'Dono', 'Kuch aur'] },
|
|
1591
|
+
{ key: 'mainRole', q: 'Tu kya karta hai?', options: ['Founder/CEO', 'Solo dev', 'Tech lead', 'AI-assisted dev', 'Designer + Dev'] },
|
|
1592
|
+
{ key: 'teamSize', q: 'Tera team kitna bada hai?', options: ['Sirf main', '2-3 log', '5-10 log', '10+ log'] },
|
|
1593
|
+
{ key: 'audience', q: 'Tera audience kaun hai?', options: ['Developers', 'Business users', 'Consumers', 'Mixed'] },
|
|
1594
|
+
{ key: 'topWish', q: 'Next project me AI se kya banwana chahta hai? (one line)' },
|
|
1595
|
+
{ key: 'biggestPain', q: 'Sabse bada pain kya hai abhi? (one line)' },
|
|
1596
|
+
{ key: 'avoidStack', q: 'Kaunsa stack AVOID karta hai? (comma separated)' },
|
|
1597
|
+
];
|
|
1598
|
+
const readline = require('readline');
|
|
1599
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
1600
|
+
const ask = (q) => new Promise(res => rl.question(q, (ans) => res(ans.trim())));
|
|
1601
|
+
for (const p of prompts) {
|
|
1602
|
+
let hint = '';
|
|
1603
|
+
if (p.options)
|
|
1604
|
+
hint = ` (${p.options.join(' / ')})`;
|
|
1605
|
+
const ans = await ask(C2.primary(` ${p.q}${hint}\n > `));
|
|
1606
|
+
profile[p.key] = ans;
|
|
1607
|
+
}
|
|
1608
|
+
rl.close();
|
|
1609
|
+
saveUserProfile(profile);
|
|
1610
|
+
console.log();
|
|
1611
|
+
console.log(C2.success(' ✅ Profile updated! Cell ab tujhe aur better samjhega.'));
|
|
1612
|
+
console.log(C2.dim(' Run `cell taste` to see your full profile.'));
|
|
1613
|
+
});
|
|
1614
|
+
program
|
|
1615
|
+
.command('style')
|
|
1616
|
+
.description('Talk to Cell about HOW you work (16 questions, ~3 min) — learns your work style, not code style')
|
|
1617
|
+
.action(async () => {
|
|
1618
|
+
const C2 = C;
|
|
1619
|
+
const { WORK_STYLE_QUESTIONS, loadWorkStyle, saveWorkStyle, applyAnswer, emptyWorkStyle } = await Promise.resolve().then(() => __importStar(require('./work-style')));
|
|
1620
|
+
console.log();
|
|
1621
|
+
console.log(C2.primary.bold(' 🎤 FIVO Cell — Work Style Interview'));
|
|
1622
|
+
console.log(C2.dim(' ─────────────────────────────────────────'));
|
|
1623
|
+
console.log(C2.dim(' Code style AI likhta hai — yeh interview tere KAAM KI STYLE samjhega.'));
|
|
1624
|
+
console.log(C2.dim(' Skip kar sakta hai — sirf Enter daba, ya quick type kar.'));
|
|
1625
|
+
console.log();
|
|
1626
|
+
const profile = loadWorkStyle() || emptyWorkStyle();
|
|
1627
|
+
const readline = require('readline');
|
|
1628
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
1629
|
+
const ask = (q) => new Promise(res => rl.question(q, (ans) => res(ans.trim())));
|
|
1630
|
+
for (const q of WORK_STYLE_QUESTIONS) {
|
|
1631
|
+
const optionsHint = q.options ? C2.dim(` Options: ${q.options.join(' / ')}`) : '';
|
|
1632
|
+
const helpHint = q.helpText ? C2.dim(` ℹ ${q.helpText}`) : '';
|
|
1633
|
+
console.log();
|
|
1634
|
+
console.log(C2.primary.bold(` Q${WORK_STYLE_QUESTIONS.indexOf(q) + 1}/${WORK_STYLE_QUESTIONS.length}: ${q.q}`));
|
|
1635
|
+
if (optionsHint)
|
|
1636
|
+
console.log(optionsHint);
|
|
1637
|
+
if (helpHint)
|
|
1638
|
+
console.log(helpHint);
|
|
1639
|
+
const ans = await ask(' ▸ ');
|
|
1640
|
+
applyAnswer(profile, q.key, ans);
|
|
1641
|
+
}
|
|
1642
|
+
rl.close();
|
|
1643
|
+
profile.updatedAt = new Date().toISOString();
|
|
1644
|
+
saveWorkStyle(profile);
|
|
1645
|
+
console.log();
|
|
1646
|
+
console.log(C2.success(' ✅ Work style saved! Cell ab tujhe samjhega.'));
|
|
1647
|
+
console.log(C2.dim(' Run `cell style` again to update. Run `cell style-show` to see it.'));
|
|
1648
|
+
});
|
|
1649
|
+
program
|
|
1650
|
+
.command('style-quick')
|
|
1651
|
+
.description('Quick work-style capture — just 5 essentials in one go')
|
|
1652
|
+
.action(async () => {
|
|
1653
|
+
const C2 = C;
|
|
1654
|
+
const { loadWorkStyle, saveWorkStyle, applyAnswer, emptyWorkStyle } = await Promise.resolve().then(() => __importStar(require('./work-style')));
|
|
1655
|
+
console.log();
|
|
1656
|
+
console.log(C2.primary.bold(' ⚡ FIVO Cell — Quick Style (5 questions)'));
|
|
1657
|
+
console.log(C2.dim(' ─────────────────────────────────────────'));
|
|
1658
|
+
console.log(C2.dim(' Freeform likh ya Enter daba — jo mann me aaye.'));
|
|
1659
|
+
console.log();
|
|
1660
|
+
const readline = require('readline');
|
|
1661
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
1662
|
+
const ask = (q) => new Promise(res => rl.question(q, (ans) => res(ans.trim())));
|
|
1663
|
+
const profile = loadWorkStyle() || emptyWorkStyle();
|
|
1664
|
+
const a1 = await ask(C2.primary(' 1️⃣ Tera naam?\n ▸ '));
|
|
1665
|
+
if (a1)
|
|
1666
|
+
applyAnswer(profile, 'identity.name', a1);
|
|
1667
|
+
const a2 = await ask(C2.primary(' 2️⃣ Tu kya banata hai? (product builder / tool builder / dono / experiments / client)\n ▸ '));
|
|
1668
|
+
if (a2)
|
|
1669
|
+
applyAnswer(profile, 'workType.primaryKind', a2);
|
|
1670
|
+
const a3 = await ask(C2.primary(' 3️⃣ Goal kya hai? (1 product bada / multiple / lifestyle / exit / seekhna)\n ▸ '));
|
|
1671
|
+
if (a3)
|
|
1672
|
+
applyAnswer(profile, 'goals.primary', a3);
|
|
1673
|
+
const a4 = await ask(C2.primary(' 4️⃣ SABSE BADA pain? (time / ideas / execute / marketing / money / focus / burnout)\n ▸ '));
|
|
1674
|
+
if (a4)
|
|
1675
|
+
applyAnswer(profile, 'pain.biggest', a4);
|
|
1676
|
+
const a5 = await ask(C2.primary(' 5️⃣ Next project me kya banana hai? (1 line)\n ▸ '));
|
|
1677
|
+
if (a5)
|
|
1678
|
+
applyAnswer(profile, 'goals.wishNextProject', a5);
|
|
1679
|
+
rl.close();
|
|
1680
|
+
profile.updatedAt = new Date().toISOString();
|
|
1681
|
+
saveWorkStyle(profile);
|
|
1682
|
+
console.log();
|
|
1683
|
+
console.log(C2.success(' ✅ Quick style saved! Cell ab tujhe samjhega.'));
|
|
1684
|
+
console.log(C2.dim(' Run `cell style-show` to see it. Run `cell style` for the full 16-question interview.'));
|
|
1685
|
+
});
|
|
1686
|
+
program
|
|
1687
|
+
.command('style-apply')
|
|
1688
|
+
.description('Apply your learned style to AI tool configs (Cursor .cursorrules, Claude CLAUDE.md, Copilot, Antigravity, AGENT.md, Prettier, ESLint)')
|
|
1689
|
+
.option('--tools <list>', 'Comma-separated tools: agent,cursor,claude,copilot,antigravity,prettier,eslint', 'agent,cursor,claude,copilot,antigravity,prettier,eslint')
|
|
1690
|
+
.option('--force', 'Overwrite existing style files')
|
|
1691
|
+
.option('--dir <dir>', 'Target directory (defaults to CWD)', process.cwd())
|
|
1692
|
+
.action(async (opts) => {
|
|
1693
|
+
const C2 = C;
|
|
1694
|
+
const { buildStyleSummary, writeStyleFiles } = await Promise.resolve().then(() => __importStar(require('./style-pull')));
|
|
1695
|
+
const target = opts.dir || process.cwd();
|
|
1696
|
+
const tools = (opts.tools || 'agent,cursor,claude,copilot,antigravity,prettier,eslint').split(',').map(s => s.trim()).filter(Boolean);
|
|
1697
|
+
console.log(C2.primary(' 🎨 Reading your learned style from ~/.fivo/cell/...'));
|
|
1698
|
+
const summary = buildStyleSummary(target);
|
|
1699
|
+
console.log(C2.success(` ✅ Loaded ${summary.topPatterns.length} top patterns + formatting rules`));
|
|
1700
|
+
console.log();
|
|
1701
|
+
console.log(C2.bold(' 📐 Detected style:'));
|
|
1702
|
+
console.log(C2.dim(` ${summary.formatting.semicolons ? '✓' : '✗'} Semicolons`));
|
|
1703
|
+
console.log(C2.dim(` ✓ Quotes: ${summary.formatting.quotes}`));
|
|
1704
|
+
console.log(C2.dim(` ✓ Indent: ${summary.formatting.indentSize} ${summary.formatting.indentStyle}s`));
|
|
1705
|
+
console.log(C2.dim(` ✓ Line width: ${summary.formatting.lineWidth}`));
|
|
1706
|
+
console.log();
|
|
1707
|
+
console.log(C2.primary(` 📝 Writing style files to: ${target}`));
|
|
1708
|
+
const result = writeStyleFiles(target, summary, { tools, force: opts.force });
|
|
1709
|
+
for (const f of result.written) {
|
|
1710
|
+
console.log(C2.success(` ✓ ${f}`));
|
|
1711
|
+
}
|
|
1712
|
+
for (const f of result.skipped) {
|
|
1713
|
+
console.log(C2.dim(` - ${f} (already exists, use --force)`));
|
|
1714
|
+
}
|
|
1715
|
+
console.log();
|
|
1716
|
+
console.log(C2.bold(' 💡 Next steps:'));
|
|
1717
|
+
console.log(C2.dim(' 1. Open this folder in Cursor / Claude Code / VSCode'));
|
|
1718
|
+
console.log(C2.dim(' 2. AI tools will auto-detect AGENT.md / CLAUDE.md / .cursorrules'));
|
|
1719
|
+
console.log(C2.dim(' 3. Every new code will follow your style automatically'));
|
|
1720
|
+
console.log();
|
|
1721
|
+
console.log(C2.dim(' Other projects: `cell style-apply --dir "C:\\path\\to\\other\\project"`'));
|
|
1722
|
+
});
|
|
1723
|
+
program
|
|
1724
|
+
.command('style-extract')
|
|
1725
|
+
.description('Extract style from current project into your learned profile (so other projects can use it)')
|
|
1726
|
+
.option('--dir <dir>', 'Project to extract style from (defaults to CWD)', process.cwd())
|
|
1727
|
+
.action(async (opts) => {
|
|
1728
|
+
const C2 = C;
|
|
1729
|
+
const { scanCodebase, saveOnboarding } = await Promise.resolve().then(() => __importStar(require('./onboarding-scan')));
|
|
1730
|
+
const target = opts.dir || process.cwd();
|
|
1731
|
+
console.log(C2.primary(` 📥 Extracting style from: ${target}`));
|
|
1732
|
+
const result = scanCodebase(target, { timeBudgetMs: 15000, maxFiles: 2000 });
|
|
1733
|
+
saveOnboarding(result);
|
|
1734
|
+
console.log(C2.success(` ✅ Extracted ${result.patterns.length} patterns`));
|
|
1735
|
+
console.log(C2.dim(` Files: ${result.filesScanned}, Lines: ${result.totalLines.toLocaleString()}`));
|
|
1736
|
+
console.log();
|
|
1737
|
+
console.log(C2.dim(' Style merged into ~/.fivo/cell/onboarding.json'));
|
|
1738
|
+
console.log(C2.dim(' Now use `cell style-apply` in any project to apply this style.'));
|
|
1739
|
+
});
|
|
1740
|
+
program
|
|
1741
|
+
.command('goal')
|
|
1742
|
+
.description('🎯 Track your learning goals')
|
|
1743
|
+
.argument('[text]', 'Goal text to add (quote it for multi-word goals)')
|
|
1744
|
+
.option('--done', 'Mark most recent active goal as complete')
|
|
1745
|
+
.action(async (text, opts) => {
|
|
1746
|
+
const C2 = C;
|
|
1747
|
+
const fs2 = require('fs');
|
|
1748
|
+
const goalPath = path.join(os.homedir(), '.fivo', 'cell', 'goals.json');
|
|
1749
|
+
let goals = [];
|
|
1750
|
+
if (fs2.existsSync(goalPath)) {
|
|
1751
|
+
try {
|
|
1752
|
+
goals = JSON.parse(fs2.readFileSync(goalPath, 'utf-8')).goals || [];
|
|
1753
|
+
}
|
|
1754
|
+
catch { }
|
|
1755
|
+
}
|
|
1756
|
+
if (opts.done) {
|
|
1757
|
+
const active = goals.filter((g) => g.status === 'active');
|
|
1758
|
+
if (active.length > 0) {
|
|
1759
|
+
active[active.length - 1].status = 'completed';
|
|
1760
|
+
active[active.length - 1].progress = 100;
|
|
1761
|
+
console.log(C2.success(` ✅ Marked "${active[active.length - 1].text}" as complete!`));
|
|
1762
|
+
}
|
|
1763
|
+
else {
|
|
1764
|
+
console.log(C2.dim(' No active goals to complete.'));
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
else if (text) {
|
|
1768
|
+
goals.push({ text, status: 'active', progress: 0, addedAt: new Date().toISOString(), notes: '' });
|
|
1769
|
+
console.log(C2.success(` ✅ Goal added: "${text}"`));
|
|
1770
|
+
}
|
|
1771
|
+
else {
|
|
1772
|
+
console.log(C2.bold(' 🎯 Your Goals:'));
|
|
1773
|
+
if (goals.length === 0) {
|
|
1774
|
+
console.log(C2.dim(' No goals yet. Add one: cell goal "learn Go"'));
|
|
1775
|
+
}
|
|
1776
|
+
for (const g of goals) {
|
|
1777
|
+
const icons = { active: '⏳', completed: '✅', stalled: '🟡', abandoned: '❌' };
|
|
1778
|
+
const bar = '█'.repeat(Math.floor(g.progress / 10)) + '░'.repeat(10 - Math.floor(g.progress / 10));
|
|
1779
|
+
console.log(` ${icons[g.status]} [${g.status}] ${g.text} ${C2.dim(`[${bar}] ${g.progress}%`)}`);
|
|
1780
|
+
console.log(C2.dim(` ${g.addedAt.slice(0, 10)}`));
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
const dir = path.join(os.homedir(), '.fivo', 'cell');
|
|
1784
|
+
if (!fs2.existsSync(dir))
|
|
1785
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
1786
|
+
fs2.writeFileSync(goalPath, JSON.stringify({ goals, updatedAt: new Date().toISOString() }, null, 2), 'utf-8');
|
|
1787
|
+
});
|
|
1788
|
+
program
|
|
1789
|
+
.command('community-compare')
|
|
1790
|
+
.description('🌍 Compare yourself with 12,400+ developers: adoption trends, blind spots, rankings')
|
|
1791
|
+
.action(async () => {
|
|
1792
|
+
const C2 = C;
|
|
1793
|
+
const { buildCommunityIntel, saveCommunityIntel } = await Promise.resolve().then(() => __importStar(require('./community-intelligence')));
|
|
1794
|
+
console.log(C2.primary(' 🌍 Comparing with community of 12,400+ developers...\n'));
|
|
1795
|
+
const report = buildCommunityIntel();
|
|
1796
|
+
saveCommunityIntel(report);
|
|
1797
|
+
console.log(C2.bold(` 📊 YOUR POSITION: ${report.summary.yourPosition}`));
|
|
1798
|
+
console.log();
|
|
1799
|
+
console.log(C2.bold(' 📈 TECH TRENDS (what 12K+ devs are doing):'));
|
|
1800
|
+
for (const t of report.trends) {
|
|
1801
|
+
const icon = t.adoption === 'hot' ? '🔥' : t.adoption === 'rising' ? '📈' : '📉';
|
|
1802
|
+
const check = t.userHasIt ? C2.success('✓') : C2.dim('✗');
|
|
1803
|
+
console.log(` ${icon} ${t.technology.padEnd(16)} ${t.adoption.toString().padEnd(10)} ${t.users} ${check} ${t.userScore}`);
|
|
1804
|
+
}
|
|
1805
|
+
console.log();
|
|
1806
|
+
console.log(C2.bold(' 📐 YOU vs COMMUNITY:'));
|
|
1807
|
+
for (const c of report.comparisons) {
|
|
1808
|
+
const v = c.verdict === 'ahead' ? '🚀' : c.verdict === 'unique' ? '💎' : c.verdict === 'behind' ? '📉' : '✅';
|
|
1809
|
+
console.log(` ${v} ${c.metric.padEnd(20)} ${c.you} vs ${c.communityAverage} avg (${c.percentile})`);
|
|
1810
|
+
}
|
|
1811
|
+
console.log();
|
|
1812
|
+
console.log(C2.bold(' 🎯 BLIND SPOT CHECK (vs community):'));
|
|
1813
|
+
for (const b of report.blindSpotCheck) {
|
|
1814
|
+
console.log(` ${b.area.padEnd(22)} ${b.yourFiles} files vs ${b.communityAvgFiles} avg`);
|
|
1815
|
+
console.log(C2.dim(` → ${b.recommendation}`));
|
|
1816
|
+
}
|
|
1817
|
+
console.log();
|
|
1818
|
+
console.log(C2.bold(' 🛠️ WHAT SUCCESSFUL DEVS USE:'));
|
|
1819
|
+
for (const w of report.whatOthersUse) {
|
|
1820
|
+
console.log(` • ${w}`);
|
|
1821
|
+
}
|
|
1822
|
+
console.log();
|
|
1823
|
+
console.log(C2.dim(' 📁 Saved: ~/.fivo/cell/community-report.json + .md'));
|
|
1824
|
+
});
|
|
1825
|
+
program
|
|
1826
|
+
.command('team-intel')
|
|
1827
|
+
.description('👥 Team intelligence: collaborators, skills, knowledge silos, collaboration graph')
|
|
1828
|
+
.option('--root <dir>', 'Root directory to analyze', process.cwd())
|
|
1829
|
+
.action(async (opts) => {
|
|
1830
|
+
const C2 = C;
|
|
1831
|
+
const { buildTeamIntelReport, saveTeamIntel } = await Promise.resolve().then(() => __importStar(require('./team-intelligence')));
|
|
1832
|
+
const startDir = opts.root || path.dirname(process.cwd());
|
|
1833
|
+
console.log(C2.primary(' 👥 Analyzing team dynamics across all projects...\n'));
|
|
1834
|
+
const report = buildTeamIntelReport(startDir);
|
|
1835
|
+
saveTeamIntel(report);
|
|
1836
|
+
console.log(C2.bold(` 📊 TEAM: ${report.summary.teamSize} people · ${report.summary.totalCommits} commits · ${report.summary.totalProjects} projects`));
|
|
1837
|
+
console.log();
|
|
1838
|
+
for (const c of report.collaborators.slice(0, 6)) {
|
|
1839
|
+
const roleIcon = c.role === 'owner' ? '👑' : c.role === 'maintainer' ? '🔧' : c.role === 'visitor' ? '👋' : '👤';
|
|
1840
|
+
console.log(` ${roleIcon} ${c.name.padEnd(22)} ${c.role.toString().padEnd(12)} ${c.commits} commits · ${(c.linesAdded + c.linesRemoved).toLocaleString()} LOC · ${c.projects.length} projects`);
|
|
1841
|
+
console.log(C2.dim(` ${c.firstCommit} → ${c.lastCommit} | Best: ${c.topHour} on ${c.topDay}`));
|
|
1842
|
+
}
|
|
1843
|
+
if (report.collaborators.length > 6) {
|
|
1844
|
+
console.log(C2.dim(` ...and ${report.collaborators.length - 6} more`));
|
|
1845
|
+
}
|
|
1846
|
+
console.log();
|
|
1847
|
+
if (report.edges.length > 0) {
|
|
1848
|
+
console.log(C2.bold(' 🔗 COLLABORATION:'));
|
|
1849
|
+
for (const e of report.edges.slice(0, 3)) {
|
|
1850
|
+
console.log(` ${e.source} ↔ ${e.target} — ${e.strength} (${e.sharedFiles} files)`);
|
|
1851
|
+
}
|
|
1852
|
+
console.log();
|
|
1853
|
+
}
|
|
1854
|
+
if (report.skills.length > 0) {
|
|
1855
|
+
console.log(C2.bold(' 🗺️ TEAM SKILLS:'));
|
|
1856
|
+
for (const s of report.skills) {
|
|
1857
|
+
const riskIcon = s.risk === 'high' ? '🔴' : s.risk === 'medium' ? '🟡' : '🟢';
|
|
1858
|
+
console.log(` ${riskIcon} ${s.area.padEnd(20)} ${s.coverage.toString().padEnd(14)} risk: ${s.risk} — ${s.description}`);
|
|
1859
|
+
}
|
|
1860
|
+
console.log();
|
|
1861
|
+
}
|
|
1862
|
+
if (report.summary.knowledgeSilos.length > 0) {
|
|
1863
|
+
console.log(C2.bold(` ⚠️ KNOWLEDGE SILOS: ${report.summary.knowledgeSilos.join(', ')}`));
|
|
1864
|
+
console.log();
|
|
1865
|
+
}
|
|
1866
|
+
if (report.recommendations.length > 0) {
|
|
1867
|
+
for (const r of report.recommendations)
|
|
1868
|
+
console.log(` 💡 ${r}`);
|
|
1869
|
+
}
|
|
1870
|
+
console.log();
|
|
1871
|
+
console.log(C2.dim(' 📁 Saved: ~/.fivo/cell/team-intel.json + .md'));
|
|
1872
|
+
});
|
|
1873
|
+
program
|
|
1874
|
+
.command('insights')
|
|
1875
|
+
.description('🔮 Your growth report: level assessment, trends, strengths, what to focus on next')
|
|
1876
|
+
.action(async () => {
|
|
1877
|
+
const C2 = C;
|
|
1878
|
+
const { buildInsightReport, saveInsightReport } = await Promise.resolve().then(() => __importStar(require('./insight-generator')));
|
|
1879
|
+
console.log(C2.primary(' 🔮 Generating your growth insights...\n'));
|
|
1880
|
+
const report = buildInsightReport();
|
|
1881
|
+
saveInsightReport(report);
|
|
1882
|
+
const levelIcons = { senior: '🏆', mid: '🔥', junior: '🌱', unclear: '❓' };
|
|
1883
|
+
console.log(C2.bold(` ${levelIcons[report.level.currentLevel]} CURRENT LEVEL: ${report.level.currentLevel.toUpperCase()} (${report.level.confidence}% confidence)`));
|
|
1884
|
+
if (report.level.evidence.length > 0) {
|
|
1885
|
+
for (const e of report.level.evidence)
|
|
1886
|
+
console.log(` ✅ ${e}`);
|
|
1887
|
+
}
|
|
1888
|
+
console.log();
|
|
1889
|
+
console.log(C2.bold(` ⏩ NEXT LEVEL: ${report.level.nextLevel.toUpperCase()} | ETA: ${report.level.timeToNextLevel}`));
|
|
1890
|
+
console.log();
|
|
1891
|
+
console.log(C2.bold(' 📈 TRENDS:'));
|
|
1892
|
+
for (const t of report.trends) {
|
|
1893
|
+
const d = t.direction === 'improving' ? '📈' : t.direction === 'declining' ? '📉' : t.direction === 'insufficient-data' ? '📊' : '➡️';
|
|
1894
|
+
console.log(` ${d} ${t.metric.padEnd(22)} ${t.direction.toUpperCase().padEnd(20)} ${C2.dim(t.details)}`);
|
|
1895
|
+
}
|
|
1896
|
+
console.log();
|
|
1897
|
+
if (report.strengths.length > 0) {
|
|
1898
|
+
console.log(C2.bold(` 💪 STRENGTHS:`));
|
|
1899
|
+
for (const s of report.strengths.slice(0, 5))
|
|
1900
|
+
console.log(` • ${s}`);
|
|
1901
|
+
console.log();
|
|
1902
|
+
}
|
|
1903
|
+
if (report.growthStory.length > 0) {
|
|
1904
|
+
console.log(C2.bold(' 📖 GROWTH STORY:'));
|
|
1905
|
+
for (const g of report.growthStory)
|
|
1906
|
+
console.log(` ${g}`);
|
|
1907
|
+
console.log();
|
|
1908
|
+
}
|
|
1909
|
+
if (report.nextFocus.length > 0) {
|
|
1910
|
+
console.log(C2.bold(' 🎯 FOCUS ON:'));
|
|
1911
|
+
for (const n of report.nextFocus)
|
|
1912
|
+
console.log(` 🔥 ${n}`);
|
|
1913
|
+
console.log();
|
|
1914
|
+
}
|
|
1915
|
+
console.log(C2.dim(' 📁 Saved: ~/.fivo/cell/insights.json + .md'));
|
|
1916
|
+
console.log(C2.dim(` 📊 Snapshots: ${report.snapshotCount} | Days tracked: ${report.daysTracked}`));
|
|
1917
|
+
console.log(C2.dim(` 💡 Run weekly: cell intelligence && cell journey && cell insights`));
|
|
1918
|
+
});
|
|
1919
|
+
program
|
|
1920
|
+
.command('journey')
|
|
1921
|
+
.description('📅 Your developer journey: timeline, skill progression, context chains, goals')
|
|
1922
|
+
.option('--root <dir>', 'Root directory to analyze', process.cwd())
|
|
1923
|
+
.action(async (opts) => {
|
|
1924
|
+
const C2 = C;
|
|
1925
|
+
const { buildJourneyReport, saveJourneyReport } = await Promise.resolve().then(() => __importStar(require('./journey-memory')));
|
|
1926
|
+
const startDir = opts.root || path.dirname(process.cwd());
|
|
1927
|
+
console.log(C2.primary(' 📅 Mapping your developer journey...\n'));
|
|
1928
|
+
const report = buildJourneyReport(startDir);
|
|
1929
|
+
saveJourneyReport(report);
|
|
1930
|
+
console.log(C2.bold(` 🎯 SUMMARY:`));
|
|
1931
|
+
console.log(` Active since: ${report.summary.activeSince}`);
|
|
1932
|
+
console.log(` Projects: ${report.summary.totalProjects}`);
|
|
1933
|
+
console.log(` Languages: ${report.summary.languagesLearned}`);
|
|
1934
|
+
console.log(` Commits: ${report.summary.totalCommits}`);
|
|
1935
|
+
console.log(` Growth rate: ${report.summary.growthRate}`);
|
|
1936
|
+
console.log();
|
|
1937
|
+
console.log(C2.bold(' 📅 TIMELINE (last 15 events):'));
|
|
1938
|
+
for (const e of report.timeline.slice(-15)) {
|
|
1939
|
+
const icon = e.type === 'first-use' ? '🆕' : e.type === 'milestone' ? '🏆' : e.type === 'shipped' ? '🚀' : '📍';
|
|
1940
|
+
console.log(` ${icon} ${e.date.slice(0, 10)} — ${e.detail} (${e.project})`);
|
|
1941
|
+
}
|
|
1942
|
+
console.log();
|
|
1943
|
+
console.log(C2.bold(' 📈 SKILL PROGRESSION:'));
|
|
1944
|
+
for (const s of report.skills) {
|
|
1945
|
+
const icons = { mastered: '🏆', proficient: '✅', intermediate: '📖', beginner: '🆕' };
|
|
1946
|
+
console.log(` ${icons[s.currentLevel]} ${s.area.padEnd(14)} ${s.currentLevel.toString().padEnd(12)} ${s.metrics.totalFiles} files ${s.metrics.cleanFileRatio}% clean`);
|
|
1947
|
+
}
|
|
1948
|
+
console.log();
|
|
1949
|
+
if (report.chains.length > 0) {
|
|
1950
|
+
console.log(C2.bold(' 🔗 CONTEXT CHAINS (patterns reused across projects):'));
|
|
1951
|
+
for (const c of report.chains.slice(0, 5)) {
|
|
1952
|
+
console.log(` ${c.pattern.padEnd(24)} ${c.reusedIn.length} projects · ${Math.round(c.successRate * 100)}% success`);
|
|
1953
|
+
}
|
|
1954
|
+
console.log();
|
|
1955
|
+
}
|
|
1956
|
+
if (report.goals.recommendations.length > 0) {
|
|
1957
|
+
console.log(C2.bold(' 💡 RECOMMENDATIONS:'));
|
|
1958
|
+
for (const r of report.goals.recommendations.slice(0, 4)) {
|
|
1959
|
+
console.log(` • ${r}`);
|
|
1960
|
+
}
|
|
1961
|
+
console.log();
|
|
1962
|
+
}
|
|
1963
|
+
console.log(C2.dim(' 📁 Saved: ~/.fivo/cell/journey.json + .md'));
|
|
1964
|
+
console.log(C2.dim(' 📁 History: ~/.fivo/cell/memory/journey-*.json'));
|
|
1965
|
+
});
|
|
1966
|
+
program
|
|
1967
|
+
.command('intelligence')
|
|
1968
|
+
.description('🧠 Your complete behavior profile: repeat mistakes, blind spots, bug history, decisions, tech mastery')
|
|
1969
|
+
.option('--root <dir>', 'Root directory to analyze', process.cwd())
|
|
1970
|
+
.action(async (opts) => {
|
|
1971
|
+
const C2 = C;
|
|
1972
|
+
const { buildIntelligenceReport, saveIntelligenceReport } = await Promise.resolve().then(() => __importStar(require('./behavior-intelligence')));
|
|
1973
|
+
const startDir = opts.root || process.cwd();
|
|
1974
|
+
console.log(C2.primary(' 🧠 Analyzing your developer DNA...\n'));
|
|
1975
|
+
const report = buildIntelligenceReport(startDir);
|
|
1976
|
+
saveIntelligenceReport(report);
|
|
1977
|
+
console.log(C2.bold(` 📊 ${report.projectCount} projects · ${report.totalFiles} files\n`));
|
|
1978
|
+
console.log(C2.bold(' 🔁 REPEAT MISTAKES:'));
|
|
1979
|
+
if (report.mistakes.length === 0) {
|
|
1980
|
+
console.log(C2.dim(' ✅ No repeat mistakes detected'));
|
|
1981
|
+
}
|
|
1982
|
+
else {
|
|
1983
|
+
for (const m of report.mistakes.slice(0, 5)) {
|
|
1984
|
+
const icon = m.stillHappening ? '⚠️' : '✅';
|
|
1985
|
+
console.log(` ${icon} [${m.category}] ${m.pattern}`);
|
|
1986
|
+
console.log(C2.dim(` ${m.count}x | Last: ${m.lastOccurrence.slice(0, 10)} | Still: ${m.stillHappening ? 'YES' : 'resolved'}`));
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
console.log();
|
|
1990
|
+
console.log(C2.bold(' 🎯 BLIND SPOTS:'));
|
|
1991
|
+
for (const b of report.blindSpots) {
|
|
1992
|
+
const sev = b.severity === 'high' ? '🔴' : b.severity === 'medium' ? '🟡' : '🟢';
|
|
1993
|
+
console.log(` ${sev} ${b.area.padEnd(18)} ${C2.dim(`${b.fileCount} files`)}`);
|
|
1994
|
+
console.log(C2.dim(` → ${b.fix}`));
|
|
1995
|
+
}
|
|
1996
|
+
console.log();
|
|
1997
|
+
console.log(C2.bold(' 🧩 PROBLEM-SOLVING STYLE:'));
|
|
1998
|
+
console.log(` • File org: ${report.problemSolving.fileOrganization}`);
|
|
1999
|
+
console.log(` • Docs: ${Math.round(report.problemSolving.comments.ratio * 100)}% files`);
|
|
2000
|
+
console.log(` • Functions: S:${report.problemSolving.functionSizes.small} M:${report.problemSolving.functionSizes.medium} L:${report.problemSolving.functionSizes.large} XL:${report.problemSolving.functionSizes.xlarge}`);
|
|
2001
|
+
console.log();
|
|
2002
|
+
console.log(C2.bold(' ⏰ TIME PATTERNS:'));
|
|
2003
|
+
console.log(` • Best: ${report.timePatterns.bestHours} on ${report.timePatterns.mostProductiveDay}`);
|
|
2004
|
+
console.log();
|
|
2005
|
+
console.log(C2.bold(' 🐛 BUG HISTORY:'));
|
|
2006
|
+
console.log(` • ${report.bugHistory.length} bugs, ${report.bugHistory.filter(b => b.wasReverted).length} reverted`);
|
|
2007
|
+
console.log();
|
|
2008
|
+
console.log(C2.bold(' 📋 DECISIONS:'));
|
|
2009
|
+
console.log(` • ${report.decisions.length} decisions tracked`);
|
|
2010
|
+
console.log();
|
|
2011
|
+
console.log(C2.bold(' 🗺️ TECH MASTERY:'));
|
|
2012
|
+
for (const t of report.techMastery.slice(0, 6)) {
|
|
2013
|
+
const masteryIcons = { mastered: '🏆', proficient: '✅', learning: '📖', new: '🆕' };
|
|
2014
|
+
console.log(` ${masteryIcons[t.assessment]} ${t.language.padEnd(15)} ${C2.dim(`${t.fileCount} files · ${t.lineCount.toLocaleString()} lines · ${t.assessment}`)}`);
|
|
2015
|
+
}
|
|
2016
|
+
console.log();
|
|
2017
|
+
console.log(C2.dim(' 📁 Saved: ~/.fivo/cell/intelligence.json + .md'));
|
|
2018
|
+
console.log(C2.dim(' 📁 History: ~/.fivo/cell/memory/intelligence-*.json'));
|
|
2019
|
+
console.log();
|
|
2020
|
+
console.log(C2.bold(' 💡 Cell ab tera BEST MATE ban raha hai — har run pe aur seekhega.'));
|
|
2021
|
+
});
|
|
2022
|
+
program
|
|
2023
|
+
.command('focus')
|
|
2024
|
+
.description('Your CO-FOUNDER view: which projects to KEEP, which to PAUSE, which to DELETE')
|
|
2025
|
+
.option('--root <dir>', 'Root directory to scan (defaults to parent of CWD)', process.cwd())
|
|
2026
|
+
.action(async (opts) => {
|
|
2027
|
+
const C2 = C;
|
|
2028
|
+
const { buildFocusReport, renderFocusMd } = await Promise.resolve().then(() => __importStar(require('./focus-report')));
|
|
2029
|
+
const startDir = opts.root || path.dirname(process.cwd());
|
|
2030
|
+
console.log(C2.primary(' 🎯 Cell scanning your portfolio...\n'));
|
|
2031
|
+
const report = buildFocusReport(startDir);
|
|
2032
|
+
console.log(C2.bold(' 📊 TERE 23+ PROJECTS KA STATUS:\n'));
|
|
2033
|
+
const statusEmoji = { active: '🟢', stalled: '🟡', abandoned: '🔴', fresh: '⚪' };
|
|
2034
|
+
const actionLabel = {
|
|
2035
|
+
keep: '🔥 KEEP',
|
|
2036
|
+
pause: '⏸️ PAUSE',
|
|
2037
|
+
archive: '📦 ARCHIVE',
|
|
2038
|
+
delete: '🗑️ DELETE',
|
|
2039
|
+
resurrect: '💎 RESURRECT',
|
|
2040
|
+
};
|
|
2041
|
+
const allProjects = [
|
|
2042
|
+
...report.topPicks.map(p => ({ ...p, sortOrder: 0 })),
|
|
2043
|
+
...report.shouldResurrect.map(p => ({ ...p, sortOrder: 1 })),
|
|
2044
|
+
...report.shouldPause.map(p => ({ ...p, sortOrder: 2 })),
|
|
2045
|
+
...report.shouldArchive.map(p => ({ ...p, sortOrder: 3 })),
|
|
2046
|
+
];
|
|
2047
|
+
for (const p of allProjects.sort((a, b) => a.lastModifiedDays - b.lastModifiedDays)) {
|
|
2048
|
+
console.log(` ${statusEmoji[p.status]} ${C2.bold(p.name.padEnd(35))} ${C2.dim(`${p.lastModifiedDays}d ago · ${p.totalFiles} files`)}`);
|
|
2049
|
+
console.log(` ${C2.dim(actionLabel[p.recommendedAction])} — ${p.reason}`);
|
|
2050
|
+
if (p.description)
|
|
2051
|
+
console.log(` ${C2.dim(`"${p.description}"`)}`);
|
|
2052
|
+
}
|
|
2053
|
+
console.log();
|
|
2054
|
+
console.log(C2.bold(' 💡 CELL KI ADVICE:\n'));
|
|
2055
|
+
for (const a of report.overallAdvice) {
|
|
2056
|
+
console.log(` ${a}`);
|
|
2057
|
+
}
|
|
2058
|
+
const mdPath = path.join(os.homedir(), '.fivo', 'cell', 'focus-report.md');
|
|
2059
|
+
try {
|
|
2060
|
+
const { writeFileSync, mkdirSync, existsSync } = require('fs');
|
|
2061
|
+
const dir = path.join(os.homedir(), '.fivo', 'cell');
|
|
2062
|
+
if (!existsSync(dir))
|
|
2063
|
+
mkdirSync(dir, { recursive: true });
|
|
2064
|
+
writeFileSync(mdPath, renderFocusMd(report), 'utf-8');
|
|
2065
|
+
console.log();
|
|
2066
|
+
console.log(C2.dim(` Full report: ${mdPath}`));
|
|
2067
|
+
}
|
|
2068
|
+
catch { }
|
|
2069
|
+
});
|
|
2070
|
+
program
|
|
2071
|
+
.command('install')
|
|
2072
|
+
.description('One-command setup: daemon + watcher + AI tools auto-start. Run once, forget forever.')
|
|
2073
|
+
.action(async () => {
|
|
2074
|
+
const C2 = C;
|
|
2075
|
+
console.log();
|
|
2076
|
+
console.log(C2.primary.bold(' 🔧 FIVO Cell — One-Time Setup'));
|
|
2077
|
+
console.log(C2.dim(' ─────────────────────────────────────────'));
|
|
2078
|
+
console.log();
|
|
2079
|
+
const steps = [];
|
|
2080
|
+
try {
|
|
2081
|
+
const { installService } = await Promise.resolve().then(() => __importStar(require('./daemon/lifecycle')));
|
|
2082
|
+
const r = installService();
|
|
2083
|
+
steps.push({ name: 'Auto-start at Windows logon', ok: r.success, detail: r.message });
|
|
2084
|
+
}
|
|
2085
|
+
catch (err) {
|
|
2086
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2087
|
+
steps.push({ name: 'Auto-start at Windows logon', ok: false, detail: message });
|
|
2088
|
+
}
|
|
2089
|
+
try {
|
|
2090
|
+
const { ensureDaemon } = await Promise.resolve().then(() => __importStar(require('./daemon/lifecycle')));
|
|
2091
|
+
const ok = await ensureDaemon({ silent: true });
|
|
2092
|
+
steps.push({ name: 'Daemon running now', ok, detail: ok ? 'Daemon started and healthy on port 9876' : 'Daemon failed to start' });
|
|
2093
|
+
}
|
|
2094
|
+
catch (err) {
|
|
2095
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2096
|
+
steps.push({ name: 'Daemon running now', ok: false, detail: message });
|
|
2097
|
+
}
|
|
2098
|
+
steps.push({
|
|
2099
|
+
name: 'File watcher',
|
|
2100
|
+
ok: true,
|
|
2101
|
+
detail: 'Will auto-start at every Windows logon via the watch-loop in fivo-cell-daemon.bat (respawns automatically if it ever dies). To start right now: cell start',
|
|
2102
|
+
});
|
|
2103
|
+
const onboardingMarker = path.join(os.homedir(), '.fivo', 'cell', '.onboarding-done');
|
|
2104
|
+
const existingOnboarding = path.join(os.homedir(), '.fivo', 'cell', 'onboarding.json');
|
|
2105
|
+
if (fs.existsSync(existingOnboarding) || fs.existsSync(onboardingMarker)) {
|
|
2106
|
+
steps.push({
|
|
2107
|
+
name: 'Codebase knowledge',
|
|
2108
|
+
ok: true,
|
|
2109
|
+
detail: 'Already onboarded. Run `cell rescan` to refresh.',
|
|
2110
|
+
});
|
|
2111
|
+
}
|
|
2112
|
+
else {
|
|
2113
|
+
console.log();
|
|
2114
|
+
console.log(C2.primary.bold(' 🧠 I ALREADY KNOW YOUR CODEBASE'));
|
|
2115
|
+
console.log(C2.dim(' ────────────────────────────────────────'));
|
|
2116
|
+
console.log();
|
|
2117
|
+
try {
|
|
2118
|
+
const { scanCodebase, saveOnboarding } = await Promise.resolve().then(() => __importStar(require('./onboarding-scan')));
|
|
2119
|
+
const result = scanCodebase(process.cwd(), { timeBudgetMs: 5000 });
|
|
2120
|
+
const stackTop = result.stack.slice(0, 4).map(s => `${s.name}${s.version ? ' ' + s.version : ''}`).join(' · ');
|
|
2121
|
+
const stylePatterns = result.patterns.filter(p => p.category === 'style');
|
|
2122
|
+
const styleMatch = stylePatterns.length > 0
|
|
2123
|
+
? Math.round((stylePatterns.filter(p => p.confidence > 0.5).length / stylePatterns.length) * 100)
|
|
2124
|
+
: 0;
|
|
2125
|
+
const styleTop = stylePatterns.filter(p => p.confidence > 0.5).slice(0, 3).map(p => p.description.split(' ').slice(0, 2).join(' ').toLowerCase()).join('/') || 'mixed';
|
|
2126
|
+
const archTop = result.patterns.filter(p => p.category === 'architecture' && p.confidence > 0.5).length;
|
|
2127
|
+
const testTop = result.patterns.filter(p => p.category === 'testing' && p.confidence > 0.5).length;
|
|
2128
|
+
const hubLine = result.hubs.length > 0
|
|
2129
|
+
? result.hubs.slice(0, 2).map(h => `${path.basename(h.file)} (${h.importedBy})`).join(' · ')
|
|
2130
|
+
: 'none yet';
|
|
2131
|
+
const issueLine = result.issues.length > 0
|
|
2132
|
+
? `${result.issues.length} (${result.issues.slice(0, 2).map(i => i.description.split(' ').slice(0, 4).join(' ')).join(' · ')})`
|
|
2133
|
+
: 'none';
|
|
2134
|
+
console.log(` ${C2.dim('Scanned')} ${result.filesScanned} ${C2.dim('files ·')} ${result.totalLines.toLocaleString()} ${C2.dim('lines ·')} ${result.totalFunctions} ${C2.dim('functions')}`);
|
|
2135
|
+
console.log(` ${C2.dim('Learned')} ${result.patterns.length} ${C2.dim('patterns · background scan continues...')}`);
|
|
2136
|
+
console.log();
|
|
2137
|
+
console.log(` ${C2.accent('Stack:')} ${stackTop || 'plain JS/TS'}`);
|
|
2138
|
+
console.log(` ${C2.accent('Style:')} ${styleTop} (${styleMatch}% match) · ${result.patterns.filter(p => p.category === 'style').length} patterns`);
|
|
2139
|
+
console.log(` ${C2.accent('Arch:')} ${archTop} architecture patterns detected`);
|
|
2140
|
+
console.log(` ${C2.accent('Tests:')} ${testTop} testing patterns detected`);
|
|
2141
|
+
console.log(` ${C2.accent('Hubs:')} ${hubLine}`);
|
|
2142
|
+
console.log(` ${C2.accent('Issues:')} ${issueLine}`);
|
|
2143
|
+
console.log();
|
|
2144
|
+
console.log(C2.dim(' Full scan continues in background. Run `cell status` in 30s for the complete picture.'));
|
|
2145
|
+
saveOnboarding(result);
|
|
2146
|
+
setTimeout(() => {
|
|
2147
|
+
try {
|
|
2148
|
+
const { scanCodebase: fullScan, saveOnboarding: saveFull } = require('./onboarding-scan');
|
|
2149
|
+
const full = fullScan(process.cwd(), { timeBudgetMs: 30000 });
|
|
2150
|
+
saveFull(full);
|
|
2151
|
+
try {
|
|
2152
|
+
fs.writeFileSync(onboardingMarker, new Date().toISOString(), 'utf-8');
|
|
2153
|
+
}
|
|
2154
|
+
catch { }
|
|
2155
|
+
try {
|
|
2156
|
+
const { PatternStore } = require('./core/pattern-store');
|
|
2157
|
+
const cellDir = path.join(os.homedir(), '.fivo', 'cell');
|
|
2158
|
+
const store = new PatternStore(cellDir);
|
|
2159
|
+
for (const p of full.patterns) {
|
|
2160
|
+
try {
|
|
2161
|
+
store.addOrUpdatePattern(p.category, p.description, 'codebase', 'detected', true, p.examples.slice(0, 3), 'global', 'onboarding', p.language || 'unknown');
|
|
2162
|
+
}
|
|
2163
|
+
catch { }
|
|
2164
|
+
}
|
|
2165
|
+
store.save();
|
|
2166
|
+
}
|
|
2167
|
+
catch { }
|
|
2168
|
+
}
|
|
2169
|
+
catch { }
|
|
2170
|
+
}, 100);
|
|
2171
|
+
steps.push({
|
|
2172
|
+
name: 'Codebase knowledge',
|
|
2173
|
+
ok: true,
|
|
2174
|
+
detail: `${result.patterns.length} patterns learned from ${result.filesScanned} files. Full scan continues in background.`,
|
|
2175
|
+
});
|
|
2176
|
+
}
|
|
2177
|
+
catch (err) {
|
|
2178
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2179
|
+
steps.push({ name: 'Codebase knowledge', ok: false, detail: message });
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
try {
|
|
2183
|
+
const r = runConnect({ silent: true });
|
|
2184
|
+
steps.push({ name: 'AI tools configured', ok: true, detail: r.targets.length > 0 ? `Configured: ${r.targets.join(', ')}` : 'All 5 AI tools already configured' });
|
|
2185
|
+
}
|
|
2186
|
+
catch (err) {
|
|
2187
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2188
|
+
steps.push({ name: 'AI tools configured', ok: false, detail: message });
|
|
2189
|
+
}
|
|
2190
|
+
for (const s of steps) {
|
|
2191
|
+
const icon = s.ok ? C2.success(' ✅') : C2.warn(' ⚠️ ');
|
|
2192
|
+
console.log(`${icon} ${s.name}`);
|
|
2193
|
+
console.log(C2.dim(` ${s.detail}`));
|
|
2194
|
+
}
|
|
2195
|
+
console.log();
|
|
2196
|
+
console.log(C2.primary.bold(' 🎉 Setup complete. You never need to run this again.'));
|
|
2197
|
+
console.log();
|
|
2198
|
+
console.log(C2.info(' Anytime you want to see what Cell learned:'));
|
|
2199
|
+
console.log(C2.primary.bold(' cell status'));
|
|
2200
|
+
console.log();
|
|
2201
|
+
console.log(C2.dim(' Cell is now invisible infrastructure:'));
|
|
2202
|
+
console.log(C2.dim(' • Daemon auto-starts at every Windows logon'));
|
|
2203
|
+
console.log(C2.dim(' • Watcher auto-respawns if it ever dies'));
|
|
2204
|
+
console.log(C2.dim(' • AI tools can use 30 MCP tools on demand'));
|
|
2205
|
+
console.log(C2.dim(' • Any `cell` command auto-starts the daemon if needed'));
|
|
2206
|
+
console.log();
|
|
2207
|
+
});
|
|
2208
|
+
daemonCmd
|
|
2209
|
+
.command('uninstall-service')
|
|
2210
|
+
.description('Remove Windows scheduled task')
|
|
2211
|
+
.action(async () => {
|
|
2212
|
+
const { uninstallService } = await Promise.resolve().then(() => __importStar(require('./daemon/lifecycle')));
|
|
2213
|
+
const r = uninstallService();
|
|
2214
|
+
console.log(r.success ? `✅ ${r.message}` : `❌ ${r.message}`);
|
|
2215
|
+
});
|
|
2216
|
+
daemonCmd
|
|
2217
|
+
.command('service-status')
|
|
2218
|
+
.description('Check Windows scheduled task status')
|
|
2219
|
+
.action(async () => {
|
|
2220
|
+
const { serviceStatus } = await Promise.resolve().then(() => __importStar(require('./daemon/lifecycle')));
|
|
2221
|
+
const s = serviceStatus();
|
|
2222
|
+
if (!s.installed) {
|
|
2223
|
+
console.log(`❌ Service '${s.taskName}' is NOT installed. Run: cell daemon install-service`);
|
|
2224
|
+
}
|
|
2225
|
+
else if (s.running) {
|
|
2226
|
+
console.log(`✅ Service '${s.taskName}' is INSTALLED and RUNNING (auto-restart on crash).`);
|
|
2227
|
+
}
|
|
2228
|
+
else {
|
|
2229
|
+
console.log(`⚠️ Service '${s.taskName}' is INSTALLED but not running.`);
|
|
2230
|
+
}
|
|
2231
|
+
});
|
|
1446
2232
|
// ─── Top-level start/stop shortcuts ────────────────────
|
|
1447
2233
|
program
|
|
1448
2234
|
.command('start')
|
|
@@ -1454,6 +2240,11 @@ program
|
|
|
1454
2240
|
const result = await startDaemon();
|
|
1455
2241
|
console.log(C.success(`✅ Daemon started (PID: ${result.pid}, Port: ${result.port})`));
|
|
1456
2242
|
console.log(C.info(` Health: http://localhost:${result.port}/health`));
|
|
2243
|
+
try {
|
|
2244
|
+
const { firstRunGreeting } = await Promise.resolve().then(() => __importStar(require('./first-run')));
|
|
2245
|
+
await firstRunGreeting();
|
|
2246
|
+
}
|
|
2247
|
+
catch { }
|
|
1457
2248
|
// Auto-start file watcher in background
|
|
1458
2249
|
try {
|
|
1459
2250
|
const scriptPath = process.argv[1];
|
|
@@ -1468,6 +2259,20 @@ program
|
|
|
1468
2259
|
catch {
|
|
1469
2260
|
console.log(C.dim('\n Run `cell watch` manually for auto-learning'));
|
|
1470
2261
|
}
|
|
2262
|
+
// Auto-start MCP server in background
|
|
2263
|
+
try {
|
|
2264
|
+
const scriptPath = process.argv[1];
|
|
2265
|
+
(0, child_process_1.spawn)('node', [scriptPath, 'mcp'], {
|
|
2266
|
+
detached: true,
|
|
2267
|
+
stdio: 'ignore',
|
|
2268
|
+
cwd: process.cwd(),
|
|
2269
|
+
}).unref();
|
|
2270
|
+
console.log(C.success('\n🔌 MCP Server: Running on http://localhost:9877/mcp'));
|
|
2271
|
+
console.log(C.dim(' Connect Gemini CLI, Codex CLI, Cursor, Claude Code'));
|
|
2272
|
+
}
|
|
2273
|
+
catch {
|
|
2274
|
+
console.log(C.dim('\n Run `cell mcp` manually for AI tool connections'));
|
|
2275
|
+
}
|
|
1471
2276
|
console.log(C.dim(' Stop daemon: cell stop\n'));
|
|
1472
2277
|
}
|
|
1473
2278
|
catch (err) {
|
|
@@ -1483,6 +2288,147 @@ program
|
|
|
1483
2288
|
const result = stopDaemon();
|
|
1484
2289
|
console.log(result.success ? C.success(`✅ ${result.message}`) : C.warn(`⚠️ ${result.message}`));
|
|
1485
2290
|
});
|
|
2291
|
+
program
|
|
2292
|
+
.command('mcp')
|
|
2293
|
+
.description('Start the MCP server (JSON-RPC on port 9877) for AI tool connections')
|
|
2294
|
+
.option('-p, --port <port>', 'Port (default: 9877)', '9877')
|
|
2295
|
+
.action((options) => {
|
|
2296
|
+
const port = parseInt(options.port, 10);
|
|
2297
|
+
const { startMCPServer, TOOLS, RESOURCES } = require('./mcp-server');
|
|
2298
|
+
startMCPServer(port);
|
|
2299
|
+
console.log('MCP server running. Available tools: ' + TOOLS.length + ' | Resources: ' + RESOURCES.length);
|
|
2300
|
+
console.log('Connect your AI tools to: http://localhost:' + port + '/mcp');
|
|
2301
|
+
});
|
|
2302
|
+
function runConnect(opts = {}) {
|
|
2303
|
+
const home = os.homedir();
|
|
2304
|
+
const cursorDir = path.join(process.cwd(), '.cursor');
|
|
2305
|
+
const cursorFile = path.join(cursorDir, 'mcp.json');
|
|
2306
|
+
const claudeFile = path.join(process.cwd(), '.mcp.json');
|
|
2307
|
+
const dotCursorFile = path.join(home, '.cursor', 'mcp.json');
|
|
2308
|
+
let created = 0;
|
|
2309
|
+
const targets = [];
|
|
2310
|
+
const cellMCPConfig = {
|
|
2311
|
+
mcpServers: {
|
|
2312
|
+
cell: {
|
|
2313
|
+
type: 'url',
|
|
2314
|
+
url: 'http://localhost:9877/mcp',
|
|
2315
|
+
description: 'FIVO Cell — anticipatory intelligence engine. 30 tools, 8 resources.',
|
|
2316
|
+
},
|
|
2317
|
+
},
|
|
2318
|
+
};
|
|
2319
|
+
const json = JSON.stringify(cellMCPConfig, null, 2);
|
|
2320
|
+
if (!fs.existsSync(cursorFile)) {
|
|
2321
|
+
if (!fs.existsSync(cursorDir))
|
|
2322
|
+
fs.mkdirSync(cursorDir, { recursive: true });
|
|
2323
|
+
fs.writeFileSync(cursorFile, json);
|
|
2324
|
+
if (!opts.silent)
|
|
2325
|
+
console.log(C.success('✅ .cursor/mcp.json created'));
|
|
2326
|
+
created++;
|
|
2327
|
+
targets.push('Cursor (project)');
|
|
2328
|
+
}
|
|
2329
|
+
if (!fs.existsSync(dotCursorFile)) {
|
|
2330
|
+
const globalCursorDir = path.join(home, '.cursor');
|
|
2331
|
+
if (!fs.existsSync(globalCursorDir))
|
|
2332
|
+
fs.mkdirSync(globalCursorDir, { recursive: true });
|
|
2333
|
+
fs.writeFileSync(dotCursorFile, json);
|
|
2334
|
+
if (!opts.silent)
|
|
2335
|
+
console.log(C.success('✅ ~/.cursor/mcp.json created (global)'));
|
|
2336
|
+
created++;
|
|
2337
|
+
targets.push('Cursor (global)');
|
|
2338
|
+
}
|
|
2339
|
+
if (!fs.existsSync(claudeFile)) {
|
|
2340
|
+
fs.writeFileSync(claudeFile, json);
|
|
2341
|
+
if (!opts.silent)
|
|
2342
|
+
console.log(C.success('✅ .mcp.json created (Claude Code)'));
|
|
2343
|
+
created++;
|
|
2344
|
+
targets.push('Claude Code');
|
|
2345
|
+
}
|
|
2346
|
+
const geminiDir = path.join(home, '.gemini');
|
|
2347
|
+
const geminiFile = path.join(geminiDir, 'settings.json');
|
|
2348
|
+
const antigravityFile = path.join(geminiDir, 'config', 'mcp_config.json');
|
|
2349
|
+
const cellMcpConfig = { transport: 'url', serverURL: 'http://localhost:9877/mcp' };
|
|
2350
|
+
let geminiUpdated = false;
|
|
2351
|
+
if (fs.existsSync(geminiFile)) {
|
|
2352
|
+
let gemini = JSON.parse(fs.readFileSync(geminiFile, 'utf-8'));
|
|
2353
|
+
if (!gemini.mcpServers)
|
|
2354
|
+
gemini.mcpServers = {};
|
|
2355
|
+
if (!gemini.mcpServers.cell) {
|
|
2356
|
+
gemini.mcpServers.cell = cellMcpConfig;
|
|
2357
|
+
fs.writeFileSync(geminiFile, JSON.stringify(gemini, null, 2));
|
|
2358
|
+
geminiUpdated = true;
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
else {
|
|
2362
|
+
if (!fs.existsSync(geminiDir))
|
|
2363
|
+
fs.mkdirSync(geminiDir, { recursive: true });
|
|
2364
|
+
fs.writeFileSync(geminiFile, JSON.stringify({
|
|
2365
|
+
mcpServers: { cell: cellMcpConfig },
|
|
2366
|
+
}, null, 2));
|
|
2367
|
+
geminiUpdated = true;
|
|
2368
|
+
}
|
|
2369
|
+
if (geminiUpdated) {
|
|
2370
|
+
if (!opts.silent)
|
|
2371
|
+
console.log(C.success('✅ ~/.gemini/settings.json created/updated'));
|
|
2372
|
+
created++;
|
|
2373
|
+
targets.push('Gemini CLI');
|
|
2374
|
+
}
|
|
2375
|
+
const antigravityDir = path.dirname(antigravityFile);
|
|
2376
|
+
if (!fs.existsSync(antigravityDir))
|
|
2377
|
+
fs.mkdirSync(antigravityDir, { recursive: true });
|
|
2378
|
+
let antiUpdated = false;
|
|
2379
|
+
if (fs.existsSync(antigravityFile)) {
|
|
2380
|
+
let anti = JSON.parse(fs.readFileSync(antigravityFile, 'utf-8'));
|
|
2381
|
+
if (!anti.mcpServers)
|
|
2382
|
+
anti.mcpServers = {};
|
|
2383
|
+
if (!anti.mcpServers.cell) {
|
|
2384
|
+
anti.mcpServers.cell = { serverURL: 'http://localhost:9877/mcp' };
|
|
2385
|
+
fs.writeFileSync(antigravityFile, JSON.stringify(anti, null, 2));
|
|
2386
|
+
antiUpdated = true;
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
else {
|
|
2390
|
+
fs.writeFileSync(antigravityFile, JSON.stringify({
|
|
2391
|
+
mcpServers: { cell: { serverURL: 'http://localhost:9877/mcp' } },
|
|
2392
|
+
}, null, 2));
|
|
2393
|
+
antiUpdated = true;
|
|
2394
|
+
}
|
|
2395
|
+
if (antiUpdated) {
|
|
2396
|
+
if (!opts.silent)
|
|
2397
|
+
console.log(C.success('✅ ~/.gemini/config/mcp_config.json created/updated (Antigravity)'));
|
|
2398
|
+
created++;
|
|
2399
|
+
targets.push('Antigravity');
|
|
2400
|
+
}
|
|
2401
|
+
const codexDir = path.join(home, '.codex');
|
|
2402
|
+
const codexFile = path.join(codexDir, 'config.json');
|
|
2403
|
+
if (!fs.existsSync(codexFile)) {
|
|
2404
|
+
if (!fs.existsSync(codexDir))
|
|
2405
|
+
fs.mkdirSync(codexDir, { recursive: true });
|
|
2406
|
+
fs.writeFileSync(codexFile, JSON.stringify({
|
|
2407
|
+
mcp: { servers: { cell: { type: 'url', url: 'http://localhost:9877/mcp' } } },
|
|
2408
|
+
}, null, 2));
|
|
2409
|
+
if (!opts.silent)
|
|
2410
|
+
console.log(C.success('✅ ~/.codex/config.json created'));
|
|
2411
|
+
created++;
|
|
2412
|
+
targets.push('Codex CLI');
|
|
2413
|
+
}
|
|
2414
|
+
if (!opts.silent) {
|
|
2415
|
+
console.log();
|
|
2416
|
+
if (created > 0) {
|
|
2417
|
+
console.log(C.accent(`${created} config files created. Restart your AI tools to connect.`));
|
|
2418
|
+
}
|
|
2419
|
+
else {
|
|
2420
|
+
console.log(C.dim('All config files already exist. Cell is ready.'));
|
|
2421
|
+
}
|
|
2422
|
+
console.log(C.dim('Run `cell start` first if daemon + MCP server are not running.'));
|
|
2423
|
+
}
|
|
2424
|
+
return { created, targets };
|
|
2425
|
+
}
|
|
2426
|
+
program
|
|
2427
|
+
.command('connect')
|
|
2428
|
+
.description('Auto-generate MCP config files for detected AI tools (Cursor, Claude Code, Gemini)')
|
|
2429
|
+
.action(() => {
|
|
2430
|
+
runConnect();
|
|
2431
|
+
});
|
|
1486
2432
|
program
|
|
1487
2433
|
.command('cloud')
|
|
1488
2434
|
.description('Manage cloud sync')
|
|
@@ -1602,7 +2548,32 @@ program
|
|
|
1602
2548
|
projectId: path.basename(process.cwd()),
|
|
1603
2549
|
};
|
|
1604
2550
|
capture.captureEditDiff(previous, current, ctx);
|
|
1605
|
-
const
|
|
2551
|
+
const daemonUrl = process.env.CELL_DAEMON_URL || 'http://localhost:9876';
|
|
2552
|
+
try {
|
|
2553
|
+
const postData = JSON.stringify({
|
|
2554
|
+
type: 'edit_diff',
|
|
2555
|
+
originalCode: previous,
|
|
2556
|
+
editedCode: current,
|
|
2557
|
+
context: ctx,
|
|
2558
|
+
});
|
|
2559
|
+
const url = new URL(`${daemonUrl}/signal`);
|
|
2560
|
+
const req = require('http').request({
|
|
2561
|
+
hostname: url.hostname,
|
|
2562
|
+
port: url.port || 9876,
|
|
2563
|
+
path: url.pathname,
|
|
2564
|
+
method: 'POST',
|
|
2565
|
+
headers: {
|
|
2566
|
+
'Content-Type': 'application/json',
|
|
2567
|
+
'Content-Length': Buffer.byteLength(postData),
|
|
2568
|
+
},
|
|
2569
|
+
timeout: 3000,
|
|
2570
|
+
}, () => { });
|
|
2571
|
+
req.on('error', () => { });
|
|
2572
|
+
req.write(postData);
|
|
2573
|
+
req.end();
|
|
2574
|
+
}
|
|
2575
|
+
catch { }
|
|
2576
|
+
const result = cascade.extract(previous, current, lang);
|
|
1606
2577
|
const spots = blindSpots.analyze(current, lang);
|
|
1607
2578
|
naming.analyze(current);
|
|
1608
2579
|
structure.analyze(current);
|
|
@@ -1786,6 +2757,1209 @@ program
|
|
|
1786
2757
|
console.log(C.success('\n ✅ Auto-start disabled\n'));
|
|
1787
2758
|
}
|
|
1788
2759
|
}));
|
|
2760
|
+
// ─── Database Management ──────────────────────────────
|
|
2761
|
+
program
|
|
2762
|
+
.command('migrate')
|
|
2763
|
+
.description('Migrate all JSON data to SQLite (idempotent)')
|
|
2764
|
+
.action(async () => {
|
|
2765
|
+
const spinner = (await Promise.resolve().then(() => __importStar(require('ora')))).default('Migrating JSON → SQLite...').start();
|
|
2766
|
+
try {
|
|
2767
|
+
const { initializeDatabase, migrateJsonToSqlite } = await Promise.resolve().then(() => __importStar(require('./core/database')));
|
|
2768
|
+
initializeDatabase();
|
|
2769
|
+
const stats = migrateJsonToSqlite();
|
|
2770
|
+
spinner.succeed(`Migrated ${stats.total} records`);
|
|
2771
|
+
console.log(C.dim(`\n 📊 patterns: ${stats.patterns}`));
|
|
2772
|
+
console.log(C.dim(` 📊 scans: ${stats.scans}`));
|
|
2773
|
+
console.log(C.dim(` 📊 behavior events: ${stats.behaviorEvents}`));
|
|
2774
|
+
console.log(C.dim(` 📊 journey events: ${stats.journeyEvents}`));
|
|
2775
|
+
console.log(C.dim(` 📊 skills: ${stats.skills}`));
|
|
2776
|
+
console.log(C.dim(` 📊 collaborators: ${stats.collaborators}`));
|
|
2777
|
+
console.log(C.dim(` 📊 silos: ${stats.silos}`));
|
|
2778
|
+
console.log(C.dim(` 📊 community: ${stats.communitySignals}`));
|
|
2779
|
+
console.log(C.dim(` 📊 projects: ${stats.projects}`));
|
|
2780
|
+
console.log(C.dim(` 📊 insights: ${stats.insights}`));
|
|
2781
|
+
console.log(C.dim(` 📊 config: ${stats.configEntries}`));
|
|
2782
|
+
console.log(C.dim(` 📊 user profiles: ${stats.userProfiles}`));
|
|
2783
|
+
console.log(C.success(`\n ✅ Migration complete. cell.db now has all your data.`));
|
|
2784
|
+
console.log(C.dim(` 📁 ~/.fivo/cell/cell.db\n`));
|
|
2785
|
+
}
|
|
2786
|
+
catch (e) {
|
|
2787
|
+
spinner.fail(`Migration failed: ${e.message}`);
|
|
2788
|
+
}
|
|
2789
|
+
});
|
|
2790
|
+
program
|
|
2791
|
+
.command('db-init')
|
|
2792
|
+
.description('Initialize SQLite database (first-run setup)')
|
|
2793
|
+
.action(async () => {
|
|
2794
|
+
try {
|
|
2795
|
+
const { initializeDatabase, getDatabaseStats } = await Promise.resolve().then(() => __importStar(require('./core/database')));
|
|
2796
|
+
initializeDatabase();
|
|
2797
|
+
const stats = getDatabaseStats();
|
|
2798
|
+
const tableCount = Object.keys(stats).filter(k => k !== 'db_path' && k !== 'db_size_bytes').length;
|
|
2799
|
+
console.log(C.success(`\n ✅ Database initialized: ${tableCount} tables\n`));
|
|
2800
|
+
console.log(C.dim(` 📁 ${stats['db_path']}`));
|
|
2801
|
+
console.log(C.dim(` 💾 ${(stats['db_size_bytes'] / 1024).toFixed(1)} KB\n`));
|
|
2802
|
+
}
|
|
2803
|
+
catch (e) {
|
|
2804
|
+
console.log(C.error(`\n ❌ DB init failed: ${e.message}\n`));
|
|
2805
|
+
}
|
|
2806
|
+
});
|
|
2807
|
+
program
|
|
2808
|
+
.command('db-stats')
|
|
2809
|
+
.description('Show SQLite database statistics')
|
|
2810
|
+
.action(async () => {
|
|
2811
|
+
try {
|
|
2812
|
+
const { initializeDatabase, getDatabaseStats } = await Promise.resolve().then(() => __importStar(require('./core/database')));
|
|
2813
|
+
initializeDatabase();
|
|
2814
|
+
const stats = getDatabaseStats();
|
|
2815
|
+
console.log(C.bold('\n 📊 Cell Database Statistics\n'));
|
|
2816
|
+
for (const [table, info] of Object.entries(stats)) {
|
|
2817
|
+
if (table === 'db_path' || table === 'db_size_bytes')
|
|
2818
|
+
continue;
|
|
2819
|
+
const { rows } = info;
|
|
2820
|
+
console.log(C.dim(` ${table.padEnd(25)} ${rows} rows`));
|
|
2821
|
+
}
|
|
2822
|
+
console.log(C.dim(`\n 📁 ${stats['db_path']}`));
|
|
2823
|
+
console.log(C.dim(` 💾 ${(stats['db_size_bytes'] / 1024).toFixed(1)} KB`));
|
|
2824
|
+
console.log('');
|
|
2825
|
+
}
|
|
2826
|
+
catch (e) {
|
|
2827
|
+
console.log(C.error(`\n ❌ DB error: ${e.message}\n`));
|
|
2828
|
+
}
|
|
2829
|
+
});
|
|
2830
|
+
program
|
|
2831
|
+
.command('backup')
|
|
2832
|
+
.description('Backup cell.db to timestamped file')
|
|
2833
|
+
.action(async () => {
|
|
2834
|
+
try {
|
|
2835
|
+
const { initializeDatabase, backupDatabase } = await Promise.resolve().then(() => __importStar(require('./core/database')));
|
|
2836
|
+
initializeDatabase();
|
|
2837
|
+
const backupPath = backupDatabase();
|
|
2838
|
+
console.log(C.success(`\n ✅ Backup saved: ${backupPath}\n`));
|
|
2839
|
+
}
|
|
2840
|
+
catch (e) {
|
|
2841
|
+
console.log(C.error(`\n ❌ Backup failed: ${e.message}\n`));
|
|
2842
|
+
}
|
|
2843
|
+
});
|
|
2844
|
+
program
|
|
2845
|
+
.command('db-optimize')
|
|
2846
|
+
.description('VACUUM, ANALYZE, and check DB integrity')
|
|
2847
|
+
.action(async () => {
|
|
2848
|
+
try {
|
|
2849
|
+
const { initializeDatabase, optimizeDatabase } = await Promise.resolve().then(() => __importStar(require('./core/database')));
|
|
2850
|
+
initializeDatabase();
|
|
2851
|
+
const stats = optimizeDatabase();
|
|
2852
|
+
console.log(C.success('\n ✅ Database optimized\n'));
|
|
2853
|
+
console.log(C.dim(` 💾 ${(stats['db_size_bytes'] / 1024).toFixed(1)} KB\n`));
|
|
2854
|
+
}
|
|
2855
|
+
catch (e) {
|
|
2856
|
+
console.log(C.error(`\n ❌ Optimize failed: ${e.message}\n`));
|
|
2857
|
+
}
|
|
2858
|
+
});
|
|
2859
|
+
program
|
|
2860
|
+
.command('db-export')
|
|
2861
|
+
.description('Export SQLite data to JSON for debugging')
|
|
2862
|
+
.action(async () => {
|
|
2863
|
+
try {
|
|
2864
|
+
const { initializeDatabase, getDb } = await Promise.resolve().then(() => __importStar(require('./core/database')));
|
|
2865
|
+
initializeDatabase();
|
|
2866
|
+
const db = getDb();
|
|
2867
|
+
const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").all();
|
|
2868
|
+
const exportDir = path.join(os.homedir(), '.fivo', 'cell', 'exports');
|
|
2869
|
+
if (!fs.existsSync(exportDir))
|
|
2870
|
+
fs.mkdirSync(exportDir, { recursive: true });
|
|
2871
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
2872
|
+
for (const { name } of tables) {
|
|
2873
|
+
try {
|
|
2874
|
+
const rows = db.prepare(`SELECT * FROM "${name}" LIMIT 1000`).all();
|
|
2875
|
+
fs.writeFileSync(path.join(exportDir, `${name}-${timestamp}.json`), JSON.stringify(rows, null, 2));
|
|
2876
|
+
}
|
|
2877
|
+
catch { /* skip tables that error */ }
|
|
2878
|
+
}
|
|
2879
|
+
console.log(C.success(`\n ✅ Exported to: ${exportDir}\n`));
|
|
2880
|
+
}
|
|
2881
|
+
catch (e) {
|
|
2882
|
+
console.log(C.error(`\n ❌ Export failed: ${e.message}\n`));
|
|
2883
|
+
}
|
|
2884
|
+
});
|
|
2885
|
+
// ─── Session Memory ───────────────────────────────────
|
|
2886
|
+
program
|
|
2887
|
+
.command('sessions')
|
|
2888
|
+
.description('Show recent cross-tool sessions')
|
|
2889
|
+
.option('-t, --tool <name>', 'Filter by tool (cursor, claude, windsurf, etc.)')
|
|
2890
|
+
.option('-l, --limit <n>', 'Max sessions to show', '10')
|
|
2891
|
+
.action(async (opts) => {
|
|
2892
|
+
try {
|
|
2893
|
+
const { SessionMemory } = await Promise.resolve().then(() => __importStar(require('./core/session-memory')));
|
|
2894
|
+
const sm = new SessionMemory();
|
|
2895
|
+
const sessions = opts.tool
|
|
2896
|
+
? sm.getSessionsByTool(opts.tool, Number(opts.limit))
|
|
2897
|
+
: sm.getRecentSessions(Number(opts.limit));
|
|
2898
|
+
if (sessions.length === 0) {
|
|
2899
|
+
console.log(C.dim('\n 📭 No sessions recorded yet. Sessions auto-record when daemon runs.\n'));
|
|
2900
|
+
return;
|
|
2901
|
+
}
|
|
2902
|
+
console.log(C.bold(`\n 🕐 Recent Sessions (${sessions.length})\n`));
|
|
2903
|
+
for (const s of sessions) {
|
|
2904
|
+
const tool = C.primary(s.toolName.padEnd(12));
|
|
2905
|
+
const project = C.warn(s.project.padEnd(20));
|
|
2906
|
+
const start = C.dim(formatTime(s.startTime));
|
|
2907
|
+
const decisions = s.keyDecisions.length > 0 ? C.dim(` | ${s.keyDecisions.length} decisions`) : '';
|
|
2908
|
+
const files = s.filesTouched.length > 0 ? C.dim(` | ${s.filesTouched.length} files`) : '';
|
|
2909
|
+
console.log(` ${tool} ${project} ${start}${decisions}${files}`);
|
|
2910
|
+
}
|
|
2911
|
+
const stats = sm.getSessionStats();
|
|
2912
|
+
console.log(C.dim(`\n 📊 ${stats.totalSessions} sessions across ${stats.byTool?.length || 0} tools`));
|
|
2913
|
+
console.log(C.dim(` ⏱ Avg session: ${stats.avgSessionMinutes}m\n`));
|
|
2914
|
+
}
|
|
2915
|
+
catch (e) {
|
|
2916
|
+
console.log(C.error(`\n ❌ ${e.message}\n`));
|
|
2917
|
+
}
|
|
2918
|
+
});
|
|
2919
|
+
program
|
|
2920
|
+
.command('search-sessions')
|
|
2921
|
+
.description('Search past sessions for decisions, files, or context')
|
|
2922
|
+
.argument('<query>', 'Search query (e.g. "auth", "payment", "webhook")')
|
|
2923
|
+
.action(async (query) => {
|
|
2924
|
+
try {
|
|
2925
|
+
const { SessionMemory } = await Promise.resolve().then(() => __importStar(require('./core/session-memory')));
|
|
2926
|
+
const sm = new SessionMemory();
|
|
2927
|
+
const results = sm.searchSessions(query);
|
|
2928
|
+
if (results.length === 0) {
|
|
2929
|
+
console.log(C.dim(`\n 🔍 No sessions found matching "${query}"\n`));
|
|
2930
|
+
return;
|
|
2931
|
+
}
|
|
2932
|
+
console.log(C.bold(`\n 🔍 "${query}" found in ${results.length} sessions\n`));
|
|
2933
|
+
for (const r of results) {
|
|
2934
|
+
console.log(` ${C.primary(r.session.toolName.padEnd(12))} ${C.warn(r.session.project.padEnd(20))} ${C.dim(formatTime(r.session.startTime))}`);
|
|
2935
|
+
for (const m of r.matches) {
|
|
2936
|
+
console.log(C.dim(` ↳ ${m.slice(0, 100)}`));
|
|
2937
|
+
}
|
|
2938
|
+
console.log('');
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
catch (e) {
|
|
2942
|
+
console.log(C.error(`\n ❌ ${e.message}\n`));
|
|
2943
|
+
}
|
|
2944
|
+
});
|
|
2945
|
+
program
|
|
2946
|
+
.command('bugs')
|
|
2947
|
+
.description('Show bug history and repeat mistakes')
|
|
2948
|
+
.option('-p, --project <name>', 'Filter by project')
|
|
2949
|
+
.action(async (opts) => {
|
|
2950
|
+
try {
|
|
2951
|
+
const { SessionMemory } = await Promise.resolve().then(() => __importStar(require('./core/session-memory')));
|
|
2952
|
+
const sm = new SessionMemory();
|
|
2953
|
+
const bugs = sm.getBugHistory(opts.project);
|
|
2954
|
+
const repeats = sm.getRepeatBugs();
|
|
2955
|
+
if (repeats.length > 0) {
|
|
2956
|
+
console.log(C.bold('\n 🐛 REPEAT MISTAKES\n'));
|
|
2957
|
+
for (const r of repeats) {
|
|
2958
|
+
console.log(` ${C.error('⚠')} ${r.description.slice(0, 80)}${C.dim(` (${r.count}x, ${r.files.length} files)`)}`);
|
|
2959
|
+
}
|
|
2960
|
+
}
|
|
2961
|
+
else {
|
|
2962
|
+
console.log(C.dim('\n 🎉 No repeat bugs detected yet.\n'));
|
|
2963
|
+
}
|
|
2964
|
+
if (bugs.length > 0) {
|
|
2965
|
+
console.log(C.bold(`\n 📋 Bug History (${bugs.length})\n`));
|
|
2966
|
+
for (const b of bugs.slice(0, 10)) {
|
|
2967
|
+
console.log(` ${C.dim(formatTime(b.occurredAt))} ${b.location.slice(0, 30).padEnd(32)} ${b.rootCause.slice(0, 40)}`);
|
|
2968
|
+
}
|
|
2969
|
+
console.log('');
|
|
2970
|
+
}
|
|
2971
|
+
}
|
|
2972
|
+
catch (e) {
|
|
2973
|
+
console.log(C.error(`\n ❌ ${e.message}\n`));
|
|
2974
|
+
}
|
|
2975
|
+
});
|
|
2976
|
+
program
|
|
2977
|
+
.command('decisions')
|
|
2978
|
+
.description('Show decision history — technologies chosen, outcomes')
|
|
2979
|
+
.option('-p, --project <name>', 'Filter by project')
|
|
2980
|
+
.action(async (opts) => {
|
|
2981
|
+
try {
|
|
2982
|
+
const { SessionMemory } = await Promise.resolve().then(() => __importStar(require('./core/session-memory')));
|
|
2983
|
+
const sm = new SessionMemory();
|
|
2984
|
+
const decisions = sm.getDecisionHistory(opts.project);
|
|
2985
|
+
const summary = sm.getDecisionSummary();
|
|
2986
|
+
if (summary.length > 0) {
|
|
2987
|
+
console.log(C.bold('\n 📊 Decision Summary\n'));
|
|
2988
|
+
for (const s of summary) {
|
|
2989
|
+
const pct = s.wasRightPct >= 70 ? C.success(`${s.wasRightPct}%`) : s.wasRightPct >= 40 ? C.warn(`${s.wasRightPct}%`) : C.error(`${s.wasRightPct}%`);
|
|
2990
|
+
console.log(` ${C.primary(s.technology.padEnd(20))} ${s.times}x chosen | ${pct} right`);
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
if (decisions.length > 0) {
|
|
2994
|
+
console.log(C.bold(`\n 📜 Decision History (${decisions.length})\n`));
|
|
2995
|
+
for (const d of decisions.slice(0, 10)) {
|
|
2996
|
+
const icon = d.wasRight === true ? C.success('✅') : d.wasRight === false ? C.error('❌') : C.dim('⬜');
|
|
2997
|
+
console.log(` ${icon} ${C.primary(d.technology.padEnd(20))} ${d.reason.slice(0, 50)}${C.dim(` | ${formatTime(d.createdAt)}`)}`);
|
|
2998
|
+
}
|
|
2999
|
+
console.log('');
|
|
3000
|
+
}
|
|
3001
|
+
else {
|
|
3002
|
+
console.log(C.dim('\n 📭 No decisions recorded yet.\n'));
|
|
3003
|
+
}
|
|
3004
|
+
}
|
|
3005
|
+
catch (e) {
|
|
3006
|
+
console.log(C.error(`\n ❌ ${e.message}\n`));
|
|
3007
|
+
}
|
|
3008
|
+
});
|
|
3009
|
+
function formatTime(iso) {
|
|
3010
|
+
try {
|
|
3011
|
+
const d = new Date(iso);
|
|
3012
|
+
return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });
|
|
3013
|
+
}
|
|
3014
|
+
catch {
|
|
3015
|
+
return iso.slice(0, 16);
|
|
3016
|
+
}
|
|
3017
|
+
}
|
|
3018
|
+
// ─── Context Injection ────────────────────────────────
|
|
3019
|
+
program
|
|
3020
|
+
.command('context')
|
|
3021
|
+
.description('Generate @cell context block for AI tools')
|
|
3022
|
+
.option('-p, --project <path>', 'Project path for specific context')
|
|
3023
|
+
.option('-t, --tool <name>', 'AI tool: cursor, claude, windsurf, copilot, antigravity')
|
|
3024
|
+
.option('-c, --compact', 'Compact format for prompt injection')
|
|
3025
|
+
.action(async (opts) => {
|
|
3026
|
+
try {
|
|
3027
|
+
const { initializeDatabase } = await Promise.resolve().then(() => __importStar(require('./core/database')));
|
|
3028
|
+
const { buildContext, formatContextForInjection } = await Promise.resolve().then(() => __importStar(require('./core/prompt-builder')));
|
|
3029
|
+
initializeDatabase();
|
|
3030
|
+
const ctx = buildContext(opts.project, opts.tool);
|
|
3031
|
+
const text = formatContextForInjection(ctx, opts.compact);
|
|
3032
|
+
console.log(C.bold('\n 🧠 @cell Context Block\n'));
|
|
3033
|
+
console.log(C.dim(' ─────────────────────────────────────────'));
|
|
3034
|
+
console.log(text.split('\n').map((l) => ' ' + l).join('\n'));
|
|
3035
|
+
console.log(C.dim('\n ─────────────────────────────────────────'));
|
|
3036
|
+
console.log(C.success(` ✅ Use @cell in any AI tool — it already knows you.`));
|
|
3037
|
+
console.log(C.dim(` 💡 Tip: Copy this into Cursor / Claude Code / Windsurf\n`));
|
|
3038
|
+
}
|
|
3039
|
+
catch (e) {
|
|
3040
|
+
console.log(C.error(`\n ❌ Context failed: ${e.message}\n`));
|
|
3041
|
+
}
|
|
3042
|
+
});
|
|
3043
|
+
// ─── Context Injection ────────────────────────────────
|
|
3044
|
+
program
|
|
3045
|
+
.command('context-apply')
|
|
3046
|
+
.description('Write @cell context into all AI tool configs (.cursorrules, CLAUDE.md, etc.)')
|
|
3047
|
+
.option('-p, --project <path>', 'Root path to apply context to')
|
|
3048
|
+
.action(async (opts) => {
|
|
3049
|
+
const dir = opts.project || process.cwd();
|
|
3050
|
+
try {
|
|
3051
|
+
const { initializeDatabase } = await Promise.resolve().then(() => __importStar(require('./core/database')));
|
|
3052
|
+
const { buildContext, formatContextForInjection } = await Promise.resolve().then(() => __importStar(require('./core/prompt-builder')));
|
|
3053
|
+
initializeDatabase();
|
|
3054
|
+
const cellBlock = '\n\n# ─── @cell Context — Auto-generated by FIVO Cell ───\n' +
|
|
3055
|
+
'# Update: cell context-apply\n' +
|
|
3056
|
+
formatContextForInjection(buildContext(dir, undefined), true)
|
|
3057
|
+
.split('\n').map((l) => '# ' + l).join('\n') +
|
|
3058
|
+
'\n# ─── End @cell Context ───\n';
|
|
3059
|
+
const configs = [
|
|
3060
|
+
{ path: path.join(dir, '.cursorrules'), name: 'Cursor' },
|
|
3061
|
+
{ path: path.join(dir, 'CLAUDE.md'), name: 'Claude Code' },
|
|
3062
|
+
{ path: path.join(dir, '.antigravity-rules.md'), name: 'Antigravity' },
|
|
3063
|
+
{ path: path.join(dir, '.github', 'copilot-instructions.md'), name: 'Copilot' },
|
|
3064
|
+
{ path: path.join(dir, 'AGENT.md'), name: 'OpenCode' },
|
|
3065
|
+
];
|
|
3066
|
+
let applied = 0;
|
|
3067
|
+
for (const cfg of configs) {
|
|
3068
|
+
try {
|
|
3069
|
+
const exists = fs.existsSync(cfg.path);
|
|
3070
|
+
let content = exists ? fs.readFileSync(cfg.path, 'utf-8') : '';
|
|
3071
|
+
const marker = '# ─── @cell Context';
|
|
3072
|
+
if (content.includes(marker)) {
|
|
3073
|
+
content = content.split(marker)[0].trimEnd();
|
|
3074
|
+
}
|
|
3075
|
+
const parent = path.dirname(cfg.path);
|
|
3076
|
+
if (!fs.existsSync(parent))
|
|
3077
|
+
fs.mkdirSync(parent, { recursive: true });
|
|
3078
|
+
fs.writeFileSync(cfg.path, content + '\n' + cellBlock);
|
|
3079
|
+
console.log(C.success(` ✅ ${cfg.name.padEnd(15)} → ${cfg.path}`));
|
|
3080
|
+
applied++;
|
|
3081
|
+
}
|
|
3082
|
+
catch (e) {
|
|
3083
|
+
console.log(C.dim(` ⚠ ${cfg.name.padEnd(15)} — skipped (${String(e).slice(0, 40)})`));
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
console.log(C.success(`\n 🧠 @cell context applied to ${applied} tool configs\n`));
|
|
3087
|
+
}
|
|
3088
|
+
catch (e) {
|
|
3089
|
+
console.log(C.error(`\n ❌ Failed: ${e.message}\n`));
|
|
3090
|
+
}
|
|
3091
|
+
});
|
|
3092
|
+
// ─── Predictive Intelligence ─────────────────────────
|
|
3093
|
+
program
|
|
3094
|
+
.command('predict')
|
|
3095
|
+
.description('Show all active predictions — pre-failures, decision regrets, scope creep, energy')
|
|
3096
|
+
.option('-p, --project <name>', 'Filter by project')
|
|
3097
|
+
.option('-t, --type <type>', 'Filter: pre_failure|decision_regret|complexity_trap|scope_creep|energy|stack')
|
|
3098
|
+
.action(async (opts) => {
|
|
3099
|
+
try {
|
|
3100
|
+
const { getAllPredictions } = await Promise.resolve().then(() => __importStar(require('./predictive-intelligence')));
|
|
3101
|
+
const predictions = getAllPredictions(opts.project);
|
|
3102
|
+
const filtered = opts.type ? predictions.filter((p) => p.type === opts.type) : predictions;
|
|
3103
|
+
if (filtered.length === 0) {
|
|
3104
|
+
console.log(C.dim('\n 🎉 No predictions — you\'re in a good zone.\n'));
|
|
3105
|
+
return;
|
|
3106
|
+
}
|
|
3107
|
+
const sevIcon = { critical: C.error('🔴'), warning: C.warn('🟡'), info: C.primary('🔵') };
|
|
3108
|
+
console.log(C.bold(`\n 🔮 Predictions (${filtered.length})\n`));
|
|
3109
|
+
for (const p of filtered.slice(0, 15)) {
|
|
3110
|
+
const icon = sevIcon[p.severity] || '⚪';
|
|
3111
|
+
const conf = `${Math.round(p.confidence * 100)}%`;
|
|
3112
|
+
console.log(` ${icon} ${C.bold(p.title)} ${C.dim(`[${p.type}] ${conf}`)}`);
|
|
3113
|
+
console.log(` ${p.message}`);
|
|
3114
|
+
if (p.suggestedAction)
|
|
3115
|
+
console.log(` ${C.dim('→')} ${C.primary(p.suggestedAction)}`);
|
|
3116
|
+
console.log();
|
|
3117
|
+
}
|
|
3118
|
+
const critCount = filtered.filter((p) => p.severity === 'critical').length;
|
|
3119
|
+
const warnCount = filtered.filter((p) => p.severity === 'warning').length;
|
|
3120
|
+
console.log(C.dim(` ${critCount} critical · ${warnCount} warning · ${filtered.length - critCount - warnCount} info\n`));
|
|
3121
|
+
}
|
|
3122
|
+
catch (e) {
|
|
3123
|
+
console.log(C.error(`\n ❌ Predict failed: ${e.message}\n`));
|
|
3124
|
+
}
|
|
3125
|
+
});
|
|
3126
|
+
program
|
|
3127
|
+
.command('predict-risk <file>')
|
|
3128
|
+
.description('Risk score + prediction for a specific file')
|
|
3129
|
+
.action(async (file) => {
|
|
3130
|
+
try {
|
|
3131
|
+
const { calculateFileRisk } = await Promise.resolve().then(() => __importStar(require('./predictive-intelligence')));
|
|
3132
|
+
const risk = calculateFileRisk(file);
|
|
3133
|
+
const score = risk.score;
|
|
3134
|
+
const color = score >= 70 ? C.error : score >= 40 ? C.warn : C.success;
|
|
3135
|
+
console.log(C.bold(`\n 🎯 Risk Score: ${color(`${score}/100`)} for ${file}\n`));
|
|
3136
|
+
if (risk.factors.length === 0) {
|
|
3137
|
+
console.log(C.dim(' No risk factors detected.\n'));
|
|
3138
|
+
}
|
|
3139
|
+
else {
|
|
3140
|
+
console.log(C.bold(' Risk Factors:'));
|
|
3141
|
+
for (const f of risk.factors) {
|
|
3142
|
+
console.log(` ${C.warn('+')} ${f.name} ${C.dim(`(weight: ${f.weight})`)}: ${f.reason}`);
|
|
3143
|
+
}
|
|
3144
|
+
console.log();
|
|
3145
|
+
}
|
|
3146
|
+
if (risk.predictions.length > 0) {
|
|
3147
|
+
console.log(C.bold(' Related Predictions:'));
|
|
3148
|
+
for (const p of risk.predictions.slice(0, 5)) {
|
|
3149
|
+
console.log(` ${C.primary('→')} ${p.title}: ${p.message.slice(0, 80)}`);
|
|
3150
|
+
}
|
|
3151
|
+
console.log();
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3154
|
+
catch (e) {
|
|
3155
|
+
console.log(C.error(`\n ❌ Risk calculation failed: ${e.message}\n`));
|
|
3156
|
+
}
|
|
3157
|
+
});
|
|
3158
|
+
program
|
|
3159
|
+
.command('predict-time <feature>')
|
|
3160
|
+
.description('Estimate completion time for a feature based on history')
|
|
3161
|
+
.action(async (feature) => {
|
|
3162
|
+
try {
|
|
3163
|
+
const { estimateFeatureTime } = await Promise.resolve().then(() => __importStar(require('./predictive-intelligence')));
|
|
3164
|
+
const estimate = estimateFeatureTime(feature);
|
|
3165
|
+
const conf = `${Math.round(estimate.confidence * 100)}%`;
|
|
3166
|
+
console.log(C.bold(`\n ⏱ Time Estimate: ${C.primary(feature)}\n`));
|
|
3167
|
+
console.log(` Estimated: ${C.bold(`${estimate.estimatedHours} hours`)} ${C.dim(`(confidence: ${conf})`)}`);
|
|
3168
|
+
console.log(` Based on: ${estimate.similarPastFeatures} similar past features`);
|
|
3169
|
+
if (estimate.basedOn.length > 0) {
|
|
3170
|
+
console.log(C.dim('\n Evidence:'));
|
|
3171
|
+
for (const b of estimate.basedOn.slice(0, 3)) {
|
|
3172
|
+
console.log(` ${C.dim('·')} ${b}`);
|
|
3173
|
+
}
|
|
3174
|
+
}
|
|
3175
|
+
console.log();
|
|
3176
|
+
}
|
|
3177
|
+
catch (e) {
|
|
3178
|
+
console.log(C.error(`\n ❌ Time estimate failed: ${e.message}\n`));
|
|
3179
|
+
}
|
|
3180
|
+
});
|
|
3181
|
+
// ─── Cross-Model Memory ────────────────────────────────
|
|
3182
|
+
program
|
|
3183
|
+
.command('tool-compare')
|
|
3184
|
+
.description('Compare all AI tools — acceptance rate, best/worst tasks, recommendations')
|
|
3185
|
+
.action(async () => {
|
|
3186
|
+
try {
|
|
3187
|
+
const { compareTools } = await Promise.resolve().then(() => __importStar(require('./cross-model-memory')));
|
|
3188
|
+
const tools = compareTools();
|
|
3189
|
+
if (tools.length === 0) {
|
|
3190
|
+
console.log(C.dim('\n No tool data yet. Use `cell sessions` to track tool usage.\n'));
|
|
3191
|
+
return;
|
|
3192
|
+
}
|
|
3193
|
+
console.log(C.bold(`\n 🔄 Tool Comparison (${tools.length} tools)\n`));
|
|
3194
|
+
for (const t of tools) {
|
|
3195
|
+
const acc = `${Math.round(t.acceptanceRate * 100)}%`;
|
|
3196
|
+
const color = t.acceptanceRate >= 0.7 ? C.success : t.acceptanceRate >= 0.5 ? C.warn : C.error;
|
|
3197
|
+
console.log(` ${color('●')} ${C.bold(t.tool)} ${C.dim(`${t.totalSessions} sessions · ${t.avgSessionMinutes}m avg`)}`);
|
|
3198
|
+
console.log(` Acceptance: ${color(acc)}`);
|
|
3199
|
+
if (t.bestFor.length > 0)
|
|
3200
|
+
console.log(` ${C.success('✓')} Best for: ${t.bestFor.join(', ')}`);
|
|
3201
|
+
if (t.worstFor.length > 0)
|
|
3202
|
+
console.log(` ${C.error('✗')} Worst for: ${t.worstFor.join(', ')}`);
|
|
3203
|
+
console.log(` ${C.dim(t.recommendation)}`);
|
|
3204
|
+
console.log();
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
catch (e) {
|
|
3208
|
+
console.log(C.error(`\n ❌ Tool compare failed: ${e.message}\n`));
|
|
3209
|
+
}
|
|
3210
|
+
});
|
|
3211
|
+
program
|
|
3212
|
+
.command('tool-suggest <task>')
|
|
3213
|
+
.description('Suggest best AI tool for a specific task type')
|
|
3214
|
+
.action(async (task) => {
|
|
3215
|
+
try {
|
|
3216
|
+
const { suggestTool } = await Promise.resolve().then(() => __importStar(require('./cross-model-memory')));
|
|
3217
|
+
const suggestions = suggestTool(task);
|
|
3218
|
+
if (suggestions.length === 0) {
|
|
3219
|
+
console.log(C.dim(`\n No data for task "${task}" yet.\n`));
|
|
3220
|
+
return;
|
|
3221
|
+
}
|
|
3222
|
+
console.log(C.bold(`\n 🎯 Best tool for "${task}"\n`));
|
|
3223
|
+
for (const s of suggestions) {
|
|
3224
|
+
const acc = `${Math.round(s.successRate * 100)}%`;
|
|
3225
|
+
const color = s.successRate >= 0.7 ? C.success : s.successRate >= 0.5 ? C.warn : C.error;
|
|
3226
|
+
const conf = `${Math.round(s.confidence * 100)}%`;
|
|
3227
|
+
console.log(` ${color('→')} ${C.bold(s.tool)} ${C.dim(`(confidence: ${conf})`)}`);
|
|
3228
|
+
console.log(` Success: ${color(acc)} · Based on ${s.basedOnSessions} sessions`);
|
|
3229
|
+
console.log(` ${C.dim(s.reason)}`);
|
|
3230
|
+
console.log();
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3233
|
+
catch (e) {
|
|
3234
|
+
console.log(C.error(`\n ❌ Tool suggest failed: ${e.message}\n`));
|
|
3235
|
+
}
|
|
3236
|
+
});
|
|
3237
|
+
program
|
|
3238
|
+
.command('model-history')
|
|
3239
|
+
.description('Per-model interaction history — sessions, files, decisions')
|
|
3240
|
+
.action(async () => {
|
|
3241
|
+
try {
|
|
3242
|
+
const { getModelHistory } = await Promise.resolve().then(() => __importStar(require('./cross-model-memory')));
|
|
3243
|
+
const history = getModelHistory();
|
|
3244
|
+
if (history.length === 0) {
|
|
3245
|
+
console.log(C.dim('\n No model history yet. Start sessions with `cell session-start`.\n'));
|
|
3246
|
+
return;
|
|
3247
|
+
}
|
|
3248
|
+
console.log(C.bold(`\n 📊 Model History\n`));
|
|
3249
|
+
for (const h of history) {
|
|
3250
|
+
console.log(` ${C.primary('●')} ${C.bold(h.tool)} ${C.dim(`${h.sessionsCount} sessions`)}`);
|
|
3251
|
+
console.log(` Files touched: ${h.totalFilesTouched} · Decisions: ${h.totalDecisions}`);
|
|
3252
|
+
console.log(` Avg session: ${h.avgSessionMinutes}m · Last used: ${h.lastUsed.slice(0, 10)}`);
|
|
3253
|
+
console.log();
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3256
|
+
catch (e) {
|
|
3257
|
+
console.log(C.error(`\n ❌ Model history failed: ${e.message}\n`));
|
|
3258
|
+
}
|
|
3259
|
+
});
|
|
3260
|
+
program
|
|
3261
|
+
.command('tool-context <tool>')
|
|
3262
|
+
.description('Show tool-specific @cell context for an AI tool')
|
|
3263
|
+
.action(async (tool) => {
|
|
3264
|
+
try {
|
|
3265
|
+
const { buildToolSpecificContext } = await Promise.resolve().then(() => __importStar(require('./cross-model-memory')));
|
|
3266
|
+
const ctx = buildToolSpecificContext(tool);
|
|
3267
|
+
console.log(C.bold(`\n 🧠 @cell for ${tool}\n`));
|
|
3268
|
+
console.log(ctx);
|
|
3269
|
+
console.log();
|
|
3270
|
+
}
|
|
3271
|
+
catch (e) {
|
|
3272
|
+
console.log(C.error(`\n ❌ Tool context failed: ${e.message}\n`));
|
|
3273
|
+
}
|
|
3274
|
+
});
|
|
3275
|
+
// ─── Team Intelligence ──────────────────────────────────
|
|
3276
|
+
program
|
|
3277
|
+
.command('team-health')
|
|
3278
|
+
.description('Team health score — bus factor, silos, skill gaps, strengths')
|
|
3279
|
+
.option('-p, --project <name>', 'Filter by project')
|
|
3280
|
+
.action(async (opts) => {
|
|
3281
|
+
try {
|
|
3282
|
+
const { getTeamHealth } = await Promise.resolve().then(() => __importStar(require('./team-collaboration')));
|
|
3283
|
+
const h = getTeamHealth(opts.project);
|
|
3284
|
+
const color = h.score >= 70 ? C.success : h.score >= 40 ? C.warn : C.error;
|
|
3285
|
+
console.log(C.bold(`\n 🏥 Team Health: ${color(`${h.score}/100`)}\n`));
|
|
3286
|
+
console.log(` Bus Factor: ${C.primary(String(h.busFactor))} · Knowledge Silos: ${C.warn(String(h.siloCount))}`);
|
|
3287
|
+
if (h.strengths.length > 0) {
|
|
3288
|
+
console.log(C.bold('\n Strengths:'));
|
|
3289
|
+
for (const s of h.strengths)
|
|
3290
|
+
console.log(` ${C.success('✓')} ${s}`);
|
|
3291
|
+
}
|
|
3292
|
+
if (h.skillGaps.length > 0) {
|
|
3293
|
+
console.log(C.bold('\n Skill Gaps:'));
|
|
3294
|
+
for (const g of h.skillGaps)
|
|
3295
|
+
console.log(` ${C.warn('⚠')} ${g}`);
|
|
3296
|
+
}
|
|
3297
|
+
if (h.recommendations.length > 0) {
|
|
3298
|
+
console.log(C.bold('\n Recommendations:'));
|
|
3299
|
+
for (const r of h.recommendations)
|
|
3300
|
+
console.log(` ${C.primary('→')} ${r}`);
|
|
3301
|
+
}
|
|
3302
|
+
console.log();
|
|
3303
|
+
}
|
|
3304
|
+
catch (e) {
|
|
3305
|
+
console.log(C.error(`\n ❌ Team health failed: ${e.message}\n`));
|
|
3306
|
+
}
|
|
3307
|
+
});
|
|
3308
|
+
program
|
|
3309
|
+
.command('team-retro')
|
|
3310
|
+
.description('Auto-generate sprint retrospective from git + pattern data')
|
|
3311
|
+
.option('-d, --days <days>', 'Lookback period in days', '14')
|
|
3312
|
+
.option('-p, --project <name>', 'Filter by project')
|
|
3313
|
+
.action(async (opts) => {
|
|
3314
|
+
try {
|
|
3315
|
+
const { generateSprintRetro } = await Promise.resolve().then(() => __importStar(require('./team-collaboration')));
|
|
3316
|
+
const retro = generateSprintRetro(parseInt(opts.days) || 14, opts.project);
|
|
3317
|
+
console.log(C.bold(`\n 📋 Sprint Retro: ${retro.period}\n`));
|
|
3318
|
+
console.log(` Events: ${retro.commits} · Bugs fixed: ${C.primary(String(retro.bugsFixed))} · Patterns: ${retro.newPatterns}`);
|
|
3319
|
+
if (retro.topContributors.length > 0) {
|
|
3320
|
+
console.log(C.bold('\n Top Contributors:'));
|
|
3321
|
+
for (const c of retro.topContributors)
|
|
3322
|
+
console.log(` ${C.primary('●')} ${c.name}: ${c.commits} sessions`);
|
|
3323
|
+
}
|
|
3324
|
+
if (retro.keyDecisions.length > 0) {
|
|
3325
|
+
console.log(C.bold('\n Key Decisions:'));
|
|
3326
|
+
for (const d of retro.keyDecisions)
|
|
3327
|
+
console.log(` ${C.dim('·')} ${d}`);
|
|
3328
|
+
}
|
|
3329
|
+
console.log(C.dim(`\n ${retro.summary}\n`));
|
|
3330
|
+
}
|
|
3331
|
+
catch (e) {
|
|
3332
|
+
console.log(C.error(`\n ❌ Retro failed: ${e.message}\n`));
|
|
3333
|
+
}
|
|
3334
|
+
});
|
|
3335
|
+
program
|
|
3336
|
+
.command('team-onboard <team>')
|
|
3337
|
+
.description('Generate onboarding package for a new team member')
|
|
3338
|
+
.option('-p, --project <name>', 'Filter by project')
|
|
3339
|
+
.action(async (team, opts) => {
|
|
3340
|
+
try {
|
|
3341
|
+
const { generateOnboardingDoc } = await Promise.resolve().then(() => __importStar(require('./team-collaboration')));
|
|
3342
|
+
const doc = generateOnboardingDoc(team, opts.project);
|
|
3343
|
+
console.log(C.bold(`\n 📦 Onboarding: ${doc.teamName}\n`));
|
|
3344
|
+
console.log(` Stack: ${doc.stack.join(', ') || 'unknown'}`);
|
|
3345
|
+
console.log(` Patterns: ${doc.patterns.length} learned`);
|
|
3346
|
+
if (doc.keyMembers.length > 0) {
|
|
3347
|
+
console.log(C.bold('\n Key Members:'));
|
|
3348
|
+
for (const m of doc.keyMembers)
|
|
3349
|
+
console.log(` ${C.primary('●')} ${m.name}: ${m.expertise.join(', ')}`);
|
|
3350
|
+
}
|
|
3351
|
+
if (doc.whoToAsk.length > 0) {
|
|
3352
|
+
console.log(C.bold('\n Who to Ask:'));
|
|
3353
|
+
for (const w of doc.whoToAsk)
|
|
3354
|
+
console.log(` ${w.area} → ${C.primary(w.person)}`);
|
|
3355
|
+
}
|
|
3356
|
+
if (doc.commonBugs.length > 0) {
|
|
3357
|
+
console.log(C.bold('\n Common Bugs:'));
|
|
3358
|
+
for (const b of doc.commonBugs)
|
|
3359
|
+
console.log(` ${C.warn('⚠')} ${b}`);
|
|
3360
|
+
}
|
|
3361
|
+
if (doc.firstWeekTasks.length > 0) {
|
|
3362
|
+
console.log(C.bold('\n First Week:'));
|
|
3363
|
+
for (let i = 0; i < doc.firstWeekTasks.length; i++) {
|
|
3364
|
+
console.log(` ${C.dim(`${i + 1}.`)} ${doc.firstWeekTasks[i]}`);
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
console.log();
|
|
3368
|
+
}
|
|
3369
|
+
catch (e) {
|
|
3370
|
+
console.log(C.error(`\n ❌ Onboard failed: ${e.message}\n`));
|
|
3371
|
+
}
|
|
3372
|
+
});
|
|
3373
|
+
program
|
|
3374
|
+
.command('team-style')
|
|
3375
|
+
.description('Show merged team coding style')
|
|
3376
|
+
.option('-p, --project <name>', 'Filter by project')
|
|
3377
|
+
.action(async (opts) => {
|
|
3378
|
+
try {
|
|
3379
|
+
const { composeTeamStyle } = await Promise.resolve().then(() => __importStar(require('./team-collaboration')));
|
|
3380
|
+
const style = composeTeamStyle(opts.project);
|
|
3381
|
+
console.log(C.bold(`\n 🎨 Team Style\n`));
|
|
3382
|
+
console.log(` Stack: ${style.languages.join(', ') || 'unknown'}`);
|
|
3383
|
+
console.log(` Test Coverage: ${style.testCoverage}`);
|
|
3384
|
+
console.log(` Code Review: ${style.codeReviewStyle}`);
|
|
3385
|
+
console.log(` Avg Files/Session: ${style.avgFileSize}`);
|
|
3386
|
+
if (style.patterns.length > 0) {
|
|
3387
|
+
console.log(C.bold('\n Top Patterns:'));
|
|
3388
|
+
for (const p of style.patterns.slice(0, 5))
|
|
3389
|
+
console.log(` ${C.dim('·')} ${p}`);
|
|
3390
|
+
}
|
|
3391
|
+
console.log();
|
|
3392
|
+
}
|
|
3393
|
+
catch (e) {
|
|
3394
|
+
console.log(C.error(`\n ❌ Team style failed: ${e.message}\n`));
|
|
3395
|
+
}
|
|
3396
|
+
});
|
|
3397
|
+
program
|
|
3398
|
+
.command('team-silos')
|
|
3399
|
+
.description('Detect knowledge silos and single points of failure')
|
|
3400
|
+
.action(async () => {
|
|
3401
|
+
try {
|
|
3402
|
+
const { detectKnowledgeSilos, calculateBusFactor, suggestKnowledgeTransfer } = await Promise.resolve().then(() => __importStar(require('./team-collaboration')));
|
|
3403
|
+
const silos = detectKnowledgeSilos();
|
|
3404
|
+
const bus = calculateBusFactor();
|
|
3405
|
+
const transfers = suggestKnowledgeTransfer();
|
|
3406
|
+
console.log(C.bold(`\n 🔒 Knowledge Silos (${silos.length})\n`));
|
|
3407
|
+
if (silos.length === 0) {
|
|
3408
|
+
console.log(C.dim(' No knowledge silos detected.'));
|
|
3409
|
+
}
|
|
3410
|
+
else {
|
|
3411
|
+
for (const s of silos.slice(0, 8)) {
|
|
3412
|
+
const icon = s.riskLevel === 'high' ? C.error('🔴') : s.riskLevel === 'medium' ? C.warn('🟡') : C.success('🟢');
|
|
3413
|
+
console.log(` ${icon} ${C.bold(s.name)} ${C.dim(`(bus: ${s.busFactor})`)}`);
|
|
3414
|
+
console.log(` ${s.description}`);
|
|
3415
|
+
}
|
|
3416
|
+
}
|
|
3417
|
+
console.log(C.bold(`\n 🚌 Bus Factor: ${bus.overallScore}/100`));
|
|
3418
|
+
if (bus.singlePointsOfFailure.length > 0) {
|
|
3419
|
+
console.log(C.warn('\n Single Points of Failure:'));
|
|
3420
|
+
for (const spf of bus.singlePointsOfFailure)
|
|
3421
|
+
console.log(` ${C.error('⚠')} ${spf}`);
|
|
3422
|
+
}
|
|
3423
|
+
if (transfers.length > 0) {
|
|
3424
|
+
console.log(C.bold('\n 📚 Suggested Knowledge Transfers:'));
|
|
3425
|
+
for (const t of transfers.slice(0, 5)) {
|
|
3426
|
+
console.log(` ${C.primary('→')} ${t.area}: ${t.from} → ${t.to} ${C.dim(`[${t.priority}]`)}`);
|
|
3427
|
+
}
|
|
3428
|
+
}
|
|
3429
|
+
console.log();
|
|
3430
|
+
}
|
|
3431
|
+
catch (e) {
|
|
3432
|
+
console.log(C.error(`\n ❌ Silos failed: ${e.message}\n`));
|
|
3433
|
+
}
|
|
3434
|
+
});
|
|
3435
|
+
program
|
|
3436
|
+
.command('handoff')
|
|
3437
|
+
.description('Generate context handoff for team member transition')
|
|
3438
|
+
.argument('<from>', 'Person handing off')
|
|
3439
|
+
.argument('<to>', 'Person receiving')
|
|
3440
|
+
.argument('<project>', 'Project name')
|
|
3441
|
+
.action(async (from, to, project) => {
|
|
3442
|
+
try {
|
|
3443
|
+
const { generateHandoff } = await Promise.resolve().then(() => __importStar(require('./team-collaboration')));
|
|
3444
|
+
const h = generateHandoff(from, to, project);
|
|
3445
|
+
console.log(C.bold(`\n 🤝 Handoff: ${h.from} → ${h.to} (${h.project})\n`));
|
|
3446
|
+
if (h.keyDecisions.length > 0) {
|
|
3447
|
+
console.log(C.bold(' Key Decisions:'));
|
|
3448
|
+
for (const d of h.keyDecisions)
|
|
3449
|
+
console.log(` ${C.dim('·')} ${d}`);
|
|
3450
|
+
}
|
|
3451
|
+
if (h.blockers.length > 0) {
|
|
3452
|
+
console.log(C.bold('\n Known Issues:'));
|
|
3453
|
+
for (const b of h.blockers)
|
|
3454
|
+
console.log(` ${C.warn('⚠')} ${b}`);
|
|
3455
|
+
}
|
|
3456
|
+
if (h.contextNotes) {
|
|
3457
|
+
console.log(C.bold('\n Context:'));
|
|
3458
|
+
console.log(` ${h.contextNotes}`);
|
|
3459
|
+
}
|
|
3460
|
+
console.log();
|
|
3461
|
+
}
|
|
3462
|
+
catch (e) {
|
|
3463
|
+
console.log(C.error(`\n ❌ Handoff failed: ${e.message}\n`));
|
|
3464
|
+
}
|
|
3465
|
+
});
|
|
3466
|
+
// ─── Community Intelligence ─────────────────────────────
|
|
3467
|
+
program
|
|
3468
|
+
.command('community-compare')
|
|
3469
|
+
.description('Compare your skills against community benchmarks')
|
|
3470
|
+
.action(async () => {
|
|
3471
|
+
try {
|
|
3472
|
+
const { benchmarkPersonal, benchmarkBlindSpots } = await Promise.resolve().then(() => __importStar(require('./community-v2')));
|
|
3473
|
+
const benchmarks = benchmarkPersonal();
|
|
3474
|
+
const blindSpots = benchmarkBlindSpots();
|
|
3475
|
+
console.log(C.bold('\n 📊 Personal vs Community\n'));
|
|
3476
|
+
for (const b of benchmarks) {
|
|
3477
|
+
const color = b.verdict === 'ahead' ? C.success : b.verdict === 'behind' ? C.warn : C.primary;
|
|
3478
|
+
const icon = b.verdict === 'ahead' ? '✓' : b.verdict === 'behind' ? '⚠' : '·';
|
|
3479
|
+
console.log(` ${color(icon)} ${C.bold(b.metric)} ${C.dim(`(${b.percentile}th percentile)`)}`);
|
|
3480
|
+
console.log(` ${b.detail}`);
|
|
3481
|
+
}
|
|
3482
|
+
console.log(C.bold('\n 🎯 Blind Spot Benchmark\n'));
|
|
3483
|
+
for (const bs of blindSpots.slice(0, 5)) {
|
|
3484
|
+
const color = bs.percentile >= 60 ? C.success : C.warn;
|
|
3485
|
+
console.log(` ${color('●')} ${bs.area} ${C.dim(`(${bs.percentile}th percentile)`)}`);
|
|
3486
|
+
console.log(` ${bs.description}`);
|
|
3487
|
+
console.log(` ${C.dim(bs.recommendation)}`);
|
|
3488
|
+
}
|
|
3489
|
+
console.log();
|
|
3490
|
+
}
|
|
3491
|
+
catch (e) {
|
|
3492
|
+
console.log(C.error(`\n ❌ Compare failed: ${e.message}\n`));
|
|
3493
|
+
}
|
|
3494
|
+
});
|
|
3495
|
+
program
|
|
3496
|
+
.command('community-trends')
|
|
3497
|
+
.description('Show technology and pattern trends from community')
|
|
3498
|
+
.action(async () => {
|
|
3499
|
+
try {
|
|
3500
|
+
const { detectTrends, getCommunityStats } = await Promise.resolve().then(() => __importStar(require('./community-v2')));
|
|
3501
|
+
const trends = detectTrends();
|
|
3502
|
+
const stats = getCommunityStats();
|
|
3503
|
+
console.log(C.bold(`\n 📈 Community Trends (${stats.totalDevelopers} devs)\n`));
|
|
3504
|
+
for (const t of trends.slice(0, 10)) {
|
|
3505
|
+
const icon = t.direction === 'rising' ? C.success('↑') : t.direction === 'declining' ? C.error('↓') : C.dim('→');
|
|
3506
|
+
const yours = t.userHasIt ? C.success(' [YOU USE THIS]') : '';
|
|
3507
|
+
console.log(` ${icon} ${C.bold(t.technology)} ${C.dim(`${t.adoption}% adoption`)}${yours}`);
|
|
3508
|
+
}
|
|
3509
|
+
console.log();
|
|
3510
|
+
}
|
|
3511
|
+
catch (e) {
|
|
3512
|
+
console.log(C.error(`\n ❌ Trends failed: ${e.message}\n`));
|
|
3513
|
+
}
|
|
3514
|
+
});
|
|
3515
|
+
program
|
|
3516
|
+
.command('community-insights')
|
|
3517
|
+
.description('Actionable community insights — benchmarks, blind spots, trends')
|
|
3518
|
+
.action(async () => {
|
|
3519
|
+
try {
|
|
3520
|
+
const { generateInsights } = await Promise.resolve().then(() => __importStar(require('./community-v2')));
|
|
3521
|
+
const insights = generateInsights();
|
|
3522
|
+
if (insights.length === 0) {
|
|
3523
|
+
console.log(C.dim('\n No insights yet. Use `cell community-compare` to start.\n'));
|
|
3524
|
+
return;
|
|
3525
|
+
}
|
|
3526
|
+
console.log(C.bold(`\n 💡 Community Insights (${insights.length})\n`));
|
|
3527
|
+
for (const i of insights.slice(0, 10)) {
|
|
3528
|
+
const icon = i.type === 'benchmark' ? '📊' : i.type === 'blind_spot' ? '🎯' : i.type === 'trend' ? '📈' : '✅';
|
|
3529
|
+
console.log(` ${icon} ${C.bold(i.title)}`);
|
|
3530
|
+
console.log(` ${i.message}`);
|
|
3531
|
+
if (i.suggestedAction)
|
|
3532
|
+
console.log(` ${C.primary('→')} ${i.suggestedAction}`);
|
|
3533
|
+
console.log();
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3536
|
+
catch (e) {
|
|
3537
|
+
console.log(C.error(`\n ❌ Insights failed: ${e.message}\n`));
|
|
3538
|
+
}
|
|
3539
|
+
});
|
|
3540
|
+
program
|
|
3541
|
+
.command('community-challenges')
|
|
3542
|
+
.description('Show weekly community challenges')
|
|
3543
|
+
.action(async () => {
|
|
3544
|
+
try {
|
|
3545
|
+
const { getWeeklyChallenges } = await Promise.resolve().then(() => __importStar(require('./community-v2')));
|
|
3546
|
+
const challenges = getWeeklyChallenges();
|
|
3547
|
+
console.log(C.bold('\n 🏆 Weekly Challenges\n'));
|
|
3548
|
+
for (const c of challenges) {
|
|
3549
|
+
const diff = c.difficulty === 'easy' ? C.success('Easy') : c.difficulty === 'medium' ? C.warn('Medium') : C.error('Hard');
|
|
3550
|
+
console.log(` ${C.bold(c.title)} ${C.dim(`[${diff}]`)}`);
|
|
3551
|
+
console.log(` ${c.description}`);
|
|
3552
|
+
console.log(` ${C.dim(`${c.participants} participants · Reward: ${c.reward}`)}`);
|
|
3553
|
+
console.log();
|
|
3554
|
+
}
|
|
3555
|
+
}
|
|
3556
|
+
catch (e) {
|
|
3557
|
+
console.log(C.error(`\n ❌ Challenges failed: ${e.message}\n`));
|
|
3558
|
+
}
|
|
3559
|
+
});
|
|
3560
|
+
// ─── Advanced Personal Intelligence ─────────────────────
|
|
3561
|
+
program
|
|
3562
|
+
.command('rhythm')
|
|
3563
|
+
.description('Show coding rhythm — best hours, best days, flow patterns')
|
|
3564
|
+
.action(async () => {
|
|
3565
|
+
try {
|
|
3566
|
+
const { detectCodingRhythm } = await Promise.resolve().then(() => __importStar(require('./personal-intelligence')));
|
|
3567
|
+
const r = detectCodingRhythm();
|
|
3568
|
+
console.log(C.bold('\n ⏰ Coding Rhythm\n'));
|
|
3569
|
+
console.log(` Best Hours: ${C.success(r.bestHours.join(', ') || 'no data')}`);
|
|
3570
|
+
console.log(` Best Days: ${C.success(r.bestDays.join(', ') || 'no data')}`);
|
|
3571
|
+
console.log(` Worst Hours: ${C.error(r.worstHours.join(', ') || 'no data')}`);
|
|
3572
|
+
console.log(` Worst Days: ${C.error(r.worstDays.join(', ') || 'no data')}`);
|
|
3573
|
+
console.log(` Avg Session: ${C.primary(String(r.avgSessionMinutes))}min · Optimal: ${C.primary(String(r.optimalSessionMinutes))}min`);
|
|
3574
|
+
console.log(` Peak Flow: ${C.success(r.peakFlowWindow)}`);
|
|
3575
|
+
console.log();
|
|
3576
|
+
}
|
|
3577
|
+
catch (e) {
|
|
3578
|
+
console.log(C.error(`\n ❌ Rhythm failed: ${e.message}\n`));
|
|
3579
|
+
}
|
|
3580
|
+
});
|
|
3581
|
+
program
|
|
3582
|
+
.command('burnout')
|
|
3583
|
+
.description('Check for burnout signals — error rate, session length, reverts')
|
|
3584
|
+
.action(async () => {
|
|
3585
|
+
try {
|
|
3586
|
+
const { detectBurnout } = await Promise.resolve().then(() => __importStar(require('./personal-intelligence')));
|
|
3587
|
+
const b = detectBurnout();
|
|
3588
|
+
const color = b.severity === 'none' ? C.success : b.severity === 'mild' ? C.warn : C.error;
|
|
3589
|
+
console.log(C.bold(`\n 🔥 Burnout Check: ${color(b.severity.toUpperCase())}\n`));
|
|
3590
|
+
console.log(` Signals: ${b.signals.length}`);
|
|
3591
|
+
for (const s of b.signals)
|
|
3592
|
+
console.log(` ${C.warn('⚠')} ${s}`);
|
|
3593
|
+
console.log(` ${C.dim(`Error rate: ${b.metrics.errorRateTrend}`)}`);
|
|
3594
|
+
console.log(` ${C.dim(`Session length: ${b.metrics.sessionLengthTrend}`)}`);
|
|
3595
|
+
console.log(` ${C.dim(`Reverts: ${b.metrics.revertRate}`)}`);
|
|
3596
|
+
console.log(`\n ${C.primary(b.suggestion)}\n`);
|
|
3597
|
+
}
|
|
3598
|
+
catch (e) {
|
|
3599
|
+
console.log(C.error(`\n ❌ Burnout check failed: ${e.message}\n`));
|
|
3600
|
+
}
|
|
3601
|
+
});
|
|
3602
|
+
program
|
|
3603
|
+
.command('mastery')
|
|
3604
|
+
.description('Technology mastery map — per-language progress and confidence')
|
|
3605
|
+
.action(async () => {
|
|
3606
|
+
try {
|
|
3607
|
+
const { getTechMasteryMap } = await Promise.resolve().then(() => __importStar(require('./personal-intelligence')));
|
|
3608
|
+
const mastery = getTechMasteryMap();
|
|
3609
|
+
if (mastery.length === 0) {
|
|
3610
|
+
console.log(C.dim('\n No technologies tracked yet.\n'));
|
|
3611
|
+
return;
|
|
3612
|
+
}
|
|
3613
|
+
console.log(C.bold(`\n 🗺️ Technology Mastery (${mastery.length})\n`));
|
|
3614
|
+
for (const m of mastery) {
|
|
3615
|
+
const stageIcon = m.stage === 'mastered' ? C.success('★') : m.stage === 'advanced' ? C.primary('●') : m.stage === 'proficient' ? C.warn('◐') : C.dim('○');
|
|
3616
|
+
const stageColor = m.stage === 'mastered' ? C.success : m.stage === 'advanced' ? C.primary : m.stage === 'proficient' ? C.warn : C.dim;
|
|
3617
|
+
console.log(` ${stageIcon} ${C.bold(m.language)} ${stageColor(m.stage)} ${C.dim(`${m.monthsActive}mo · ${m.fileCount} files`)}`);
|
|
3618
|
+
console.log(` Confidence: ${m.confidence}% · Actual: ${m.actualPerformance}% · Gap: ${m.confidenceGap}%`);
|
|
3619
|
+
}
|
|
3620
|
+
console.log();
|
|
3621
|
+
}
|
|
3622
|
+
catch (e) {
|
|
3623
|
+
console.log(C.error(`\n ❌ Mastery failed: ${e.message}\n`));
|
|
3624
|
+
}
|
|
3625
|
+
});
|
|
3626
|
+
program
|
|
3627
|
+
.command('growth')
|
|
3628
|
+
.description('Career trajectory — current level, senior readiness, recommendations')
|
|
3629
|
+
.action(async () => {
|
|
3630
|
+
try {
|
|
3631
|
+
const { getCareerTrajectory } = await Promise.resolve().then(() => __importStar(require('./personal-intelligence')));
|
|
3632
|
+
const t = getCareerTrajectory();
|
|
3633
|
+
const levelColor = t.currentLevel === 'senior' || t.currentLevel === 'staff' ? C.success : t.currentLevel === 'mid' ? C.primary : C.warn;
|
|
3634
|
+
console.log(C.bold(`\n 📈 Career Trajectory\n`));
|
|
3635
|
+
console.log(` Level: ${levelColor(t.currentLevel.toUpperCase())} ${C.dim(`(${t.levelConfidence}% confidence)`)}`);
|
|
3636
|
+
console.log(` Senior Readiness: ${C.primary(String(t.seniorReadiness))}% · ETA: ${t.monthsToSenior} months`);
|
|
3637
|
+
console.log(` Growth Rate: ${t.growthRate}% per month`);
|
|
3638
|
+
if (t.strongAreas.length > 0) {
|
|
3639
|
+
console.log(C.bold('\n Strong Areas:'));
|
|
3640
|
+
for (const a of t.strongAreas)
|
|
3641
|
+
console.log(` ${C.success('✓')} ${a}`);
|
|
3642
|
+
}
|
|
3643
|
+
if (t.weakAreas.length > 0) {
|
|
3644
|
+
console.log(C.bold('\n Weak Areas:'));
|
|
3645
|
+
for (const a of t.weakAreas)
|
|
3646
|
+
console.log(` ${C.warn('⚠')} ${a}`);
|
|
3647
|
+
}
|
|
3648
|
+
if (t.recommendations.length > 0) {
|
|
3649
|
+
console.log(C.bold('\n Recommendations:'));
|
|
3650
|
+
for (const r of t.recommendations)
|
|
3651
|
+
console.log(` ${C.primary('→')} ${r}`);
|
|
3652
|
+
}
|
|
3653
|
+
console.log();
|
|
3654
|
+
}
|
|
3655
|
+
catch (e) {
|
|
3656
|
+
console.log(C.error(`\n ❌ Growth failed: ${e.message}\n`));
|
|
3657
|
+
}
|
|
3658
|
+
});
|
|
3659
|
+
program
|
|
3660
|
+
.command('insights-weekly')
|
|
3661
|
+
.description('Weekly digest — sessions, bugs, decisions, highlights')
|
|
3662
|
+
.action(async () => {
|
|
3663
|
+
try {
|
|
3664
|
+
const { generateWeeklyDigest } = await Promise.resolve().then(() => __importStar(require('./personal-intelligence')));
|
|
3665
|
+
const d = generateWeeklyDigest();
|
|
3666
|
+
console.log(C.bold(`\n 📋 Weekly Digest: ${d.period}\n`));
|
|
3667
|
+
console.log(` Sessions: ${C.primary(String(d.totalSessions))} · Bugs: ${d.totalBugs} · Decisions: ${d.totalDecisions} · Patterns: ${d.newPatterns}`);
|
|
3668
|
+
console.log(` Top Languages: ${d.topLanguages.join(', ') || 'none'}`);
|
|
3669
|
+
if (d.highlights.length > 0) {
|
|
3670
|
+
console.log(C.bold('\n Highlights:'));
|
|
3671
|
+
for (const h of d.highlights)
|
|
3672
|
+
console.log(` ${C.success('✓')} ${h}`);
|
|
3673
|
+
}
|
|
3674
|
+
if (d.areasToFocus.length > 0) {
|
|
3675
|
+
console.log(C.bold('\n Focus Areas:'));
|
|
3676
|
+
for (const f of d.areasToFocus)
|
|
3677
|
+
console.log(` ${C.warn('⚠')} ${f}`);
|
|
3678
|
+
}
|
|
3679
|
+
console.log();
|
|
3680
|
+
}
|
|
3681
|
+
catch (e) {
|
|
3682
|
+
console.log(C.error(`\n ❌ Weekly digest failed: ${e.message}\n`));
|
|
3683
|
+
}
|
|
3684
|
+
});
|
|
3685
|
+
// ─── Production Hardening ───────────────────────────────
|
|
3686
|
+
program
|
|
3687
|
+
.command('health')
|
|
3688
|
+
.description('System health — DB status, memory, uptime, platform')
|
|
3689
|
+
.action(async () => {
|
|
3690
|
+
try {
|
|
3691
|
+
const { getHealthStatus } = await Promise.resolve().then(() => __importStar(require('./production')));
|
|
3692
|
+
const h = getHealthStatus();
|
|
3693
|
+
const color = h.status === 'healthy' ? C.success : h.status === 'degraded' ? C.warn : C.error;
|
|
3694
|
+
console.log(C.bold(`\n 🏥 System Health: ${color(h.status.toUpperCase())}\n`));
|
|
3695
|
+
console.log(` Uptime: ${C.primary(formatUptime(h.uptime))}`);
|
|
3696
|
+
console.log(` Platform: ${h.platform} · Node: ${process.version}`);
|
|
3697
|
+
console.log(` DB: ${color(h.dbStatus)} · Size: ${formatBytes(h.dbSizeBytes)}`);
|
|
3698
|
+
console.log(` Memory: ${C.primary(String(h.memoryUsageMB))}MB`);
|
|
3699
|
+
console.log(` Last Scan: ${h.lastScan}`);
|
|
3700
|
+
console.log(` Version: ${h.version}`);
|
|
3701
|
+
console.log();
|
|
3702
|
+
}
|
|
3703
|
+
catch (e) {
|
|
3704
|
+
console.log(C.error(`\n ❌ Health check failed: ${e.message}\n`));
|
|
3705
|
+
}
|
|
3706
|
+
});
|
|
3707
|
+
program
|
|
3708
|
+
.command('metrics')
|
|
3709
|
+
.description('System metrics — queries/sec, patterns, sessions, DB tables')
|
|
3710
|
+
.action(async () => {
|
|
3711
|
+
try {
|
|
3712
|
+
const { getMetrics } = await Promise.resolve().then(() => __importStar(require('./production')));
|
|
3713
|
+
const m = getMetrics();
|
|
3714
|
+
console.log(C.bold('\n 📊 System Metrics\n'));
|
|
3715
|
+
console.log(` Queries/sec: ${C.primary(String(m.queriesPerSecond))}`);
|
|
3716
|
+
console.log(` Patterns: ${C.primary(String(m.patternsCount))}`);
|
|
3717
|
+
console.log(` Sessions: ${m.sessionsCount}`);
|
|
3718
|
+
console.log(` DB Size: ${formatBytes(m.dbSizeBytes)}`);
|
|
3719
|
+
console.log(` Memory: ${m.memoryUsageMB}MB`);
|
|
3720
|
+
console.log(` Uptime: ${formatUptime(m.uptimeSeconds)}`);
|
|
3721
|
+
console.log(C.bold('\n Table Counts:'));
|
|
3722
|
+
for (const [table, count] of Object.entries(m.dbTableCounts).sort((a, b) => b[1] - a[1]).slice(0, 10)) {
|
|
3723
|
+
console.log(` ${table}: ${count}`);
|
|
3724
|
+
}
|
|
3725
|
+
console.log();
|
|
3726
|
+
}
|
|
3727
|
+
catch (e) {
|
|
3728
|
+
console.log(C.error(`\n ❌ Metrics failed: ${e.message}\n`));
|
|
3729
|
+
}
|
|
3730
|
+
});
|
|
3731
|
+
program
|
|
3732
|
+
.command('security')
|
|
3733
|
+
.description('Security status — auth, encryption, rate limits')
|
|
3734
|
+
.action(async () => {
|
|
3735
|
+
try {
|
|
3736
|
+
const { generateToken, rotateAuthToken } = await Promise.resolve().then(() => __importStar(require('./production')));
|
|
3737
|
+
const config = JSON.parse(require('fs').readFileSync(require('path').join(require('os').homedir(), '.fivo', 'cell', 'security.json'), 'utf-8'));
|
|
3738
|
+
console.log(C.bold('\n 🔒 Security Status\n'));
|
|
3739
|
+
console.log(` Auth Token: ${config.authToken.slice(0, 8)}...${config.authToken.slice(-4)}`);
|
|
3740
|
+
console.log(` Rate Limit: ${config.rateLimitPerMinute}/min`);
|
|
3741
|
+
console.log(` Last Rotation: ${config.lastTokenRotation}`);
|
|
3742
|
+
console.log(` Encryption: ${config.encryptionEnabled ? C.success('Enabled') : C.warn('Disabled')}`);
|
|
3743
|
+
console.log();
|
|
3744
|
+
}
|
|
3745
|
+
catch (e) {
|
|
3746
|
+
console.log(C.error(`\n ❌ Security check failed: ${e.message}\n`));
|
|
3747
|
+
}
|
|
3748
|
+
});
|
|
3749
|
+
program
|
|
3750
|
+
.command('backup')
|
|
3751
|
+
.description('Create backup of cell database')
|
|
3752
|
+
.action(async () => {
|
|
3753
|
+
try {
|
|
3754
|
+
const { autoBackup } = await Promise.resolve().then(() => __importStar(require('./production')));
|
|
3755
|
+
const result = autoBackup();
|
|
3756
|
+
if (result) {
|
|
3757
|
+
console.log(C.success(`\n ✅ Backup created: ${result.path}`));
|
|
3758
|
+
console.log(` Size: ${formatBytes(result.size)}\n`);
|
|
3759
|
+
}
|
|
3760
|
+
else {
|
|
3761
|
+
console.log(C.error('\n ❌ Backup failed\n'));
|
|
3762
|
+
}
|
|
3763
|
+
}
|
|
3764
|
+
catch (e) {
|
|
3765
|
+
console.log(C.error(`\n ❌ Backup failed: ${e.message}\n`));
|
|
3766
|
+
}
|
|
3767
|
+
});
|
|
3768
|
+
program
|
|
3769
|
+
.command('optimize')
|
|
3770
|
+
.description('Optimize database — VACUUM, ANALYZE, prune')
|
|
3771
|
+
.action(async () => {
|
|
3772
|
+
try {
|
|
3773
|
+
const { optimizeDatabase } = await Promise.resolve().then(() => __importStar(require('./production')));
|
|
3774
|
+
const result = optimizeDatabase();
|
|
3775
|
+
console.log(C.success('\n ✅ Database optimized\n'));
|
|
3776
|
+
console.log(` Before: ${formatBytes(result.before.dbSizeBytes)}`);
|
|
3777
|
+
console.log(` After: ${formatBytes(result.after.dbSizeBytes)}`);
|
|
3778
|
+
console.log(` Freed: ${formatBytes(result.freed)}\n`);
|
|
3779
|
+
}
|
|
3780
|
+
catch (e) {
|
|
3781
|
+
console.log(C.error(`\n ❌ Optimize failed: ${e.message}\n`));
|
|
3782
|
+
}
|
|
3783
|
+
});
|
|
3784
|
+
// ─── IDE Intelligence ──────────────────────────────────────
|
|
3785
|
+
program
|
|
3786
|
+
.command('debug-style')
|
|
3787
|
+
.description('Debugging style — console.log vs debugger, efficiency, recommendations')
|
|
3788
|
+
.action(async () => {
|
|
3789
|
+
try {
|
|
3790
|
+
const { initializeIDETables, getDebugStyle } = await Promise.resolve().then(() => __importStar(require('./ide-intelligence')));
|
|
3791
|
+
initializeIDETables();
|
|
3792
|
+
const s = getDebugStyle();
|
|
3793
|
+
console.log(C.bold('\n 🐛 Debug Style\n'));
|
|
3794
|
+
console.log(` Total Sessions: ${C.primary(String(s.totalSessions))}`);
|
|
3795
|
+
console.log(` Preferred: ${C.primary(s.preferredMethod)}`);
|
|
3796
|
+
console.log(` Console.log: ${C.primary(s.consoleLogPercent + '%')}`);
|
|
3797
|
+
console.log(` Debugger: ${s.debuggerPercent + '%'}%`);
|
|
3798
|
+
console.log(` Avg Resolution: ${s.avgResolutionTimeMs}ms`);
|
|
3799
|
+
console.log(` Efficiency: ${C.primary(String(s.efficiencyScore))}/100`);
|
|
3800
|
+
console.log(`\n ${C.dim(s.recommendation)}\n`);
|
|
3801
|
+
}
|
|
3802
|
+
catch (e) {
|
|
3803
|
+
console.log(C.error(`\n ❌ Debug style failed: ${e.message}\n`));
|
|
3804
|
+
}
|
|
3805
|
+
});
|
|
3806
|
+
program
|
|
3807
|
+
.command('prompt-style')
|
|
3808
|
+
.description('Prompt style — length, structure, iteration patterns')
|
|
3809
|
+
.action(async () => {
|
|
3810
|
+
try {
|
|
3811
|
+
const { initializeIDETables, getPromptStyle } = await Promise.resolve().then(() => __importStar(require('./ide-intelligence')));
|
|
3812
|
+
initializeIDETables();
|
|
3813
|
+
const s = getPromptStyle();
|
|
3814
|
+
console.log(C.bold('\n 💬 Prompt Style\n'));
|
|
3815
|
+
console.log(` Total Prompts: ${C.primary(String(s.totalPrompts))}`);
|
|
3816
|
+
console.log(` Avg Words: ${C.primary(String(s.avgWordCount))}`);
|
|
3817
|
+
console.log(` Style: ${C.primary(s.preferredStyle)}`);
|
|
3818
|
+
console.log(` Code-First: ${s.structureBreakdown['code-first'] || 0}%`);
|
|
3819
|
+
console.log(` Avg Iterations: ${s.avgIterations}`);
|
|
3820
|
+
console.log(` Acceptance: ${C.primary(s.acceptanceRate + '%')}`);
|
|
3821
|
+
console.log(` Best Length: ${s.bestPromptLength}`);
|
|
3822
|
+
console.log(`\n ${C.dim(s.recommendation)}\n`);
|
|
3823
|
+
}
|
|
3824
|
+
catch (e) {
|
|
3825
|
+
console.log(C.error(`\n ❌ Prompt style failed: ${e.message}\n`));
|
|
3826
|
+
}
|
|
3827
|
+
});
|
|
3828
|
+
program
|
|
3829
|
+
.command('focus')
|
|
3830
|
+
.description('Focus analysis — deep work, shallow work, tab switching')
|
|
3831
|
+
.action(async () => {
|
|
3832
|
+
try {
|
|
3833
|
+
const { initializeIDETables, getFocusAnalysis } = await Promise.resolve().then(() => __importStar(require('./ide-intelligence')));
|
|
3834
|
+
initializeIDETables();
|
|
3835
|
+
const f = getFocusAnalysis();
|
|
3836
|
+
console.log(C.bold('\n 🎯 Focus Analysis\n'));
|
|
3837
|
+
console.log(` Total Focus: ${formatUptime(Math.round(f.totalFocusTimeMs / 1000))}`);
|
|
3838
|
+
console.log(` Deep Work: ${C.primary(f.deepWorkPercent + '%')}`);
|
|
3839
|
+
console.log(` Shallow Work: ${f.shallowWorkPercent}%`);
|
|
3840
|
+
console.log(` Avg Block: ${formatUptime(Math.round(f.avgFocusBlockMs / 1000))}`);
|
|
3841
|
+
console.log(` Longest: ${formatUptime(Math.round(f.longestFocusMs / 1000))}`);
|
|
3842
|
+
console.log(` Peak Hour: ${f.peakFocusHour}:00`);
|
|
3843
|
+
console.log(` Score: ${C.primary(String(f.focusScore))}/100`);
|
|
3844
|
+
console.log(`\n ${C.dim(f.recommendation)}\n`);
|
|
3845
|
+
}
|
|
3846
|
+
catch (e) {
|
|
3847
|
+
console.log(C.error(`\n ❌ Focus analysis failed: ${e.message}\n`));
|
|
3848
|
+
}
|
|
3849
|
+
});
|
|
3850
|
+
program
|
|
3851
|
+
.command('ide-insights')
|
|
3852
|
+
.description('Full IDE intelligence — debug, prompt, focus, copy-paste, refactor combined')
|
|
3853
|
+
.action(async () => {
|
|
3854
|
+
try {
|
|
3855
|
+
const { initializeIDETables, getIDEInsights } = await Promise.resolve().then(() => __importStar(require('./ide-intelligence')));
|
|
3856
|
+
initializeIDETables();
|
|
3857
|
+
const i = getIDEInsights();
|
|
3858
|
+
console.log(C.bold('\n 🧠 IDE Intelligence Overview\n'));
|
|
3859
|
+
console.log(` Overall Score: ${C.primary(String(i.overallScore))}/100`);
|
|
3860
|
+
console.log(` Debug Efficiency: ${i.debug.efficiencyScore}/100`);
|
|
3861
|
+
console.log(` Prompt Acceptance: ${i.prompt.acceptanceRate}%`);
|
|
3862
|
+
console.log(` Focus Score: ${i.focus.focusScore}/100`);
|
|
3863
|
+
console.log(` Copy-Paste Events: ${i.copyPaste.length}`);
|
|
3864
|
+
console.log(` Refactor Events: ${i.refactor.length}`);
|
|
3865
|
+
console.log(` Stuck Events: ${i.stuck.length}`);
|
|
3866
|
+
if (i.topInsights.length > 0) {
|
|
3867
|
+
console.log(C.bold('\n Top Insights:'));
|
|
3868
|
+
for (const insight of i.topInsights) {
|
|
3869
|
+
console.log(` ${C.dim('→')} ${insight}`);
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
console.log();
|
|
3873
|
+
}
|
|
3874
|
+
catch (e) {
|
|
3875
|
+
console.log(C.error(`\n ❌ IDE insights failed: ${e.message}\n`));
|
|
3876
|
+
}
|
|
3877
|
+
});
|
|
3878
|
+
// ─── Cloud Sync ────────────────────────────────────────────────
|
|
3879
|
+
program
|
|
3880
|
+
.command('cloud-status')
|
|
3881
|
+
.description('Cloud sync status — pending, sent, failed, device ID')
|
|
3882
|
+
.action(async () => {
|
|
3883
|
+
try {
|
|
3884
|
+
const { getSyncStatus } = await Promise.resolve().then(() => __importStar(require('./cloud-sync')));
|
|
3885
|
+
const s = getSyncStatus();
|
|
3886
|
+
console.log(C.bold('\n ☁️ Cloud Sync Status\n'));
|
|
3887
|
+
console.log(` Device: ${C.primary(s.deviceId.slice(0, 12))}...`);
|
|
3888
|
+
console.log(` Anonymous: ${C.primary(s.anonymousId)}`);
|
|
3889
|
+
console.log(` Pending: ${s.pending}`);
|
|
3890
|
+
console.log(` Sent: ${C.success(String(s.sent))}`);
|
|
3891
|
+
console.log(` Failed: ${s.failed > 0 ? C.error(String(s.failed)) : C.success('0')}`);
|
|
3892
|
+
console.log(` Last Sync: ${s.lastSync || 'never'}`);
|
|
3893
|
+
console.log();
|
|
3894
|
+
}
|
|
3895
|
+
catch (e) {
|
|
3896
|
+
console.log(C.error(`\n ❌ Cloud status failed: ${e.message}\n`));
|
|
3897
|
+
}
|
|
3898
|
+
});
|
|
3899
|
+
program
|
|
3900
|
+
.command('cloud-validate')
|
|
3901
|
+
.description('Validate a payload for cloud sync — check forbidden fields + size')
|
|
3902
|
+
.argument('[data]', 'JSON data to validate')
|
|
3903
|
+
.action(async (data) => {
|
|
3904
|
+
try {
|
|
3905
|
+
const { validatePayload } = await Promise.resolve().then(() => __importStar(require('./cloud-sync')));
|
|
3906
|
+
const payload = data ? JSON.parse(data) : { test: 'example', language: 'typescript' };
|
|
3907
|
+
const v = validatePayload(payload);
|
|
3908
|
+
console.log(C.bold('\n 🔍 Payload Validation\n'));
|
|
3909
|
+
console.log(` Valid: ${v.valid ? C.success('YES') : C.error('NO')}`);
|
|
3910
|
+
console.log(` Size: ${v.payloadSize}B / ${v.maxPayloadSize}B`);
|
|
3911
|
+
if (v.blockedFields.length > 0) {
|
|
3912
|
+
console.log(` Blocked: ${C.error(v.blockedFields.join(', '))}`);
|
|
3913
|
+
}
|
|
3914
|
+
if (v.errors.length > 0) {
|
|
3915
|
+
console.log(` Errors: ${C.error(v.errors.join('; '))}`);
|
|
3916
|
+
}
|
|
3917
|
+
console.log();
|
|
3918
|
+
}
|
|
3919
|
+
catch (e) {
|
|
3920
|
+
console.log(C.error(`\n ❌ Validate failed: ${e.message}\n`));
|
|
3921
|
+
}
|
|
3922
|
+
});
|
|
3923
|
+
program
|
|
3924
|
+
.command('cloud-queue')
|
|
3925
|
+
.description('Show offline queue — pending, failed, sent')
|
|
3926
|
+
.action(async () => {
|
|
3927
|
+
try {
|
|
3928
|
+
const { getPendingQueue, retryFailedEntries } = await Promise.resolve().then(() => __importStar(require('./cloud-sync')));
|
|
3929
|
+
const pending = getPendingQueue();
|
|
3930
|
+
const failed = retryFailedEntries();
|
|
3931
|
+
console.log(C.bold('\n 📦 Offline Queue\n'));
|
|
3932
|
+
console.log(` Pending: ${C.primary(String(pending.length))}`);
|
|
3933
|
+
console.log(` Retryable: ${failed.length}`);
|
|
3934
|
+
if (pending.length > 0) {
|
|
3935
|
+
console.log(C.bold('\n Pending Entries:'));
|
|
3936
|
+
for (const e of pending.slice(0, 5)) {
|
|
3937
|
+
console.log(` ${C.dim(e.timestamp)} — ${e.priority} — ${e.status}`);
|
|
3938
|
+
}
|
|
3939
|
+
}
|
|
3940
|
+
console.log();
|
|
3941
|
+
}
|
|
3942
|
+
catch (e) {
|
|
3943
|
+
console.log(C.error(`\n ❌ Queue failed: ${e.message}\n`));
|
|
3944
|
+
}
|
|
3945
|
+
});
|
|
3946
|
+
function formatUptime(seconds) {
|
|
3947
|
+
const h = Math.floor(seconds / 3600);
|
|
3948
|
+
const m = Math.floor((seconds % 3600) / 60);
|
|
3949
|
+
const s = seconds % 60;
|
|
3950
|
+
if (h > 0)
|
|
3951
|
+
return `${h}h ${m}m`;
|
|
3952
|
+
if (m > 0)
|
|
3953
|
+
return `${m}m ${s}s`;
|
|
3954
|
+
return `${s}s`;
|
|
3955
|
+
}
|
|
3956
|
+
function formatBytes(bytes) {
|
|
3957
|
+
if (bytes < 1024)
|
|
3958
|
+
return `${bytes}B`;
|
|
3959
|
+
if (bytes < 1024 * 1024)
|
|
3960
|
+
return `${Math.round(bytes / 1024)}KB`;
|
|
3961
|
+
return `${Math.round(bytes / (1024 * 1024))}MB`;
|
|
3962
|
+
}
|
|
1789
3963
|
// ─── Number Command Interception ──────────────────────
|
|
1790
3964
|
const rawArgs = process.argv.slice(2);
|
|
1791
3965
|
if (rawArgs.length === 0) {
|
|
@@ -1796,5 +3970,21 @@ const nums = parseNumberArg(rawArgs[0]);
|
|
|
1796
3970
|
if (nums.length > 0) {
|
|
1797
3971
|
runNumbers(nums);
|
|
1798
3972
|
}
|
|
3973
|
+
const SKIP_DAEMON_COMMANDS = new Set([
|
|
3974
|
+
'start', 'stop', 'restart', 'status',
|
|
3975
|
+
'install-service', 'uninstall-service', 'service-status',
|
|
3976
|
+
'install', 'mcp', 'connect', 'init', 'run', 'help',
|
|
3977
|
+
'--help', '-h', '--version', '-V',
|
|
3978
|
+
]);
|
|
3979
|
+
program.hook('preAction', async (thisCommand) => {
|
|
3980
|
+
const cmdName = thisCommand.name();
|
|
3981
|
+
if (SKIP_DAEMON_COMMANDS.has(cmdName))
|
|
3982
|
+
return;
|
|
3983
|
+
const parentName = thisCommand.parent?.name();
|
|
3984
|
+
if (parentName === 'daemon')
|
|
3985
|
+
return;
|
|
3986
|
+
const { ensureDaemon } = await Promise.resolve().then(() => __importStar(require('./daemon/lifecycle')));
|
|
3987
|
+
await ensureDaemon({ silent: true });
|
|
3988
|
+
});
|
|
1799
3989
|
program.parse(process.argv);
|
|
1800
3990
|
//# sourceMappingURL=cli.js.map
|