MCPcopy
hub / github.com/afar1/fieldtheory-cli / buildCli

Function buildCli

src/cli.ts:757–3400  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

755// ── CLI ─────────────────────────────────────────────────────────────────────
756
757export function buildCli() {
758 // One-time migration of ideas data from ~/.ft-bookmarks/automation/{ideas,adjacent}/
759 // to ~/.fieldtheory/ideas/. Idempotent and cheap on hot paths — two fs.existsSync
760 // calls after the first run. Runs before any command so every subcommand sees
761 // the new layout.
762 try {
763 const migration = migrateLegacyIdeasData();
764 if (migration.migrated) {
765 process.stderr.write(` Migrated ideas data → ${migration.newRoot}\n`);
766 process.stderr.write(` Legacy copies left intact at ${migration.legacyIdeasRoot} and ${migration.legacyAdjacentRoot}.\n`);
767 }
768 } catch (err) {
769 process.stderr.write(` Warning: ideas data migration failed — ${(err as Error).message}\n`);
770 }
771
772 const program = new Command();
773
774 async function rebuildIndex(): Promise<number> {
775 process.stderr.write(' Building search index...\n');
776 const idx = await buildIndex();
777 process.stderr.write(` \u2713 ${idx.recordCount} bookmarks indexed (${idx.newRecords} new)\n`);
778 return idx.newRecords;
779 }
780
781 async function classifyNew(override?: string): Promise<void> {
782 const engine = await resolveEngine({ override });
783
784 const start = Date.now();
785 process.stderr.write(' Classifying new bookmarks (categories)...\n');
786 const catResult = await classifyWithLlm({
787 engine,
788 onBatch: (done: number, total: number) => {
789 const pct = total > 0 ? Math.round((done / total) * 100) : 0;
790 const elapsed = Math.round((Date.now() - start) / 1000);
791 process.stderr.write(` Categories: ${done}/${total} (${pct}%) \u2502 ${elapsed}s elapsed\n`);
792 },
793 });
794 if (catResult.classified > 0) {
795 process.stderr.write(` \u2713 ${catResult.classified} categorized\n`);
796 }
797
798 const domStart = Date.now();
799 process.stderr.write(' Classifying new bookmarks (domains)...\n');
800 const domResult = await classifyDomainsWithLlm({
801 engine,
802 all: false,
803 onBatch: (done: number, total: number) => {
804 const pct = total > 0 ? Math.round((done / total) * 100) : 0;
805 const elapsed = Math.round((Date.now() - domStart) / 1000);
806 process.stderr.write(` Domains: ${done}/${total} (${pct}%) \u2502 ${elapsed}s elapsed\n`);
807 },
808 });
809 if (domResult.classified > 0) {
810 process.stderr.write(` \u2713 ${domResult.classified} domains assigned\n`);
811 }
812 }
813
814 program

Callers 4

cli.tsFile · 0.85
engine.test.tsFile · 0.85
cli.test.tsFile · 0.85
ft.mjsFile · 0.85

Calls 15

migrateLegacyIdeasDataFunction · 0.85
getLocalVersionFunction · 0.85
shouldSkipCommandChromeFunction · 0.85
logoFunction · 0.85
showWhatsNewFunction · 0.85
engineOptionFunction · 0.85
isFirstRunFunction · 0.85
showSyncWelcomeFunction · 0.85
ensureDataDirFunction · 0.85
resolveEngineFunction · 0.85
createSpinnerFunction · 0.85
parseCookieOptionFunction · 0.85

Tested by

no test coverage detected