Markdown Converter
Agent skill for markdown-converter
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Sign in to like and favorite skills
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
DJ DataForge v6 is an Excel-like data grid with a formula engine, plugin system, and multi-company support. It runs entirely client-side using TypeScript, Vite, and IndexedDB for persistence.
npm run dev # Start dev server (http://localhost:5173) npm run build # TypeScript compile + production build npm run preview # Preview production build (http://localhost:4173) npm run type-check # TypeScript type checking (no emit)
npm run lint # ESLint (src/**/*.ts) npm run format # Prettier formatting
npm run test # Run all tests (vitest) npm run test:unit # Unit tests only npm run test:e2e # Playwright E2E tests npm run test:watch # Watch mode npm run coverage # Coverage report npm run bench # Performance benchmarks
npm run build:plugin # Build plugin using vite.config.plugin.ts npm run build:standalone # Build standalone version (pre + post processing)
dist/index.html directly in browser (CORS policy blocks file:// protocol)npm run preview or a local HTTP server to test builds┌─────────────────────────────────────────────────────┐ │ UI Layer (ui-manager.ts) │ │ Grid View | Dashboard Mode | Selection | Toolbar │ ├─────────────────────────────────────────────────────┤ │ Plugin Layer │ │ FX-Finance | Charts | ProLease | Custom Plugins │ ├─────────────────────────────────────────────────────┤ │ API Layer (PluginContext + EventBus) │ │ Events | UI Integration | Storage API | Formulas │ ├─────────────────────────────────────────────────────┤ │ Core Services (Kernel) │ │ Workbook | CalcEngine | Dashboard | Table | Grid │ ├─────────────────────────────────────────────────────┤ │ Persistence Layer (storage-utils) │ │ IndexedDB | Companies | Workbooks | Plugin Data │ └─────────────────────────────────────────────────────┘
The Kernel is a singleton that orchestrates all system components:
kernel.workbookManager // Manages workbooks and sheets kernel.calcEngine // Formula parser and evaluator kernel.storageManager // IndexedDB persistence kernel.companyManager // Multi-company contexts kernel.pluginHost // Plugin loading and management kernel.eventBus // Pub/sub event system kernel.sessionManager // Session tracking kernel.dashboardManager // Dashboard creation and management kernel.tableManager // Table operations and data structures
Access kernel via:
import { kernel } from '@core/kernel' or DJDataForgeKernel.getInstance()
The codebase uses consolidated files (not yet split into modules):
Core Layer (
src/@core/):
types/index.ts - All TypeScript typesworkbook-consolidated.ts - Workbook, Sheet, Column, Cell, WorkbookManagercalc-engine-consolidated.ts - Parser, Evaluator, Registry, DAGcalc/parser.ts - Tokenizer and AST builder (modular)storage-utils-consolidated.ts - Storage, Logger, Formatters, Assertkernel.ts - Kernel orchestrator, EventBus, CompanyManagerplugin-system-consolidated.ts - Plugin host and interfacesgrid-virtual-consolidated.ts - Virtual grid renderingio-transform-consolidated.ts - Import/export, transformationsdashboard-manager.ts - Dashboard orchestration and state managementdashboard-widgets.ts - Widget definitions and lifecycledashboard-renderer.ts - Canvas/SVG rendering enginewidget-registry.ts - Widget catalog and registrationtable-manager.ts - Table data structures and operationsUI Layer:
src/app.ts - Application entry point and initializationsrc/main.ts - Vite entry pointsrc/ui-manager.ts - UI state management and event handlingPlugin Layer (
src/plugins/):
fx-finance-plugin.ts - FX rates and financial formulascharts-plugin.ts - Chart.js integrationprolease-ifrs16-plugin.ts - IFRS 16 lease accountingchart-manager.ts - Chart configuration managerindex.ts - Plugin registry and loaderNOTE: Consolidated files have
// FUTURE SPLIT POINTS: comments indicating where to split when refactoring.
TypeScript path mapping (configured in tsconfig.json and vite.config.ts):
@core/* → src/@core/* @ui/* → src/@ui/* @plugins/* → src/@plugins/*
Always use path aliases when importing core modules.
This project uses strict mode with aggressive linting:
When writing code, ensure full type safety and handle all edge cases explicitly.
The CalcEngine provides a full formula parser and evaluator:
Built-in Functions (40+ formulas across core + plugins):
Core Functions (20 formulas):
Plugin Functions (FX-Finance Plugin):
Registering Custom Functions:
const registry = kernel.calcEngine.getRegistry(); registry.register('MY_FUNC', (arg1: number, arg2: number) => { return arg1 + arg2; }, { argCount: 2, description: 'My custom function' });
Formula Evaluation Flow:
=SOMA(A1:A10)Formulas support dependency tracking and automatic recalculation.
All plugins implement the
Plugin interface:
interface Plugin { manifest: PluginManifest; init(context: PluginContext): Promise<void>; dispose?(): Promise<void>; }
Each plugin receives a
PluginContext with access to:
context.kernel - Full kernel servicescontext.storage - Plugin-specific persistent storage (IndexedDB)context.ui - UI integration (toolbar buttons, panels, menus)context.events - Event pub/sub systemBuilt-in Plugins:
src/plugins/fx-finance-plugin.ts) - Exchange rates (PTAX/BCB API), 8 FX formulas (FX.RATE, FX.CONVERT, etc.), 6 financial formulas (FIN.PV, FIN.FV, FIN.PMT, etc.), and economic indices trackingsrc/plugins/charts-plugin.ts) - Chart.js integration with 8 chart types, 5 themes, wizard-based creation, PNG export, and persistent storagesrc/plugins/prolease-ifrs16-plugin.ts) - Lease accounting with IFRS 16 compliance, amortization schedules, Web Worker calculations, and contract managementWorkbook → Sheets → Cells
// Create workbook const wb = kernel.workbookManager.createWorkbook('My Workbook'); // Add sheet const sheet = wb.addSheet('Sheet1'); // Set cell values sheet.setCell(0, 0, 'Name'); sheet.setCell(1, 0, 'John', { type: 'text' }); // Set formula sheet.setCell(1, 1, '=A2&" Smith"', { formula: '=A2&" Smith"', type: 'formula' }); // Recalculate await kernel.recalculate(sheet.id);
Storage: Sparse data structure - empty cells are not stored. Rows and columns use
Map<number, ...> for efficient memory usage.
Every workbook can belong to a company context:
const company = await kernel.companyManager.createCompany('Acme Corp'); kernel.companyManager.setActiveCompany(company.id); // Workbooks created now will inherit company settings const wb = kernel.workbookManager.createWorkbook('Q4 Sales'); // wb.companyId === company.id
Company contexts include settings for locale, currency, date format, number format, decimals, and timezone.
Use the EventBus for decoupled communication:
// Listen to events kernel.eventBus.on('workbook:saved', (data) => { console.log('Workbook saved:', data.workbookId); }); // Emit events kernel.eventBus.emit('custom:event', { data: 'payload' });
Standard Events:
kernel:ready, kernel:shutdown, kernel:recalc-done, kernel:autosave-doneworkbook:created, workbook:deleted, workbook:savedsheet:created, sheet:deleted, sheet:renamed, sheet:activatedplugin:loaded, plugin:unloadedcell:changed, cell:editeddashboard:created, widget:added, widget:updatedAll data persists to IndexedDB (
DJ_DataForge_v6 database):
Object Stores:
companies - Company contextsworkbooks - Workbook data (indexed by companyId)snapshots - Recovery snapshotsplugin_data - Plugin-specific data (indexed by pluginId)plugin_settings - Plugin configurationssettings - Global settingsAuto-save: Runs every 10 seconds automatically. Use
kernel.saveWorkbook(id) or kernel.saveAllWorkbooks() for manual saves.
DJ DataForge v6 includes a dashboard system for creating interactive data visualizations and KPI displays:
Dashboard Manager (
kernel.dashboardManager):
Widget System:
Usage Example:
// Create dashboard const dashboard = kernel.dashboardManager.createDashboard('Sales Dashboard'); // Add KPI widget dashboard.addWidget({ type: 'kpi-card', config: { title: 'Total Revenue', dataSource: '=SOMA(Sales!D:D)', format: 'currency' } }); // Render to sheet await dashboard.renderToSheet('Dashboard Sheet');
Plugin Integration: Dashboard widgets can be registered by plugins, allowing custom visualizations beyond the built-in types.
The UI Manager (
src/ui-manager.ts) handles all UI state and user interactions:
Key Responsibilities:
Dashboard Mode:
Integration with Kernel:
// Access UI state const uiManager = window.DJUIManager; // Switch to dashboard mode uiManager.setMode('dashboard'); // Get current selection const selection = uiManager.getSelection(); // Register custom keyboard shortcut uiManager.registerShortcut('Ctrl+Shift+D', () => { // Custom action });
src/@core/calc-engine-consolidated.tsFormulaRegistry constructorthis.register('MY_FORMULA', (arg1: number, arg2: number) => { return arg1 * arg2; }, { argCount: 2, description: 'Multiplies two numbers' });
src/plugins/my-plugin.ts:import type { Plugin, PluginContext, PluginManifest } from '@core/types'; export class MyPlugin implements Plugin { manifest: PluginManifest = { id: 'my-plugin', name: 'My Plugin', version: '1.0.0', author: 'Your Name', description: 'Does something cool', permissions: ['read:workbook', 'write:workbook', 'ui:toolbar'], entryPoint: 'my-plugin.js', }; async init(context: PluginContext): Promise<void> { // Register custom formulas const registry = context.kernel.calcEngine.getRegistry(); registry.register('MY_FUNC', (arg: number) => arg * 2, { argCount: 1, description: 'Doubles a number' }); // Add UI elements context.ui.addToolbarButton({ id: 'my-button', label: 'My Action', icon: '🚀', onClick: () => this.handleClick(context) }); context.ui.showToast('My Plugin loaded!', 'success'); } private handleClick(context: PluginContext): void { // Plugin logic here } async dispose(): Promise<void> { // Cleanup resources } }
src/plugins/index.ts:import { MyPlugin } from './my-plugin'; export const myPlugin = new MyPlugin();
src/app.ts during kernel initialization:await kernel.pluginHost.loadPlugin(myPlugin);
// Get active workbook const wb = kernel.workbookManager.getActiveWorkbook(); if (!wb) return; // Add sheet with data const sheet = wb.addSheet('Data'); const headers = ['ID', 'Name', 'Amount']; headers.forEach((h, col) => sheet.setCell(0, col, h)); // Add data rows const data = [[1, 'Alice', 100], [2, 'Bob', 200]]; data.forEach((row, rowIdx) => { row.forEach((val, colIdx) => { sheet.setCell(rowIdx + 1, colIdx, val); }); }); // Recalculate and save await kernel.recalculate(sheet.id); await kernel.saveWorkbook(wb.id);
The FX-Finance plugin provides exchange rate formulas and financial calculations:
// Get exchange rate for a specific date sheet.setCell(0, 0, '=FX.RATE("USD", "2025-01-15")'); // Get today's rate sheet.setCell(1, 0, '=FX.TODAY("EUR")'); // Convert currency amounts sheet.setCell(2, 0, '=FX.CONVERT(1000, "USD", "BRL", "2025-01-15")'); // Calculate variation between dates sheet.setCell(3, 0, '=FX.VARIATION("USD", "2025-01-01", "2025-01-15")'); // Financial formulas sheet.setCell(4, 0, '=FIN.PV(0.05/12, 60, -500)'); // Present Value sheet.setCell(5, 0, '=FIN.FV(0.05/12, 60, -500)'); // Future Value sheet.setCell(6, 0, '=FIN.PMT(0.05/12, 60, 10000)'); // Payment // Sync PTAX rates from BCB (Brazilian Central Bank) // This is done via UI button or programmatically: const fxPlugin = kernel.pluginHost.getPlugin('fx-finance'); await fxPlugin.syncPTAX('2025-01-01', '2025-12-31');
FX Rate Cache: Rates are cached in IndexedDB for fast O(1) lookups. Manual rates can be added via the plugin UI for currencies not covered by PTAX.
npm run type-check first to catch TypeScript errorsnpm run dev to test in browsernpm run test for automated testsnpm run preview to test production buildThe project includes a Logger utility:
import { logger } from '@core/storage-utils-consolidated'; logger.info('Message', { data: 'optional object' }); logger.warn('Warning'); logger.error('Error occurred', error); logger.debug('Debug info'); // Get log history const logs = logger.getHistory({ level: 'error' }); // Set log level logger.setLevel('debug'); // 'debug' | 'info' | 'warn' | 'error'
All logs appear in browser console and are stored in memory (can be exported).
// FUTURE SPLIT POINTS: comments to mark logical boundariesany without good reason)WorkbookManager)createWorkbook)MAX_CELL_SIZE)_ or use private keywordcalc-engine-consolidated.ts)The project is currently in Phase 1 (Foundation) with these remaining phases:
Comprehensive specifications are available in the project root:
When implementing new features, consult the relevant SPEC documents for detailed requirements and design decisions.