fivocell 2.0.0 → 3.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 +104 -697
- package/dist/behavioral-tracker.d.ts +90 -0
- package/dist/behavioral-tracker.d.ts.map +1 -0
- package/dist/behavioral-tracker.js +185 -0
- package/dist/behavioral-tracker.js.map +1 -0
- package/dist/cli.d.ts +1 -6
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +430 -3862
- package/dist/cli.js.map +1 -1
- package/dist/code-scanner.d.ts +51 -0
- package/dist/code-scanner.d.ts.map +1 -0
- package/dist/code-scanner.js +966 -0
- package/dist/code-scanner.js.map +1 -0
- package/dist/community-intel.d.ts +34 -0
- package/dist/community-intel.d.ts.map +1 -0
- package/dist/community-intel.js +148 -0
- package/dist/community-intel.js.map +1 -0
- package/dist/daemon/lifecycle.d.ts +0 -15
- package/dist/daemon/lifecycle.d.ts.map +1 -1
- package/dist/daemon/lifecycle.js +88 -231
- package/dist/daemon/lifecycle.js.map +1 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +368 -19
- package/dist/daemon/server.js.map +1 -1
- package/dist/developer-intelligence.d.ts +18 -0
- package/dist/developer-intelligence.d.ts.map +1 -0
- package/dist/developer-intelligence.js +180 -0
- package/dist/developer-intelligence.js.map +1 -0
- package/dist/layers.d.ts +92 -0
- package/dist/layers.d.ts.map +1 -0
- package/dist/layers.js +226 -0
- package/dist/layers.js.map +1 -0
- package/dist/mcp-server.d.ts +194 -1842
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +169 -875
- package/dist/mcp-server.js.map +1 -1
- package/dist/pc-scanner.d.ts +46 -0
- package/dist/pc-scanner.d.ts.map +1 -0
- package/dist/pc-scanner.js +488 -0
- package/dist/pc-scanner.js.map +1 -0
- package/dist/predictive-engine.d.ts +19 -0
- package/dist/predictive-engine.d.ts.map +1 -0
- package/dist/predictive-engine.js +107 -0
- package/dist/predictive-engine.js.map +1 -0
- package/dist/style-pull.d.ts +1 -1
- package/dist/style-pull.js +2 -2
- package/dist/team-git.d.ts +47 -0
- package/dist/team-git.d.ts.map +1 -0
- package/dist/team-git.js +305 -0
- package/dist/team-git.js.map +1 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -37,3954 +37,522 @@ 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;
|
|
41
|
-
const commander_1 = require("commander");
|
|
42
40
|
const path = __importStar(require("path"));
|
|
43
41
|
const fs = __importStar(require("fs"));
|
|
44
|
-
const os = __importStar(require("os"));
|
|
45
42
|
const chalk_1 = __importDefault(require("chalk"));
|
|
46
43
|
const figlet_1 = __importDefault(require("figlet"));
|
|
47
44
|
const gradient_string_1 = __importDefault(require("gradient-string"));
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
|
|
45
|
+
const database_1 = require("./core/database");
|
|
46
|
+
const layers_1 = require("./layers");
|
|
47
|
+
(0, database_1.initializeDatabase)();
|
|
51
48
|
const C = {
|
|
52
49
|
primary: chalk_1.default.hex('#FF6B35'),
|
|
53
|
-
primaryLight: chalk_1.default.hex('#FF8C42'),
|
|
54
|
-
primaryDark: chalk_1.default.hex('#E65100'),
|
|
55
|
-
accent: chalk_1.default.hex('#FFAB91'),
|
|
56
50
|
success: chalk_1.default.green,
|
|
57
|
-
error: chalk_1.default.red,
|
|
58
51
|
warn: chalk_1.default.yellow,
|
|
59
|
-
info: chalk_1.default.hex('#FFAB91'),
|
|
60
52
|
dim: chalk_1.default.dim,
|
|
61
53
|
bold: chalk_1.default.bold,
|
|
62
54
|
num: (s) => chalk_1.default.hex('#FF6B35').bold(s),
|
|
63
|
-
header: (s) => chalk_1.default.hex('#FF8C42').bold(s),
|
|
64
|
-
sub: (s) => chalk_1.default.hex('#FFAB91').dim(s),
|
|
65
55
|
};
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
f = 'FIVO CELL';
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
const banner = (0, gradient_string_1.default)(['#FF6B35', '#FF8C42', '#FFAB91'])(f);
|
|
108
|
-
console.log(banner);
|
|
109
|
-
console.log(C.accent(centerText('Anticipatory Intelligence Engine v1.0.0')));
|
|
110
|
-
console.log(thick);
|
|
111
|
-
console.log(C.primary.bold('\n ▸ Named Commands'));
|
|
112
|
-
console.log(line);
|
|
113
|
-
console.log(` ${C.primary.bold('run')} ${C.primary.bold('status')} ${C.primary.bold('start')} ${C.primary.bold('stop')}`);
|
|
114
|
-
console.log(C.primary.bold('\n ▸ Quick Commands'));
|
|
115
|
-
console.log(line);
|
|
116
|
-
const imp = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
117
|
-
for (let i = 0; i < imp.length; i += 5) {
|
|
118
|
-
const row = imp.slice(i, i + 5).map(n => `${C.num(String(n).padStart(2))} ${C.bold(NUM[n].padEnd(14))}`).join(C.dim(' │ '));
|
|
119
|
-
console.log(` ${row}`);
|
|
120
|
-
}
|
|
121
|
-
console.log(C.primary.bold('\n ▸ Other Commands: 11-39'));
|
|
122
|
-
console.log(line);
|
|
123
|
-
console.log(C.dim(' cell 9 → Run command by number'));
|
|
124
|
-
console.log(C.dim(' cell 1,2,3 → Run multiple commands'));
|
|
125
|
-
console.log(C.dim(' cell 1-5 → Run range of commands'));
|
|
126
|
-
console.log();
|
|
127
|
-
console.log(thick);
|
|
128
|
-
console.log();
|
|
129
|
-
}
|
|
130
|
-
// ─── Number Argument Parser ────────────────────────────
|
|
131
|
-
function parseNumberArg(input) {
|
|
132
|
-
if (/^\d+$/.test(input))
|
|
133
|
-
return [parseInt(input)];
|
|
134
|
-
if (/^\d+-\d+$/.test(input)) {
|
|
135
|
-
const [s, e] = input.split('-').map(Number);
|
|
136
|
-
if (s > e)
|
|
137
|
-
return [];
|
|
138
|
-
return Array.from({ length: e - s + 1 }, (_, i) => s + i);
|
|
139
|
-
}
|
|
140
|
-
if (/^\d+(,\d+)+$/.test(input)) {
|
|
141
|
-
return [...new Set(input.split(',').map(Number))];
|
|
142
|
-
}
|
|
143
|
-
return [];
|
|
144
|
-
}
|
|
145
|
-
function runNumbers(nums) {
|
|
146
|
-
const script = process.argv[1];
|
|
147
|
-
for (const n of nums) {
|
|
148
|
-
const cmd = NUM[n];
|
|
149
|
-
if (!cmd) {
|
|
150
|
-
console.error(C.error(`Unknown command number: ${n}`));
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
console.log(C.primary(`\n ──▶ ${n}: ${cmd} ${'─'.repeat(50)}`));
|
|
154
|
-
(0, child_process_1.execSync)(`node "${script}" ${cmd}`, { stdio: 'inherit', cwd: process.cwd() });
|
|
155
|
-
}
|
|
156
|
-
process.exit(0);
|
|
157
|
-
}
|
|
158
|
-
const program = new commander_1.Command();
|
|
159
|
-
program
|
|
160
|
-
.name('cell')
|
|
161
|
-
.description('FIVO Cell — Anticipatory Intelligence. Learns your coding taste.')
|
|
162
|
-
.version('1.0.0');
|
|
163
|
-
program
|
|
164
|
-
.command('run')
|
|
165
|
-
.description('Initialize FIVO Cell in the current project')
|
|
166
|
-
.action(() => {
|
|
167
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
168
|
-
if (!fs.existsSync(cellDir)) {
|
|
169
|
-
fs.mkdirSync(cellDir, { recursive: true });
|
|
170
|
-
}
|
|
171
|
-
const store = new index_1.PatternStore(cellDir);
|
|
172
|
-
store.save();
|
|
173
|
-
const thick = C.primary(hline('━'));
|
|
174
|
-
const line = C.primaryDark(hline('─'));
|
|
175
|
-
console.clear();
|
|
176
|
-
console.log();
|
|
177
|
-
console.log(thick);
|
|
178
|
-
console.log(C.success.bold(centerText('✅ FIVO Cell Initialized')));
|
|
179
|
-
console.log(thick);
|
|
180
|
-
console.log();
|
|
181
|
-
console.log(C.info(' Directory: ') + C.bold(cellDir));
|
|
182
|
-
console.log(line);
|
|
183
|
-
console.log();
|
|
184
|
-
console.log(C.primary.bold(' 🌐 Cloud Sync: ON (Anonymous pattern stats only)'));
|
|
185
|
-
console.log(C.sub(' → Better suggestions from 10K+ developers'));
|
|
186
|
-
console.log(C.sub(' → Your code NEVER leaves your machine'));
|
|
187
|
-
console.log(C.sub(' → What we share (just stats, no code):'));
|
|
188
|
-
console.log(C.sub(' "prefers const over let (87%)"'));
|
|
189
|
-
console.log(C.sub(' "uses named exports, not default (83%)"'));
|
|
190
|
-
console.log(C.sub(' "vitest over jest (91%)"'));
|
|
191
|
-
console.log(C.sub(' "pnpm over npm (86%)"'));
|
|
192
|
-
console.log(C.sub(' → No file paths. No project names. No source code.'));
|
|
193
|
-
console.log(C.sub(' → Turn off anytime: cell cloud off'));
|
|
194
|
-
console.log();
|
|
195
|
-
console.log(line);
|
|
196
|
-
console.log(C.info(' Run ') + C.primary.bold('cell status') + C.info(' to see your taste profile.'));
|
|
197
|
-
console.log(C.dim(' Run ') + C.primary('cell watch') + C.dim(' for auto-learning from file edits'));
|
|
198
|
-
console.log(thick);
|
|
199
|
-
console.log();
|
|
200
|
-
// Auto-install git hook
|
|
201
|
-
const gitDir = path.join(process.cwd(), '.git');
|
|
202
|
-
if (fs.existsSync(gitDir)) {
|
|
203
|
-
const hooksDir = path.join(gitDir, 'hooks');
|
|
204
|
-
if (!fs.existsSync(hooksDir))
|
|
205
|
-
fs.mkdirSync(hooksDir, { recursive: true });
|
|
206
|
-
const hookPath = path.join(hooksDir, 'post-commit');
|
|
207
|
-
if (!fs.existsSync(hookPath)) {
|
|
208
|
-
const cellBin = process.argv[1];
|
|
209
|
-
const hook = `#!/bin/sh
|
|
210
|
-
# FIVO Cell — auto-learn on commit
|
|
211
|
-
DIFF=$(git diff --cached --diff-algorithm=histogram)
|
|
212
|
-
if [ -n "$DIFF" ]; then
|
|
213
|
-
node "${cellBin}" learn --original "$(echo "$DIFF" | head -200)" --edited "committed" 2>/dev/null
|
|
214
|
-
fi
|
|
215
|
-
`;
|
|
216
|
-
fs.writeFileSync(hookPath, hook, { mode: 0o755 });
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
// Migration: legacy → .cell/ format
|
|
220
|
-
try {
|
|
221
|
-
const store = new index_1.CellStore(path.join(process.cwd(), '.cell'));
|
|
222
|
-
const result = store.migrateFromLegacy(cellDir);
|
|
223
|
-
if (result.migrated > 0) {
|
|
224
|
-
console.log(C.dim(` 📦 Migrated ${result.migrated} patterns to .cell/ format`));
|
|
225
|
-
console.log(C.dim(` 📁 .cell/personal/style.json`));
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
catch { }
|
|
229
|
-
// Rebuild search index
|
|
230
|
-
try {
|
|
231
|
-
const se = new index_1.SearchEngine();
|
|
232
|
-
const r = se.rebuild();
|
|
233
|
-
if (r.indexed > 0)
|
|
234
|
-
console.log(C.dim(` 🔍 Search index: ${r.indexed} files indexed`));
|
|
235
|
-
}
|
|
236
|
-
catch { }
|
|
237
|
-
});
|
|
238
|
-
program
|
|
239
|
-
.command('status')
|
|
240
|
-
.description('Show current taste profile summary')
|
|
241
|
-
.action(() => {
|
|
242
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
243
|
-
if (!fs.existsSync(cellDir)) {
|
|
244
|
-
console.log('❌ Cell not initialized. Run `cell init` first.');
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
const store = new index_1.PatternStore(cellDir);
|
|
248
|
-
const thick = C.primary(hline('━'));
|
|
249
|
-
const line = C.primaryDark(hline('─'));
|
|
250
|
-
const patterns = store.getAllPatterns();
|
|
251
|
-
console.clear();
|
|
252
|
-
console.log();
|
|
253
|
-
console.log(thick);
|
|
254
|
-
console.log(C.primary.bold(centerText('📊 FIVO Cell — Taste Profile')));
|
|
255
|
-
console.log(thick);
|
|
256
|
-
console.log();
|
|
257
|
-
if (patterns.length === 0) {
|
|
258
|
-
console.log(C.warn(centerText('No patterns learned yet. Start coding to teach Cell your style.')));
|
|
259
|
-
console.log();
|
|
260
|
-
console.log(thick);
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
console.log(` Total patterns: ${C.bold(String(patterns.length))}`);
|
|
264
|
-
console.log(` Total signals: ${C.bold(String(store.getTotalSignals()))}`);
|
|
265
|
-
console.log(line);
|
|
266
|
-
const strong = store.getPatternsByTier('strong');
|
|
267
|
-
const moderate = store.getPatternsByTier('moderate');
|
|
268
|
-
const weak = store.getPatternsByTier('weak');
|
|
269
|
-
console.log(C.primary.bold('\n Tiers:'));
|
|
270
|
-
console.log(C.success(` ● Strong (>0.80): ${String(strong.length).padStart(3)} patterns`));
|
|
271
|
-
console.log(C.warn(` ● Moderate (0.50-0.80): ${String(moderate.length).padStart(3)} patterns`));
|
|
272
|
-
console.log(C.dim(` ● Weak (0.30-0.50): ${String(weak.length).padStart(3)} patterns`));
|
|
273
|
-
if (strong.length > 0) {
|
|
274
|
-
console.log(C.primary.bold('\n Top Patterns:'));
|
|
275
|
-
const top = patterns
|
|
276
|
-
.sort((a, b) => b.confidence.mean - a.confidence.mean)
|
|
277
|
-
.slice(0, 5);
|
|
278
|
-
for (const p of top) {
|
|
279
|
-
console.log(C.success(` ✅ ${p.description}`) + C.dim(` (${p.confidence.mean}, ${p.signals?.positive || 0}/${p.signals?.total || 0} signals)`));
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
// Blind spots
|
|
283
|
-
try {
|
|
284
|
-
const bs = new index_1.BlindSpotEngine(cellDir);
|
|
285
|
-
const summary = bs.getSummary();
|
|
286
|
-
if (summary.top.length > 0) {
|
|
287
|
-
console.log(line);
|
|
288
|
-
console.log(C.primary.bold('\n 👁️ Blind Spots Detected:'));
|
|
289
|
-
for (const s of summary.top.slice(0, 3)) {
|
|
290
|
-
const sev = s.severity === 'critical' ? C.error('●') : s.severity === 'high' ? C.warn('●') : C.info('●');
|
|
291
|
-
console.log(C.warn(` ${sev} ${s.description} (${Math.round(s.missedRate * 100)}% of cases)`));
|
|
292
|
-
console.log(C.dim(` ${s.suggestion}`));
|
|
293
|
-
}
|
|
294
|
-
console.log(C.dim(`\n Total: ${summary.total} blind spots · Critical: ${summary.critical} · High: ${summary.high}`));
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
catch { }
|
|
298
|
-
// Naming + Structure + Architecture + Productivity
|
|
299
|
-
try {
|
|
300
|
-
const namingSummary = new index_1.NamingEngine().getSummary();
|
|
301
|
-
const structureSummary = new index_1.StructureEngine().getSummary();
|
|
302
|
-
const frontendSummary = new index_1.FrontendEngine().getSummary();
|
|
303
|
-
const backendSummary = new index_1.BackendEngine().getSummary();
|
|
304
|
-
const productivitySummary = new index_1.ProductivityEngine().getSummary();
|
|
305
|
-
const syntaxSummary = new index_1.SyntaxEngine().getSummary();
|
|
306
|
-
if (namingSummary.length > 0 && structureSummary.length > 0) {
|
|
307
|
-
console.log(line);
|
|
308
|
-
console.log(C.primary.bold('\n 📐 Style Intelligence:'));
|
|
309
|
-
for (const s of namingSummary)
|
|
310
|
-
console.log(C.info(` ${s}`));
|
|
311
|
-
for (const s of structureSummary)
|
|
312
|
-
console.log(C.info(` ${s}`));
|
|
313
|
-
for (const s of syntaxSummary)
|
|
314
|
-
console.log(C.info(` ${s}`));
|
|
315
|
-
}
|
|
316
|
-
const archSummary = new index_1.ArchitectureEngine().getSummary();
|
|
317
|
-
if (frontendSummary.length > 0 || backendSummary.length > 0 || archSummary.length > 0) {
|
|
318
|
-
console.log(line);
|
|
319
|
-
console.log(C.primary.bold('\n 🏗️ Architecture Intelligence:'));
|
|
320
|
-
for (const s of frontendSummary)
|
|
321
|
-
console.log(C.info(` ${s}`));
|
|
322
|
-
for (const s of backendSummary)
|
|
323
|
-
console.log(C.info(` ${s}`));
|
|
324
|
-
for (const s of archSummary)
|
|
325
|
-
console.log(C.info(` ${s}`));
|
|
326
|
-
}
|
|
327
|
-
if (productivitySummary.length > 0) {
|
|
328
|
-
console.log(line);
|
|
329
|
-
console.log(C.primary.bold('\n ⚡ Productivity Intelligence:'));
|
|
330
|
-
for (const s of productivitySummary)
|
|
331
|
-
console.log(C.info(` ${s}`));
|
|
332
|
-
}
|
|
333
|
-
const knowledgeSummary = new index_1.KnowledgeGraphEngine().getSummary();
|
|
334
|
-
if (knowledgeSummary.length > 0) {
|
|
335
|
-
console.log(line);
|
|
336
|
-
console.log(C.primary.bold('\n 🧠 Knowledge Graph:'));
|
|
337
|
-
for (const s of knowledgeSummary)
|
|
338
|
-
console.log(C.info(` ${s}`));
|
|
339
|
-
}
|
|
340
|
-
const teamAdvSummary = new index_1.TeamAdvancedEngine().getSummary();
|
|
341
|
-
const communityAdvSummary = new index_1.CommunityAdvancedEngine().getSummary();
|
|
342
|
-
if (teamAdvSummary.length > 0) {
|
|
343
|
-
console.log(line);
|
|
344
|
-
console.log(C.primary.bold('\n 👥 Team Advanced:'));
|
|
345
|
-
for (const s of teamAdvSummary)
|
|
346
|
-
console.log(C.info(` ${s}`));
|
|
347
|
-
}
|
|
348
|
-
if (communityAdvSummary.length > 0) {
|
|
349
|
-
console.log(line);
|
|
350
|
-
console.log(C.primary.bold('\n 🌐 Community Advanced:'));
|
|
351
|
-
for (const s of communityAdvSummary)
|
|
352
|
-
console.log(C.info(` ${s}`));
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
catch { }
|
|
356
|
-
console.log();
|
|
357
|
-
console.log(thick);
|
|
358
|
-
console.log();
|
|
359
|
-
});
|
|
360
|
-
program
|
|
361
|
-
.command('taste show')
|
|
362
|
-
.description('Display your cell.md profile')
|
|
363
|
-
.action(() => {
|
|
364
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
365
|
-
const mdPath = path.join(cellDir, 'cell.md');
|
|
366
|
-
if (!fs.existsSync(mdPath)) {
|
|
367
|
-
console.log('❌ No taste profile found. Run `cell init` first, then start coding.');
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
console.log(fs.readFileSync(mdPath, 'utf-8'));
|
|
371
|
-
});
|
|
372
|
-
program
|
|
373
|
-
.command('taste reset')
|
|
374
|
-
.description('Reset all learned patterns')
|
|
375
|
-
.action(() => {
|
|
376
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
377
|
-
if (!fs.existsSync(cellDir)) {
|
|
378
|
-
console.log('❌ Cell not initialized.');
|
|
379
|
-
return;
|
|
380
|
-
}
|
|
381
|
-
const store = new index_1.PatternStore(cellDir);
|
|
382
|
-
store.clear();
|
|
383
|
-
console.log('✅ All patterns reset. Cell will relearn from scratch.');
|
|
384
|
-
});
|
|
385
|
-
program
|
|
386
|
-
.command('learn')
|
|
387
|
-
.description('Feed a code edit to Cell for learning')
|
|
388
|
-
.option('-o, --original <code>', 'Original AI-generated code')
|
|
389
|
-
.option('-e, --edited <code>', 'Your edited version')
|
|
390
|
-
.option('-a, --accept', 'Mark as accepted (no edits)')
|
|
391
|
-
.option('-r, --reject', 'Mark as rejected')
|
|
392
|
-
.option('--audit', 'Run security and error analysis on edited code')
|
|
393
|
-
.action((options) => {
|
|
394
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
395
|
-
if (!fs.existsSync(cellDir)) {
|
|
396
|
-
console.log('❌ Cell not initialized. Run `cell init` first.');
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
const capture = new index_1.SignalCapture();
|
|
400
|
-
const cascade = new index_1.ExtractionCascade();
|
|
401
|
-
const store = new index_1.PatternStore(cellDir);
|
|
402
|
-
const context = {
|
|
403
|
-
language: 'typescript',
|
|
404
|
-
framework: 'unknown',
|
|
405
|
-
fileType: 'unknown',
|
|
406
|
-
strictness: 'moderate',
|
|
407
|
-
projectId: path.basename(process.cwd()),
|
|
408
|
-
};
|
|
409
|
-
if (options.accept && options.original) {
|
|
410
|
-
const signal = capture.captureAccept(options.original, context);
|
|
411
|
-
console.log(`✅ Accept signal captured (session: ${signal.sessionId})`);
|
|
412
|
-
}
|
|
413
|
-
else if (options.reject && options.original) {
|
|
414
|
-
const signal = capture.captureReject(options.original, context);
|
|
415
|
-
console.log(`❌ Reject signal captured (session: ${signal.sessionId})`);
|
|
416
|
-
}
|
|
417
|
-
else if (options.original && options.edited) {
|
|
418
|
-
const signal = capture.captureEditDiff(options.original, options.edited, context);
|
|
419
|
-
const result = cascade.extract(options.original, options.edited, context.language);
|
|
420
|
-
console.log(`📝 Edit diff captured (session: ${signal.sessionId})`);
|
|
421
|
-
console.log(` Step used: ${result.stepUsed}`);
|
|
422
|
-
console.log(` Latency: ${result.latencyMs}ms`);
|
|
423
|
-
console.log(` Patterns found: ${result.patterns.length}`);
|
|
424
|
-
for (const p of result.patterns) {
|
|
425
|
-
const pattern = store.addOrUpdatePattern(p.category, p.description, p.from, p.to, true, p.conditions, 'global', result.stepUsed, result.language);
|
|
426
|
-
console.log(` → ${p.description} (confidence: ${pattern.confidence.mean}, quality: ${pattern.quality.score})`);
|
|
427
|
-
}
|
|
428
|
-
store.save();
|
|
429
|
-
try {
|
|
430
|
-
new index_1.CellStore().syncFromPatternStore(store);
|
|
431
|
-
}
|
|
432
|
-
catch { }
|
|
433
|
-
console.log(`\n✅ Taste profile updated. ${store.getPatternCount()} patterns total.`);
|
|
434
|
-
if (options.audit && options.edited) {
|
|
435
|
-
const auditResult = cascade.audit(options.edited);
|
|
436
|
-
if (auditResult.security.length > 0 || auditResult.errors.length > 0) {
|
|
437
|
-
console.log(`\n🔍 Code audit results:`);
|
|
438
|
-
for (const s of auditResult.security) {
|
|
439
|
-
console.log(` ⚠ [${s.severity}] ${s.type}:${s.line} ${s.message}`);
|
|
440
|
-
}
|
|
441
|
-
for (const e of auditResult.errors) {
|
|
442
|
-
console.log(` ⚠ [${e.severity}] ${e.type}:${e.line} ${e.message}`);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
else {
|
|
446
|
-
console.log(`\n🔍 Code audit: no issues found`);
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
else {
|
|
451
|
-
console.log('❌ Provide --original and --edited, or --accept with --original, or --reject with --original');
|
|
452
|
-
}
|
|
453
|
-
});
|
|
454
|
-
program
|
|
455
|
-
.command('push')
|
|
456
|
-
.description('Push your taste to team directory')
|
|
457
|
-
.option('-u, --username <name>', 'Your username')
|
|
458
|
-
.action((options) => {
|
|
459
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
460
|
-
if (!fs.existsSync(cellDir)) {
|
|
461
|
-
console.log('❌ Cell not initialized. Run `cell init` first.');
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
const username = options.username || 'anonymous';
|
|
465
|
-
const store = new index_1.PatternStore(cellDir);
|
|
466
|
-
const composer = new index_1.TeamComposer(store, cellDir);
|
|
467
|
-
composer.pushTaste(username);
|
|
468
|
-
console.log(`✅ Taste pushed for ${username}.`);
|
|
469
|
-
console.log(` Team members: ${composer.getTeamMembers().join(', ') || 'none yet'}`);
|
|
470
|
-
});
|
|
471
|
-
program
|
|
472
|
-
.command('pull')
|
|
473
|
-
.description('Pull team or member taste')
|
|
474
|
-
.option('-u, --username <name>', 'Pull specific member taste')
|
|
475
|
-
.option('--team', 'Pull full team composite')
|
|
476
|
-
.action((options) => {
|
|
477
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
478
|
-
if (!fs.existsSync(cellDir)) {
|
|
479
|
-
console.log('❌ Cell not initialized.');
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
const store = new index_1.PatternStore(cellDir);
|
|
483
|
-
const composer = new index_1.TeamComposer(store, cellDir);
|
|
484
|
-
if (options.username) {
|
|
485
|
-
const taste = composer.pullTaste(options.username);
|
|
486
|
-
if (!taste) {
|
|
487
|
-
console.log(`❌ No taste found for ${options.username}.`);
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
|
-
console.log(`📥 Pulled taste from ${options.username}:`);
|
|
491
|
-
console.log(` Patterns: ${taste.patterns.length}`);
|
|
492
|
-
console.log(` Signals: ${taste.totalSignals}`);
|
|
493
|
-
}
|
|
494
|
-
else {
|
|
495
|
-
const taste = composer.pullTeamTaste();
|
|
496
|
-
if (!taste) {
|
|
497
|
-
console.log('❌ No team taste available. Have teammates pushed yet?');
|
|
498
|
-
return;
|
|
499
|
-
}
|
|
500
|
-
console.log(`📥 Pulled team taste (${composer.getTeamMembers().length} members):`);
|
|
501
|
-
console.log(` Patterns: ${taste.patterns.length}`);
|
|
502
|
-
console.log(` Total signals: ${taste.totalSignals}`);
|
|
503
|
-
}
|
|
504
|
-
});
|
|
505
|
-
program
|
|
506
|
-
.command('vote')
|
|
507
|
-
.description('Vote on a pattern conflict')
|
|
508
|
-
.option('-p, --pattern <id>', 'Pattern conflict ID (e.g., p_abc_vs_p_def)')
|
|
509
|
-
.option('-v, --vote <choice>', 'Your vote: A, B, or none')
|
|
510
|
-
.option('--status', 'Show vote status')
|
|
511
|
-
.action((options) => {
|
|
512
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
513
|
-
if (!fs.existsSync(cellDir)) {
|
|
514
|
-
console.log('❌ Cell not initialized.');
|
|
515
|
-
return;
|
|
516
|
-
}
|
|
517
|
-
const detector = new index_1.ConflictDetector(cellDir);
|
|
518
|
-
if (options.status && options.pattern) {
|
|
519
|
-
const sessions = fs.existsSync(detector['voteStorePath'])
|
|
520
|
-
? JSON.parse(fs.readFileSync(detector['voteStorePath'], 'utf-8'))
|
|
521
|
-
: [];
|
|
522
|
-
const session = sessions.find((s) => s.patternId === options.pattern);
|
|
523
|
-
if (!session) {
|
|
524
|
-
console.log('❌ Vote session not found.');
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
console.log(detector.getVoteStatus(session));
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
|
-
if (options.pattern && options.vote) {
|
|
531
|
-
const username = 'anonymous';
|
|
532
|
-
const session = detector.castVote(options.pattern, username, options.vote);
|
|
533
|
-
if (!session) {
|
|
534
|
-
console.log('❌ Vote failed. Check pattern ID and deadline.');
|
|
535
|
-
return;
|
|
536
|
-
}
|
|
537
|
-
console.log(`✅ Vote cast: ${options.vote}`);
|
|
538
|
-
console.log(detector.getVoteStatus(session));
|
|
539
|
-
return;
|
|
540
|
-
}
|
|
541
|
-
console.log('Usage: cell taste vote --pattern "X_vs_Y" --vote A');
|
|
542
|
-
console.log(' cell taste vote --pattern "X_vs_Y" --status');
|
|
543
|
-
});
|
|
544
|
-
program
|
|
545
|
-
.command('community')
|
|
546
|
-
.description('Show community prior patterns')
|
|
547
|
-
.action(() => {
|
|
548
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
549
|
-
if (!fs.existsSync(cellDir)) {
|
|
550
|
-
console.log('❌ Cell not initialized.');
|
|
551
|
-
return;
|
|
552
|
-
}
|
|
553
|
-
const prior = new index_1.CommunityPrior(cellDir);
|
|
554
|
-
if (prior.getPatternCount() === 0) {
|
|
555
|
-
console.log('🌱 Generating synthetic community seed...');
|
|
556
|
-
prior.generateSyntheticSeed();
|
|
557
|
-
}
|
|
558
|
-
console.log(`\n🌍 ${prior.getDisplayLabel()}`);
|
|
559
|
-
console.log(` Total patterns: ${prior.getPatternCount()}`);
|
|
560
|
-
console.log(` Synthetic: ${prior.getSyntheticPatterns().length}`);
|
|
561
|
-
console.log(` Live-learned: ${prior.getLivePatterns().length}`);
|
|
562
|
-
const patterns = prior.getPatterns(0.5);
|
|
563
|
-
if (patterns.length > 0) {
|
|
564
|
-
console.log('\nTop community patterns:');
|
|
565
|
-
for (const p of patterns.slice(0, 5)) {
|
|
566
|
-
const marker = prior.getSyntheticPatterns().some(sp => sp.patternId === p.patternId) ? '🧪' : '👥';
|
|
567
|
-
console.log(` ${marker} ${p.description} (${p.confidence.mean})`);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
console.log('');
|
|
571
|
-
});
|
|
572
|
-
program
|
|
573
|
-
.command('next')
|
|
574
|
-
.description('Predict next coding action')
|
|
575
|
-
.option('-a, --action <name>', 'Record an action for sequence learning')
|
|
576
|
-
.option('-f, --feedback <action>', 'Give feedback on a prediction (was it useful?)')
|
|
577
|
-
.action((options) => {
|
|
578
|
-
const predictor = new index_1.NextActionPredictor();
|
|
579
|
-
if (options.action) {
|
|
580
|
-
predictor.recordAction(options.action);
|
|
581
|
-
console.log(`✅ Recorded action: ${options.action}`);
|
|
582
|
-
const predictions = predictor.predictNext([]);
|
|
583
|
-
if (predictions.length > 0) {
|
|
584
|
-
console.log('\nPredicted next actions:');
|
|
585
|
-
for (const p of predictions) {
|
|
586
|
-
console.log(` → ${p.description} (confidence: ${p.confidence})`);
|
|
587
|
-
}
|
|
588
|
-
const bulk = predictor.getBulkSuggestion(predictions);
|
|
589
|
-
if (bulk)
|
|
590
|
-
console.log(` ⚡ ${bulk.description}`);
|
|
591
|
-
}
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
594
|
-
if (options.feedback) {
|
|
595
|
-
predictor.recordFeedback(options.feedback, true);
|
|
596
|
-
console.log(`✅ Feedback recorded for: ${options.feedback}`);
|
|
597
|
-
return;
|
|
598
|
-
}
|
|
599
|
-
const predictions = predictor.predictNext([]);
|
|
600
|
-
console.log('Predicted next actions:');
|
|
601
|
-
for (const p of predictions) {
|
|
602
|
-
console.log(` → ${p.description} (confidence: ${p.confidence})`);
|
|
603
|
-
}
|
|
604
|
-
});
|
|
605
|
-
program
|
|
606
|
-
.command('branch')
|
|
607
|
-
.description('Pre-generate files from git branch name')
|
|
608
|
-
.option('-b, --branch <name>', 'Branch name (e.g., feature/payment-gateway)')
|
|
609
|
-
.action((options) => {
|
|
610
|
-
if (!options.branch) {
|
|
611
|
-
console.log('❌ Provide --branch name');
|
|
612
|
-
return;
|
|
613
|
-
}
|
|
614
|
-
const generator = new index_1.GitBranchPreGenerator();
|
|
615
|
-
const summary = generator.getIntentSummary(options.branch);
|
|
616
|
-
console.log(`📋 ${summary}`);
|
|
617
|
-
const files = generator.generateFiles(options.branch, []);
|
|
618
|
-
for (const f of files) {
|
|
619
|
-
console.log(`\n--- ${f.path} ---`);
|
|
620
|
-
console.log(f.content);
|
|
621
|
-
}
|
|
622
|
-
});
|
|
623
|
-
program
|
|
624
|
-
.command('gentests')
|
|
625
|
-
.description('Generate test cases for a function')
|
|
626
|
-
.option('-c, --code <code>', 'Function code to analyze')
|
|
627
|
-
.action((options) => {
|
|
628
|
-
if (!options.code) {
|
|
629
|
-
console.log('❌ Provide --code with function signature');
|
|
630
|
-
return;
|
|
631
|
-
}
|
|
632
|
-
const anticipator = new index_1.TestAnticipator();
|
|
633
|
-
const tests = anticipator.generateTests(options.code);
|
|
634
|
-
console.log(`Generated ${tests.length} test cases:\n`);
|
|
635
|
-
for (const t of tests) {
|
|
636
|
-
console.log(`[${t.type}] ${t.name}`);
|
|
637
|
-
console.log(t.code);
|
|
638
|
-
console.log('');
|
|
639
|
-
}
|
|
640
|
-
});
|
|
641
|
-
program
|
|
642
|
-
.command('errors')
|
|
643
|
-
.description('Predict potential errors in code')
|
|
644
|
-
.option('-c, --code <code>', 'Code to analyze')
|
|
645
|
-
.action((options) => {
|
|
646
|
-
if (!options.code) {
|
|
647
|
-
console.log('❌ Provide --code to analyze');
|
|
648
|
-
return;
|
|
649
|
-
}
|
|
650
|
-
const predictor = new index_1.ErrorPredictor();
|
|
651
|
-
const predictions = predictor.predict(options.code);
|
|
652
|
-
if (predictions.length === 0) {
|
|
653
|
-
console.log('✅ No potential errors detected.');
|
|
654
|
-
return;
|
|
655
|
-
}
|
|
656
|
-
console.log(`Found ${predictions.length} potential errors:\n`);
|
|
657
|
-
for (const p of predictions) {
|
|
658
|
-
console.log(`[${p.severity}] Line ${p.line}: ${p.message}`);
|
|
659
|
-
console.log(` Fix: ${predictor.getQuickFix(p)}`);
|
|
660
|
-
console.log('');
|
|
661
|
-
}
|
|
662
|
-
});
|
|
663
|
-
program
|
|
664
|
-
.command('buildcheck')
|
|
665
|
-
.description('Predict build failures (TS, ESLint, tests)')
|
|
666
|
-
.option('-c, --code <code>', 'Code to analyze')
|
|
667
|
-
.action((options) => {
|
|
668
|
-
if (!options.code) {
|
|
669
|
-
console.log('❌ Provide --code to analyze');
|
|
670
|
-
return;
|
|
671
|
-
}
|
|
672
|
-
const predictor = new index_1.BuildFailurePredictor();
|
|
673
|
-
const result = predictor.predictAll(options.code);
|
|
674
|
-
const all = [...result.tsErrors, ...result.eslintViolations, ...result.testFailures];
|
|
675
|
-
if (all.length === 0) {
|
|
676
|
-
console.log('✅ No build failures predicted.');
|
|
677
|
-
return;
|
|
678
|
-
}
|
|
679
|
-
console.log(`Predicted ${all.length} build failures:\n`);
|
|
680
|
-
for (const p of all) {
|
|
681
|
-
const auto = p.autoFixable ? ' [AUTO-FIXABLE]' : '';
|
|
682
|
-
console.log(`[${p.type}] Line ${p.line}: ${p.message}${auto}`);
|
|
683
|
-
if (p.fix)
|
|
684
|
-
console.log(` Fix: ${p.fix}`);
|
|
685
|
-
console.log('');
|
|
686
|
-
}
|
|
687
|
-
const stats = predictor.getStats(all);
|
|
688
|
-
console.log(`Summary: ${stats.total} total, ${stats.autoFixable} auto-fixable`);
|
|
689
|
-
});
|
|
690
|
-
program
|
|
691
|
-
.command('mergecheck')
|
|
692
|
-
.description('Predict merge conflicts between branches')
|
|
693
|
-
.option('-a, --diff-a <diff>', 'Diff from branch A')
|
|
694
|
-
.option('-b, --diff-b <diff>', 'Diff from branch B')
|
|
695
|
-
.action((options) => {
|
|
696
|
-
if (!options.diffA || !options.diffB) {
|
|
697
|
-
console.log('❌ Provide --diff-a and --diff-b');
|
|
698
|
-
return;
|
|
699
|
-
}
|
|
700
|
-
const predictor = new index_1.MergeConflictPredictor();
|
|
701
|
-
const conflicts = predictor.predictConflicts(options.diffA, options.diffB);
|
|
702
|
-
if (conflicts.length === 0) {
|
|
703
|
-
console.log('✅ No merge conflicts predicted.');
|
|
704
|
-
return;
|
|
705
|
-
}
|
|
706
|
-
console.log(`Predicted ${conflicts.length} merge conflicts:\n`);
|
|
707
|
-
for (const c of conflicts) {
|
|
708
|
-
console.log(`[${c.type}] ${c.file}:${c.line} (confidence: ${c.confidence})`);
|
|
709
|
-
console.log(` ${c.suggestion}`);
|
|
710
|
-
console.log('');
|
|
711
|
-
}
|
|
712
|
-
});
|
|
713
|
-
program
|
|
714
|
-
.command('scan')
|
|
715
|
-
.description('Scan code for security vulnerabilities')
|
|
716
|
-
.option('-c, --code <code>', 'Code to scan')
|
|
717
|
-
.action((options) => {
|
|
718
|
-
if (!options.code) {
|
|
719
|
-
console.log('❌ Provide --code to scan');
|
|
720
|
-
return;
|
|
721
|
-
}
|
|
722
|
-
const predictor = new index_1.SecurityPredictor();
|
|
723
|
-
const predictions = predictor.predict(options.code);
|
|
724
|
-
if (predictions.length === 0) {
|
|
725
|
-
console.log('✅ No security vulnerabilities detected.');
|
|
726
|
-
return;
|
|
727
|
-
}
|
|
728
|
-
console.log(`Found ${predictions.length} security issues:\n`);
|
|
729
|
-
for (const p of predictions) {
|
|
730
|
-
console.log(`[${p.severity}] ${p.type}: Line ${p.line}`);
|
|
731
|
-
console.log(` ${p.message}`);
|
|
732
|
-
console.log(` Fix: ${p.sanitizedVersion}`);
|
|
733
|
-
console.log('');
|
|
734
|
-
}
|
|
735
|
-
});
|
|
736
|
-
program
|
|
737
|
-
.command('perf')
|
|
738
|
-
.description('Analyze code for performance issues')
|
|
739
|
-
.option('-c, --code <code>', 'Code to analyze')
|
|
740
|
-
.action((options) => {
|
|
741
|
-
if (!options.code) {
|
|
742
|
-
console.log('❌ Provide --code to analyze');
|
|
743
|
-
return;
|
|
744
|
-
}
|
|
745
|
-
const predictor = new index_1.PerformancePredictor();
|
|
746
|
-
const predictions = predictor.predict(options.code);
|
|
747
|
-
if (predictions.length === 0) {
|
|
748
|
-
console.log('✅ No performance issues detected.');
|
|
749
|
-
return;
|
|
750
|
-
}
|
|
751
|
-
console.log(`Found ${predictions.length} performance issues:\n`);
|
|
752
|
-
for (const p of predictions) {
|
|
753
|
-
console.log(`[${p.severity}] ${p.type}: Line ${p.line}`);
|
|
754
|
-
console.log(` ${p.message}`);
|
|
755
|
-
console.log(` Fix: ${p.suggestion}`);
|
|
756
|
-
console.log('');
|
|
757
|
-
}
|
|
758
|
-
});
|
|
759
|
-
program
|
|
760
|
-
.command('snapshot')
|
|
761
|
-
.description('Capture or restore project context')
|
|
762
|
-
.option('-p, --project <id>', 'Project ID')
|
|
763
|
-
.option('-r, --restore', 'Restore last snapshot')
|
|
764
|
-
.action((options) => {
|
|
765
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
766
|
-
const restore = new index_1.ContextRestore(cellDir);
|
|
767
|
-
if (options.restore && options.project) {
|
|
768
|
-
const snapshot = restore.restore(options.project);
|
|
769
|
-
if (!snapshot) {
|
|
770
|
-
console.log('❌ No snapshot found.');
|
|
771
|
-
return;
|
|
772
|
-
}
|
|
773
|
-
console.log(restore.getResumePrompt(snapshot));
|
|
774
|
-
return;
|
|
775
|
-
}
|
|
776
|
-
if (options.project) {
|
|
777
|
-
restore.capture(options.project, [], '', 0, [], '', 'main');
|
|
778
|
-
console.log(`✅ Snapshot captured for ${options.project}`);
|
|
779
|
-
return;
|
|
780
|
-
}
|
|
781
|
-
const snapshots = restore.getAllSnapshots();
|
|
782
|
-
console.log(`${snapshots.length} snapshots available:`);
|
|
783
|
-
for (const s of snapshots) {
|
|
784
|
-
console.log(` ${s.projectId} (${s.timestamp})`);
|
|
785
|
-
}
|
|
786
|
-
});
|
|
787
|
-
program
|
|
788
|
-
.command('sync')
|
|
789
|
-
.description('Sync patterns across projects')
|
|
790
|
-
.option('-s, --source <id>', 'Source project ID')
|
|
791
|
-
.option('-t, --target <id>', 'Target project ID')
|
|
792
|
-
.action((options) => {
|
|
793
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
794
|
-
const store = new index_1.PatternStore(cellDir);
|
|
795
|
-
const sync = new index_1.CrossProjectSync(store, cellDir);
|
|
796
|
-
if (options.source && options.target) {
|
|
797
|
-
const adapted = sync.generateAdaptedPatterns(options.source, options.target);
|
|
798
|
-
console.log(`${adapted.length} patterns compatible with ${options.target}:`);
|
|
799
|
-
for (const a of adapted) {
|
|
800
|
-
console.log(` ${a.original.description} (compatibility: ${a.compatibilityScore})`);
|
|
801
|
-
}
|
|
802
|
-
return;
|
|
803
|
-
}
|
|
804
|
-
const stats = sync.getSyncStats();
|
|
805
|
-
console.log(`Cross-project sync: ${stats.projects} projects, ${stats.totalPatterns} patterns`);
|
|
806
|
-
});
|
|
807
|
-
program
|
|
808
|
-
.command('solutions')
|
|
809
|
-
.description('Search solution index')
|
|
810
|
-
.option('-q, --query <text>', 'Search query')
|
|
811
|
-
.option('-a, --add <title>', 'Add a solution')
|
|
812
|
-
.option('-d, --desc <text>', 'Solution description')
|
|
813
|
-
.option('-p, --project <id>', 'Project ID')
|
|
814
|
-
.option('--stats', 'Show solution index stats')
|
|
815
|
-
.action((options) => {
|
|
816
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
817
|
-
const index = new index_1.SolutionIndex(cellDir);
|
|
818
|
-
if (options.stats) {
|
|
819
|
-
const stats = index.getStats();
|
|
820
|
-
console.log(`Solution index: ${stats.projects} projects, ${stats.totalSolutions} solutions`);
|
|
821
|
-
console.log(`Top tags: ${stats.topTags.join(', ')}`);
|
|
822
|
-
if (index.isColdStart())
|
|
823
|
-
console.log(index.getColdStartMessage());
|
|
824
|
-
return;
|
|
825
|
-
}
|
|
826
|
-
if (options.add && options.desc && options.project) {
|
|
827
|
-
const sol = index.addSolution(options.add, options.desc, [], options.project, [], '');
|
|
828
|
-
console.log(`✅ Solution added: ${sol.id}`);
|
|
829
|
-
return;
|
|
830
|
-
}
|
|
831
|
-
if (options.query) {
|
|
832
|
-
const results = index.search(options.query);
|
|
833
|
-
console.log(`Found ${results.length} solutions for "${options.query}":`);
|
|
834
|
-
for (const s of results) {
|
|
835
|
-
console.log(` 📋 ${s.title} (${s.projectId})`);
|
|
836
|
-
console.log(` ${s.description}`);
|
|
837
|
-
}
|
|
838
|
-
return;
|
|
839
|
-
}
|
|
840
|
-
console.log('Usage: cell solutions --query "auth middleware"');
|
|
841
|
-
console.log(' cell solutions --add "Title" --desc "Description" --project "my-project"');
|
|
842
|
-
console.log(' cell solutions --stats');
|
|
843
|
-
});
|
|
844
|
-
program
|
|
845
|
-
.command('langswitch')
|
|
846
|
-
.description('Get language switch guide')
|
|
847
|
-
.option('-f, --from <lang>', 'Source language')
|
|
848
|
-
.option('-t, --to <lang>', 'Target language')
|
|
849
|
-
.action((options) => {
|
|
850
|
-
const assistant = new index_1.LanguageSwitchAssistant();
|
|
851
|
-
if (options.from && options.to) {
|
|
852
|
-
const guide = assistant.getGuide(options.from, options.to);
|
|
853
|
-
if (!guide) {
|
|
854
|
-
console.log(`❌ No guide for ${options.from}→${options.to}`);
|
|
855
|
-
console.log(`Available: ${assistant.getAvailableTransitions().join(', ')}`);
|
|
856
|
-
return;
|
|
857
|
-
}
|
|
858
|
-
console.log(`\n📖 ${guide.from} → ${guide.to} Guide\n`);
|
|
859
|
-
console.log('⚠️ Gotchas:');
|
|
860
|
-
for (const g of guide.gotchas)
|
|
861
|
-
console.log(` • ${g}`);
|
|
862
|
-
console.log('\n💡 Style Tips:');
|
|
863
|
-
for (const t of guide.styleTips)
|
|
864
|
-
console.log(` • ${t}`);
|
|
865
|
-
return;
|
|
866
|
-
}
|
|
867
|
-
console.log('Available transitions:');
|
|
868
|
-
for (const t of assistant.getAvailableTransitions()) {
|
|
869
|
-
console.log(` ${t}`);
|
|
870
|
-
}
|
|
871
|
-
});
|
|
872
|
-
program
|
|
873
|
-
.command('resume')
|
|
874
|
-
.description('Check for interruption and resume')
|
|
875
|
-
.action(() => {
|
|
876
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
877
|
-
const recovery = new index_1.InterruptionRecovery(cellDir);
|
|
878
|
-
const interruption = recovery.detectInterruption();
|
|
879
|
-
if (interruption) {
|
|
880
|
-
console.log(recovery.getContinuePrompt(interruption));
|
|
881
|
-
console.log(recovery.getSummaryPrompt(interruption));
|
|
882
|
-
console.log(recovery.getRestartPrompt());
|
|
883
|
-
}
|
|
884
|
-
else {
|
|
885
|
-
console.log('✅ No interruption detected. Ready to work.');
|
|
886
|
-
}
|
|
887
|
-
});
|
|
888
|
-
program
|
|
889
|
-
.command('handoff')
|
|
890
|
-
.description('Generate teammate handoff summary')
|
|
891
|
-
.option('-t, --teammate <name>', 'Teammate name')
|
|
892
|
-
.option('-b, --branch <name>', 'Branch name')
|
|
893
|
-
.action((options) => {
|
|
894
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
895
|
-
const detector = new index_1.HandoffDetector(cellDir);
|
|
896
|
-
if (options.teammate && options.branch) {
|
|
897
|
-
const isAbsent = detector.detectAbsence(options.teammate, options.branch);
|
|
898
|
-
if (isAbsent) {
|
|
899
|
-
const summary = detector.generateReturnSummary(options.teammate, options.branch, [], [], [], new Date().toISOString());
|
|
900
|
-
console.log(detector.getReturnPrompt(summary));
|
|
901
|
-
}
|
|
902
|
-
else {
|
|
903
|
-
console.log(`✅ ${options.teammate} is active on ${options.branch}.`);
|
|
904
|
-
}
|
|
905
|
-
return;
|
|
906
|
-
}
|
|
907
|
-
console.log('Usage: cell handoff --teammate "alice" --branch "feature/auth"');
|
|
908
|
-
});
|
|
909
|
-
program
|
|
910
|
-
.command('silos')
|
|
911
|
-
.description('Detect knowledge silos')
|
|
912
|
-
.option('-m, --modules <json>', 'Module→contributors mapping as JSON')
|
|
913
|
-
.action((options) => {
|
|
914
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
915
|
-
const detector = new index_1.KnowledgeSiloDetector(cellDir);
|
|
916
|
-
if (options.modules) {
|
|
917
|
-
const mapping = JSON.parse(options.modules);
|
|
918
|
-
const reports = detector.analyzeProject(mapping);
|
|
919
|
-
const risks = detector.getTopRisks(reports);
|
|
920
|
-
console.log(`${reports.length} modules analyzed. ${risks.length} at risk:\n`);
|
|
921
|
-
for (const r of risks) {
|
|
922
|
-
console.log(`🔴 ${r.module} (risk: ${r.riskScore}, bus factor: ${r.busFactor})`);
|
|
923
|
-
console.log(` ${r.recommendation}`);
|
|
924
|
-
}
|
|
925
|
-
return;
|
|
926
|
-
}
|
|
927
|
-
const saved = detector.loadReport();
|
|
928
|
-
if (saved.length === 0) {
|
|
929
|
-
console.log('No silo reports. Run: cell silos --modules \'{"auth":["alice"],"api":["bob","carol"]}\'');
|
|
930
|
-
return;
|
|
931
|
-
}
|
|
932
|
-
console.log(`${saved.length} modules in saved report.`);
|
|
933
|
-
});
|
|
934
|
-
program
|
|
935
|
-
.command('review')
|
|
936
|
-
.description('Generate PR review summary')
|
|
937
|
-
.option('-t, --title <text>', 'PR title')
|
|
938
|
-
.option('-d, --diff <text>', 'PR diff content')
|
|
939
|
-
.action((options) => {
|
|
940
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
941
|
-
const store = new index_1.PatternStore(cellDir);
|
|
942
|
-
const assistant = new index_1.PRReviewAssistant();
|
|
943
|
-
if (options.title && options.diff) {
|
|
944
|
-
const patterns = store.getAllPatterns();
|
|
945
|
-
const summary = assistant.generateSummary(options.title, options.diff, patterns);
|
|
946
|
-
console.log(`\n📋 PR Review: ${summary.title}`);
|
|
947
|
-
console.log(` Files: ${summary.filesChanged} | +${summary.linesAdded} -${summary.linesRemoved}`);
|
|
948
|
-
if (summary.potentialBugs.length > 0) {
|
|
949
|
-
console.log(`\n🐛 Potential Bugs (${summary.potentialBugs.length}):`);
|
|
950
|
-
for (const b of summary.potentialBugs)
|
|
951
|
-
console.log(` • ${b}`);
|
|
952
|
-
}
|
|
953
|
-
if (summary.patternDeviations.length > 0) {
|
|
954
|
-
console.log(`\n⚠️ Pattern Deviations (${summary.patternDeviations.length}):`);
|
|
955
|
-
for (const d of summary.patternDeviations)
|
|
956
|
-
console.log(` • ${d}`);
|
|
957
|
-
}
|
|
958
|
-
if (summary.potentialBugs.length === 0 && summary.patternDeviations.length === 0) {
|
|
959
|
-
console.log('\n✅ No issues detected.');
|
|
960
|
-
}
|
|
961
|
-
return;
|
|
962
|
-
}
|
|
963
|
-
console.log('Usage: cell review --title "Add auth" --diff "<git diff>"');
|
|
964
|
-
});
|
|
965
|
-
program
|
|
966
|
-
.command('standup')
|
|
967
|
-
.description('Generate daily standup')
|
|
968
|
-
.option('-c, --completed <items>', 'Completed items (comma-separated)')
|
|
969
|
-
.option('-p, --progress <items>', 'In-progress items (comma-separated)')
|
|
970
|
-
.option('-b, --blocked <items>', 'Blocked items (comma-separated)')
|
|
971
|
-
.option('-n, --plan <items>', 'Planned items (comma-separated)')
|
|
972
|
-
.action((options) => {
|
|
973
|
-
const generator = new index_1.StandupGenerator();
|
|
974
|
-
if (options.completed || options.progress || options.plan) {
|
|
975
|
-
const completed = options.completed ? options.completed.split(',') : [];
|
|
976
|
-
const inProgress = options.progress ? options.progress.split(',') : [];
|
|
977
|
-
const blocked = options.blocked ? options.blocked.split(',') : [];
|
|
978
|
-
const plan = options.plan ? options.plan.split(',') : [];
|
|
979
|
-
const entry = generator.generateDaily(completed, inProgress, blocked, plan);
|
|
980
|
-
console.log(generator.formatStandup(entry));
|
|
981
|
-
return;
|
|
982
|
-
}
|
|
983
|
-
const summary = generator.getWeeklySummary();
|
|
984
|
-
console.log(summary);
|
|
985
|
-
});
|
|
986
|
-
program
|
|
987
|
-
.command('offline')
|
|
988
|
-
.description('Check offline queue status')
|
|
989
|
-
.option('--heartbeat', 'Send engine heartbeat')
|
|
990
|
-
.action((options) => {
|
|
991
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
992
|
-
const queue = new index_1.OfflineQueue(cellDir);
|
|
993
|
-
if (options.heartbeat) {
|
|
994
|
-
queue.heartbeat();
|
|
995
|
-
console.log('✅ Heartbeat sent. Engine is ONLINE.');
|
|
996
|
-
return;
|
|
997
|
-
}
|
|
998
|
-
const status = queue.checkEngineHealth();
|
|
999
|
-
console.log(`Engine: ${status.state}`);
|
|
1000
|
-
console.log(`Queue size: ${queue.getQueueSize()}`);
|
|
1001
|
-
console.log(queue.getDegradedMessage(status));
|
|
1002
|
-
});
|
|
1003
|
-
program
|
|
1004
|
-
.command('deadcode')
|
|
1005
|
-
.description('Detect dead code in a file')
|
|
1006
|
-
.option('-c, --code <code>', 'Code to analyze')
|
|
1007
|
-
.option('-f, --file <name>', 'File name')
|
|
1008
|
-
.action((options) => {
|
|
1009
|
-
if (!options.code || !options.file) {
|
|
1010
|
-
console.log('❌ Provide --code and --file');
|
|
1011
|
-
return;
|
|
1012
|
-
}
|
|
1013
|
-
const detector = new index_1.DeadCodeDetector();
|
|
1014
|
-
const reports = detector.detectAll(options.code, options.file);
|
|
1015
|
-
if (reports.length === 0) {
|
|
1016
|
-
console.log('✅ No dead code detected.');
|
|
1017
|
-
return;
|
|
1018
|
-
}
|
|
1019
|
-
console.log(`Found ${reports.length} dead code items:\n`);
|
|
1020
|
-
for (const r of reports) {
|
|
1021
|
-
console.log(`[${r.type}] ${r.file}:${r.line} — ${r.name}`);
|
|
1022
|
-
console.log(` ${r.suggestion}`);
|
|
1023
|
-
}
|
|
1024
|
-
});
|
|
1025
|
-
program
|
|
1026
|
-
.command('cycles')
|
|
1027
|
-
.description('Detect circular dependencies')
|
|
1028
|
-
.option('-i, --imports <json>', 'Import edges as JSON array of {from,to}')
|
|
1029
|
-
.action((options) => {
|
|
1030
|
-
if (!options.imports) {
|
|
1031
|
-
console.log('❌ Provide --imports as JSON');
|
|
1032
|
-
return;
|
|
1033
|
-
}
|
|
1034
|
-
const detector = new index_1.CircularDependencyDetector();
|
|
1035
|
-
const edges = JSON.parse(options.imports);
|
|
1036
|
-
const graph = detector.buildGraph(edges);
|
|
1037
|
-
const cycles = detector.detectCycles(graph);
|
|
1038
|
-
if (cycles.length === 0) {
|
|
1039
|
-
console.log('✅ No circular dependencies detected.');
|
|
1040
|
-
return;
|
|
1041
|
-
}
|
|
1042
|
-
console.log(`Found ${cycles.length} circular dependencies:\n`);
|
|
1043
|
-
for (const c of cycles) {
|
|
1044
|
-
console.log(`🔴 Cycle (${c.length} nodes): ${c.cycle.join(' → ')}`);
|
|
1045
|
-
console.log(` Break at: ${c.breakPoint}`);
|
|
1046
|
-
}
|
|
1047
|
-
const stats = detector.getStats(cycles);
|
|
1048
|
-
console.log(`\nStats: ${stats.totalCycles} cycles, max length ${stats.maxLength}, avg ${stats.avgLength}`);
|
|
1049
|
-
});
|
|
1050
|
-
program
|
|
1051
|
-
.command('dupes')
|
|
1052
|
-
.description('Detect code duplication')
|
|
1053
|
-
.option('-f, --files <json>', 'Files as JSON {filepath: code}')
|
|
1054
|
-
.action((options) => {
|
|
1055
|
-
if (!options.files) {
|
|
1056
|
-
console.log('❌ Provide --files as JSON');
|
|
1057
|
-
return;
|
|
1058
|
-
}
|
|
1059
|
-
const detector = new index_1.DuplicationDetector();
|
|
1060
|
-
const files = JSON.parse(options.files);
|
|
1061
|
-
const groups = detector.detectClones(files);
|
|
1062
|
-
if (groups.length === 0) {
|
|
1063
|
-
console.log('✅ No code duplication detected.');
|
|
1064
|
-
return;
|
|
1065
|
-
}
|
|
1066
|
-
console.log(`Found ${groups.length} duplication groups:\n`);
|
|
1067
|
-
for (const g of groups.slice(0, 5)) {
|
|
1068
|
-
console.log(`📋 Group ${g.id} (${(g.similarity * 100).toFixed(0)}% similar)`);
|
|
1069
|
-
console.log(` Files: ${g.files.join(', ')}`);
|
|
1070
|
-
console.log(` ${detector.getExtractHelperAction(g)}`);
|
|
1071
|
-
}
|
|
1072
|
-
const stats = detector.getStats(groups);
|
|
1073
|
-
console.log(`\nStats: ${stats.totalGroups} groups across ${stats.totalFiles} files, avg similarity ${stats.avgSimilarity}`);
|
|
1074
|
-
});
|
|
1075
|
-
program
|
|
1076
|
-
.command('complexity')
|
|
1077
|
-
.description('Analyze code complexity')
|
|
1078
|
-
.option('-c, --code <code>', 'Code to analyze')
|
|
1079
|
-
.option('-f, --file <name>', 'File name')
|
|
1080
|
-
.action((options) => {
|
|
1081
|
-
if (!options.code || !options.file) {
|
|
1082
|
-
console.log('❌ Provide --code and --file');
|
|
1083
|
-
return;
|
|
1084
|
-
}
|
|
1085
|
-
const analyzer = new index_1.ComplexityAnalyzer();
|
|
1086
|
-
const reports = analyzer.analyze(options.code, options.file);
|
|
1087
|
-
if (reports.length === 0) {
|
|
1088
|
-
console.log('✅ No functions found.');
|
|
1089
|
-
return;
|
|
1090
|
-
}
|
|
1091
|
-
const hotspots = analyzer.getHotspots(reports);
|
|
1092
|
-
console.log(`${reports.length} functions analyzed. ${hotspots.length} hotspots:\n`);
|
|
1093
|
-
for (const r of hotspots) {
|
|
1094
|
-
const icon = r.level === 'high' ? '🔴' : '🟡';
|
|
1095
|
-
console.log(`${icon} ${r.function} (complexity: ${r.complexity}, ${r.level})`);
|
|
1096
|
-
console.log(` ${r.file}:${r.line}`);
|
|
1097
|
-
console.log(` ${r.suggestion}`);
|
|
1098
|
-
console.log('');
|
|
1099
|
-
}
|
|
1100
|
-
const stats = analyzer.getStats(reports);
|
|
1101
|
-
console.log(`Stats: ${stats.total} functions, ${stats.high} high, ${stats.medium} medium, ${stats.low} low, avg ${stats.avgComplexity}`);
|
|
1102
|
-
});
|
|
1103
|
-
program
|
|
1104
|
-
.command('deps')
|
|
1105
|
-
.description('Check dependency health')
|
|
1106
|
-
.option('-d, --deps <json>', 'Dependencies as JSON {name: version}')
|
|
1107
|
-
.option('-l, --latest <json>', 'Latest versions as JSON {name: version}')
|
|
1108
|
-
.action((options) => {
|
|
1109
|
-
if (!options.deps || !options.latest) {
|
|
1110
|
-
console.log('❌ Provide --deps and --latest as JSON');
|
|
1111
|
-
return;
|
|
1112
|
-
}
|
|
1113
|
-
const checker = new index_1.DependencyHealthChecker();
|
|
1114
|
-
const deps = JSON.parse(options.deps);
|
|
1115
|
-
const latest = JSON.parse(options.latest);
|
|
1116
|
-
const reports = checker.check(deps, latest);
|
|
1117
|
-
console.log(`${reports.length} dependencies checked:\n`);
|
|
1118
|
-
for (const r of reports) {
|
|
1119
|
-
const icons = { up_to_date: '✅', minor_behind: '🟡', major_behind: '🟠', deprecated: '🔴' };
|
|
1120
|
-
console.log(`${icons[r.status]} ${r.name}: ${r.current} → ${r.latest} ${r.breakingChanges ? '(BREAKING)' : ''}`);
|
|
1121
|
-
}
|
|
1122
|
-
console.log(`\n${checker.getFullUpdatePlan(reports)}`);
|
|
1123
|
-
const stats = checker.getStats(reports);
|
|
1124
|
-
console.log(`Stats: ${stats.total} total, ${stats.outdated} outdated, ${stats.deprecated} deprecated, ${stats.upToDate} up-to-date`);
|
|
1125
|
-
});
|
|
1126
|
-
program
|
|
1127
|
-
.command('abtest')
|
|
1128
|
-
.description('Run A/B test')
|
|
1129
|
-
.option('-n, --name <name>', 'Test name')
|
|
1130
|
-
.option('-c, --control <n>', 'Control group size', '10')
|
|
1131
|
-
.option('-e, --experiment <n>', 'Experiment group size', '10')
|
|
1132
|
-
.option('-t, --test-id <id>', 'Test ID for recording predictions')
|
|
1133
|
-
.option('-p, --prediction <id>', 'Prediction ID')
|
|
1134
|
-
.option('-g, --group <group>', 'Group: control or experiment')
|
|
1135
|
-
.option('-w, --was-correct', 'Was the prediction correct?')
|
|
1136
|
-
.option('--significance', 'Check statistical significance')
|
|
1137
|
-
.action((options) => {
|
|
1138
|
-
const framework = new index_1.ABTestFramework();
|
|
1139
|
-
if (options.name) {
|
|
1140
|
-
const test = framework.createTest(options.name, parseInt(options.control), parseInt(options.experiment));
|
|
1141
|
-
console.log(`✅ A/B test created: ${test.id}`);
|
|
1142
|
-
console.log(` Control: ${test.controlGroup.length}, Experiment: ${test.experimentGroup.length}`);
|
|
1143
|
-
return;
|
|
1144
|
-
}
|
|
1145
|
-
if (options.testId && options.prediction && options.group) {
|
|
1146
|
-
framework.recordPrediction(options.testId, options.prediction, options.wasCorrect || false, options.group);
|
|
1147
|
-
const stats = framework.getStats(options.testId);
|
|
1148
|
-
console.log(`📊 Test ${options.testId}:`);
|
|
1149
|
-
console.log(` Control accuracy: ${stats.controlAccuracy}`);
|
|
1150
|
-
console.log(` Experiment accuracy: ${stats.experimentAccuracy}`);
|
|
1151
|
-
console.log(` Total predictions: ${stats.totalPredictions}`);
|
|
1152
|
-
return;
|
|
1153
|
-
}
|
|
1154
|
-
if (options.significance && options.testId) {
|
|
1155
|
-
const result = framework.computeSignificance(options.testId);
|
|
1156
|
-
console.log(`📊 Significance test for ${options.testId}:`);
|
|
1157
|
-
console.log(` p-value: ${result.pValue}`);
|
|
1158
|
-
console.log(` Significant: ${result.isSignificant ? 'YES' : 'NO'}`);
|
|
1159
|
-
console.log(` Winner: ${result.winner}`);
|
|
1160
|
-
return;
|
|
1161
|
-
}
|
|
1162
|
-
const tests = framework.getAllTests();
|
|
1163
|
-
console.log(`${tests.length} A/B tests:`);
|
|
1164
|
-
for (const t of tests) {
|
|
1165
|
-
console.log(` ${t.id}: ${t.name} (${t.predictions.length} predictions)`);
|
|
1166
|
-
}
|
|
1167
|
-
});
|
|
1168
|
-
program
|
|
1169
|
-
.command('community-live')
|
|
1170
|
-
.description('Show live community prior stats')
|
|
1171
|
-
.option('--ingest <json>', 'Ingest signals JSON')
|
|
1172
|
-
.option('--decay', 'Apply faster decay to synthetic patterns')
|
|
1173
|
-
.option('--opt-out <user>', 'Opt out of community contribution')
|
|
1174
|
-
.option('--opt-in <user>', 'Opt back into community contribution')
|
|
1175
|
-
.action((options) => {
|
|
1176
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
1177
|
-
const live = new index_1.CommunityLive(cellDir);
|
|
1178
|
-
if (options.ingest) {
|
|
1179
|
-
const signals = JSON.parse(options.ingest);
|
|
1180
|
-
const stats = live.ingestSignals(signals);
|
|
1181
|
-
console.log(`📥 Ingested: ${stats.totalIngested} total, ${stats.syntheticReplaced} synthetic→live`);
|
|
1182
|
-
console.log(` Remaining synthetic: ${stats.remainingSynthetic}`);
|
|
1183
|
-
console.log(` Weekly rate: ${stats.weeklyRate}`);
|
|
1184
|
-
return;
|
|
1185
|
-
}
|
|
1186
|
-
if (options.decay) {
|
|
1187
|
-
live.applyFasterDecay();
|
|
1188
|
-
console.log('✅ Faster decay applied to synthetic patterns.');
|
|
1189
|
-
return;
|
|
1190
|
-
}
|
|
1191
|
-
if (options.optOut) {
|
|
1192
|
-
live.optOut(options.optOut);
|
|
1193
|
-
console.log(`✅ ${options.optOut} opted out of community contribution.`);
|
|
1194
|
-
return;
|
|
1195
|
-
}
|
|
1196
|
-
if (options.optIn) {
|
|
1197
|
-
live.optIn(options.optIn);
|
|
1198
|
-
console.log(`✅ ${options.optIn} opted back into community contribution.`);
|
|
1199
|
-
return;
|
|
1200
|
-
}
|
|
1201
|
-
const stats = live.getStats();
|
|
1202
|
-
console.log(`\n🌍 ${live.getDisplayLabel()}`);
|
|
1203
|
-
console.log(` Total ingested: ${stats.totalIngested}`);
|
|
1204
|
-
console.log(` Synthetic replaced: ${stats.syntheticReplaced}`);
|
|
1205
|
-
console.log(` Remaining synthetic: ${stats.remainingSynthetic}`);
|
|
1206
|
-
console.log(` Weekly rate: ${stats.weeklyRate}`);
|
|
1207
|
-
});
|
|
1208
|
-
program
|
|
1209
|
-
.command('community-full')
|
|
1210
|
-
.description('Show full community prior dashboard')
|
|
1211
|
-
.option('--translate <json>', 'Translate pattern across languages {pattern, from, to}')
|
|
1212
|
-
.action((options) => {
|
|
1213
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
1214
|
-
const full = new index_1.CommunityFull(cellDir);
|
|
1215
|
-
if (options.translate) {
|
|
1216
|
-
const { pattern, from, to } = JSON.parse(options.translate);
|
|
1217
|
-
const translated = full.translatePattern(pattern, from, to);
|
|
1218
|
-
if (translated) {
|
|
1219
|
-
console.log(`✅ Translated: ${translated.description} (confidence: ${translated.confidence.mean})`);
|
|
1220
|
-
}
|
|
1221
|
-
else {
|
|
1222
|
-
console.log('❌ No cross-language mapping available.');
|
|
1223
|
-
}
|
|
1224
|
-
return;
|
|
1225
|
-
}
|
|
1226
|
-
const ds = full.getCommunityStats();
|
|
1227
|
-
console.log(`\n📊 Community Stats`);
|
|
1228
|
-
console.log(`──────────────────────────────────`);
|
|
1229
|
-
console.log(` Total patterns: ${ds.totalPatterns}`);
|
|
1230
|
-
console.log(` Live patterns: ${ds.livePatterns}`);
|
|
1231
|
-
console.log(` Synthetic patterns: ${ds.syntheticPatterns}`);
|
|
1232
|
-
console.log(` Avg confidence: ${ds.avgConfidence}`);
|
|
1233
|
-
console.log(` Calibration: ${ds.calibrationPhase}`);
|
|
1234
|
-
console.log(` Cross-language maps: ${ds.crossLanguageMappings}`);
|
|
1235
|
-
console.log(`\n${full.getDisplayLabel()}`);
|
|
1236
|
-
const s = full.getStats();
|
|
1237
|
-
console.log(`\n All-real guarantee: ${s.isAllReal ? '✅ YES' : '❌ NO'}`);
|
|
1238
|
-
});
|
|
1239
|
-
program
|
|
1240
|
-
.command('xdomain')
|
|
1241
|
-
.description('Cross-domain projections (RESEARCH)')
|
|
1242
|
-
.option('-f, --from <domain>', 'Source domain')
|
|
1243
|
-
.option('-t, --to <domain>', 'Target domain')
|
|
1244
|
-
.option('--gate', 'Check research gate status')
|
|
1245
|
-
.action((options) => {
|
|
1246
|
-
const { CrossDomainProjections } = require('./core/cross-domain-projections');
|
|
1247
|
-
const projections = new CrossDomainProjections();
|
|
1248
|
-
if (options.gate) {
|
|
1249
|
-
console.log(projections.getResearchGateStatus());
|
|
1250
|
-
return;
|
|
1251
|
-
}
|
|
1252
|
-
if (options.from && options.to) {
|
|
1253
|
-
const proj = projections.getProjection(options.from, options.to);
|
|
1254
|
-
if (!proj) {
|
|
1255
|
-
console.log('❌ No projection available.');
|
|
1256
|
-
return;
|
|
1257
|
-
}
|
|
1258
|
-
console.log(`\n🔬 ${proj.sourceDomain} → ${proj.targetDomain}`);
|
|
1259
|
-
console.log(` Transfer accuracy: ${proj.transferAccuracy}`);
|
|
1260
|
-
console.log(` Confidence: ${proj.confidence}`);
|
|
1261
|
-
console.log(` Passes 65% gate: ${projections.validateTransferAccuracy(proj) ? '✅' : '❌'}`);
|
|
1262
|
-
console.log('\n Concept mappings:');
|
|
1263
|
-
for (const [from, to] of Object.entries(proj.mappedConcepts)) {
|
|
1264
|
-
console.log(` ${from} → ${to}`);
|
|
1265
|
-
}
|
|
1266
|
-
return;
|
|
1267
|
-
}
|
|
1268
|
-
console.log('Cross-domain projections:');
|
|
1269
|
-
for (const p of projections.getAllProjections()) {
|
|
1270
|
-
console.log(` ${p.sourceDomain} → ${p.targetDomain} (${p.transferAccuracy})`);
|
|
1271
|
-
}
|
|
1272
|
-
console.log(`\n${projections.getResearchGateStatus()}`);
|
|
1273
|
-
});
|
|
1274
|
-
// ─── SEARCH ────────────────────────────────────────────
|
|
1275
|
-
program
|
|
1276
|
-
.command('search')
|
|
1277
|
-
.description('Search across all personal intelligence data')
|
|
1278
|
-
.argument('<query>', 'Search query (e.g., "error handling", "naming conventions")')
|
|
1279
|
-
.option('-l, --limit <n>', 'Max results', '5')
|
|
1280
|
-
.action((query, options) => {
|
|
1281
|
-
const se = new index_1.SearchEngine();
|
|
1282
|
-
se.rebuild(); // Always rebuild before search
|
|
1283
|
-
const results = se.search(query, parseInt(options.limit));
|
|
1284
|
-
const thick = C.primary(hline('━'));
|
|
1285
|
-
console.clear();
|
|
1286
|
-
console.log();
|
|
1287
|
-
console.log(thick);
|
|
1288
|
-
console.log(C.primary.bold(centerText(`🔍 Search: "${query}"`)));
|
|
1289
|
-
console.log(thick);
|
|
1290
|
-
console.log();
|
|
1291
|
-
if (results.length === 0) {
|
|
1292
|
-
console.log(C.warn(centerText('No results found. Try different keywords.')));
|
|
1293
|
-
console.log();
|
|
1294
|
-
console.log(thick);
|
|
1295
|
-
return;
|
|
1296
|
-
}
|
|
1297
|
-
for (const r of results) {
|
|
1298
|
-
console.log(C.num(` ${r.score} `) + C.bold(r.file));
|
|
1299
|
-
console.log(C.dim(` ${r.snippet}`));
|
|
1300
|
-
console.log(C.dim(` Tags: ${r.tags.join(', ')}`));
|
|
1301
|
-
console.log();
|
|
1302
|
-
}
|
|
1303
|
-
console.log(C.dim(` ${results.length} results found`));
|
|
1304
|
-
console.log();
|
|
1305
|
-
console.log(thick);
|
|
1306
|
-
});
|
|
1307
|
-
// ─── TEAM ─────────────────────────────────────────────
|
|
1308
|
-
program
|
|
1309
|
-
.command('team')
|
|
1310
|
-
.description('Show team intelligence overview')
|
|
1311
|
-
.option('-o, --onboard', 'Generate onboarding document')
|
|
1312
|
-
.option('-a, --add-pattern <name>', 'Add team approved pattern')
|
|
1313
|
-
.option('-d, --desc <text>', 'Pattern description (with --add-pattern)')
|
|
1314
|
-
.option('-c, --category <cat>', 'Pattern category')
|
|
1315
|
-
.action((options) => {
|
|
1316
|
-
const te = new index_1.TeamEngine();
|
|
1317
|
-
if (options.addPattern && options.desc) {
|
|
1318
|
-
const cat = options.category || 'general';
|
|
1319
|
-
const r = te.addPattern(options.addPattern, options.desc, cat, 'local');
|
|
1320
|
-
console.log(C.success(`\n ✅ Team pattern added: ${r.id}`));
|
|
1321
|
-
console.log(C.dim(` "${options.addPattern}": ${options.desc}\n`));
|
|
1322
|
-
return;
|
|
1323
|
-
}
|
|
1324
|
-
if (options.onboard) {
|
|
1325
|
-
const doc = te.generateOnboarding();
|
|
1326
|
-
const outPath = path.join(process.cwd(), 'TEAM-ONBOARDING.md');
|
|
1327
|
-
fs.writeFileSync(outPath, doc, 'utf-8');
|
|
1328
|
-
console.log(C.success(`\n ✅ Onboarding doc generated: ${outPath}\n`));
|
|
1329
|
-
return;
|
|
1330
|
-
}
|
|
1331
|
-
const summary = te.getSummary();
|
|
1332
|
-
const thick = C.primary(hline('━'));
|
|
1333
|
-
console.clear();
|
|
1334
|
-
console.log();
|
|
1335
|
-
console.log(thick);
|
|
1336
|
-
console.log(C.primary.bold(centerText('👥 Team Intelligence')));
|
|
1337
|
-
console.log(thick);
|
|
1338
|
-
console.log();
|
|
1339
|
-
if (summary.length === 0) {
|
|
1340
|
-
console.log(C.warn(centerText('No team data yet. Members push their taste with `cell push`.\nThen patterns and knowledge map will populate automatically.')));
|
|
1341
|
-
console.log();
|
|
1342
|
-
console.log(thick);
|
|
1343
|
-
return;
|
|
1344
|
-
}
|
|
1345
|
-
for (const s of summary)
|
|
1346
|
-
console.log(C.info(` ${s}`));
|
|
1347
|
-
console.log();
|
|
1348
|
-
console.log(C.dim(' Commands:'));
|
|
1349
|
-
console.log(C.dim(' cell team --onboard Generate onboarding doc'));
|
|
1350
|
-
console.log(C.dim(' cell team --add-pattern <name> --desc <text> Add pattern'));
|
|
1351
|
-
console.log(C.dim(' cell push Share your taste'));
|
|
1352
|
-
console.log(C.dim(' cell pull Pull team taste'));
|
|
1353
|
-
console.log(C.dim(' cell silos Check knowledge gaps'));
|
|
1354
|
-
console.log();
|
|
1355
|
-
console.log(thick);
|
|
1356
|
-
});
|
|
1357
|
-
// ─── PROOF ────────────────────────────────────────────
|
|
1358
|
-
program
|
|
1359
|
-
.command('proof')
|
|
1360
|
-
.description('Show evidence for every claim Cell makes')
|
|
1361
|
-
.action(() => {
|
|
1362
|
-
const proof = new index_1.ProofEngine();
|
|
1363
|
-
const report = proof.getReport();
|
|
1364
|
-
const summary = proof.getSummary();
|
|
1365
|
-
const thick = C.primary(hline('━'));
|
|
1366
|
-
const line = C.primaryDark(hline('─'));
|
|
1367
|
-
console.clear();
|
|
1368
|
-
console.log();
|
|
1369
|
-
console.log(thick);
|
|
1370
|
-
console.log(C.primary.bold(centerText('🔬 Proof System — Evidence For Every Claim')));
|
|
1371
|
-
console.log(thick);
|
|
1372
|
-
console.log();
|
|
1373
|
-
if (summary.length === 0 || summary[0].includes('Need more data')) {
|
|
1374
|
-
console.log(C.warn(centerText('Not enough data yet. Keep coding to build evidence.')));
|
|
1375
|
-
console.log();
|
|
1376
|
-
console.log(C.info(' Cell needs 3+ occurrences of each pattern before it can prove claims.'));
|
|
1377
|
-
console.log(C.info(' cell watch chalu rakho — evidence auto-build hoga.'));
|
|
1378
|
-
}
|
|
1379
|
-
else {
|
|
1380
|
-
for (const s of summary)
|
|
1381
|
-
console.log(C.info(` ${s}`));
|
|
1382
|
-
}
|
|
1383
|
-
console.log();
|
|
1384
|
-
console.log(thick);
|
|
1385
|
-
console.log();
|
|
1386
|
-
});
|
|
1387
|
-
// ─── DAEMON COMMANDS ──────────────────────────────────
|
|
1388
|
-
const daemonCmd = program.command('daemon').description('Manage Cell Daemon (background service)');
|
|
1389
|
-
daemonCmd
|
|
1390
|
-
.command('start')
|
|
1391
|
-
.description('Start the Cell Daemon in background')
|
|
1392
|
-
.action(async () => {
|
|
1393
|
-
console.log('Starting Cell Daemon...');
|
|
1394
|
-
try {
|
|
1395
|
-
const { startDaemon } = await Promise.resolve().then(() => __importStar(require('./daemon/lifecycle')));
|
|
1396
|
-
const result = await startDaemon();
|
|
1397
|
-
console.log(`✅ Daemon started (PID: ${result.pid}, Port: ${result.port})`);
|
|
1398
|
-
console.log(` Health: http://localhost:${result.port}/health`);
|
|
1399
|
-
}
|
|
1400
|
-
catch (err) {
|
|
1401
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1402
|
-
console.error(`❌ Failed to start daemon: ${message}`);
|
|
1403
|
-
}
|
|
1404
|
-
});
|
|
1405
|
-
daemonCmd
|
|
1406
|
-
.command('stop')
|
|
1407
|
-
.description('Stop the Cell Daemon')
|
|
1408
|
-
.action(async () => {
|
|
1409
|
-
const { stopDaemon } = await Promise.resolve().then(() => __importStar(require('./daemon/lifecycle')));
|
|
1410
|
-
const result = stopDaemon();
|
|
1411
|
-
console.log(result.success ? `✅ ${result.message}` : `⚠️ ${result.message}`);
|
|
1412
|
-
});
|
|
1413
|
-
daemonCmd
|
|
1414
|
-
.command('restart')
|
|
1415
|
-
.description('Restart the Cell Daemon')
|
|
1416
|
-
.action(async () => {
|
|
1417
|
-
console.log('Restarting Cell Daemon...');
|
|
1418
|
-
try {
|
|
1419
|
-
const { restartDaemon } = await Promise.resolve().then(() => __importStar(require('./daemon/lifecycle')));
|
|
1420
|
-
const result = await restartDaemon();
|
|
1421
|
-
console.log(`✅ Daemon restarted (PID: ${result.pid}, Port: ${result.port})`);
|
|
1422
|
-
}
|
|
1423
|
-
catch (err) {
|
|
1424
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1425
|
-
console.error(`❌ Failed to restart daemon: ${message}`);
|
|
1426
|
-
}
|
|
1427
|
-
});
|
|
1428
|
-
daemonCmd
|
|
1429
|
-
.command('status')
|
|
1430
|
-
.description('Show daemon status')
|
|
1431
|
-
.action(async () => {
|
|
1432
|
-
const { statusDaemon } = await Promise.resolve().then(() => __importStar(require('./daemon/lifecycle')));
|
|
1433
|
-
const status = await statusDaemon();
|
|
1434
|
-
if (status.running && status.health) {
|
|
1435
|
-
const h = status.health;
|
|
1436
|
-
console.log('✅ Daemon is running');
|
|
1437
|
-
console.log(` PID: ${status.pid} | Port: ${status.port}`);
|
|
1438
|
-
console.log(` Uptime: ${Math.round(h.uptime)}s | Patterns: ${h.patterns} | Signals: ${h.signals}`);
|
|
1439
|
-
console.log(` Modules: ${h.modulesLoaded || 'N/A'} | Memory: ${Math.round(h.memory / 1024 / 1024)}MB`);
|
|
1440
|
-
}
|
|
1441
|
-
else {
|
|
1442
|
-
console.log('❌ Daemon is not running');
|
|
1443
|
-
if (status.pid)
|
|
1444
|
-
console.log(` Stale PID found: ${status.pid}`);
|
|
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
|
-
});
|
|
2232
|
-
// ─── Top-level start/stop shortcuts ────────────────────
|
|
2233
|
-
program
|
|
2234
|
-
.command('start')
|
|
2235
|
-
.description('Start the Cell Daemon + auto-learn file watcher')
|
|
2236
|
-
.action(async () => {
|
|
2237
|
-
console.log(C.primary('Starting Cell Daemon...'));
|
|
2238
|
-
try {
|
|
2239
|
-
const { startDaemon } = await Promise.resolve().then(() => __importStar(require('./daemon/lifecycle')));
|
|
2240
|
-
const result = await startDaemon();
|
|
2241
|
-
console.log(C.success(`✅ Daemon started (PID: ${result.pid}, Port: ${result.port})`));
|
|
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 { }
|
|
2248
|
-
// Auto-start file watcher in background
|
|
2249
|
-
try {
|
|
2250
|
-
const scriptPath = process.argv[1];
|
|
2251
|
-
(0, child_process_1.spawn)('node', [scriptPath, 'watch'], {
|
|
2252
|
-
detached: true,
|
|
2253
|
-
stdio: 'ignore',
|
|
2254
|
-
cwd: process.cwd(),
|
|
2255
|
-
}).unref();
|
|
2256
|
-
console.log(C.accent('\n👁️ Auto-Learn: Watching files for changes...'));
|
|
2257
|
-
console.log(C.dim(' Edit any source file → Cell learns automatically'));
|
|
2258
|
-
}
|
|
2259
|
-
catch {
|
|
2260
|
-
console.log(C.dim('\n Run `cell watch` manually for auto-learning'));
|
|
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
|
-
}
|
|
2276
|
-
console.log(C.dim(' Stop daemon: cell stop\n'));
|
|
2277
|
-
}
|
|
2278
|
-
catch (err) {
|
|
2279
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
2280
|
-
console.error(C.error(`❌ Failed to start daemon: ${message}`));
|
|
2281
|
-
}
|
|
2282
|
-
});
|
|
2283
|
-
program
|
|
2284
|
-
.command('stop')
|
|
2285
|
-
.description('Stop the Cell Daemon')
|
|
2286
|
-
.action(async () => {
|
|
2287
|
-
const { stopDaemon } = await Promise.resolve().then(() => __importStar(require('./daemon/lifecycle')));
|
|
2288
|
-
const result = stopDaemon();
|
|
2289
|
-
console.log(result.success ? C.success(`✅ ${result.message}`) : C.warn(`⚠️ ${result.message}`));
|
|
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
|
-
});
|
|
2432
|
-
program
|
|
2433
|
-
.command('cloud')
|
|
2434
|
-
.description('Manage cloud sync')
|
|
2435
|
-
.addCommand(new commander_1.Command('on')
|
|
2436
|
-
.description('Enable cloud sync (anonymous pattern stats only)')
|
|
2437
|
-
.action(() => {
|
|
2438
|
-
const cellDir = path.join(os.homedir(), '.fivo', 'cell');
|
|
2439
|
-
if (!fs.existsSync(cellDir))
|
|
2440
|
-
fs.mkdirSync(cellDir, { recursive: true });
|
|
2441
|
-
const configPath = path.join(cellDir, 'cell-meta.json');
|
|
2442
|
-
let meta = {};
|
|
2443
|
-
if (fs.existsSync(configPath))
|
|
2444
|
-
meta = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
2445
|
-
meta.cloudSyncEnabled = true;
|
|
2446
|
-
fs.writeFileSync(configPath, JSON.stringify(meta, null, 2), 'utf-8');
|
|
2447
|
-
console.log('🌐 Cloud sync: ON');
|
|
2448
|
-
console.log(' Anonymous pattern stats shared. Code NEVER leaves your machine.');
|
|
2449
|
-
console.log(' Turn off: cell cloud off');
|
|
2450
|
-
}))
|
|
2451
|
-
.addCommand(new commander_1.Command('off')
|
|
2452
|
-
.description('Disable cloud sync (fully offline)')
|
|
2453
|
-
.action(() => {
|
|
2454
|
-
const cellDir = path.join(os.homedir(), '.fivo', 'cell');
|
|
2455
|
-
if (!fs.existsSync(cellDir))
|
|
2456
|
-
fs.mkdirSync(cellDir, { recursive: true });
|
|
2457
|
-
const configPath = path.join(cellDir, 'cell-meta.json');
|
|
2458
|
-
let meta = {};
|
|
2459
|
-
if (fs.existsSync(configPath))
|
|
2460
|
-
meta = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
2461
|
-
meta.cloudSyncEnabled = false;
|
|
2462
|
-
fs.writeFileSync(configPath, JSON.stringify(meta, null, 2), 'utf-8');
|
|
2463
|
-
console.log('🔒 Cloud sync: OFF');
|
|
2464
|
-
console.log(' Fully offline. Nothing leaves your machine.');
|
|
2465
|
-
console.log(' Turn on: cell cloud on');
|
|
2466
|
-
}));
|
|
2467
|
-
program
|
|
2468
|
-
.command('privacy')
|
|
2469
|
-
.description('Show privacy settings and current sharing status')
|
|
2470
|
-
.action(async () => {
|
|
2471
|
-
const http = await Promise.resolve().then(() => __importStar(require('http')));
|
|
2472
|
-
return new Promise((resolve) => {
|
|
2473
|
-
http.get('http://localhost:9876/privacy/mode', (res) => {
|
|
2474
|
-
let data = '';
|
|
2475
|
-
res.on('data', (chunk) => data += chunk);
|
|
2476
|
-
res.on('end', () => {
|
|
2477
|
-
try {
|
|
2478
|
-
const { mode } = JSON.parse(data);
|
|
2479
|
-
console.log(`\n🔒 Privacy Mode: ${mode}`);
|
|
2480
|
-
console.log(` Change: cell cloud on (community) | cell cloud off (private)\n`);
|
|
2481
|
-
}
|
|
2482
|
-
catch {
|
|
2483
|
-
console.log('\n🔒 Privacy Mode: private (daemon not reachable, showing default)\n');
|
|
2484
|
-
}
|
|
2485
|
-
resolve();
|
|
2486
|
-
});
|
|
2487
|
-
}).on('error', () => {
|
|
2488
|
-
console.log('\n🔒 Privacy Mode: private (daemon not reachable, showing default)\n');
|
|
2489
|
-
resolve();
|
|
2490
|
-
});
|
|
2491
|
-
});
|
|
2492
|
-
});
|
|
2493
|
-
// ─── Auto-Learn: File Watcher ──────────────────────────
|
|
2494
|
-
program
|
|
2495
|
-
.command('watch')
|
|
2496
|
-
.description('Watch files and learn automatically from every edit')
|
|
2497
|
-
.action(() => {
|
|
2498
|
-
const cellDir = path.join(process.cwd(), index_1.DEFAULT_CONFIG.cellDir);
|
|
2499
|
-
if (!fs.existsSync(cellDir)) {
|
|
2500
|
-
fs.mkdirSync(cellDir, { recursive: true });
|
|
2501
|
-
const store = new index_1.PatternStore(cellDir);
|
|
2502
|
-
store.save();
|
|
2503
|
-
}
|
|
2504
|
-
const store = new index_1.PatternStore(cellDir);
|
|
2505
|
-
const cellStore = new index_1.CellStore();
|
|
2506
|
-
const capture = new index_1.SignalCapture();
|
|
2507
|
-
const cascade = new index_1.ExtractionCascade();
|
|
2508
|
-
const cellDir2 = path.join(process.cwd(), '.cell');
|
|
2509
|
-
const blindSpots = new index_1.BlindSpotEngine(cellDir);
|
|
2510
|
-
const naming = new index_1.NamingEngine(cellDir2);
|
|
2511
|
-
const structure = new index_1.StructureEngine(cellDir2);
|
|
2512
|
-
const frontend = new index_1.FrontendEngine(cellDir2);
|
|
2513
|
-
const backend = new index_1.BackendEngine(cellDir2);
|
|
2514
|
-
const productivity = new index_1.ProductivityEngine(cellDir2);
|
|
2515
|
-
const syntax = new index_1.SyntaxEngine(cellDir2);
|
|
2516
|
-
const arch = new index_1.ArchitectureEngine(cellDir2);
|
|
2517
|
-
const knowledge = new index_1.KnowledgeGraphEngine(cellDir2);
|
|
2518
|
-
const proof = new index_1.ProofEngine(cellDir2);
|
|
2519
|
-
const filePrevMap = new Map();
|
|
2520
|
-
const timers = {};
|
|
2521
|
-
let learned = 0;
|
|
2522
|
-
function getLang(fp) {
|
|
2523
|
-
const ext = path.extname(fp).toLowerCase();
|
|
2524
|
-
const m = {
|
|
2525
|
-
'.ts': 'typescript', '.tsx': 'typescript', '.js': 'javascript', '.jsx': 'javascript',
|
|
2526
|
-
'.py': 'python', '.go': 'go', '.java': 'java', '.rb': 'ruby', '.rs': 'rust',
|
|
2527
|
-
'.cs': 'csharp', '.php': 'php', '.swift': 'swift', '.kt': 'kotlin',
|
|
2528
|
-
};
|
|
2529
|
-
return m[ext] || 'unknown';
|
|
2530
|
-
}
|
|
2531
|
-
const fileVersions = new Map();
|
|
2532
|
-
function processFile(filePath) {
|
|
2533
|
-
clearTimeout(timers[filePath]);
|
|
2534
|
-
timers[filePath] = setTimeout(() => {
|
|
2535
|
-
try {
|
|
2536
|
-
const current = fs.readFileSync(filePath, 'utf-8');
|
|
2537
|
-
const rel = path.relative(process.cwd(), filePath);
|
|
2538
|
-
const previous = fileVersions.get(filePath) || '';
|
|
2539
|
-
fileVersions.set(filePath, current);
|
|
2540
|
-
if (!previous || previous === current)
|
|
2541
|
-
return;
|
|
2542
|
-
const lang = getLang(filePath);
|
|
2543
|
-
const ctx = {
|
|
2544
|
-
language: lang,
|
|
2545
|
-
framework: 'unknown',
|
|
2546
|
-
fileType: path.extname(filePath),
|
|
2547
|
-
strictness: 'moderate',
|
|
2548
|
-
projectId: path.basename(process.cwd()),
|
|
2549
|
-
};
|
|
2550
|
-
capture.captureEditDiff(previous, current, ctx);
|
|
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);
|
|
2577
|
-
const spots = blindSpots.analyze(current, lang);
|
|
2578
|
-
naming.analyze(current);
|
|
2579
|
-
structure.analyze(current);
|
|
2580
|
-
frontend.analyze(current);
|
|
2581
|
-
backend.analyze(current);
|
|
2582
|
-
syntax.analyze(current);
|
|
2583
|
-
arch.analyze(current, rel);
|
|
2584
|
-
knowledge.detectTechnologies(current, rel);
|
|
2585
|
-
knowledge.updateSession(rel, 'edited');
|
|
2586
|
-
productivity.analyzeEngineering(current, rel);
|
|
2587
|
-
if (previous)
|
|
2588
|
-
productivity.recordEdit(previous, current);
|
|
2589
|
-
for (const p of result.patterns) {
|
|
2590
|
-
store.addOrUpdatePattern(p.category, p.description, p.from, p.to, true, p.conditions, 'global', result.stepUsed, lang);
|
|
2591
|
-
}
|
|
2592
|
-
store.save();
|
|
2593
|
-
try {
|
|
2594
|
-
cellStore.syncFromPatternStore(store);
|
|
2595
|
-
}
|
|
2596
|
-
catch { }
|
|
2597
|
-
// Auto-verify claims
|
|
2598
|
-
try {
|
|
2599
|
-
const allPatterns = store.getAllPatterns();
|
|
2600
|
-
proof.verifyMemory(allPatterns.map((p) => ({ name: p.description, firstSeen: p.lifecycle?.firstSeen || 0, lastSeen: p.lifecycle?.lastSeen || 0 })));
|
|
2601
|
-
for (const s of spots)
|
|
2602
|
-
proof.verifyPrediction(s.description, s.hitRate > 0.3);
|
|
2603
|
-
}
|
|
2604
|
-
catch { }
|
|
2605
|
-
learned += result.patterns.length;
|
|
2606
|
-
const parts = [];
|
|
2607
|
-
if (result.patterns.length > 0)
|
|
2608
|
-
parts.push(C.success(`${result.patterns.length}p`));
|
|
2609
|
-
if (spots.length > 0)
|
|
2610
|
-
parts.push(C.warn(`${spots.length} blind spots`));
|
|
2611
|
-
console.log(C.success(` 📝 ${rel}`) + C.dim(` → ${parts.join(', ')} (total: ${learned})`));
|
|
2612
|
-
}
|
|
2613
|
-
catch { }
|
|
2614
|
-
}, 600);
|
|
2615
|
-
}
|
|
2616
|
-
function watchDir(dir) {
|
|
2617
|
-
try {
|
|
2618
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
2619
|
-
for (const e of entries) {
|
|
2620
|
-
const full = path.join(dir, e.name);
|
|
2621
|
-
if (e.isDirectory() && !['node_modules', '.fivo', '.git', 'dist', 'coverage', '.next', '.cache'].includes(e.name)) {
|
|
2622
|
-
watchDir(full);
|
|
2623
|
-
// Watch directory for new files
|
|
2624
|
-
try {
|
|
2625
|
-
fs.watch(full, (ev) => {
|
|
2626
|
-
if (ev === 'rename') {
|
|
2627
|
-
setTimeout(() => {
|
|
2628
|
-
try {
|
|
2629
|
-
const newEntries = fs.readdirSync(full, { withFileTypes: true });
|
|
2630
|
-
for (const ne of newEntries) {
|
|
2631
|
-
const nf = path.join(full, ne.name);
|
|
2632
|
-
if (ne.isFile() && /\.(ts|tsx|js|jsx|py|go|java|rb|rs|cs|php|swift|kt)$/.test(ne.name)) {
|
|
2633
|
-
if (!fileVersions.has(nf)) {
|
|
2634
|
-
fileVersions.set(nf, fs.readFileSync(nf, 'utf-8'));
|
|
2635
|
-
console.log(C.dim(` 📄 New file: ${path.relative(process.cwd(), nf)}`));
|
|
2636
|
-
}
|
|
2637
|
-
fs.watch(nf, (ev2) => { if (ev2 === 'change')
|
|
2638
|
-
processFile(nf); });
|
|
2639
|
-
}
|
|
2640
|
-
}
|
|
2641
|
-
}
|
|
2642
|
-
catch { }
|
|
2643
|
-
}, 200);
|
|
2644
|
-
}
|
|
2645
|
-
});
|
|
2646
|
-
}
|
|
2647
|
-
catch { }
|
|
2648
|
-
}
|
|
2649
|
-
else if (e.isFile() && /\.(ts|tsx|js|jsx|py|go|java|rb|rs|cs|php|swift|kt)$/.test(e.name)) {
|
|
2650
|
-
if (!fileVersions.has(full)) {
|
|
2651
|
-
try {
|
|
2652
|
-
fileVersions.set(full, fs.readFileSync(full, 'utf-8'));
|
|
2653
|
-
}
|
|
2654
|
-
catch { }
|
|
2655
|
-
}
|
|
2656
|
-
fs.watch(full, (ev) => { if (ev === 'change')
|
|
2657
|
-
processFile(full); });
|
|
2658
|
-
}
|
|
2659
|
-
}
|
|
2660
|
-
}
|
|
2661
|
-
catch { }
|
|
2662
|
-
}
|
|
2663
|
-
const thick = C.primary(hline('━'));
|
|
2664
|
-
console.clear();
|
|
2665
|
-
console.log();
|
|
2666
|
-
console.log(thick);
|
|
2667
|
-
console.log(C.primary.bold(centerText('👁️ Auto-Learn Mode')));
|
|
2668
|
-
console.log(thick);
|
|
2669
|
-
console.log();
|
|
2670
|
-
console.log(C.info(' Watching all source files for edits...'));
|
|
2671
|
-
console.log(C.dim(' Edit any file → Cell learns automatically'));
|
|
2672
|
-
console.log(C.dim(' Press Ctrl+C to stop'));
|
|
2673
|
-
console.log();
|
|
2674
|
-
console.log(thick);
|
|
2675
|
-
console.log();
|
|
2676
|
-
watchDir(process.cwd());
|
|
2677
|
-
});
|
|
2678
|
-
// ─── Auto-Learn: Git Hook ──────────────────────────────
|
|
2679
|
-
program
|
|
2680
|
-
.command('install-hook')
|
|
2681
|
-
.description('Install git hook for auto-learning on every commit')
|
|
2682
|
-
.action(() => {
|
|
2683
|
-
const gitDir = path.join(process.cwd(), '.git');
|
|
2684
|
-
if (!fs.existsSync(gitDir)) {
|
|
2685
|
-
console.log(C.error(' ❌ Not a git repository. Run `git init` first.'));
|
|
2686
|
-
return;
|
|
2687
|
-
}
|
|
2688
|
-
const hooksDir = path.join(gitDir, 'hooks');
|
|
2689
|
-
if (!fs.existsSync(hooksDir))
|
|
2690
|
-
fs.mkdirSync(hooksDir, { recursive: true });
|
|
2691
|
-
const hookPath = path.join(hooksDir, 'post-commit');
|
|
2692
|
-
const cellBin = process.argv[1];
|
|
2693
|
-
const hook = `#!/bin/sh
|
|
2694
|
-
# FIVO Cell — auto-learn on commit
|
|
2695
|
-
DIFF=$(git diff --cached --diff-algorithm=histogram)
|
|
2696
|
-
if [ -n "$DIFF" ]; then
|
|
2697
|
-
node "${cellBin}" learn --original "$(echo "$DIFF" | head -200)" --edited "committed" 2>/dev/null
|
|
2698
|
-
fi
|
|
2699
|
-
`;
|
|
2700
|
-
fs.writeFileSync(hookPath, hook, { mode: 0o755 });
|
|
2701
|
-
console.log(C.success('\n ✅ Git hook installed: post-commit'));
|
|
2702
|
-
console.log(C.info(' Every commit → Cell learns from the diff automatically.'));
|
|
2703
|
-
console.log(C.dim(' To remove: delete .git/hooks/post-commit\n'));
|
|
2704
|
-
});
|
|
2705
|
-
// ─── Auto-Start ───────────────────────────────────────
|
|
2706
|
-
program
|
|
2707
|
-
.command('autostart')
|
|
2708
|
-
.description('Auto-start Cell daemon on PC reboot')
|
|
2709
|
-
.addCommand(new commander_1.Command('on')
|
|
2710
|
-
.description('Enable auto-start on boot')
|
|
2711
|
-
.action(() => {
|
|
2712
|
-
const isWin = process.platform === 'win32';
|
|
2713
|
-
const cellCmd = process.argv[1];
|
|
2714
|
-
if (isWin) {
|
|
2715
|
-
const startupDir = path.join(os.homedir(), 'AppData', 'Roaming', 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup');
|
|
2716
|
-
if (!fs.existsSync(startupDir))
|
|
2717
|
-
fs.mkdirSync(startupDir, { recursive: true });
|
|
2718
|
-
const batPath = path.join(startupDir, 'fivo-cell-start.bat');
|
|
2719
|
-
fs.writeFileSync(batPath, `@echo off\r\n${cellCmd} start\r\n`, 'utf-8');
|
|
2720
|
-
console.log(C.success('\n ✅ Auto-start enabled (Windows)'));
|
|
2721
|
-
console.log(C.dim(` ${batPath}`));
|
|
2722
|
-
console.log(C.info(' PC reboot → Cell auto-starts\n'));
|
|
2723
|
-
}
|
|
2724
|
-
else {
|
|
2725
|
-
const bashrc = path.join(os.homedir(), '.bashrc');
|
|
2726
|
-
const line = `(cell status > /dev/null 2>&1) || ${cellCmd} start`;
|
|
2727
|
-
if (!fs.existsSync(bashrc))
|
|
2728
|
-
fs.writeFileSync(bashrc, '');
|
|
2729
|
-
const content = fs.readFileSync(bashrc, 'utf-8');
|
|
2730
|
-
if (!content.includes('cell start')) {
|
|
2731
|
-
fs.writeFileSync(bashrc, content + `\n# FIVO Cell auto-start\n${line}\n`);
|
|
2732
|
-
}
|
|
2733
|
-
console.log(C.success('\n ✅ Auto-start enabled (Linux/Mac)'));
|
|
2734
|
-
console.log(C.dim(` Added to ~/.bashrc`));
|
|
2735
|
-
console.log(C.info(' Terminal open → Cell auto-starts\n'));
|
|
2736
|
-
}
|
|
2737
|
-
}))
|
|
2738
|
-
.addCommand(new commander_1.Command('off')
|
|
2739
|
-
.description('Disable auto-start on boot')
|
|
2740
|
-
.action(() => {
|
|
2741
|
-
const isWin = process.platform === 'win32';
|
|
2742
|
-
if (isWin) {
|
|
2743
|
-
const startupDir = path.join(os.homedir(), 'AppData', 'Roaming', 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup');
|
|
2744
|
-
const batPath = path.join(startupDir, 'fivo-cell-start.bat');
|
|
2745
|
-
if (fs.existsSync(batPath))
|
|
2746
|
-
fs.unlinkSync(batPath);
|
|
2747
|
-
console.log(C.success('\n ✅ Auto-start disabled\n'));
|
|
2748
|
-
}
|
|
2749
|
-
else {
|
|
2750
|
-
const bashrc = path.join(os.homedir(), '.bashrc');
|
|
2751
|
-
if (fs.existsSync(bashrc)) {
|
|
2752
|
-
const content = fs.readFileSync(bashrc, 'utf-8')
|
|
2753
|
-
.replace(/\n# FIVO Cell auto-start\n.*\n?/, '\n')
|
|
2754
|
-
.trim();
|
|
2755
|
-
fs.writeFileSync(bashrc, content + '\n');
|
|
2756
|
-
}
|
|
2757
|
-
console.log(C.success('\n ✅ Auto-start disabled\n'));
|
|
2758
|
-
}
|
|
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 () => {
|
|
56
|
+
const project = path.basename(process.cwd());
|
|
57
|
+
// ─── Parse ──────────────────────────────────────────────────────────────────
|
|
58
|
+
const args = process.argv.slice(2);
|
|
59
|
+
const cmd = args[0] || '';
|
|
60
|
+
switch (cmd) {
|
|
61
|
+
case 'start':
|
|
62
|
+
doStart();
|
|
63
|
+
break;
|
|
64
|
+
case 'stop':
|
|
65
|
+
doStop();
|
|
66
|
+
break;
|
|
67
|
+
case 'scan':
|
|
68
|
+
doScan();
|
|
69
|
+
break;
|
|
70
|
+
case 'status':
|
|
71
|
+
doStatus();
|
|
72
|
+
break;
|
|
73
|
+
case 'team':
|
|
74
|
+
doTeam();
|
|
75
|
+
break;
|
|
76
|
+
case 'community':
|
|
77
|
+
doCommunity();
|
|
78
|
+
break;
|
|
79
|
+
case 'help':
|
|
80
|
+
doHelp();
|
|
81
|
+
break;
|
|
82
|
+
default:
|
|
83
|
+
doStatus();
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
// ─── cell start ─────────────────────────────────────────────────────────────
|
|
87
|
+
function doStart() {
|
|
88
|
+
const banner = figlet_1.default.textSync('CELL', { font: 'ANSI Shadow', horizontalLayout: 'fitted' });
|
|
89
|
+
console.log((0, gradient_string_1.default)(['#FF6B35', '#FFAB91'])(banner));
|
|
90
|
+
console.log(C.dim(' Starting everything...\n'));
|
|
91
|
+
// 0. First-run greeting
|
|
3186
92
|
try {
|
|
3187
|
-
const {
|
|
3188
|
-
|
|
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`));
|
|
93
|
+
const { firstRunGreeting } = require('./first-run');
|
|
94
|
+
firstRunGreeting();
|
|
3209
95
|
}
|
|
3210
|
-
}
|
|
3211
|
-
|
|
3212
|
-
.command('tool-suggest <task>')
|
|
3213
|
-
.description('Suggest best AI tool for a specific task type')
|
|
3214
|
-
.action(async (task) => {
|
|
96
|
+
catch { }
|
|
97
|
+
// 1. Kill any stale daemon (clean restart)
|
|
3215
98
|
try {
|
|
3216
|
-
const {
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
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`));
|
|
99
|
+
const { stopDaemon } = require('./daemon/lifecycle');
|
|
100
|
+
stopDaemon();
|
|
101
|
+
// Wait for port to be released
|
|
102
|
+
const { execSync } = require('child_process');
|
|
103
|
+
execSync('timeout /t 1 /nobreak >nul 2>&1', { stdio: 'ignore' });
|
|
3235
104
|
}
|
|
3236
|
-
}
|
|
3237
|
-
program
|
|
3238
|
-
.command('model-history')
|
|
3239
|
-
.description('Per-model interaction history — sessions, files, decisions')
|
|
3240
|
-
.action(async () => {
|
|
105
|
+
catch { }
|
|
3241
106
|
try {
|
|
3242
|
-
const
|
|
3243
|
-
const
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
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();
|
|
107
|
+
const fsMod = require('fs');
|
|
108
|
+
const osMod = require('os');
|
|
109
|
+
const pidFile = require('path').join(osMod.homedir(), '.fivo', 'cell', 'daemon.pid');
|
|
110
|
+
try {
|
|
111
|
+
fsMod.unlinkSync(pidFile);
|
|
3254
112
|
}
|
|
113
|
+
catch { }
|
|
3255
114
|
}
|
|
3256
|
-
catch
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
const
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
115
|
+
catch { }
|
|
116
|
+
// 2. Start daemon as detached background process
|
|
117
|
+
console.log(C.primary(' Starting daemon + MCP...'));
|
|
118
|
+
try {
|
|
119
|
+
const { spawn } = require('child_process');
|
|
120
|
+
const pathMod = require('path');
|
|
121
|
+
const fsMod = require('fs');
|
|
122
|
+
const osMod = require('os');
|
|
123
|
+
const serverPath = pathMod.join(__dirname, 'daemon', 'server.js');
|
|
124
|
+
const child = spawn('node', [serverPath], {
|
|
125
|
+
detached: true,
|
|
126
|
+
stdio: 'ignore',
|
|
127
|
+
});
|
|
128
|
+
child.unref();
|
|
129
|
+
// Write PID
|
|
130
|
+
const pidFile = pathMod.join(osMod.homedir(), '.fivo', 'cell', 'daemon.pid');
|
|
131
|
+
fsMod.mkdirSync(pathMod.dirname(pidFile), { recursive: true });
|
|
132
|
+
fsMod.writeFileSync(pidFile, String(child.pid), 'utf-8');
|
|
133
|
+
console.log(C.success(` Daemon + MCP started (PID: ${child.pid})`));
|
|
134
|
+
console.log(C.dim(' Daemon + MCP: http://localhost:9876'));
|
|
135
|
+
console.log(C.dim(' MCP endpoint: POST http://localhost:9876/mcp'));
|
|
3269
136
|
console.log();
|
|
3270
|
-
|
|
3271
|
-
|
|
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
|
-
}
|
|
137
|
+
console.log(C.dim(' Next: cell scan (scan codebase + build layers)'));
|
|
138
|
+
console.log(C.dim(' Then: cell status'));
|
|
3302
139
|
console.log();
|
|
140
|
+
process.exit(0);
|
|
3303
141
|
}
|
|
3304
142
|
catch (e) {
|
|
3305
|
-
console.log(C.
|
|
143
|
+
console.log(C.warn(' Start failed: ' + String(e)));
|
|
144
|
+
process.exit(1);
|
|
3306
145
|
}
|
|
3307
|
-
}
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
.
|
|
3311
|
-
.option('-d, --days <days>', 'Lookback period in days', '14')
|
|
3312
|
-
.option('-p, --project <name>', 'Filter by project')
|
|
3313
|
-
.action(async (opts) => {
|
|
146
|
+
}
|
|
147
|
+
// ─── cell stop ──────────────────────────────────────────────────────────────
|
|
148
|
+
function doStop() {
|
|
149
|
+
console.log(C.dim(' Stopping Cell daemon...'));
|
|
3314
150
|
try {
|
|
3315
|
-
const {
|
|
3316
|
-
const
|
|
3317
|
-
console.log(C.
|
|
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`));
|
|
151
|
+
const { stopDaemon } = require('./daemon/lifecycle');
|
|
152
|
+
const result = stopDaemon();
|
|
153
|
+
console.log(result.success ? C.success(` ${result.message}`) : C.warn(` ${result.message}`));
|
|
3330
154
|
}
|
|
3331
155
|
catch (e) {
|
|
3332
|
-
console.log(C.
|
|
156
|
+
console.log(C.warn(' Stop failed: ' + String(e)));
|
|
3333
157
|
}
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
.
|
|
3339
|
-
.
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
const
|
|
3343
|
-
|
|
3344
|
-
console.log(`
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
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
|
-
}
|
|
158
|
+
console.log();
|
|
159
|
+
}
|
|
160
|
+
// ─── cell scan ───────────────────────────────────────────────────────────────
|
|
161
|
+
function doScan() {
|
|
162
|
+
const banner = figlet_1.default.textSync('CELL', { font: 'ANSI Shadow', horizontalLayout: 'fitted' });
|
|
163
|
+
console.log((0, gradient_string_1.default)(['#FF6B35', '#FFAB91'])(banner));
|
|
164
|
+
console.log(C.dim(' Scanning codebase + building all layers...\n'));
|
|
165
|
+
try {
|
|
166
|
+
const { scanCodebase } = require('./code-scanner');
|
|
167
|
+
const result = scanCodebase(process.cwd(), project);
|
|
168
|
+
console.log(C.success(` [1/2] Scanned ${result.filesScanned} files, ${result.totalLines.toLocaleString()} lines`));
|
|
169
|
+
(0, layers_1.populateAllLayers)({
|
|
170
|
+
profile: result.profile,
|
|
171
|
+
patterns: result.patterns,
|
|
172
|
+
project,
|
|
173
|
+
});
|
|
174
|
+
console.log(C.success(' [2/2] Populated all layers:'));
|
|
175
|
+
console.log(C.dim(' .cell/personal/ — profile, style, errors, decisions'));
|
|
176
|
+
console.log(C.dim(' .cell/team/ — shared patterns, blind spots'));
|
|
177
|
+
console.log(C.dim(' .cell/community/ — community patterns, trends'));
|
|
3367
178
|
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
|
-
}
|
|
179
|
+
console.log(C.dim(' Run: cell status'));
|
|
3391
180
|
console.log();
|
|
3392
181
|
}
|
|
3393
182
|
catch (e) {
|
|
3394
|
-
console.log(C.
|
|
183
|
+
console.log(C.warn(' Scan failed: ' + String(e)));
|
|
184
|
+
console.log();
|
|
3395
185
|
}
|
|
3396
|
-
}
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
.
|
|
3400
|
-
.
|
|
186
|
+
}
|
|
187
|
+
// ─── cell status ────────────────────────────────────────────────────────────
|
|
188
|
+
function doStatus() {
|
|
189
|
+
const banner = figlet_1.default.textSync('CELL', { font: 'ANSI Shadow', horizontalLayout: 'fitted' });
|
|
190
|
+
console.log((0, gradient_string_1.default)(['#FF6B35', '#FFAB91'])(banner));
|
|
191
|
+
console.log();
|
|
192
|
+
// Check daemon
|
|
193
|
+
const http = require('http');
|
|
3401
194
|
try {
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
}
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
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();
|
|
195
|
+
http.get('http://localhost:9876/health', (res) => {
|
|
196
|
+
let data = '';
|
|
197
|
+
res.on('data', (c) => data += c);
|
|
198
|
+
res.on('end', () => {
|
|
199
|
+
console.log(C.success(' Daemon: Running'));
|
|
200
|
+
showProjectStatus();
|
|
201
|
+
});
|
|
202
|
+
}).on('error', () => {
|
|
203
|
+
console.log(C.warn(' Daemon: Not running (run: cell start)'));
|
|
204
|
+
showProjectStatus();
|
|
205
|
+
});
|
|
3430
206
|
}
|
|
3431
|
-
catch
|
|
3432
|
-
|
|
207
|
+
catch {
|
|
208
|
+
showProjectStatus();
|
|
3433
209
|
}
|
|
3434
|
-
}
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
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
|
-
}
|
|
210
|
+
}
|
|
211
|
+
function showProjectStatus() {
|
|
212
|
+
const { getDeveloperProfile } = require('./code-scanner');
|
|
213
|
+
const profile = getDeveloperProfile(project);
|
|
214
|
+
if (!profile) {
|
|
215
|
+
console.log(C.warn(`\n No profile for "${project}". Run: cell start`));
|
|
3460
216
|
console.log();
|
|
217
|
+
return;
|
|
3461
218
|
}
|
|
3462
|
-
|
|
3463
|
-
|
|
219
|
+
console.log();
|
|
220
|
+
console.log(C.bold(` Project: ${project}`));
|
|
221
|
+
// ─── Personal Layer ──────────────────────────────────────────────────────
|
|
222
|
+
console.log();
|
|
223
|
+
console.log(C.bold(' 📂 Personal Layer'));
|
|
224
|
+
console.log(C.dim(' ─────────────────'));
|
|
225
|
+
console.log(` Style: ${C.num(profile.quoteStyle)} quotes, ${C.num(profile.semicolonStyle)} semis, ${C.num(profile.indentStyle)}`);
|
|
226
|
+
console.log(` Code: ${C.num(profile.functionStyle)} functions, ${C.num(profile.asyncStyle)}, ${C.num(profile.errorHandling)} errors`);
|
|
227
|
+
console.log(` Arch: ${C.num(profile.architectureStyle)}, ${C.num(profile.testPattern)} tests`);
|
|
228
|
+
if (profile.strengths.length) {
|
|
229
|
+
for (const s of profile.strengths)
|
|
230
|
+
console.log(` ${C.success('+')} ${s}`);
|
|
3464
231
|
}
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
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();
|
|
232
|
+
if (profile.improvements.length) {
|
|
233
|
+
for (const i of profile.improvements)
|
|
234
|
+
console.log(` ${C.warn('!')} ${i}`);
|
|
3490
235
|
}
|
|
3491
|
-
|
|
3492
|
-
|
|
236
|
+
// Show .cell/personal/ files
|
|
237
|
+
const personalDir = path.join(layers_1.CELL_DIR, 'personal');
|
|
238
|
+
if (fs.existsSync(personalDir)) {
|
|
239
|
+
const files = fs.readdirSync(personalDir);
|
|
240
|
+
console.log(C.dim(` Files: ${files.join(', ')}`));
|
|
3493
241
|
}
|
|
3494
|
-
|
|
3495
|
-
program
|
|
3496
|
-
.command('community-trends')
|
|
3497
|
-
.description('Show technology and pattern trends from community')
|
|
3498
|
-
.action(async () => {
|
|
242
|
+
// Behavioral data
|
|
3499
243
|
try {
|
|
3500
|
-
const {
|
|
3501
|
-
const
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
244
|
+
const { getBehaviorSummary } = require('./behavioral-tracker');
|
|
245
|
+
const b = getBehaviorSummary(project);
|
|
246
|
+
if (b.totalErrors > 0 || b.totalDecisions > 0 || b.currentContext || b.stuckIssues.length > 0) {
|
|
247
|
+
console.log(C.bold(' Behavior:'));
|
|
248
|
+
if (b.totalErrors > 0)
|
|
249
|
+
console.log(` Errors: ${b.totalErrors} logged`);
|
|
250
|
+
if (b.totalDecisions > 0)
|
|
251
|
+
console.log(` Decisions: ${b.totalDecisions} logged`);
|
|
252
|
+
if (b.currentContext)
|
|
253
|
+
console.log(` Working on: ${b.currentContext.task}`);
|
|
254
|
+
if (b.stuckIssues.length > 0)
|
|
255
|
+
console.log(` Stuck: ${b.stuckIssues.length} issues`);
|
|
3508
256
|
}
|
|
3509
|
-
console.log();
|
|
3510
|
-
}
|
|
3511
|
-
catch (e) {
|
|
3512
|
-
console.log(C.error(`\n ❌ Trends failed: ${e.message}\n`));
|
|
3513
257
|
}
|
|
3514
|
-
}
|
|
3515
|
-
|
|
3516
|
-
.command('community-insights')
|
|
3517
|
-
.description('Actionable community insights — benchmarks, blind spots, trends')
|
|
3518
|
-
.action(async () => {
|
|
258
|
+
catch { }
|
|
259
|
+
// ─── Git Intelligence ────────────────────────────────────────────────────
|
|
3519
260
|
try {
|
|
3520
|
-
const {
|
|
3521
|
-
const
|
|
3522
|
-
if (
|
|
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}`);
|
|
261
|
+
const { buildDeveloperIntelligence } = require('./developer-intelligence');
|
|
262
|
+
const gitIntel = buildDeveloperIntelligence(process.cwd());
|
|
263
|
+
if (gitIntel) {
|
|
3533
264
|
console.log();
|
|
265
|
+
console.log(C.bold(' 🧠 Git Intelligence'));
|
|
266
|
+
console.log(C.dim(' ──────────────────'));
|
|
267
|
+
console.log(` Score: ${C.num(String(gitIntel.behavioralScore))}/100`);
|
|
268
|
+
if (gitIntel.timeSummary)
|
|
269
|
+
console.log(C.dim(` ${gitIntel.timeSummary}`));
|
|
270
|
+
if (gitIntel.journeySummary)
|
|
271
|
+
console.log(C.dim(` ${gitIntel.journeySummary}`));
|
|
272
|
+
if (gitIntel.topBlindSpots.length > 0) {
|
|
273
|
+
console.log(C.bold(' Top Blind Spots:'));
|
|
274
|
+
for (const bs of gitIntel.topBlindSpots.slice(0, 3)) {
|
|
275
|
+
console.log(` ${C.warn('!')} ${bs}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (gitIntel.topMistakes.length > 0) {
|
|
279
|
+
console.log(C.bold(' Repeat Mistakes:'));
|
|
280
|
+
for (const m of gitIntel.topMistakes.slice(0, 3)) {
|
|
281
|
+
console.log(` ${C.warn('↻')} ${m}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
if (gitIntel.topStrengths.length > 0) {
|
|
285
|
+
for (const s of gitIntel.topStrengths.slice(0, 3)) {
|
|
286
|
+
console.log(` ${C.success('+')} ${s}`);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
3534
289
|
}
|
|
3535
290
|
}
|
|
3536
|
-
catch
|
|
3537
|
-
|
|
3538
|
-
}
|
|
3539
|
-
});
|
|
3540
|
-
program
|
|
3541
|
-
.command('community-challenges')
|
|
3542
|
-
.description('Show weekly community challenges')
|
|
3543
|
-
.action(async () => {
|
|
291
|
+
catch { }
|
|
292
|
+
// ─── Predictions ─────────────────────────────────────────────────────────
|
|
3544
293
|
try {
|
|
3545
|
-
const {
|
|
3546
|
-
const
|
|
3547
|
-
|
|
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}`)}`);
|
|
294
|
+
const { getQuickWarnings } = require('./predictive-engine');
|
|
295
|
+
const warnings = getQuickWarnings(project);
|
|
296
|
+
if (warnings.length > 0) {
|
|
3553
297
|
console.log();
|
|
298
|
+
console.log(C.bold(' 🔮 Predictions'));
|
|
299
|
+
console.log(C.dim(' ──────────────'));
|
|
300
|
+
for (const w of warnings) {
|
|
301
|
+
console.log(` ${w}`);
|
|
302
|
+
}
|
|
3554
303
|
}
|
|
3555
304
|
}
|
|
3556
|
-
catch
|
|
3557
|
-
|
|
305
|
+
catch { }
|
|
306
|
+
// ─── Team Layer ──────────────────────────────────────────────────────────
|
|
307
|
+
console.log();
|
|
308
|
+
console.log(C.bold(' 👥 Team Layer'));
|
|
309
|
+
console.log(C.dim(' ─────────────'));
|
|
310
|
+
const teamData = (0, layers_1.getTeamMembers)();
|
|
311
|
+
if (teamData && teamData.members && teamData.members.length > 0) {
|
|
312
|
+
for (const m of teamData.members) {
|
|
313
|
+
console.log(` ${C.success('•')} ${m.name} — ${m.role}`);
|
|
314
|
+
}
|
|
3558
315
|
}
|
|
3559
|
-
|
|
3560
|
-
|
|
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();
|
|
316
|
+
else {
|
|
317
|
+
console.log(C.dim(' No team members. Add: cell team add <name>'));
|
|
3576
318
|
}
|
|
3577
|
-
|
|
3578
|
-
|
|
319
|
+
const teamPatterns = (0, layers_1.getTeamPatterns)();
|
|
320
|
+
if (teamPatterns && teamPatterns.patterns && teamPatterns.patterns.length > 0) {
|
|
321
|
+
console.log(C.dim(` Shared patterns: ${teamPatterns.patterns.length}`));
|
|
3579
322
|
}
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
.
|
|
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`);
|
|
323
|
+
const teamBlinds = (0, layers_1.getTeamBlindSpots)();
|
|
324
|
+
if (teamBlinds && teamBlinds.blindSpots && teamBlinds.blindSpots.length > 0) {
|
|
325
|
+
console.log(C.warn(` Blind spots: ${teamBlinds.blindSpots.length}`));
|
|
3597
326
|
}
|
|
3598
|
-
|
|
3599
|
-
|
|
327
|
+
// ─── Community Layer ─────────────────────────────────────────────────────
|
|
328
|
+
console.log();
|
|
329
|
+
console.log(C.bold(' 🌐 Community Layer'));
|
|
330
|
+
console.log(C.dim(' ──────────────────'));
|
|
331
|
+
const commPatterns = (0, layers_1.getCommunityPatterns)();
|
|
332
|
+
if (commPatterns && commPatterns.patterns && commPatterns.patterns.length > 0) {
|
|
333
|
+
console.log(C.dim(` Patterns shared: ${commPatterns.patterns.length}`));
|
|
3600
334
|
}
|
|
3601
|
-
|
|
3602
|
-
|
|
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();
|
|
335
|
+
else {
|
|
336
|
+
console.log(C.dim(' No community patterns yet. Run: cell community'));
|
|
3621
337
|
}
|
|
3622
|
-
|
|
3623
|
-
|
|
338
|
+
const commTrends = (0, layers_1.getCommunityTrends)();
|
|
339
|
+
if (commTrends && commTrends.trends && commTrends.trends.length > 0) {
|
|
340
|
+
console.log(C.dim(` Trends: ${commTrends.trends.length}`));
|
|
3624
341
|
}
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
.
|
|
3628
|
-
|
|
3629
|
-
.
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
342
|
+
const commRank = (0, layers_1.getCommunityRankings)();
|
|
343
|
+
if (commRank && commRank.rankings && commRank.rankings.length > 0) {
|
|
344
|
+
console.log(C.dim(` Rankings: ${commRank.rankings.length}`));
|
|
345
|
+
}
|
|
346
|
+
console.log();
|
|
347
|
+
}
|
|
348
|
+
// ─── cell team ──────────────────────────────────────────────────────────────
|
|
349
|
+
function doTeam() {
|
|
350
|
+
console.log();
|
|
351
|
+
console.log(C.bold(' Cell Team'));
|
|
352
|
+
console.log(C.dim(' ─────────'));
|
|
353
|
+
console.log();
|
|
354
|
+
const db = (0, database_1.getDb)();
|
|
355
|
+
db.exec(`
|
|
356
|
+
CREATE TABLE IF NOT EXISTS team_members (
|
|
357
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
358
|
+
name TEXT NOT NULL,
|
|
359
|
+
role TEXT DEFAULT 'developer',
|
|
360
|
+
joined_at TEXT DEFAULT (datetime('now'))
|
|
361
|
+
)
|
|
362
|
+
`);
|
|
363
|
+
const sub = args[1] || '';
|
|
364
|
+
// ─── team push ──────────────────────────────────────────────────────
|
|
365
|
+
if (sub === 'push') {
|
|
366
|
+
console.log(C.primary(' Pushing your patterns to team...'));
|
|
367
|
+
const { teamPush } = require('./team-git');
|
|
368
|
+
const name = args[2];
|
|
369
|
+
if (!name) {
|
|
370
|
+
console.log(C.warn(' Usage: cell team push <your-name> [role]'));
|
|
371
|
+
console.log();
|
|
372
|
+
return;
|
|
3652
373
|
}
|
|
374
|
+
const role = args[3] || 'developer';
|
|
375
|
+
const result = teamPush(name, role);
|
|
376
|
+
console.log(result.success ? C.success(` ${result.message}`) : C.warn(` ${result.message}`));
|
|
3653
377
|
console.log();
|
|
378
|
+
return;
|
|
3654
379
|
}
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
});
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
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}`);
|
|
380
|
+
// ─── team pull ──────────────────────────────────────────────────────
|
|
381
|
+
if (sub === 'pull') {
|
|
382
|
+
console.log(C.primary(' Pulling team data...'));
|
|
383
|
+
const { teamPull } = require('./team-git');
|
|
384
|
+
const result = teamPull();
|
|
385
|
+
if (result.success) {
|
|
386
|
+
console.log(C.success(` ${result.message}`));
|
|
387
|
+
console.log(C.dim(` Members: ${result.newMembers}, Patterns: ${result.newPatterns}`));
|
|
3673
388
|
}
|
|
3674
|
-
|
|
3675
|
-
console.log(C.
|
|
3676
|
-
for (const f of d.areasToFocus)
|
|
3677
|
-
console.log(` ${C.warn('⚠')} ${f}`);
|
|
389
|
+
else {
|
|
390
|
+
console.log(C.warn(` ${result.message}`));
|
|
3678
391
|
}
|
|
3679
392
|
console.log();
|
|
393
|
+
return;
|
|
3680
394
|
}
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
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}`);
|
|
395
|
+
// ─── team status ────────────────────────────────────────────────────
|
|
396
|
+
if (sub === 'status') {
|
|
397
|
+
const { teamStatus } = require('./team-git');
|
|
398
|
+
const intel = teamStatus();
|
|
399
|
+
if (!intel) {
|
|
400
|
+
console.log(C.dim(' No team data. Run: cell team push <your-name>'));
|
|
401
|
+
console.log();
|
|
402
|
+
return;
|
|
3724
403
|
}
|
|
404
|
+
console.log(C.bold(` Team: ${intel.summary.totalMembers} members`));
|
|
405
|
+
console.log(C.dim(` Patterns: ${intel.summary.totalPatterns}, Bus Factor: ${intel.summary.avgBusFactor}`));
|
|
3725
406
|
console.log();
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
}
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
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`);
|
|
407
|
+
if (intel.members.length > 0) {
|
|
408
|
+
console.log(C.bold(' Members:'));
|
|
409
|
+
for (const m of intel.members) {
|
|
410
|
+
console.log(` ${C.success('•')} ${m.name} (${m.role}) — ${m.patterns} patterns`);
|
|
411
|
+
if (m.strengths.length > 0)
|
|
412
|
+
console.log(C.dim(` Strengths: ${m.strengths.join(', ')}`));
|
|
413
|
+
}
|
|
414
|
+
console.log();
|
|
3759
415
|
}
|
|
3760
|
-
|
|
3761
|
-
console.log(C.
|
|
416
|
+
if (intel.knowledgeMap.length > 0) {
|
|
417
|
+
console.log(C.bold(' Knowledge Map:'));
|
|
418
|
+
for (const k of intel.knowledgeMap) {
|
|
419
|
+
const risk = k.busFactor <= 1 ? C.warn('⚠ BUS=1') : C.dim(`bus=${k.busFactor}`);
|
|
420
|
+
console.log(` ${k.area}: ${k.experts.join(', ')} ${risk}`);
|
|
421
|
+
}
|
|
422
|
+
console.log();
|
|
3762
423
|
}
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
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}`);
|
|
424
|
+
if (intel.sharedPatterns.length > 0) {
|
|
425
|
+
console.log(C.bold(' Top Shared Patterns:'));
|
|
426
|
+
for (const p of intel.sharedPatterns.slice(0, 5)) {
|
|
427
|
+
console.log(` ${C.dim('•')} ${p.name}: ${p.value} (${p.count}x)`);
|
|
3870
428
|
}
|
|
429
|
+
console.log();
|
|
3871
430
|
}
|
|
431
|
+
if (intel.summary.strongestArea)
|
|
432
|
+
console.log(C.success(` + Strongest: ${intel.summary.strongestArea}`));
|
|
433
|
+
if (intel.summary.weakestArea)
|
|
434
|
+
console.log(C.warn(` ! Weakest: ${intel.summary.weakestArea}`));
|
|
435
|
+
if (intel.summary.criticalBlindSpots > 0)
|
|
436
|
+
console.log(C.warn(` ! ${intel.summary.criticalBlindSpots} critical blind spots`));
|
|
437
|
+
console.log();
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
if (sub === 'add' && args[2]) {
|
|
441
|
+
const name = args[2];
|
|
442
|
+
const role = args[3] || 'developer';
|
|
443
|
+
db.prepare('INSERT INTO team_members (name, role) VALUES (?, ?)').run(name, role);
|
|
444
|
+
const members = db.prepare('SELECT name, role, joined_at FROM team_members').all();
|
|
445
|
+
(0, layers_1.saveTeamMembers)(members.map((m) => ({ name: m.name, role: m.role, joinedAt: m.joined_at })));
|
|
446
|
+
console.log(C.success(` Added: ${name} (${role})`));
|
|
447
|
+
console.log(C.dim(' Saved to .cell/team/members.json'));
|
|
3872
448
|
console.log();
|
|
449
|
+
return;
|
|
3873
450
|
}
|
|
3874
|
-
|
|
3875
|
-
|
|
451
|
+
if (sub === 'remove' && args[2]) {
|
|
452
|
+
db.prepare('DELETE FROM team_members WHERE name = ?').run(args[2]);
|
|
453
|
+
const members = db.prepare('SELECT name, role, joined_at FROM team_members').all();
|
|
454
|
+
(0, layers_1.saveTeamMembers)(members.map((m) => ({ name: m.name, role: m.role, joinedAt: m.joined_at })));
|
|
455
|
+
console.log(C.success(` Removed: ${args[2]}`));
|
|
456
|
+
console.log();
|
|
457
|
+
return;
|
|
3876
458
|
}
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
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'}`);
|
|
459
|
+
// Default: show member list + team commands
|
|
460
|
+
const members = db.prepare('SELECT name, role, joined_at FROM team_members').all();
|
|
461
|
+
if (members.length === 0) {
|
|
462
|
+
console.log(C.dim(' No team members yet.'));
|
|
3893
463
|
console.log();
|
|
3894
464
|
}
|
|
3895
|
-
|
|
3896
|
-
|
|
465
|
+
console.log(C.bold(' Members:'));
|
|
466
|
+
for (const m of members) {
|
|
467
|
+
console.log(` ${C.num(m.name)} — ${m.role}`);
|
|
3897
468
|
}
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
.
|
|
3901
|
-
.
|
|
3902
|
-
.
|
|
3903
|
-
.
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
469
|
+
console.log();
|
|
470
|
+
console.log(' Commands:');
|
|
471
|
+
console.log(` ${C.primary('cell team push <name>')} Share your patterns with team`);
|
|
472
|
+
console.log(` ${C.primary('cell team pull')} Pull team data from git`);
|
|
473
|
+
console.log(` ${C.primary('cell team status')} Team intelligence dashboard`);
|
|
474
|
+
console.log(` ${C.primary('cell team add/remove')} Manage members`);
|
|
475
|
+
console.log();
|
|
476
|
+
}
|
|
477
|
+
// ─── cell community ─────────────────────────────────────────────────────────
|
|
478
|
+
function doCommunity() {
|
|
479
|
+
console.log();
|
|
480
|
+
console.log(C.bold(' Cell Community'));
|
|
481
|
+
console.log(C.dim(' ──────────────'));
|
|
482
|
+
console.log();
|
|
483
|
+
const sub = args[1] || '';
|
|
484
|
+
if (sub === 'share') {
|
|
485
|
+
try {
|
|
486
|
+
const { sharePatterns } = require('./community-intel');
|
|
487
|
+
const result = sharePatterns();
|
|
488
|
+
console.log(result.success ? C.success(` ${result.message}`) : C.warn(` ${result.message}`));
|
|
489
|
+
console.log(C.dim(' Anonymous — only pattern types shared, zero code.'));
|
|
3913
490
|
}
|
|
3914
|
-
|
|
3915
|
-
console.log(
|
|
491
|
+
catch {
|
|
492
|
+
console.log(C.warn(' Share failed. Run cell scan first.'));
|
|
3916
493
|
}
|
|
3917
494
|
console.log();
|
|
495
|
+
return;
|
|
3918
496
|
}
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
.
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
497
|
+
if (sub === 'browse' || sub === '') {
|
|
498
|
+
try {
|
|
499
|
+
const { generateCommunityReport } = require('./community-intel');
|
|
500
|
+
const report = generateCommunityReport();
|
|
501
|
+
if (report.patterns.length > 0) {
|
|
502
|
+
console.log(C.bold(` 📊 Top Patterns (${report.patterns.length} total):`));
|
|
503
|
+
for (const p of report.patterns.slice(0, 8)) {
|
|
504
|
+
console.log(` ${C.num(String(p.percentage))}% ${p.category}: ${p.description}`);
|
|
505
|
+
}
|
|
506
|
+
console.log();
|
|
507
|
+
}
|
|
508
|
+
if (report.benchmarks.length > 0) {
|
|
509
|
+
console.log(C.bold(' 📈 Benchmarks:'));
|
|
510
|
+
for (const b of report.benchmarks) {
|
|
511
|
+
console.log(` ${b.metric}: ${C.num(String(b.percentile))}th percentile — ${b.interpretation}`);
|
|
512
|
+
}
|
|
513
|
+
console.log();
|
|
514
|
+
}
|
|
515
|
+
if (report.topStacks.length > 0) {
|
|
516
|
+
console.log(C.bold(' 🏗️ Top Stacks:'));
|
|
517
|
+
for (const s of report.topStacks) {
|
|
518
|
+
console.log(` ${C.success('•')} ${s.stack} (${s.count}x)`);
|
|
519
|
+
}
|
|
520
|
+
console.log();
|
|
521
|
+
}
|
|
522
|
+
if (report.topBlindSpots.length > 0) {
|
|
523
|
+
console.log(C.bold(' ⚠️ Common Blind Spots:'));
|
|
524
|
+
for (const b of report.topBlindSpots) {
|
|
525
|
+
console.log(` ${C.warn('!')} ${b.blindSpot} (${b.percentage}%)`);
|
|
526
|
+
}
|
|
527
|
+
console.log();
|
|
3938
528
|
}
|
|
3939
529
|
}
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
530
|
+
catch {
|
|
531
|
+
console.log(C.dim(' No community data yet. Run: cell scan first.'));
|
|
532
|
+
}
|
|
533
|
+
return;
|
|
3944
534
|
}
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
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
|
-
}
|
|
3963
|
-
// ─── Number Command Interception ──────────────────────
|
|
3964
|
-
const rawArgs = process.argv.slice(2);
|
|
3965
|
-
if (rawArgs.length === 0) {
|
|
3966
|
-
showBanner();
|
|
3967
|
-
process.exit(0);
|
|
535
|
+
console.log(' Commands:');
|
|
536
|
+
console.log(' cell community browse Browse community patterns & benchmarks');
|
|
537
|
+
console.log(' cell community share Share patterns anonymously');
|
|
538
|
+
console.log();
|
|
3968
539
|
}
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
540
|
+
// ─── cell help ──────────────────────────────────────────────────────────────
|
|
541
|
+
function doHelp() {
|
|
542
|
+
console.log();
|
|
543
|
+
console.log(C.bold(' Cell Commands'));
|
|
544
|
+
console.log(C.dim(' ─────────────'));
|
|
545
|
+
console.log();
|
|
546
|
+
console.log(` ${C.primary('cell start')} Start daemon + MCP (port 9876)`);
|
|
547
|
+
console.log(` ${C.primary('cell stop')} Stop daemon`);
|
|
548
|
+
console.log(` ${C.primary('cell scan')} Scan codebase + build layers`);
|
|
549
|
+
console.log(` ${C.primary('cell status')} What Cell knows about you`);
|
|
550
|
+
console.log(` ${C.primary('cell team')} Team collaboration (git-based)`);
|
|
551
|
+
console.log(` ${C.primary('cell community')} Community features`);
|
|
552
|
+
console.log(` ${C.primary('cell help')} Show this help`);
|
|
553
|
+
console.log();
|
|
554
|
+
console.log(C.dim(' Install: npm i -g fivocell'));
|
|
555
|
+
console.log(C.dim(' Then: cell start'));
|
|
556
|
+
console.log();
|
|
3972
557
|
}
|
|
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
|
-
});
|
|
3989
|
-
program.parse(process.argv);
|
|
3990
558
|
//# sourceMappingURL=cli.js.map
|