@datasynx/agentic-crm 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.md +10 -0
  2. package/dist/{attachments-rLa96rOK.js → attachments-BddHbCt8.js} +51 -32
  3. package/dist/{attachments-D207gXfN.js.map → attachments-BddHbCt8.js.map} +1 -1
  4. package/dist/{attachments-D207gXfN.js → attachments-Co3kXIvu.js} +46 -31
  5. package/dist/{attachments-rLa96rOK.js.map → attachments-Co3kXIvu.js.map} +1 -1
  6. package/dist/{attachments-CX2GAtsw.cjs → attachments-Dbe7Bidz.cjs} +46 -31
  7. package/dist/{attachments-CX2GAtsw.cjs.map → attachments-Dbe7Bidz.cjs.map} +1 -1
  8. package/dist/attachments-YQKYmg6N.js +2 -0
  9. package/dist/cli.js +61 -3
  10. package/dist/cli.js.map +1 -1
  11. package/dist/daemon/worker.js +1 -1
  12. package/dist/{gmail-sync-DIbrPnTK.js → gmail-sync-BHLa8v51.js} +2 -2
  13. package/dist/{gmail-sync-DIbrPnTK.js.map → gmail-sync-BHLa8v51.js.map} +1 -1
  14. package/dist/{gmail-sync-BpSVESSe.cjs → gmail-sync-CodrUNR4.cjs} +2 -2
  15. package/dist/{gmail-sync-BpSVESSe.cjs.map → gmail-sync-CodrUNR4.cjs.map} +1 -1
  16. package/dist/{gmail-sync-B4Iu3AQb.js → gmail-sync-SvECok5p.js} +2 -2
  17. package/dist/{gmail-sync-B4Iu3AQb.js.map → gmail-sync-SvECok5p.js.map} +1 -1
  18. package/dist/imap-o6PRuBvm.js +270 -0
  19. package/dist/imap-o6PRuBvm.js.map +1 -0
  20. package/dist/{index-DMTVVYwr.d.cts → index-Dspvybo0.d.cts} +22 -22
  21. package/dist/index-Dspvybo0.d.cts.map +1 -0
  22. package/dist/index.d.cts +22 -22
  23. package/dist/index.d.cts.map +1 -1
  24. package/dist/mcp.cjs +2 -2
  25. package/dist/mcp.js +2 -2
  26. package/dist/{server-BhNLrnAD.js → server-uqXUhF4H.js} +3 -3
  27. package/dist/{server-BhNLrnAD.js.map → server-uqXUhF4H.js.map} +1 -1
  28. package/package.json +4 -1
  29. package/dist/index-DMTVVYwr.d.cts.map +0 -1
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":["HOME","HOME","HOME","HOME","HOME","HOME","HOME","getPidFile","slugify","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir"],"sources":["../src/commands/create.ts","../src/ui/table.ts","../src/commands/list.ts","../src/commands/validate.ts","../src/commands/guide.ts","../src/setup/harness-content.ts","../src/setup/adapters/claude-code.ts","../src/setup/adapters/claude-desktop.ts","../src/setup/adapters/codex.ts","../src/setup/adapters/openclaw.ts","../src/setup/adapters/hermes.ts","../src/setup/adapters/antigravity.ts","../src/setup/adapters/cursor.ts","../src/setup/adapters/windsurf.ts","../src/setup/adapters/cline.ts","../src/setup/adapters/grok.ts","../src/setup/framework-registry.ts","../src/commands/init.ts","../src/commands/sync.ts","../src/commands/daemon.ts","../src/commands/status.ts","../src/commands/agent.ts","../src/commands/import.ts","../src/commands/server.ts","../src/commands/audit.ts","../src/commands/logs.ts","../src/commands/doctor.ts","../src/commands/rbac.ts","../src/commands/gdpr.ts","../src/commands/security-report.ts","../src/commands/pipeline-stages.ts","../src/core/plugin-registry.ts","../src/commands/plugin.ts","../src/commands/goal.ts","../src/commands/push.ts","../src/commands/attach.ts","../src/commands/template.ts","../src/commands/sequence.ts","../src/commands/quote.ts","../src/commands/ticket.ts","../src/commands/survey.ts","../src/commands/kb.ts","../src/commands/fields.ts","../src/commands/webhook.ts","../src/commands/segment.ts","../src/commands/identity.ts","../src/commands/metrics.ts","../src/commands/usage.ts","../src/commands/approvals.ts","../src/commands/hygiene.ts","../src/commands/memory.ts","../src/commands/sop.ts","../src/commands/tone.ts","../src/commands/autofill.ts","../src/commands/ask.ts","../src/commands/nba.ts","../src/commands/vault.ts","../src/commands/churn.ts","../src/commands/leadscore.ts","../src/commands/enrich.ts","../src/commands/coach.ts","../src/commands/compliance.ts","../src/commands/registry.ts","../src/cli.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport slugify from \"slug\";\nimport { ensureCustomerDir, writeMainFacts } from \"../fs/customer-dir.js\";\nimport { writeFileAtomic } from \"../fs/atomic-write.js\";\nimport { writeJsonFile } from \"../fs/json-store.js\";\nimport { success, error, bold } from \"../ui/colors.js\";\n\nexport async function createCustomer(opts: {\n name: string;\n domain?: string;\n email?: string;\n dataDir?: string;\n}): Promise<{ id: string; dir: string }> {\n const id = slugify(opts.name, { lower: true });\n const dataDir = opts.dataDir ?? process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n await ensureCustomerDir(dataDir, id);\n const dir = path.join(dataDir, \"customers\", id);\n\n // Write main_facts.md\n const today = new Date().toISOString().slice(0, 10);\n await writeMainFacts(dataDir, id, {\n name: opts.name,\n domain: opts.domain,\n email: opts.email,\n relationship_stage: \"prospect\",\n tags: [],\n currency: \"EUR\",\n created: today,\n updated: today,\n });\n\n // Create interactions.md\n const interactionsPath = path.join(dir, \"interactions.md\");\n if (!fs.existsSync(interactionsPath)) {\n writeFileAtomic(interactionsPath, `# Interactions — ${opts.name}\\n\\n`);\n }\n\n // Create pipeline.md\n const pipelinePath = path.join(dir, \"pipeline.md\");\n if (!fs.existsSync(pipelinePath)) {\n writeFileAtomic(\n pipelinePath,\n `# Pipeline — ${opts.name}\\n\\n| Deal | Stage | Value | Currency | Probability | Close Date | Updated | Notes |\\n|---|---|---|---|---|---|---|---|\\n`\n );\n }\n\n // Create sources.json\n const sourcesPath = path.join(dir, \"sources.json\");\n if (!fs.existsSync(sourcesPath)) {\n const gmailQuery = opts.domain\n ? `from:${opts.domain} OR to:${opts.domain}`\n : opts.email\n ? `from:${opts.email} OR to:${opts.email}`\n : \"\";\n const sources = {\n gmail: {\n type: \"gmail\",\n query: gmailQuery,\n enabled: true,\n },\n version: 1,\n created: new Date().toISOString(),\n };\n writeJsonFile(sourcesPath, sources);\n }\n\n return { id, dir };\n}\n\nexport const createCommand = new Command(\"create\")\n .description(\"Create a new customer\")\n .argument(\"<name>\", \"Customer name\")\n .option(\"--domain <domain>\", \"Primary domain (for Gmail sync)\")\n .option(\"--email <email>\", \"Primary contact email\")\n .action(async (name: string, opts: { domain?: string; email?: string }) => {\n try {\n const { id, dir } = await createCustomer({ name, ...opts });\n console.log(success(`✓ Created customer: ${bold(id)}`));\n console.log(` Dir: ${dir}`);\n console.log(` Files: main_facts.md, interactions.md, pipeline.md, sources.json`);\n } catch (err) {\n console.error(error(`✗ ${(err as Error).message}`));\n process.exit(1);\n }\n });\n","import Table from \"cli-table3\";\nimport type { MainFacts } from \"../schemas/main-facts.js\";\nimport type { PipelineDeal } from \"../schemas/pipeline.js\";\n\nexport interface CustomerRow {\n slug: string;\n facts: MainFacts;\n lastTouchpoint?: string;\n}\n\nexport function renderCustomerTable(customers: CustomerRow[]): string {\n const table = new Table({\n head: [\"Slug\", \"Name\", \"Stage\", \"Industry\", \"Tags\", \"Updated\"],\n style: { head: [\"cyan\"] },\n colWidths: [20, 25, 15, 15, 20, 12],\n wordWrap: true,\n });\n\n for (const { slug, facts } of customers) {\n table.push([\n slug,\n facts.name,\n facts.relationship_stage,\n facts.industry ?? \"—\",\n facts.tags.join(\", \") || \"—\",\n facts.updated,\n ]);\n }\n\n return table.toString();\n}\n\nexport function renderPipelineTable(deals: PipelineDeal[]): string {\n const table = new Table({\n head: [\"Name\", \"Stage\", \"Value\", \"Prob%\", \"Close Date\", \"Updated\"],\n style: { head: [\"cyan\"] },\n colWidths: [30, 15, 12, 8, 12, 12],\n wordWrap: true,\n });\n\n for (const deal of deals) {\n const valueStr =\n deal.value !== undefined ? `${deal.value.toLocaleString()} ${deal.currency}` : \"—\";\n const probStr = deal.probability !== undefined ? `${deal.probability}%` : \"—\";\n table.push([deal.name, deal.stage, valueStr, probStr, deal.close_date ?? \"—\", deal.updated]);\n }\n\n return table.toString();\n}\n","import { Command } from \"commander\";\nimport { readMainFacts, listCustomerSlugs } from \"../fs/customer-dir.js\";\nimport { renderCustomerTable } from \"../ui/table.js\";\nimport type { MainFacts } from \"../schemas/main-facts.js\";\n\nexport const listCommand = new Command(\"list\")\n .description(\"List all customers\")\n .option(\"--filter <query>\", \"Filter by name or slug\")\n .action(async (opts: { filter?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const slugs = listCustomerSlugs(dataDir);\n\n if (slugs.length === 0) {\n console.log('No customers yet. Run: dxcrm create \"Customer Name\"');\n return;\n }\n\n const customers: Array<{\n slug: string;\n facts: MainFacts;\n }> = [];\n\n for (const slug of slugs) {\n try {\n const facts = await readMainFacts(dataDir, slug);\n if (opts.filter) {\n const q = opts.filter.toLowerCase();\n if (\n !facts.name.toLowerCase().includes(q) &&\n !slug.includes(q) &&\n !(facts.relationship_stage ?? \"\").toLowerCase().includes(q)\n )\n continue;\n }\n customers.push({ slug, facts });\n } catch {\n /* skip invalid */\n }\n }\n\n if (customers.length === 0) {\n console.log(opts.filter ? `No customers matching \"${opts.filter}\"` : \"No customers yet.\");\n return;\n }\n\n console.log(renderCustomerTable(customers));\n });\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { MainFactsSchema } from \"../schemas/main-facts.js\";\nimport { listCustomerSlugs } from \"../fs/customer-dir.js\";\nimport matter from \"gray-matter\";\nimport { success, error, warning, info } from \"../ui/colors.js\";\n\nconst RECOVERABLE_DEFAULTS: Record<string, unknown> = {\n tags: [],\n currency: \"EUR\",\n};\n\nexport function applyFix(\n factsPath: string,\n content: string,\n data: Record<string, unknown>\n): { fixed: string[]; content: string } | null {\n const fixed: string[] = [];\n const patched = { ...data };\n\n for (const [field, defaultValue] of Object.entries(RECOVERABLE_DEFAULTS)) {\n if (patched[field] === undefined || patched[field] === null) {\n patched[field] = defaultValue;\n fixed.push(`${field} → ${JSON.stringify(defaultValue)}`);\n }\n }\n\n if (patched[\"updated\"] === undefined && patched[\"created\"]) {\n patched[\"updated\"] = patched[\"created\"];\n fixed.push(`updated → ${String(patched[\"created\"])}`);\n }\n\n if (fixed.length === 0) return null;\n\n const parsed = matter(content);\n const newContent = matter.stringify(parsed.content, patched);\n fs.writeFileSync(factsPath, newContent);\n return { fixed, content: newContent };\n}\n\nexport async function runValidate(opts: { fix?: boolean }, dataDir: string): Promise<void> {\n const customersDir = path.join(dataDir, \"customers\");\n\n if (!fs.existsSync(customersDir)) {\n console.log(warning(\"⚠ No customers directory found.\"));\n return;\n }\n\n const slugs = listCustomerSlugs(dataDir);\n\n let errorCount = 0;\n let fixedCount = 0;\n\n for (const slug of slugs) {\n const factsPath = path.join(customersDir, slug, \"main_facts.md\");\n const interactionsPath = path.join(customersDir, slug, \"interactions.md\");\n\n if (!fs.existsSync(factsPath)) {\n console.log(error(`✗ ${slug}: missing main_facts.md`));\n errorCount++;\n continue;\n }\n\n try {\n let content = fs.readFileSync(factsPath, \"utf-8\") as string;\n let parsed = matter(content);\n\n if (opts.fix) {\n const result = applyFix(factsPath, content, parsed.data as Record<string, unknown>);\n if (result) {\n content = result.content;\n parsed = matter(content); // only re-parse when a fix actually rewrote content\n fixedCount++;\n console.log(info(`⚙ ${slug}: fixed ${result.fixed.join(\", \")}`));\n }\n }\n\n MainFactsSchema.parse(parsed.data);\n\n if (!fs.existsSync(interactionsPath)) {\n console.log(warning(`⚠ ${slug}: missing interactions.md`));\n } else {\n console.log(success(`✓ ${slug}`));\n }\n } catch (err) {\n console.log(error(`✗ ${slug}: ${(err as Error).message}`));\n errorCount++;\n }\n }\n\n if (opts.fix && fixedCount > 0) {\n console.log(info(`\\n⚙ Fixed ${fixedCount} customer(s).`));\n }\n\n if (errorCount > 0) {\n console.error(error(`\\n${errorCount} error(s) found.`));\n process.exit(1);\n } else {\n console.log(success(\"\\n✓ All customers valid.\"));\n }\n}\n\nexport const validateCommand = new Command(\"validate\")\n .description(\"Validate all customer data against schemas\")\n .option(\"--fix\", \"Auto-fix recoverable issues\")\n .action(async (opts: { fix?: boolean }) => {\n await runValidate(opts, process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd());\n });\n","import { Command } from \"commander\";\nimport { CAPABILITIES_TEXT } from \"../mcp/capabilities.js\";\nimport { info } from \"../ui/colors.js\";\n\nexport const guideCommand = new Command(\"guide\")\n .description(\"Full CRM documentation in terminal\")\n .action(() => {\n console.log(CAPABILITIES_TEXT);\n });\n\nexport const mcpCommand = new Command(\"mcp\").description(\"MCP server management and documentation\");\n\nmcpCommand.command(\"docs\").action(() => {\n console.log(CAPABILITIES_TEXT);\n});\n\nmcpCommand\n .command(\"token\")\n .description(\"Mint a bearer token for the HTTP MCP server (printed once)\")\n .requiredOption(\"--actor <actor>\", \"Actor/user the token authenticates as\")\n .option(\"--role <role>\", \"RBAC role: admin | manager | rep\", \"rep\")\n .option(\"--label <label>\", \"Optional label (e.g. device name)\")\n .action(async (opts: { actor: string; role: string; label?: string }) => {\n const role = [\"admin\", \"manager\", \"rep\"].includes(opts.role)\n ? (opts.role as \"admin\" | \"manager\" | \"rep\")\n : \"rep\";\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const { createMcpToken } = await import(\"../mcp/auth.js\");\n const token = createMcpToken(dataDir, opts.actor, role, opts.label);\n console.log(info(\"MCP bearer token (store it now — it is not shown again):\"));\n console.log(token);\n console.log(info(`actor=${opts.actor} role=${role} — HTTP /mcp now requires this token.`));\n });\n\nmcpCommand\n .command(\"start\")\n .description(\"Start MCP server (stdio by default)\")\n .option(\"--http\", \"Use HTTP transport instead of stdio\")\n .option(\"--port <port>\", \"HTTP port (default 3847)\", \"3847\")\n .action(async (opts: { http?: boolean; port: string }) => {\n if (opts.http) {\n const port = parseInt(opts.port, 10);\n console.error(info(`Starting MCP server in HTTP mode on port ${port}...`));\n const { startHttp } = await import(\"../mcp/server.js\");\n await startHttp(port);\n } else {\n const { startStdio } = await import(\"../mcp/server.js\");\n await startStdio();\n }\n });\n","// src/setup/harness-content.ts\n// Single Source of Truth for all harness file content — v2 (see TOOL_COUNT below).\n\n// All registered MCP tools — keep in sync with src/mcp/server.ts\nconst ALL_TOOLS = [\n // Core v1\n \"get_capabilities\",\n \"get_active_session\",\n \"get_customer_context\",\n \"search_customer_knowledge\",\n \"list_customers\",\n \"log_interaction\",\n \"update_deal\",\n \"export_customer\",\n \"update_customer_facts\",\n \"get_deal_health\",\n \"get_pipeline_forecast\",\n \"summarize_meeting\",\n \"get_pipeline_stages\",\n \"get_market_intelligence\",\n // Graph & Health (D11/D12)\n \"get_relationship_graph\",\n \"get_relationship_health\",\n // Autonomous Agent (D13)\n \"run_deal_agent\",\n \"approve_agent_action\",\n // Revenue Intelligence (D14/D18)\n \"simulate_revenue\",\n \"get_org_intelligence\",\n // Playbooks (D15)\n \"get_playbook\",\n \"create_playbook\",\n \"list_playbooks\",\n \"distill_playbook\",\n // Goals (D16)\n \"pursue_goal\",\n \"get_goal_status\",\n // Push (D17)\n \"register_push_subscription\",\n \"get_push_status\",\n // Proactive & Deal Room (D19/D20)\n \"open_deal_room\",\n \"get_proactive_briefing\",\n // Email Templates (H2)\n \"list_email_templates\",\n \"get_email_template\",\n \"draft_email\",\n // Email Sequences (H1)\n \"enroll_in_sequence\",\n \"list_sequence_enrollments\",\n \"unenroll_from_sequence\",\n \"list_sequences\",\n // Quote Generator (H4)\n \"generate_quote\",\n \"get_quote_status\",\n // Calendly Scheduler (H3)\n \"get_booking_link\",\n // Ticket Management (H6)\n \"create_ticket\",\n \"update_ticket\",\n \"list_tickets\",\n \"close_ticket\",\n // NPS/CSAT Survey (H7)\n \"send_nps_survey\",\n \"get_survey_results\",\n // Knowledge Base (H8)\n \"search_knowledge_base\",\n \"create_kb_article\",\n // Backup (Enterprise)\n \"backup_now\",\n \"list_backups\",\n // Sync & Audit (Enterprise)\n \"trigger_sync\",\n \"get_audit_log\",\n \"get_logs\",\n \"get_diagnostics\",\n // Metadata / custom objects (Platform)\n \"define_custom_object\",\n \"create_record\",\n \"list_records\",\n \"list_custom_objects\",\n] as const;\n\nexport type McpToolName = (typeof ALL_TOOLS)[number];\nexport { ALL_TOOLS };\nexport const TOOL_COUNT = ALL_TOOLS.length; // 58\n\n/** Claude Code: CLAUDE.md in CRM dataDir */\nexport function buildClaudeMd(dataDir: string): string {\n return `# DatasynxOpenCRM v2 — Agent Instructions (${TOOL_COUNT} MCP Tools)\n\n## Proactive — Act Without Being Asked\nAt the start of every session, before the user says anything:\n1. \\`get_proactive_briefing()\\` — today's urgent items, forecast, top action\n2. \\`get_goal_status()\\` — if active goals exist, show progress\n\n## Before Every Deal Conversation\nUse \\`open_deal_room({ slug, dealName })\\` — not \\`get_customer_context()\\`.\nIt combines graph, health, revenue simulation, playbook, and org intelligence in one call (~3–5s).\n\n## Standard Workflow\n| Trigger | Tool |\n|---|---|\n| Customer mentioned | \\`get_customer_context(slug)\\` or \\`open_deal_room(slug, dealName)\\` |\n| After call/meeting/email | \\`log_interaction(slug, type, summary, nextSteps)\\` |\n| Deal stage changes | \\`update_deal(slug, dealName, { stage, probability, value })\\` |\n| Historical question | \\`search_customer_knowledge(slug, query)\\` |\n| \"What should I do today?\" | \\`get_proactive_briefing()\\` |\n| \"Close €X this quarter\" | \\`pursue_goal(goal, deadline)\\` |\n\n## Autonomy Patterns\n\n**User says \"Look at Acme Corp\":**\n1. \\`open_deal_room({ slug: \"acme-corp\", dealName: \"<active deal>\" })\\`\n2. Summarize in 3 bullets, recommend 1 action\n\n**User says \"What do I need to do today?\":**\n1. \\`get_proactive_briefing()\\`\n2. \\`get_goal_status()\\` if goals are active\n3. Reply with prioritized actions\n\n**User says \"Deal is stalled\":**\n1. \\`run_deal_agent({ slug, dealName, autonomyLevel: \"suggest\" })\\`\n2. Present the plan, ask for approval before acting\n\n## All ${TOOL_COUNT} MCP Tools\n\n### Foundation\n- \\`get_capabilities()\\` — complete tool reference with schemas\n- \\`get_active_session()\\` — which customer is currently open\n- \\`get_customer_context(slug?)\\` — full briefing, triggers background Gmail sync\n- \\`search_customer_knowledge(slug, query)\\` — semantic vector search across emails + transcripts\n- \\`list_customers(filter?)\\` — all customers with health score and last touchpoint\n- \\`log_interaction(slug, type, summary, nextSteps?)\\` — write to CRM; auto-updates graph + health\n- \\`update_deal(slug, dealName, fields)\\` — pipeline stage, value, probability, close date\n- \\`export_customer(slug, format?)\\` — export as JSON or Markdown ZIP\n- \\`update_customer_facts(slug, fields)\\` — name, domain, email, primary_contact, tags\n- \\`get_deal_health(slug)\\` — health score A–F with warnings per deal\n- \\`get_pipeline_forecast()\\` — weighted pipeline total and deal list\n- \\`summarize_meeting(transcript)\\` — LLM meeting analysis → structured notes\n- \\`get_pipeline_stages()\\` — configured stages with default probabilities\n- \\`get_market_intelligence(slug)\\` — competitor mentions and market context\n\n### Graph & Relationship (D11/D12)\n- \\`get_relationship_graph(slug)\\` — stakeholder graph: champions, blockers, economic buyers, warm intro paths\n- \\`get_relationship_health(slug)\\` — contact health scores A–F, decay detection, risk flags\n\n### Autonomous Deal Agent (D13)\n- \\`run_deal_agent({ slug, dealName, autonomyLevel })\\` — AI deal analysis + action plan; autonomyLevel: \"observe\" | \"suggest\" | \"act\"\n- \\`approve_agent_action({ actionId, approved })\\` — approve or reject a queued agent action\n\n### Revenue Intelligence (D14/D18)\n- \\`simulate_revenue({ horizon })\\` — Monte Carlo P10/P50/P90 forecast over full pipeline\n- \\`get_org_intelligence({ slug, dealName })\\` — stakeholder map, missing roles, external signals (funding, news)\n\n### Playbooks (D15)\n- \\`get_playbook({ slug, situation })\\` — matching playbook for current deal situation\n- \\`create_playbook({ name, trigger, content })\\` — save a new playbook\n- \\`list_playbooks()\\` — all available playbooks\n- \\`distill_playbook({ slug, dealName, outcome })\\` — learn from a won/lost deal\n\n### Goals (D16)\n- \\`pursue_goal({ goal, deadline, context? })\\` — decompose a revenue goal into prioritized sub-actions\n- \\`get_goal_status()\\` — progress of all active goals\n\n### Push (D17)\n- \\`register_push_subscription({ provider, webhookUrl })\\` — gmail | microsoft-graph | slack real-time push\n- \\`get_push_status()\\` — active subscriptions and expiry dates\n\n### Intelligence Synthesis (D19/D20)\n- \\`open_deal_room({ slug, dealName })\\` — orchestrates 7 sub-tools; returns complete deal brief in one call\n- \\`get_proactive_briefing({ date? })\\` — AI-generated daily briefing: urgent items, opportunities, forecast\n\n### Email Templates (H2)\n- \\`list_email_templates({ category? })\\` — list templates; filter by category (outreach, followup, support)\n- \\`get_email_template({ id })\\` — get full template with auto-detected variables\n- \\`draft_email({ slug, templateId, overrides? })\\` — draft personalized email from template + customer facts\n\n### Email Sequences (H1)\n- \\`enroll_in_sequence({ slug, contactEmail, sequenceId })\\` — enroll contact in automated email sequence\n- \\`list_sequence_enrollments({ slug?, status? })\\` — list enrollments; filter by slug or status\n- \\`unenroll_from_sequence({ enrollmentId })\\` — pause an active enrollment\n- \\`list_sequences()\\` — all sequences with step count and enrollment count\n\n### Quotes & Invoices (H4)\n- \\`generate_quote({ slug, dealName, lineItems, vatPercent?, validUntilDays? })\\` — create HTML quote with auto-numbering Q-YYYY-NNN\n- \\`get_quote_status({ quoteNumber?, slug? })\\` — get quote or list all quotes for customer\n\n### Meeting Scheduler (H3)\n- \\`get_booking_link({ slug, eventType?, prefillName? })\\` — get Calendly booking URL, optionally pre-filled with customer name/email\n\n### Ticket Management (H6)\n- \\`create_ticket({ slug, title, priority?, assignee? })\\` — open support ticket with auto-SLA due date\n- \\`update_ticket({ slug, ticketId, status?, assignee? })\\` — update ticket status or assignee\n- \\`list_tickets({ slug?, status?, priority?, assignee? })\\` — list tickets sorted by priority\n- \\`close_ticket({ slug, ticketId, resolution? })\\` — close ticket and optionally log resolution\n\n### NPS/CSAT Surveys (H7)\n- \\`send_nps_survey({ slug, contactEmail, surveyId, serverUrl? })\\` — generate survey token and email body for NPS/CSAT survey\n- \\`get_survey_results({ surveyId, slug? })\\` — NPS score, promoters/passives/detractors, all responses\n\n### Knowledge Base (H8)\n- \\`search_knowledge_base({ query, publicOnly? })\\` — full-text search across KB articles\n- \\`create_kb_article({ id, title, body, category?, tags?, public?, sourceTicketId? })\\` — create or update KB article\n\n### Backup (Enterprise)\n- \\`backup_now({ remote?, note? })\\` — trigger immediate backup of customers/ + .agentic/ with manifest + integrity check\n- \\`list_backups({ limit? })\\` — list available backups with date, size, verification status, customer count\n\n### Sync & Audit (Enterprise)\n- \\`trigger_sync({ slug?, since? })\\` — force immediate Gmail sync for one or all customers (bypasses 30-min daemon cycle)\n- \\`get_audit_log({ slug?, actor?, limit? })\\` — read append-only audit log of all write operations\n- \\`get_logs({ level?, component?, since?, contains?, limit?, summary? })\\` — query/aggregate the structured application log\n- \\`get_diagnostics({ fix? })\\` — self-diagnostic health check (data integrity, temp files, log errors, backups)\n\n### Custom Objects (Platform / metadata)\n- \\`define_custom_object({ name, label?, fields })\\` — define a runtime entity type with typed fields (no migration), admin\n- \\`create_record({ object, values })\\` — create a record of a custom object, validated against its schema, rep+\n- \\`list_records({ object })\\` — list records of a custom object\n- \\`list_custom_objects()\\` — list all defined custom objects and their schemas\n\n## Rules\n- Never discuss a customer without first loading their context\n- Always log interactions — calls, emails, Slack, demos, proposals\n- Never invent information — if uncertain, use search_customer_knowledge\n- Use open_deal_room before any deal conversation, not get_customer_context\n\n## Data Directory\n${dataDir}`.trim();\n}\n\n/** OpenClaw / Hermes: SOUL.md */\nexport function buildSoulMd(framework: \"openclaw\" | \"hermes\"): string {\n return `# Identity\nI am a CRM-integrated AI assistant powered by DatasynxOpenCRM v2 (${TOOL_COUNT} MCP tools).\nMy purpose is to help manage customer relationships proactively — acting before being asked.\n\n# Core Behaviors\n- **Proactive first.** At session start I call \\`get_proactive_briefing()\\` without being asked.\n- **Context before action.** Before any customer discussion: \\`open_deal_room()\\` or \\`get_customer_context()\\`.\n- **Log everything.** Every interaction — calls, emails, meetings, Slack — goes into the CRM via \\`log_interaction()\\`.\n- **Cite sources.** All customer information is cited: gmail://, file://, transcript://.\n- **Glass-box reasoning.** When using \\`run_deal_agent()\\`, I surface the trace so the user can inspect my reasoning.\n\n# Tool Hierarchy\n1. \\`open_deal_room()\\` — for deal conversations (combines 7 sub-tools)\n2. \\`get_proactive_briefing()\\` — for morning / session start\n3. \\`get_customer_context()\\` — for general customer questions\n4. \\`run_deal_agent()\\` — when a deal needs AI-driven analysis\n\n# Boundaries\n- I do not invent customer data. I search or sync first.\n- I do not skip logging — even quick Slack messages deserve a \\`log_interaction()\\`.\n- I do not act autonomously beyond \"suggest\" level without explicit human approval via \\`approve_agent_action()\\`.\n- I do not discuss a customer without context loaded.\n\n# Communication\nDirect. Action-oriented. Lead with the most important insight.\nBullet points for next steps. End every deal summary with: \"What do you want to do first?\"\n\n# Framework\n${framework === \"openclaw\" ? \"OpenClaw — tool prefix: datasynx_opencrm:\" : \"Hermes — skill: datasynx-crm\"}`.trim();\n}\n\n/** Hermes SOUL.md is same as OpenClaw */\nexport const buildHermesSoulMd = buildSoulMd;\n\n/** Codex / OpenClaw / Antigravity: AGENTS.md in dataDir */\nexport function buildAgentsMd(dataDir: string): string {\n return `# DatasynxOpenCRM v2 — Agent Instructions (${TOOL_COUNT} MCP Tools)\n\n## Role\nYou are a proactive CRM AI assistant. You act before being asked.\nAt every session start: call \\`get_proactive_briefing()\\`.\n\n## Priority Tool Order\n1. \\`open_deal_room(slug, dealName)\\` — before any deal conversation\n2. \\`get_proactive_briefing()\\` — at session start, or when asked \"what should I do?\"\n3. \\`get_customer_context(slug)\\` — for general customer questions\n4. \\`run_deal_agent(slug, dealName, \"suggest\")\\` — when a deal is stalled\n\n## Core Workflow\n- Customer mentioned → \\`get_customer_context(slug)\\` immediately\n- Deal conversation → \\`open_deal_room(slug, dealName)\\` first\n- After interaction → \\`log_interaction(slug, type, summary, nextSteps)\\`\n- Deal stage change → \\`update_deal(slug, dealName, { stage, probability })\\`\n- Revenue goal → \\`pursue_goal(goal, deadline)\\`\n\n## Available Tools (${TOOL_COUNT})\n**Foundation:** get_capabilities · get_active_session · get_customer_context ·\nsearch_customer_knowledge · list_customers · log_interaction · update_deal ·\nexport_customer · update_customer_facts · get_deal_health · get_pipeline_forecast ·\nsummarize_meeting · get_pipeline_stages · get_market_intelligence\n\n**Graph & Health (D11/D12):** get_relationship_graph · get_relationship_health\n\n**Autonomous Agent (D13):** run_deal_agent · approve_agent_action\n\n**Revenue (D14/D18):** simulate_revenue · get_org_intelligence\n\n**Playbooks (D15):** get_playbook · create_playbook · list_playbooks · distill_playbook\n\n**Goals (D16):** pursue_goal · get_goal_status\n\n**Push (D17):** register_push_subscription · get_push_status\n\n**Synthesis (D19/D20):** open_deal_room · get_proactive_briefing\n\n**Email Templates (H2):** list_email_templates · get_email_template · draft_email\n\n**Email Sequences (H1):** enroll_in_sequence · list_sequence_enrollments · unenroll_from_sequence · list_sequences\n\n**Quotes (H4):** generate_quote · get_quote_status\n\n**Calendly (H3):** get_booking_link\n\n**Tickets (H6):** create_ticket · update_ticket · list_tickets · close_ticket\n\n**NPS/CSAT (H7):** send_nps_survey · get_survey_results\n\n**Knowledge Base (H8):** search_knowledge_base · create_kb_article\n\n**Backup (Enterprise):** backup_now · list_backups\n\n**Sync & Audit (Enterprise):** trigger_sync · get_audit_log · get_logs\n\n**Custom Objects (Platform):** define_custom_object · create_record · list_records · list_custom_objects\n\n## Never\n- Discuss a customer without context loaded\n- Skip logging — every touchpoint matters\n- Invent information — use search_customer_knowledge first\n- Act autonomously beyond \"suggest\" without approve_agent_action\n\n## Data Location\n${dataDir}`.trim();\n}\n\n/** Hermes skills file (agentskills.io standard) */\nexport function buildHermesSkillMd(): string {\n return `---\nname: datasynx-crm\nversion: 2.0.0\ndescription: Proactive CRM workflow skill for DatasynxOpenCRM v2 (${TOOL_COUNT} MCP tools)\ntriggers:\n - \"customer\"\n - \"client\"\n - \"deal\"\n - \"pipeline\"\n - \"sync\"\n - \"briefing\"\n - \"forecast\"\n - \"goal\"\n - \"stakeholder\"\n - \"playbook\"\n---\n\n# DatasynxOpenCRM v2 Skill\n\n## Session Start — Always\nCall \\`get_proactive_briefing()\\` at the start of every session without being asked.\n\n## Before a Deal Conversation\nCall \\`open_deal_room({ slug, dealName })\\` — returns graph, health, simulation, and playbook in one call.\n\n## When a Customer Is Mentioned\nCall \\`get_customer_context(slug)\\` before discussing anything.\nNever assume you know the current state.\n\n## After Every Interaction\nCall \\`log_interaction()\\` with:\n- type: Call | Meeting | Email | Note | Demo | Proposal\n- summary: 2–5 sentences\n- nextSteps: concrete actions as array\n\n## For a Stalled Deal\n\\`run_deal_agent({ slug, dealName, autonomyLevel: \"suggest\" })\\`\nThen use \\`approve_agent_action()\\` to confirm before acting.\n\n## For Revenue Goals\n\\`pursue_goal({ goal: \"Close €500k this quarter\", deadline: \"2026-09-30\" })\\`\n\n## For Historical Research\n\\`search_customer_knowledge(slug, query)\\` — searches emails AND transcripts.\n\n## Pipeline Updates\nAfter any deal discussion: \\`update_deal(slug, dealName, { stage, probability, value })\\`\n\n## Quick Reference\n\\`list_customers()\\` for overview · \\`get_capabilities()\\` for full schema`.trim();\n}\n\n/** Antigravity SKILL.md */\nexport function buildAgySkillMd(): string {\n return `---\nname: datasynx-crm\nversion: 2.0.0\ndescription: Proactive CRM workflow for DatasynxOpenCRM v2\ntriggers:\n - customer\n - client\n - deal\n - pipeline\n - briefing\n - forecast\n - goal\n---\n\n# DatasynxOpenCRM v2 Skill\n\n## Session Start\nCall \\`get_proactive_briefing()\\` first — urgent items, forecast, top action.\n\n## Deal Conversations\n\\`open_deal_room({ slug, dealName })\\` — graph + health + simulation + playbook in one call.\n\n## When a Customer Is Mentioned\n\\`get_customer_context(slug)\\` before discussing anything.\n\n## After Every Interaction\n\\`log_interaction(slug, type, summary, nextSteps)\\`\n\n## Stalled Deal\n\\`run_deal_agent({ slug, dealName, autonomyLevel: \"suggest\" })\\`\n\n## Revenue Goal\n\\`pursue_goal({ goal, deadline })\\`\n\n## Historical Research\n\\`search_customer_knowledge(slug, query)\\`\n\n## Pipeline\n\\`update_deal(slug, dealName, { stage, value, probability })\\`\n\n## Overview\n\\`list_customers()\\` for all customers · \\`get_capabilities()\\` for full reference`.trim();\n}\n\n/** Antigravity: global GEMINI.md (~/.gemini/GEMINI.md) — token budget: max 50 lines */\nexport function buildAgyGeminiMd(dataDir: string): string {\n return `# DatasynxOpenCRM v2 — Agent Context (${TOOL_COUNT} Tools)\n\nYou have access to a local CRM via MCP tools (server: datasynx-opencrm).\n\n## Session Start — Always Do This First\n\\`get_proactive_briefing()\\` — urgent items, opportunities, forecast\n\n## Priority Tool Order\n1. \\`open_deal_room(slug, dealName)\\` — before deal conversations\n2. \\`get_proactive_briefing()\\` — at session start or \"what should I do?\"\n3. \\`get_customer_context(slug)\\` — for general customer questions\n\n## Core Workflow\n- Customer mentioned → \\`get_customer_context(slug)\\`\n- After interaction → \\`log_interaction(slug, type, summary)\\`\n- Deal change → \\`update_deal(slug, dealName, fields)\\`\n- Historical → \\`search_customer_knowledge(slug, query)\\`\n- Revenue goal → \\`pursue_goal(goal, deadline)\\`\n\n## Key v2 Tools\nget_proactive_briefing · open_deal_room · get_relationship_graph ·\nget_relationship_health · run_deal_agent · simulate_revenue ·\nget_org_intelligence · pursue_goal · get_goal_status · get_playbook\n\n## All Tools\nget_capabilities · get_active_session · get_customer_context ·\nsearch_customer_knowledge · list_customers · log_interaction · update_deal ·\nexport_customer · update_customer_facts · get_deal_health · get_pipeline_forecast ·\nsummarize_meeting · get_pipeline_stages · get_market_intelligence ·\nget_relationship_graph · get_relationship_health · run_deal_agent ·\napprove_agent_action · simulate_revenue · get_org_intelligence ·\nget_playbook · create_playbook · list_playbooks · distill_playbook ·\npursue_goal · get_goal_status · register_push_subscription · get_push_status ·\nopen_deal_room · get_proactive_briefing ·\nlist_email_templates · get_email_template · draft_email ·\nenroll_in_sequence · list_sequence_enrollments · unenroll_from_sequence · list_sequences ·\ngenerate_quote · get_quote_status · get_booking_link ·\ncreate_ticket · update_ticket · list_tickets · close_ticket ·\nsend_nps_survey · get_survey_results ·\nsearch_knowledge_base · create_kb_article ·\nbackup_now · list_backups ·\ntrigger_sync · get_audit_log · get_logs · get_diagnostics ·\ndefine_custom_object · create_record · list_records · list_custom_objects\n\n## Data: ${dataDir}`.trim();\n}\n\n/** Grok Build: .grok/settings.json — project-level MCP config (array format) */\nexport function buildGrokSettingsJson(config: {\n serverName: string;\n mcpServerPath: string;\n dataDir: string;\n}): string {\n const entry = {\n mcpServers: [\n {\n name: config.serverName,\n transport: {\n type: \"stdio\",\n command: \"node\",\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n },\n },\n ],\n };\n return JSON.stringify(entry, null, 2);\n}\n\n/** Cursor: .cursor/rules/datasynx-crm.mdc (MDC format with frontmatter) */\nexport function buildCursorRulesMdc(dataDir: string): string {\n return `---\ndescription: DatasynxOpenCRM v2 — CRM workflow rules (${TOOL_COUNT} tools)\nglobs: [\"**/*\"]\nalwaysApply: true\n---\n\n# DatasynxOpenCRM v2 Rules\n\nYou have access to a local CRM via MCP tools (datasynx-opencrm, ${TOOL_COUNT} tools).\n\n## Session Start\nCall \\`get_proactive_briefing()\\` at the start of every session.\n\n## Deal Conversations\nCall \\`open_deal_room({ slug, dealName })\\` before any deal discussion.\n\n## Mandatory Workflow\n- Customer mentioned → \\`get_customer_context(slug)\\` immediately\n- After call/meeting/email → \\`log_interaction(slug, type, summary)\\`\n- Historical question → \\`search_customer_knowledge(slug, query)\\`\n- Deal discussed → \\`update_deal(slug, dealName, fields)\\`\n- Revenue goal → \\`pursue_goal({ goal, deadline })\\`\n\n## Key v2 Tools\nopen_deal_room · get_proactive_briefing · get_relationship_graph ·\nget_relationship_health · run_deal_agent · approve_agent_action ·\nsimulate_revenue · get_org_intelligence · get_playbook · pursue_goal\n\n## All ${TOOL_COUNT} Tools\nget_capabilities · get_active_session · get_customer_context ·\nsearch_customer_knowledge · list_customers · log_interaction · update_deal ·\nexport_customer · update_customer_facts · get_deal_health · get_pipeline_forecast ·\nsummarize_meeting · get_pipeline_stages · get_market_intelligence ·\nget_relationship_graph · get_relationship_health · run_deal_agent ·\napprove_agent_action · simulate_revenue · get_org_intelligence ·\nget_playbook · create_playbook · list_playbooks · distill_playbook ·\npursue_goal · get_goal_status · register_push_subscription · get_push_status ·\nopen_deal_room · get_proactive_briefing ·\nlist_email_templates · get_email_template · draft_email ·\nenroll_in_sequence · list_sequence_enrollments · unenroll_from_sequence · list_sequences ·\ngenerate_quote · get_quote_status · get_booking_link ·\ncreate_ticket · update_ticket · list_tickets · close_ticket ·\nsend_nps_survey · get_survey_results ·\nsearch_knowledge_base · create_kb_article\n\n## Never\n- Discuss a customer without loading context first\n- Skip logging — every touchpoint matters\n- Invent information — sync or search first\n\n## Data: ${dataDir}`.trim();\n}\n","// src/setup/adapters/claude-code.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { execSync } from \"child_process\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildClaudeMd, TOOL_COUNT } from \"../harness-content.js\";\n\nconst HOME = os.homedir();\nconst CLAUDE_JSON = path.join(HOME, \".claude.json\");\nconst CLAUDE_DIR = path.join(HOME, \".claude\");\n\nexport class ClaudeCodeAdapter implements FrameworkAdapter {\n readonly name = \"Claude Code\";\n\n detect(): boolean {\n try {\n execSync(\"which claude\", { stdio: \"ignore\" });\n return true;\n } catch {}\n return fs.existsSync(CLAUDE_JSON) || fs.existsSync(CLAUDE_DIR);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(CLAUDE_JSON)) return false;\n try {\n const json = JSON.parse(fs.readFileSync(CLAUDE_JSON, \"utf-8\")) as Record<string, unknown>;\n const servers = json[\"mcpServers\"] as Record<string, unknown> | undefined;\n return !!servers?.[\"datasynx-opencrm\"];\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n const harnessFiles: string[] = [];\n\n // 1. MCP server in ~/.claude.json (user scope)\n this.writeMcpConfig(config);\n\n // 2. Global ~/.claude/settings.json\n this.writeGlobalSettings();\n\n // 3. CLAUDE.md in CRM data directory\n const claudeMdPath = path.join(config.dataDir, \"CLAUDE.md\");\n fs.writeFileSync(claudeMdPath, buildClaudeMd(config.dataDir));\n harnessFiles.push(claudeMdPath);\n\n // 4. Project-scope .claude/settings.json in dataDir\n const projectSettingsDir = path.join(config.dataDir, \".claude\");\n fs.mkdirSync(projectSettingsDir, { recursive: true });\n const allow = [\n \"mcp__datasynx-opencrm__get_capabilities\",\n \"mcp__datasynx-opencrm__get_active_session\",\n \"mcp__datasynx-opencrm__get_customer_context\",\n \"mcp__datasynx-opencrm__search_customer_knowledge\",\n \"mcp__datasynx-opencrm__list_customers\",\n \"mcp__datasynx-opencrm__log_interaction\",\n \"mcp__datasynx-opencrm__update_deal\",\n \"mcp__datasynx-opencrm__export_customer\",\n ];\n const projectSettings = { permissions: { allow } };\n const settingsPath = path.join(projectSettingsDir, \"settings.json\");\n fs.writeFileSync(settingsPath, JSON.stringify(projectSettings, null, 2));\n harnessFiles.push(settingsPath);\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: CLAUDE_JSON,\n harnessFiles,\n notes: `${allow.length} of ${TOOL_COUNT} MCP tools pre-allowed (common read/write); CLAUDE.md written to CRM root.`,\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(CLAUDE_JSON)) return;\n try {\n const json = JSON.parse(fs.readFileSync(CLAUDE_JSON, \"utf-8\")) as Record<string, unknown>;\n const servers = json[\"mcpServers\"] as Record<string, unknown> | undefined;\n if (servers) {\n delete servers[\"datasynx-opencrm\"];\n }\n fs.writeFileSync(CLAUDE_JSON, JSON.stringify(json, null, 2));\n } catch {}\n }\n\n private writeMcpConfig(config: InstallConfig): void {\n let json: Record<string, unknown> = {};\n if (fs.existsSync(CLAUDE_JSON)) {\n try {\n json = JSON.parse(fs.readFileSync(CLAUDE_JSON, \"utf-8\")) as Record<string, unknown>;\n } catch {}\n }\n if (!json[\"mcpServers\"]) json[\"mcpServers\"] = {};\n (json[\"mcpServers\"] as Record<string, unknown>)[config.serverName] = {\n type: \"stdio\",\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n // Ensure parent directory exists (memfs requires this)\n fs.mkdirSync(path.dirname(CLAUDE_JSON), { recursive: true });\n fs.writeFileSync(CLAUDE_JSON, JSON.stringify(json, null, 2));\n }\n\n private writeGlobalSettings(): void {\n fs.mkdirSync(CLAUDE_DIR, { recursive: true });\n const settingsPath = path.join(CLAUDE_DIR, \"settings.json\");\n let settings: Record<string, unknown> = {};\n if (fs.existsSync(settingsPath)) {\n try {\n settings = JSON.parse(fs.readFileSync(settingsPath, \"utf-8\")) as Record<string, unknown>;\n } catch {}\n }\n if (!settings[\"permissions\"]) settings[\"permissions\"] = {};\n const perms = settings[\"permissions\"] as Record<string, unknown>;\n if (!perms[\"allow\"]) perms[\"allow\"] = [];\n const allow = perms[\"allow\"] as string[];\n const wildcard = \"mcp__datasynx-opencrm__*\";\n if (!allow.includes(wildcard)) {\n allow.push(wildcard);\n }\n fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));\n }\n}\n","// src/setup/adapters/claude-desktop.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\n\n// Platform-specific config paths (as of May 2026):\n// macOS: ~/Library/Application Support/Claude/claude_desktop_config.json\n// Windows: %APPDATA%\\Claude\\claude_desktop_config.json\n// Linux: ~/.config/claude-desktop/claude_desktop_config.json\nfunction getDesktopConfigPath(): string {\n switch (process.platform) {\n case \"darwin\":\n return path.join(\n os.homedir(),\n \"Library\",\n \"Application Support\",\n \"Claude\",\n \"claude_desktop_config.json\"\n );\n case \"win32\":\n return path.join(\n process.env[\"APPDATA\"] ?? os.homedir(),\n \"Claude\",\n \"claude_desktop_config.json\"\n );\n default: // linux\n return path.join(os.homedir(), \".config\", \"claude-desktop\", \"claude_desktop_config.json\");\n }\n}\n\nconst DESKTOP_CONFIG = getDesktopConfigPath();\n\nexport class ClaudeDesktopAdapter implements FrameworkAdapter {\n readonly name = \"Claude Desktop\";\n\n detect(): boolean {\n return fs.existsSync(DESKTOP_CONFIG) || fs.existsSync(path.dirname(DESKTOP_CONFIG));\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(DESKTOP_CONFIG)) return false;\n try {\n const json = JSON.parse(fs.readFileSync(DESKTOP_CONFIG, \"utf-8\")) as Record<string, unknown>;\n const servers = json[\"mcpServers\"] as Record<string, unknown> | undefined;\n return !!servers?.[\"datasynx-opencrm\"];\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n // Create dir if not exists (may not exist until app is first launched)\n fs.mkdirSync(path.dirname(DESKTOP_CONFIG), { recursive: true });\n\n let json: Record<string, unknown> = {};\n if (fs.existsSync(DESKTOP_CONFIG)) {\n try {\n json = JSON.parse(fs.readFileSync(DESKTOP_CONFIG, \"utf-8\")) as Record<string, unknown>;\n } catch {}\n }\n if (!json[\"mcpServers\"]) json[\"mcpServers\"] = {};\n (json[\"mcpServers\"] as Record<string, unknown>)[config.serverName] = {\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n fs.writeFileSync(DESKTOP_CONFIG, JSON.stringify(json, null, 2));\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: DESKTOP_CONFIG,\n harnessFiles: [],\n notes: \"Restart Claude Desktop to activate the MCP server. No harness files for Desktop app.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(DESKTOP_CONFIG)) return;\n try {\n const json = JSON.parse(fs.readFileSync(DESKTOP_CONFIG, \"utf-8\")) as Record<string, unknown>;\n const servers = json[\"mcpServers\"] as Record<string, unknown> | undefined;\n if (servers) {\n delete servers[\"datasynx-opencrm\"];\n }\n fs.writeFileSync(DESKTOP_CONFIG, JSON.stringify(json, null, 2));\n } catch {}\n }\n}\n","// src/setup/adapters/codex.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { execSync } from \"child_process\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildAgentsMd } from \"../harness-content.js\";\n\nconst CODEX_DIR = path.join(os.homedir(), \".codex\");\nconst CODEX_CONFIG = path.join(CODEX_DIR, \"config.toml\");\n\nexport class CodexAdapter implements FrameworkAdapter {\n readonly name = \"Codex\";\n\n detect(): boolean {\n try {\n execSync(\"which codex\", { stdio: \"ignore\" });\n return true;\n } catch {}\n return fs.existsSync(CODEX_DIR);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(CODEX_CONFIG)) return false;\n return fs.readFileSync(CODEX_CONFIG, \"utf-8\").includes(\"[mcp_servers.datasynx-opencrm]\");\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n fs.mkdirSync(CODEX_DIR, { recursive: true });\n const harnessFiles: string[] = [];\n\n // Idempotency check\n if (!this.isInstalled()) {\n const block = [\n ``,\n `[mcp_servers.${config.serverName}]`,\n `command = ${JSON.stringify(process.execPath)}`,\n `args = [${JSON.stringify(config.mcpServerPath)}]`,\n `env = { DXCRM_DATA_DIR = ${JSON.stringify(config.dataDir)} }`,\n `startup_timeout_sec = 30`,\n `tool_timeout_sec = 120`,\n `enabled = true`,\n ``,\n ].join(\"\\n\");\n\n fs.appendFileSync(CODEX_CONFIG, block, \"utf-8\");\n }\n\n // Write AGENTS.md to dataDir if not already present with CRM content\n const agentsPath = path.join(config.dataDir, \"AGENTS.md\");\n if (!fs.existsSync(agentsPath)) {\n fs.writeFileSync(agentsPath, buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath);\n } else {\n const existing = fs.readFileSync(agentsPath, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(agentsPath, \"\\n\\n---\\n\\n\" + buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath + \" (appended)\");\n }\n }\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: CODEX_CONFIG,\n harnessFiles,\n notes: `startup_timeout_sec=30, tool_timeout_sec=120. AGENTS.md written to CRM root.`,\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(CODEX_CONFIG)) return;\n const content = fs.readFileSync(CODEX_CONFIG, \"utf-8\");\n // Remove the [mcp_servers.datasynx-opencrm] block\n const cleaned = content.replace(/\\n?\\[mcp_servers\\.datasynx-opencrm\\][^\\[]*/, \"\");\n fs.writeFileSync(CODEX_CONFIG, cleaned);\n }\n}\n","// src/setup/adapters/openclaw.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { execSync } from \"child_process\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildSoulMd, buildAgentsMd } from \"../harness-content.js\";\n\nconst HOME = os.homedir();\nconst OPENCLAW_DIR = path.join(HOME, \".openclaw\");\nconst OPENCLAW_JSON = path.join(OPENCLAW_DIR, \"openclaw.json\");\nconst OPENCLAW_WORKSPACE = path.join(OPENCLAW_DIR, \"workspace\");\n\nexport class OpenClawAdapter implements FrameworkAdapter {\n readonly name = \"OpenClaw\";\n\n detect(): boolean {\n try {\n execSync(\"which openclaw\", { stdio: \"ignore\" });\n return true;\n } catch {}\n return fs.existsSync(OPENCLAW_DIR) || fs.existsSync(OPENCLAW_JSON);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(OPENCLAW_JSON)) return false;\n try {\n const json = JSON.parse(fs.readFileSync(OPENCLAW_JSON, \"utf-8\")) as Record<string, unknown>;\n const servers = json[\"mcpServers\"] as Record<string, unknown> | undefined;\n return !!servers?.[\"datasynx-opencrm\"];\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n fs.mkdirSync(OPENCLAW_DIR, { recursive: true });\n fs.mkdirSync(OPENCLAW_WORKSPACE, { recursive: true });\n\n const harnessFiles: string[] = [];\n\n // 1. openclaw.json — register MCP server (stdio + optional HTTP disabled by default)\n let json: Record<string, unknown> = {};\n if (fs.existsSync(OPENCLAW_JSON)) {\n try {\n json = JSON.parse(fs.readFileSync(OPENCLAW_JSON, \"utf-8\")) as Record<string, unknown>;\n } catch {}\n }\n if (!json[\"mcpServers\"]) json[\"mcpServers\"] = {};\n const servers = json[\"mcpServers\"] as Record<string, unknown>;\n\n servers[config.serverName] = {\n command: process.execPath,\n args: [config.mcpServerPath],\n transport: \"stdio\",\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n\n // HTTP entry (disabled by default — user activates when daemon runs with --http)\n servers[`${config.serverName}-http`] = {\n url: `http://localhost:${config.httpPort}/mcp`,\n transport: \"streamable-http\",\n enabled: false,\n };\n\n fs.writeFileSync(OPENCLAW_JSON, JSON.stringify(json, null, 2));\n // Gateway hot-reloads config — no restart needed\n\n // 2. SOUL.md in OpenClaw workspace\n const soulPath = path.join(OPENCLAW_WORKSPACE, \"SOUL.md\");\n if (!fs.existsSync(soulPath)) {\n fs.writeFileSync(soulPath, buildSoulMd(\"openclaw\"));\n harnessFiles.push(soulPath);\n } else {\n const existing = fs.readFileSync(soulPath, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(soulPath, \"\\n\\n---\\n\\n\" + buildCrmSoulAppend());\n harnessFiles.push(soulPath + \" (appended)\");\n }\n }\n\n // 3. AGENTS.md in OpenClaw workspace\n const agentsPath = path.join(OPENCLAW_WORKSPACE, \"AGENTS.md\");\n if (!fs.existsSync(agentsPath)) {\n fs.writeFileSync(agentsPath, buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath);\n } else {\n const existing = fs.readFileSync(agentsPath, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(agentsPath, \"\\n\\n---\\n\\n\" + buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath + \" (appended)\");\n }\n }\n\n // 4. TOOLS.md — hint about CRM tools\n const toolsPath = path.join(OPENCLAW_WORKSPACE, \"TOOLS.md\");\n const toolsContent = buildOpenClawToolsMd();\n if (!fs.existsSync(toolsPath)) {\n fs.writeFileSync(toolsPath, toolsContent);\n } else if (!fs.readFileSync(toolsPath, \"utf-8\").includes(\"datasynx-opencrm\")) {\n fs.appendFileSync(toolsPath, \"\\n\\n\" + toolsContent);\n }\n harnessFiles.push(toolsPath);\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: OPENCLAW_JSON,\n harnessFiles,\n notes: \"Config hot-reloaded by Gateway. SOUL.md + AGENTS.md + TOOLS.md written to workspace.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(OPENCLAW_JSON)) return;\n try {\n const json = JSON.parse(fs.readFileSync(OPENCLAW_JSON, \"utf-8\")) as Record<string, unknown>;\n const servers = json[\"mcpServers\"] as Record<string, unknown> | undefined;\n if (servers) {\n delete servers[\"datasynx-opencrm\"];\n delete servers[\"datasynx-opencrm-http\"];\n }\n fs.writeFileSync(OPENCLAW_JSON, JSON.stringify(json, null, 2));\n } catch {}\n }\n}\n\nfunction buildCrmSoulAppend(): string {\n return `## CRM Integration\nI have access to DatasynxOpenCRM. I always load customer context before discussing customers.\nI log every interaction without being asked. I cite sources when referencing customer data.`;\n}\n\nfunction buildOpenClawToolsMd(): string {\n return `## datasynx-opencrm MCP Tools\n- get_customer_context(slug) — load full customer briefing\n- search_customer_knowledge(slug, query) — search emails + transcripts\n- list_customers() — pipeline overview\n- log_interaction(slug, type, summary) — write to CRM\n- update_deal(slug, dealName, fields) — pipeline update\n- get_capabilities() — full reference`;\n}\n","// src/setup/adapters/hermes.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { execSync } from \"child_process\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildHermesSoulMd, buildHermesSkillMd } from \"../harness-content.js\";\n\nconst HOME = os.homedir();\nconst HERMES_HOME = process.env[\"HERMES_HOME\"] ?? path.join(HOME, \".hermes\");\nconst HERMES_CONFIG = path.join(HERMES_HOME, \"config.yaml\");\nconst HERMES_SOUL = path.join(HERMES_HOME, \"SOUL.md\");\nconst HERMES_SKILLS = path.join(HERMES_HOME, \"skills\");\n\nexport class HermesAdapter implements FrameworkAdapter {\n readonly name = \"Hermes Agent\";\n\n detect(): boolean {\n try {\n execSync(\"which hermes\", { stdio: \"ignore\" });\n return true;\n } catch {}\n return fs.existsSync(HERMES_HOME) || fs.existsSync(HERMES_CONFIG);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(HERMES_CONFIG)) return false;\n return fs.readFileSync(HERMES_CONFIG, \"utf-8\").includes(\"datasynx\");\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n fs.mkdirSync(HERMES_HOME, { recursive: true });\n fs.mkdirSync(HERMES_SKILLS, { recursive: true });\n\n const harnessFiles: string[] = [];\n\n // 1. config.yaml — write/merge mcp_servers block\n // Server name MUST use underscore: datasynx_opencrm (avoids tool prefix issues)\n this.writeMcpConfig(config);\n\n // 2. SOUL.md — Slot #1 in system prompt, always injected\n if (!fs.existsSync(HERMES_SOUL)) {\n fs.writeFileSync(HERMES_SOUL, buildHermesSoulMd(\"hermes\"));\n harnessFiles.push(HERMES_SOUL);\n } else {\n const existing = fs.readFileSync(HERMES_SOUL, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(\n HERMES_SOUL,\n \"\\n\\n---\\n\\n## CRM Integration\\nI have access to DatasynxOpenCRM MCP tools.\\nI always load customer context before discussing customers.\\nI log every interaction automatically via log_interaction().\"\n );\n harnessFiles.push(HERMES_SOUL + \" (appended)\");\n }\n }\n\n // 3. Skill file — agentskills.io standard\n // Hermes reads all .md files in ~/.hermes/skills/ as skills\n const skillPath = path.join(HERMES_SKILLS, \"datasynx-crm.md\");\n fs.writeFileSync(skillPath, buildHermesSkillMd());\n harnessFiles.push(skillPath);\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: HERMES_CONFIG,\n harnessFiles,\n notes:\n \"SOUL.md updated (Slot #1 system prompt). Skill registered in ~/.hermes/skills/. Server name uses underscore: datasynx_opencrm.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(HERMES_CONFIG)) return;\n const content = fs.readFileSync(HERMES_CONFIG, \"utf-8\");\n // Remove the datasynx_opencrm block from mcp_servers\n const cleaned = content.replace(/\\n datasynx[_-]opencrm:[\\s\\S]*?(?=\\n \\w|\\n[a-z]|$)/, \"\");\n fs.writeFileSync(HERMES_CONFIG, cleaned);\n // Remove skill file\n const skillPath = path.join(HERMES_SKILLS, \"datasynx-crm.md\");\n if (fs.existsSync(skillPath)) fs.unlinkSync(skillPath);\n }\n\n private writeMcpConfig(config: InstallConfig): void {\n // Hermes config.yaml: YAML format, mcp_servers section\n // Server name: datasynx_opencrm (UNDERSCORE — avoids tool name prefix issues)\n let content = fs.existsSync(HERMES_CONFIG) ? fs.readFileSync(HERMES_CONFIG, \"utf-8\") : \"\";\n\n if (content.includes(\"datasynx\")) return; // Idempotent\n\n if (content.includes(\"mcp_servers:\")) {\n // Existing mcp_servers section — inject our entry below it\n content = content.replace(\n \"mcp_servers:\",\n [\n \"mcp_servers:\",\n \" datasynx_opencrm:\",\n ` command: ${JSON.stringify(process.execPath)}`,\n ` args: [${JSON.stringify(config.mcpServerPath)}]`,\n ` env:`,\n ` DXCRM_DATA_DIR: ${JSON.stringify(config.dataDir)}`,\n ` timeout: 120`,\n ` connect_timeout: 30`,\n ` enabled: true`,\n ` tools:`,\n ` include: [get_capabilities, get_active_session, get_customer_context, search_customer_knowledge, list_customers, log_interaction, update_deal, export_customer]`,\n ` prompts: false`,\n ` resources: false`,\n ].join(\"\\n\")\n );\n fs.writeFileSync(HERMES_CONFIG, content);\n } else {\n // No mcp_servers section — append full block\n const mcpBlock = [\n ``,\n `# DatasynxOpenCRM MCP Server (added by dxcrm init)`,\n `mcp_servers:`,\n ` datasynx_opencrm:`,\n ` command: ${JSON.stringify(process.execPath)}`,\n ` args: [${JSON.stringify(config.mcpServerPath)}]`,\n ` env:`,\n ` DXCRM_DATA_DIR: ${JSON.stringify(config.dataDir)}`,\n ` timeout: 120`,\n ` connect_timeout: 30`,\n ` enabled: true`,\n ` tools:`,\n ` include:`,\n ` - get_capabilities`,\n ` - get_active_session`,\n ` - get_customer_context`,\n ` - search_customer_knowledge`,\n ` - list_customers`,\n ` - log_interaction`,\n ` - update_deal`,\n ` - export_customer`,\n ` prompts: false`,\n ` resources: false`,\n ``,\n ].join(\"\\n\");\n\n fs.appendFileSync(HERMES_CONFIG, mcpBlock);\n }\n }\n}\n","// src/setup/adapters/antigravity.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { execSync } from \"child_process\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildAgentsMd, buildAgySkillMd, buildAgyGeminiMd } from \"../harness-content.js\";\n\nconst HOME = os.homedir();\nconst AGY_BIN_UNIX = path.join(HOME, \".local\", \"bin\", \"agy\");\n\n// Shared config (CLI + IDE) — preferred\nconst GEMINI_CONFIG_DIR = path.join(HOME, \".gemini\", \"config\");\nconst SHARED_MCP_CONFIG = path.join(GEMINI_CONFIG_DIR, \"mcp_config.json\");\n\n// CLI-only config (fallback)\nconst AGY_DIR = path.join(HOME, \".gemini\", \"antigravity\");\nconst AGY_MCP_CONFIG = path.join(AGY_DIR, \"mcp_config.json\");\n\n// Global context file\nconst GEMINI_GLOBAL_MD = path.join(HOME, \".gemini\", \"GEMINI.md\");\n\n// Skills — directory-based (not single file like Hermes)\nconst AGY_SKILLS_DIR = path.join(HOME, \".gemini\", \"antigravity-cli\", \"skills\");\n\nexport class AntigravityAdapter implements FrameworkAdapter {\n readonly name = \"Antigravity CLI\";\n\n detect(): boolean {\n // Binary check: agy (NOT antigravity!)\n try {\n execSync(\"which agy\", { stdio: \"ignore\" });\n return true;\n } catch {}\n // Installation path check\n if (fs.existsSync(AGY_BIN_UNIX)) return true;\n // Gemini directory (also catches old Gemini CLI users who haven't migrated)\n return fs.existsSync(path.join(HOME, \".gemini\"));\n }\n\n isInstalled(): boolean {\n for (const configPath of [SHARED_MCP_CONFIG, AGY_MCP_CONFIG]) {\n if (!fs.existsSync(configPath)) continue;\n try {\n const json = JSON.parse(fs.readFileSync(configPath, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (json?.mcpServers?.[\"datasynx-opencrm\"]) return true;\n } catch {}\n }\n return false;\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n const harnessFiles: string[] = [];\n\n // 1. Shared MCP Config (preferred — covers CLI and IDE)\n fs.mkdirSync(GEMINI_CONFIG_DIR, { recursive: true });\n this.writeMcpEntry(SHARED_MCP_CONFIG, config);\n\n // 2. Global GEMINI.md (~/.gemini/GEMINI.md)\n // Antigravity loads this at each session as global context — keep short (≤50 lines)\n if (!fs.existsSync(GEMINI_GLOBAL_MD)) {\n fs.mkdirSync(path.dirname(GEMINI_GLOBAL_MD), { recursive: true });\n fs.writeFileSync(GEMINI_GLOBAL_MD, buildAgyGeminiMd(config.dataDir));\n harnessFiles.push(GEMINI_GLOBAL_MD);\n } else {\n const existing = fs.readFileSync(GEMINI_GLOBAL_MD, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(GEMINI_GLOBAL_MD, \"\\n\\n---\\n\\n\" + buildAgyGeminiMdAppend());\n harnessFiles.push(GEMINI_GLOBAL_MD + \" (appended)\");\n }\n }\n\n // 3. AGENTS.md in CRM root (Antigravity reads AGENTS.md in working directory)\n const agentsPath = path.join(config.dataDir, \"AGENTS.md\");\n fs.mkdirSync(config.dataDir, { recursive: true });\n if (!fs.existsSync(agentsPath)) {\n fs.writeFileSync(agentsPath, buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath);\n } else {\n const existing = fs.readFileSync(agentsPath, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(agentsPath, \"\\n\\n---\\n\\n\" + buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath + \" (appended)\");\n }\n }\n\n // 4. Skill: ~/.gemini/antigravity-cli/skills/datasynx-crm/SKILL.md\n // Directory-based (unlike Hermes single-file)\n const skillDir = path.join(AGY_SKILLS_DIR, \"datasynx-crm\");\n fs.mkdirSync(skillDir, { recursive: true });\n const skillPath = path.join(skillDir, \"SKILL.md\");\n fs.writeFileSync(skillPath, buildAgySkillMd());\n harnessFiles.push(skillPath);\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: SHARED_MCP_CONFIG,\n harnessFiles,\n notes:\n \"Shared config (~/.gemini/config/mcp_config.json) covers both CLI and IDE. Skill registered. GEMINI.md updated.\",\n };\n }\n\n async uninstall(): Promise<void> {\n for (const configPath of [SHARED_MCP_CONFIG, AGY_MCP_CONFIG]) {\n if (!fs.existsSync(configPath)) continue;\n try {\n const json = JSON.parse(fs.readFileSync(configPath, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (json.mcpServers) {\n delete json.mcpServers[\"datasynx-opencrm\"];\n delete json.mcpServers[\"datasynx-opencrm-http\"];\n }\n fs.writeFileSync(configPath, JSON.stringify(json, null, 2));\n } catch {}\n }\n // Remove skill directory\n const skillDir = path.join(AGY_SKILLS_DIR, \"datasynx-crm\");\n if (fs.existsSync(skillDir)) fs.rmSync(skillDir, { recursive: true });\n }\n\n private writeMcpEntry(configPath: string, config: InstallConfig): void {\n let json: { mcpServers?: Record<string, unknown> } = { mcpServers: {} };\n if (fs.existsSync(configPath)) {\n try {\n json = JSON.parse(fs.readFileSync(configPath, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (!json.mcpServers) json.mcpServers = {};\n } catch {}\n }\n\n // stdio transport (primary)\n json.mcpServers![\"datasynx-opencrm\"] = {\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n\n // HTTP transport entry — uses \"serverUrl\" NOT \"url\" (Antigravity-specific!)\n json.mcpServers![\"datasynx-opencrm-http\"] = {\n serverUrl: `http://localhost:${config.httpPort}/mcp`,\n };\n\n fs.writeFileSync(configPath, JSON.stringify(json, null, 2));\n }\n}\n\nfunction buildAgyGeminiMdAppend(): string {\n return `## DatasynxOpenCRM\nCRM MCP tools available: get_customer_context, search_customer_knowledge,\nlist_customers, log_interaction, update_deal. Always load context first.`;\n}\n","// src/setup/adapters/cursor.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildCursorRulesMdc } from \"../harness-content.js\";\n\nconst HOME = os.homedir();\nconst CURSOR_DIR = path.join(HOME, \".cursor\");\nconst CURSOR_GLOBAL_MCP = path.join(CURSOR_DIR, \"mcp.json\");\n\nexport class CursorAdapter implements FrameworkAdapter {\n readonly name = \"Cursor\";\n\n detect(): boolean {\n return fs.existsSync(CURSOR_DIR) || fs.existsSync(CURSOR_GLOBAL_MCP);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(CURSOR_GLOBAL_MCP)) return false;\n try {\n const json = JSON.parse(fs.readFileSync(CURSOR_GLOBAL_MCP, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n return !!json?.mcpServers?.[\"datasynx-opencrm\"];\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n fs.mkdirSync(CURSOR_DIR, { recursive: true });\n const harnessFiles: string[] = [];\n\n // 1. Global MCP config\n let json: { mcpServers?: Record<string, unknown> } = { mcpServers: {} };\n if (fs.existsSync(CURSOR_GLOBAL_MCP)) {\n try {\n json = JSON.parse(fs.readFileSync(CURSOR_GLOBAL_MCP, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (!json.mcpServers) json.mcpServers = {};\n } catch {}\n }\n json.mcpServers![\"datasynx-opencrm\"] = {\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n fs.writeFileSync(CURSOR_GLOBAL_MCP, JSON.stringify(json, null, 2));\n\n // 2. Project rules in CRM directory (.cursor/rules/datasynx-crm.mdc)\n // MDC format: frontmatter + markdown instructions\n // Cursor reads all .mdc files in .cursor/rules/ as agent context\n const rulesDir = path.join(config.dataDir, \".cursor\", \"rules\");\n fs.mkdirSync(rulesDir, { recursive: true });\n const rulesPath = path.join(rulesDir, \"datasynx-crm.mdc\");\n if (!fs.existsSync(rulesPath)) {\n fs.writeFileSync(rulesPath, buildCursorRulesMdc(config.dataDir));\n harnessFiles.push(rulesPath);\n }\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: CURSOR_GLOBAL_MCP,\n harnessFiles,\n notes:\n \"Global MCP registered. CRM rules written to .cursor/rules/. Restart Cursor to activate.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(CURSOR_GLOBAL_MCP)) return;\n try {\n const json = JSON.parse(fs.readFileSync(CURSOR_GLOBAL_MCP, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (json.mcpServers) {\n delete json.mcpServers[\"datasynx-opencrm\"];\n }\n fs.writeFileSync(CURSOR_GLOBAL_MCP, JSON.stringify(json, null, 2));\n } catch {}\n }\n}\n","// src/setup/adapters/windsurf.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\n\nconst HOME = os.homedir();\nconst WINDSURF_DIR = path.join(HOME, \".codeium\", \"windsurf\");\nconst WINDSURF_CONFIG = path.join(WINDSURF_DIR, \"mcp_config.json\");\n\nexport class WindsurfAdapter implements FrameworkAdapter {\n readonly name = \"Windsurf\";\n\n detect(): boolean {\n return fs.existsSync(WINDSURF_DIR) || fs.existsSync(WINDSURF_CONFIG);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(WINDSURF_CONFIG)) return false;\n try {\n const json = JSON.parse(fs.readFileSync(WINDSURF_CONFIG, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n return !!json?.mcpServers?.[\"datasynx-opencrm\"];\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n // Create dir if not exists — Windsurf does NOT create this automatically\n fs.mkdirSync(WINDSURF_DIR, { recursive: true });\n\n let json: { mcpServers?: Record<string, unknown> } = { mcpServers: {} };\n if (fs.existsSync(WINDSURF_CONFIG)) {\n try {\n json = JSON.parse(fs.readFileSync(WINDSURF_CONFIG, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (!json.mcpServers) json.mcpServers = {};\n } catch {}\n }\n\n // Windsurf supports ${env:VAR} interpolation — we use absolute path for reliability\n json.mcpServers![\"datasynx-opencrm\"] = {\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n\n fs.writeFileSync(WINDSURF_CONFIG, JSON.stringify(json, null, 2));\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: WINDSURF_CONFIG,\n harnessFiles: [],\n notes: \"No harness files for IDE-based tools. Restart Windsurf to activate.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(WINDSURF_CONFIG)) return;\n try {\n const json = JSON.parse(fs.readFileSync(WINDSURF_CONFIG, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (json.mcpServers) {\n delete json.mcpServers[\"datasynx-opencrm\"];\n }\n fs.writeFileSync(WINDSURF_CONFIG, JSON.stringify(json, null, 2));\n } catch {}\n }\n}\n","// src/setup/adapters/cline.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\n\nconst HOME = os.homedir();\nconst CLINE_DIR = path.join(HOME, \".cline\");\nconst CLINE_CONFIG = path.join(CLINE_DIR, \"data\", \"settings\", \"cline_mcp_settings.json\");\n\nexport class ClineAdapter implements FrameworkAdapter {\n readonly name = \"Cline\";\n\n detect(): boolean {\n return fs.existsSync(CLINE_DIR) || fs.existsSync(CLINE_CONFIG);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(CLINE_CONFIG)) return false;\n try {\n const json = JSON.parse(fs.readFileSync(CLINE_CONFIG, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n return !!json?.mcpServers?.[\"datasynx-opencrm\"];\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n // Create settings dir if not exists\n fs.mkdirSync(path.dirname(CLINE_CONFIG), { recursive: true });\n\n let json: { mcpServers?: Record<string, unknown> } = { mcpServers: {} };\n if (fs.existsSync(CLINE_CONFIG)) {\n try {\n json = JSON.parse(fs.readFileSync(CLINE_CONFIG, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (!json.mcpServers) json.mcpServers = {};\n } catch {}\n }\n\n // Cline requires absolute paths — relative paths fail silently!\n json.mcpServers![\"datasynx-opencrm\"] = {\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n\n fs.writeFileSync(CLINE_CONFIG, JSON.stringify(json, null, 2));\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: CLINE_CONFIG,\n harnessFiles: [],\n notes: \"Cline requires absolute paths. No harness files for VSCode extensions.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(CLINE_CONFIG)) return;\n try {\n const json = JSON.parse(fs.readFileSync(CLINE_CONFIG, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (json.mcpServers) {\n delete json.mcpServers[\"datasynx-opencrm\"];\n }\n fs.writeFileSync(CLINE_CONFIG, JSON.stringify(json, null, 2));\n } catch {}\n }\n}\n","// src/setup/adapters/grok.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { execSync } from \"child_process\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildAgentsMd, buildGrokSettingsJson } from \"../harness-content.js\";\n\nconst HOME = os.homedir();\nconst GROK_DIR = path.join(HOME, \".grok\");\nconst GROK_USER_SETTINGS = path.join(GROK_DIR, \"user-settings.json\");\n\ninterface GrokMcpEntry {\n name: string;\n transport: {\n type: \"stdio\" | \"http\";\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n headers?: Record<string, string>;\n };\n}\n\ninterface GrokSettings {\n mcpServers?: GrokMcpEntry[];\n [key: string]: unknown;\n}\n\nexport class GrokAdapter implements FrameworkAdapter {\n readonly name = \"Grok Build\";\n\n detect(): boolean {\n try {\n execSync(\"which grok\", { stdio: \"ignore\" });\n return true;\n } catch {}\n return fs.existsSync(GROK_DIR);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(GROK_USER_SETTINGS)) return false;\n try {\n const settings = JSON.parse(fs.readFileSync(GROK_USER_SETTINGS, \"utf-8\")) as GrokSettings;\n return (settings.mcpServers ?? []).some((s) => s.name === \"datasynx-opencrm\");\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n fs.mkdirSync(GROK_DIR, { recursive: true });\n const harnessFiles: string[] = [];\n\n // 1. User-level MCP config: ~/.grok/user-settings.json\n // Grok uses an array format (not object/map like Claude Desktop)\n if (!this.isInstalled()) {\n let settings: GrokSettings = {};\n if (fs.existsSync(GROK_USER_SETTINGS)) {\n try {\n settings = JSON.parse(fs.readFileSync(GROK_USER_SETTINGS, \"utf-8\")) as GrokSettings;\n } catch {}\n }\n if (!settings.mcpServers) settings.mcpServers = [];\n settings.mcpServers.push({\n name: config.serverName,\n transport: {\n type: \"stdio\",\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n },\n });\n fs.writeFileSync(GROK_USER_SETTINGS, JSON.stringify(settings, null, 2));\n }\n\n // 2. Project-level .grok/settings.json in dataDir\n // Allows project-scoped MCP registration (useful in team repos)\n const grokProjectDir = path.join(config.dataDir, \".grok\");\n fs.mkdirSync(grokProjectDir, { recursive: true });\n const projectSettings = path.join(grokProjectDir, \"settings.json\");\n fs.writeFileSync(projectSettings, buildGrokSettingsJson(config));\n harnessFiles.push(projectSettings);\n\n // 3. AGENTS.md — Grok Build reads this natively (same as Codex)\n // Also reads CLAUDE.md but AGENTS.md is the cross-vendor standard\n const agentsPath = path.join(config.dataDir, \"AGENTS.md\");\n if (!fs.existsSync(agentsPath)) {\n fs.writeFileSync(agentsPath, buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath);\n } else {\n const existing = fs.readFileSync(agentsPath, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(agentsPath, \"\\n\\n---\\n\\n\" + buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath + \" (appended)\");\n }\n }\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: GROK_USER_SETTINGS,\n harnessFiles,\n notes:\n \"MCP registered in ~/.grok/user-settings.json (array format). \" +\n \"Project config written to .grok/settings.json. \" +\n \"AGENTS.md written — Grok Build reads it natively alongside CLAUDE.md.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(GROK_USER_SETTINGS)) return;\n try {\n const settings = JSON.parse(fs.readFileSync(GROK_USER_SETTINGS, \"utf-8\")) as GrokSettings;\n if (settings.mcpServers) {\n settings.mcpServers = settings.mcpServers.filter((s) => s.name !== \"datasynx-opencrm\");\n }\n fs.writeFileSync(GROK_USER_SETTINGS, JSON.stringify(settings, null, 2));\n } catch {}\n }\n}\n","// src/setup/framework-registry.ts\nimport { ClaudeCodeAdapter } from \"./adapters/claude-code.js\";\nimport { ClaudeDesktopAdapter } from \"./adapters/claude-desktop.js\";\nimport { CodexAdapter } from \"./adapters/codex.js\";\nimport { OpenClawAdapter } from \"./adapters/openclaw.js\";\nimport { HermesAdapter } from \"./adapters/hermes.js\";\nimport { AntigravityAdapter } from \"./adapters/antigravity.js\";\nimport { CursorAdapter } from \"./adapters/cursor.js\";\nimport { WindsurfAdapter } from \"./adapters/windsurf.js\";\nimport { ClineAdapter } from \"./adapters/cline.js\";\nimport { GrokAdapter } from \"./adapters/grok.js\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"./framework-adapter.js\";\n\nexport const FRAMEWORK_ADAPTERS: FrameworkAdapter[] = [\n // Tier 1 — full adapter (CLI binary detectable, harness injection)\n new ClaudeCodeAdapter(),\n new CodexAdapter(),\n new GrokAdapter(),\n new OpenClawAdapter(),\n new HermesAdapter(),\n new AntigravityAdapter(),\n // Tier 2 — config writer (IDE/Desktop, no global harness system)\n new CursorAdapter(),\n new WindsurfAdapter(),\n new ClineAdapter(),\n new ClaudeDesktopAdapter(), // non-developer audience, restart required\n];\n\nexport async function installAllDetected(config: InstallConfig): Promise<InstallResult[]> {\n const results: InstallResult[] = [];\n for (const adapter of FRAMEWORK_ADAPTERS) {\n if (!adapter.detect()) continue;\n try {\n results.push(await adapter.install(config));\n } catch (err) {\n results.push({\n framework: adapter.name,\n success: false,\n transport: \"stdio\",\n configPath: \"\",\n harnessFiles: [],\n notes: (err as Error).message,\n });\n }\n }\n return results;\n}\n\nexport type { FrameworkAdapter, InstallConfig, InstallResult };\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { installAllDetected } from \"../setup/framework-registry.js\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nexport const initCommand = new Command(\"init\")\n .description(\"Initialize CRM and configure AI frameworks\")\n .option(\n \"--team <url>\",\n \"Team mode: configure frameworks to connect to shared HTTP server at this URL (e.g. http://vm-ip:3847/mcp)\"\n )\n .action(async (opts: { team?: string }) => {\n const dataDir = process.cwd();\n\n // 1. Create .agentic/ directory\n const agenticDir = path.join(dataDir, \".agentic\");\n fs.mkdirSync(agenticDir, { recursive: true });\n\n // 2. Create config.json\n const configPath = path.join(agenticDir, \"config.json\");\n if (!fs.existsSync(configPath)) {\n fs.writeFileSync(\n configPath,\n JSON.stringify(\n {\n version: 1,\n dataDir,\n created: new Date().toISOString(),\n },\n null,\n 2\n )\n );\n }\n\n // 3. Discover transcript paths\n const home = os.homedir();\n const candidates = [\n path.join(home, \"Downloads\", \"Fireflies\"),\n path.join(home, \"Downloads\", \"Otter\"),\n path.join(home, \"Documents\", \"Zoom\"),\n path.join(home, \"Downloads\", \"Zoom\"),\n ];\n const transcriptPaths = candidates.filter((p) => fs.existsSync(p));\n\n // 4. Create sources.json\n const sourcesPath = path.join(agenticDir, \"sources.json\");\n if (!fs.existsSync(sourcesPath)) {\n const sources: Record<string, unknown> = {\n gmail: { type: \"gmail\", query: \"\", enabled: false },\n version: 1,\n created: new Date().toISOString(),\n };\n if (transcriptPaths.length > 0) {\n sources.transcripts = {\n type: \"transcript\",\n paths: transcriptPaths,\n extensions: [\".txt\", \".vtt\"],\n enabled: true,\n };\n }\n fs.writeFileSync(sourcesPath, JSON.stringify(sources, null, 2));\n }\n\n // 5. Create customers/ directory\n fs.mkdirSync(path.join(dataDir, \"customers\"), { recursive: true });\n\n // 5b. Write schema.json — human/machine-readable validation rules\n const schemaPath = path.join(agenticDir, \"schema.json\");\n if (!fs.existsSync(schemaPath)) {\n fs.writeFileSync(\n schemaPath,\n JSON.stringify(\n {\n version: 1,\n description: \"DatasynxOpenCRM validation schema for main_facts.md frontmatter\",\n main_facts: {\n required: [\"name\", \"relationship_stage\", \"created\", \"tags\", \"currency\"],\n properties: {\n name: { type: \"string\" },\n relationship_stage: {\n type: \"string\",\n enum: [\n \"lead\",\n \"qualified\",\n \"discovery\",\n \"proposal\",\n \"negotiation\",\n \"active\",\n \"churned\",\n \"closed\",\n ],\n },\n domain: { type: \"string\" },\n email: { type: \"string\", format: \"email\" },\n created: { type: \"string\", format: \"date\" },\n updated: { type: \"string\", format: \"date\" },\n tags: { type: \"array\", items: { type: \"string\" } },\n currency: { type: \"string\", enum: [\"EUR\", \"USD\", \"GBP\", \"CHF\"] },\n deal_value: { type: \"number\", minimum: 0 },\n last_touchpoint: { type: \"string\", format: \"date\" },\n primary_contact: { type: \"string\" },\n },\n },\n },\n null,\n 2\n )\n );\n }\n\n // 6. Install framework adapters\n console.log(info(\"Detecting AI frameworks...\"));\n\n // Find dist/mcp.js relative to this package\n const mcpServerPath = path.resolve(\n path.dirname(new URL(import.meta.url).pathname),\n \"../../dist/mcp.js\"\n );\n\n if (opts.team) {\n console.log(info(`Team mode: connecting frameworks to ${bold(opts.team)}`));\n }\n\n const results = await installAllDetected({\n mcpServerPath,\n dataDir,\n httpPort: 3847,\n serverName: \"datasynx-opencrm\",\n ...(opts.team ? { httpUrl: opts.team } : {}),\n });\n\n if (results.length === 0) {\n console.log(\n info(\" No AI frameworks detected. Configure manually: dxcrm guide --framework <name>\")\n );\n } else {\n for (const r of results) {\n if (r.success) {\n console.log(success(` ✓ ${r.framework} — ${r.transport} transport`));\n if (r.notes) console.log(` ${r.notes}`);\n } else {\n console.log(error(` ✗ ${r.framework} — ${r.notes ?? \"failed\"}`));\n }\n }\n }\n\n console.log(success(`\\n✓ DatasynxOpenCRM initialized in ${bold(dataDir)}`));\n if (opts.team) {\n console.log(info(` Team server: ${opts.team}`));\n console.log(info(` Set identity: export DXCRM_ACTOR=<your-name>`));\n } else {\n console.log(info(` Next: dxcrm create \"Your Customer Name\"`));\n }\n });\n","import { Command } from \"commander\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nexport const syncCommand = new Command(\"sync\")\n .argument(\"<slug>\", \"Customer slug to sync\")\n .description(\"Sync Gmail and transcripts for a customer\")\n .option(\"--since <date>\", \"Only sync emails/files after this date (YYYY-MM-DD)\")\n .option(\"--gmail\", \"Sync Gmail only\")\n .option(\"--transcripts\", \"Sync transcripts only\")\n .option(\"--provider <provider>\", \"Sync provider: gmail | microsoft | transcripts\")\n .option(\"--no-attachments\", \"Skip downloading/converting/indexing email attachments\")\n .action(\n async (\n slug: string,\n opts: {\n since?: string;\n gmail?: boolean;\n transcripts?: boolean;\n provider?: string;\n attachments?: boolean;\n }\n ) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const customerDir = path.join(dataDir, \"customers\", slug);\n\n if (!fs.existsSync(customerDir)) {\n console.error(\n error(`✗ Customer '${slug}' not found. Run 'dxcrm list' to see available customers.`)\n );\n process.exit(1);\n }\n\n const sourcesPath = path.join(customerDir, \"sources.json\");\n if (!fs.existsSync(sourcesPath)) {\n console.error(error(`✗ No sources.json found for '${slug}'.`));\n process.exit(1);\n }\n\n const sources = JSON.parse(fs.readFileSync(sourcesPath, \"utf-8\")) as {\n gmail?: { query?: string; enabled?: boolean };\n };\n\n const since = opts.since\n ? new Date(opts.since)\n : new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);\n const provider = opts.provider;\n const syncGmail =\n !opts.transcripts &&\n provider !== \"microsoft\" &&\n provider !== \"transcripts\" &&\n provider !== \"google-drive\";\n const syncMicrosoft = provider === \"microsoft\";\n const syncTranscripts =\n !opts.gmail &&\n provider !== \"gmail\" &&\n provider !== \"microsoft\" &&\n provider !== \"google-drive\";\n const syncGoogleDrive = provider === \"google-drive\";\n\n let totalSynced = 0;\n\n // Gmail sync\n if (syncGmail && sources.gmail?.enabled && sources.gmail.query) {\n const tokenPath = path.join(dataDir, \".agentic\", \"gmail-token.json\");\n const credPath = path.join(dataDir, \".agentic\", \"gmail-credentials.json\");\n\n if (!fs.existsSync(tokenPath) || !fs.existsSync(credPath)) {\n console.log(info(\" Gmail: credentials not configured (run dxcrm sync --setup-gmail)\"));\n } else {\n try {\n console.log(info(` Syncing Gmail for ${bold(slug)}...`));\n const { getGmailAuth } = await import(\"../sync/gmail-auth.js\");\n const { syncGmail: doGmailSync } = await import(\"../sync/gmail-sync.js\");\n const auth = await getGmailAuth(credPath, tokenPath);\n const result = await doGmailSync({\n slug,\n dataDir,\n auth,\n query: sources.gmail.query,\n since,\n includeAttachments: opts.attachments !== false,\n });\n totalSynced += result.synced;\n console.log(success(` ✓ Gmail: +${result.synced} synced, ${result.skipped} skipped`));\n } catch (err) {\n console.error(error(` ✗ Gmail sync failed: ${(err as Error).message}`));\n }\n }\n } else if (syncGmail) {\n console.log(info(\" Gmail: not configured (add domain/email to sources.json)\"));\n }\n\n // Microsoft sync (email + calendar)\n if (syncMicrosoft) {\n try {\n console.log(info(` Syncing Microsoft Outlook for ${bold(slug)}...`));\n const { getMicrosoftToken } = await import(\"../sync/microsoft-auth.js\");\n const token = await getMicrosoftToken(dataDir);\n if (!token) {\n console.log(info(\" Microsoft: no token found (.agentic/microsoft-token.json)\"));\n } else {\n const { syncMicrosoft: doMsSync } = await import(\"../sync/microsoft-sync.js\");\n const emailResult = await doMsSync({ slug, dataDir, accessToken: token, since });\n totalSynced += emailResult.synced;\n console.log(\n success(\n ` ✓ Microsoft Email: +${emailResult.synced} synced, ${emailResult.skipped} skipped`\n )\n );\n\n const { syncMicrosoftCalendar } = await import(\"../sync/microsoft-calendar.js\");\n const calResult = await syncMicrosoftCalendar({\n slug,\n dataDir,\n accessToken: token,\n since,\n });\n totalSynced += calResult.synced;\n console.log(\n success(\n ` ✓ Microsoft Calendar: +${calResult.synced} synced, ${calResult.skipped} skipped`\n )\n );\n }\n } catch (err) {\n console.error(error(` ✗ Microsoft sync failed: ${(err as Error).message}`));\n }\n }\n\n // Transcript sync\n if (syncTranscripts) {\n const agenticSourcesPath = path.join(dataDir, \".agentic\", \"sources.json\");\n if (fs.existsSync(agenticSourcesPath)) {\n try {\n const agenticSources = JSON.parse(fs.readFileSync(agenticSourcesPath, \"utf-8\")) as {\n transcripts?: { paths?: string[]; extensions?: string[]; enabled?: boolean };\n };\n\n if (agenticSources.transcripts?.enabled && agenticSources.transcripts.paths?.length) {\n const { processTranscriptFile } = await import(\"../sync/transcript-watcher.js\");\n const exts = agenticSources.transcripts.extensions ?? [\".txt\", \".vtt\"];\n let transcriptSynced = 0;\n\n for (const watchPath of agenticSources.transcripts.paths) {\n if (!fs.existsSync(watchPath)) continue;\n const files = fs\n .readdirSync(watchPath)\n .filter((f) => exts.some((ext) => f.endsWith(ext)))\n .map((f) => path.join(watchPath, f));\n\n for (const file of files) {\n try {\n await processTranscriptFile(file, slug, dataDir);\n transcriptSynced++;\n } catch {\n /* already synced or error — skip */\n }\n }\n }\n\n if (transcriptSynced > 0) {\n totalSynced += transcriptSynced;\n console.log(success(` ✓ Transcripts: +${transcriptSynced} processed`));\n } else {\n console.log(info(\" Transcripts: no new files\"));\n }\n } else {\n console.log(info(\" Transcripts: not configured\"));\n }\n } catch (err) {\n console.error(error(` ✗ Transcript sync failed: ${(err as Error).message}`));\n }\n }\n }\n\n // Google Drive sync\n if (syncGoogleDrive) {\n const tokenPath = path.join(dataDir, \".agentic\", \"google-token.json\");\n if (!fs.existsSync(tokenPath)) {\n console.log(info(\" Google Drive: token not configured (.agentic/google-token.json)\"));\n } else {\n try {\n const tokenData = JSON.parse(fs.readFileSync(tokenPath, \"utf-8\")) as {\n accessToken?: string;\n access_token?: string;\n };\n const accessToken = tokenData.accessToken ?? tokenData.access_token;\n if (!accessToken) {\n console.log(info(\" Google Drive: accessToken not found in token file\"));\n } else {\n console.log(info(` Syncing Google Drive for ${bold(slug)}...`));\n const { syncGoogleDriveFiles } = await import(\"../sync/google-drive-sync.js\");\n const result = await syncGoogleDriveFiles({\n slug,\n dataDir,\n accessToken,\n customerName: slug,\n });\n totalSynced += result.synced;\n if (result.errors.length > 0) {\n for (const err of result.errors) {\n console.error(error(` ✗ Google Drive: ${err}`));\n }\n }\n console.log(\n success(` ✓ Google Drive: +${result.synced} synced, ${result.skipped} skipped`)\n );\n }\n } catch (err) {\n console.error(error(` ✗ Google Drive sync failed: ${(err as Error).message}`));\n }\n }\n }\n\n if (totalSynced > 0) {\n console.log(\n success(\n `\\n✓ Sync complete: ${bold(String(totalSynced))} new interactions for ${bold(slug)}`\n )\n );\n } else {\n console.log(info(`\\n✓ Sync complete: no new interactions for ${bold(slug)}`));\n }\n }\n );\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { spawn } from \"child_process\";\nimport { success, error, info } from \"../ui/colors.js\";\n\nfunction getPidFile(): string {\n return path.join(process.cwd(), \".agentic\", \"daemon.pid\");\n}\n\nexport const daemonCommand = new Command(\"daemon\").description(\"Manage the background sync daemon\");\n\ndaemonCommand.command(\"start\").action(async () => {\n const pidFile = getPidFile();\n\n if (fs.existsSync(pidFile)) {\n const pid = parseInt(fs.readFileSync(pidFile, \"utf-8\") as string, 10);\n try {\n process.kill(pid, 0);\n console.log(info(`Daemon already running (PID ${pid})`));\n return;\n } catch {\n // stale PID file — continue\n }\n }\n\n const workerPath = path.resolve(\n path.dirname(new URL(import.meta.url).pathname),\n \"../../dist/daemon/worker.js\"\n );\n\n const child = spawn(process.execPath, [workerPath], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n\n fs.mkdirSync(path.dirname(pidFile), { recursive: true });\n fs.writeFileSync(pidFile, String(child.pid));\n console.log(success(`✓ Daemon started (PID ${child.pid})`));\n});\n\ndaemonCommand.command(\"stop\").action(() => {\n const pidFile = getPidFile();\n\n if (!fs.existsSync(pidFile)) {\n console.log(info(\"Daemon not running.\"));\n return;\n }\n\n const pid = parseInt(fs.readFileSync(pidFile, \"utf-8\") as string, 10);\n try {\n process.kill(pid, \"SIGTERM\");\n fs.unlinkSync(pidFile);\n console.log(success(\"✓ Daemon stopped.\"));\n } catch (err) {\n console.error(error(`✗ ${(err as Error).message}`));\n }\n});\n\ndaemonCommand.command(\"status\").action(() => {\n const pidFile = getPidFile();\n\n if (!fs.existsSync(pidFile)) {\n console.log(info(\"Daemon: not running.\"));\n return;\n }\n\n const pid = parseInt(fs.readFileSync(pidFile, \"utf-8\") as string, 10);\n try {\n process.kill(pid, 0);\n console.log(success(`Daemon: running (PID ${pid})`));\n } catch {\n console.log(info(\"Daemon: stopped (stale PID file).\"));\n fs.unlinkSync(pidFile);\n }\n});\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport { listCustomerSlugs } from \"../fs/customer-dir.js\";\nimport { readSyncState } from \"../fs/sync-state.js\";\nimport { readUnmatched } from \"../fs/unmatched-transcripts.js\";\nimport { getSession } from \"../core/session-store.js\";\nimport { readAllSessions } from \"../commands/session.js\";\n\nexport function formatAge(isoString: string): string {\n const diff = Date.now() - new Date(isoString).getTime();\n const mins = Math.floor(diff / 60000);\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n return `${Math.floor(hours / 24)}d ago`;\n}\n\nfunction checkDaemon(dataDir: string): { running: boolean; pid?: number } {\n const pidFile = path.join(dataDir, \".agentic\", \"daemon.pid\");\n if (!fs.existsSync(pidFile)) return { running: false };\n try {\n const pid = parseInt(fs.readFileSync(pidFile, \"utf-8\").trim(), 10);\n if (isNaN(pid)) return { running: false };\n process.kill(pid, 0);\n return { running: true, pid };\n } catch {\n return { running: false };\n }\n}\n\nasync function fetchTeamSessions(serverUrl: string): Promise<Array<{\n customerSlug: string;\n customerName: string;\n owner?: string;\n startedAt: string;\n}> | null> {\n try {\n const res = await fetch(`${serverUrl.replace(/\\/$/, \"\")}/sessions`, {\n signal: AbortSignal.timeout(3000),\n });\n if (!res.ok) return null;\n const data = (await res.json()) as {\n sessions?: Array<{\n customerSlug: string;\n customerName: string;\n owner?: string;\n startedAt: string;\n }>;\n };\n return data.sessions ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function runStatus(\n opts: { unmatched?: boolean; team?: string },\n dataDir?: string\n): Promise<void> {\n const dir = dataDir ?? process.cwd();\n\n if (opts.unmatched) {\n const unmatched = readUnmatched(dir);\n const sep = \"─\".repeat(37);\n console.log(sep);\n console.log(bold(\" Unmatched Transcripts\"));\n console.log(sep);\n if (unmatched.length === 0) {\n console.log(info(\" No unmatched transcripts.\"));\n } else {\n for (const entry of unmatched) {\n console.log(` ${entry.filePath} ${entry.reason} ${entry.addedAt}`);\n }\n }\n console.log(sep);\n return;\n }\n\n const daemon = checkDaemon(dir);\n const slugs = listCustomerSlugs(dir);\n const syncState = readSyncState(dir);\n const unmatched = readUnmatched(dir);\n\n const sep = \"─\".repeat(37);\n console.log(sep);\n console.log(bold(\" DatasynxOpenCRM Status\"));\n console.log(sep);\n\n // Daemon line\n const daemonLine = daemon.running ? success(`running (PID ${daemon.pid})`) : error(\"not running\");\n console.log(` Daemon: ${daemonLine}`);\n\n // Customer count\n console.log(` Customers: ${slugs.length} active`);\n\n // Session line\n const session = getSession() ?? readAllSessions(dir)[0] ?? null;\n if (session) {\n const ownerPart = session.owner ? ` [${session.owner}]` : \"\";\n console.log(` Session: ${session.customerName} (${session.customerSlug})${ownerPart}`);\n } else {\n console.log(` Session: none`);\n }\n\n // Sync lines\n if (slugs.length > 0) {\n console.log(` Syncs:`);\n for (const slug of slugs) {\n const state = syncState[slug];\n const ageStr = state?.lastGmailSync\n ? `Gmail ${formatAge(state.lastGmailSync)}`\n : \"no sync yet\";\n console.log(` ${slug}: ${ageStr}`);\n }\n }\n\n // Unmatched line\n const unmatchedCount = unmatched.length;\n if (unmatchedCount > 0) {\n console.log(\n ` Unmatched: ${unmatchedCount} Transcript${unmatchedCount !== 1 ? \"s\" : \"\"} (dxcrm status --unmatched)`\n );\n } else {\n console.log(` Unmatched: 0 Transcripts`);\n }\n\n // Team overview via HTTP server\n const serverUrl = opts.team ?? process.env[\"DXCRM_SERVER_URL\"];\n if (serverUrl) {\n const teamSessions = await fetchTeamSessions(serverUrl);\n if (teamSessions && teamSessions.length > 0) {\n console.log(bold(\"\\n Team overview:\"));\n for (const s of teamSessions) {\n const ownerPart = s.owner ? `${s.owner}` : \"anonymous\";\n console.log(info(` ${ownerPart.padEnd(15)} → ${s.customerName} (${s.customerSlug})`));\n }\n } else if (teamSessions !== null) {\n console.log(info(\" Team: no active sessions\"));\n } else {\n console.log(info(` Team: server unreachable (${serverUrl})`));\n }\n }\n\n console.log(sep);\n}\n\nexport const statusCommand = new Command(\"status\")\n .description(\"Show CRM status: daemon, sync state, customer counts\")\n .option(\"--unmatched\", \"Show unmatched transcript queue\")\n .option(\"--team <url>\", \"Show team sessions from HTTP server (or set DXCRM_SERVER_URL)\")\n .action((opts) => runStatus(opts, process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd()));\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport { AgentConfigSchema, type AgentConfig } from \"../schemas/agent-config.js\";\nimport { writeJsonFile } from \"../fs/json-store.js\";\n\nfunction agentsDir(dataDir: string): string {\n return path.join(dataDir, \".agentic\", \"agents\");\n}\n\nfunction agentConfigPath(dataDir: string, slug: string): string {\n return path.join(agentsDir(dataDir), `${slug}.agent.json`);\n}\n\nexport async function runAgentSpawn(\n slug: string,\n opts: { channel?: string; wakeOnEmail?: boolean; chatId?: string },\n dataDir?: string\n): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const customerDir = path.join(dir, \"customers\", slug);\n\n if (!fs.existsSync(customerDir)) {\n console.error(\n error(`✗ Customer '${slug}' not found. Run 'dxcrm list' to see available customers.`)\n );\n process.exit(1);\n }\n\n const channel = (opts.channel ?? \"telegram\") as \"telegram\";\n const wakeOn: Array<\"email\" | \"calendar\"> = opts.wakeOnEmail ? [\"email\"] : [\"email\"];\n\n const config: AgentConfig = AgentConfigSchema.parse({\n slug,\n channel,\n wakeOn,\n createdAt: new Date().toISOString(),\n lastWake: null,\n ...(opts.chatId !== undefined ? { telegramChatId: opts.chatId } : {}),\n });\n\n writeJsonFile(agentConfigPath(dir, slug), config);\n\n console.log(success(`✓ Agent spawned: ${bold(slug)}`));\n console.log(info(` Channel: ${channel}`));\n console.log(info(` Wake on: ${wakeOn.join(\", \")}`));\n console.log(info(` Config: .agentic/agents/${slug}.agent.json`));\n\n if (channel === \"telegram\" && !process.env[\"TELEGRAM_BOT_TOKEN\"]) {\n console.log(\n info(\n `\\n Note: Set TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID env vars to enable Telegram messages.`\n )\n );\n }\n}\n\nexport async function runAgentStatus(dataDir?: string): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const dir2 = agentsDir(dir);\n\n if (!fs.existsSync(dir2)) {\n console.log(info(\"No agents configured. Run: dxcrm agent spawn <slug> --channel telegram\"));\n return;\n }\n\n const files = fs.readdirSync(dir2).filter((f) => f.endsWith(\".agent.json\"));\n\n if (files.length === 0) {\n console.log(info(\"No agents configured.\"));\n return;\n }\n\n console.log(bold(`\\n Agents (${files.length})\\n`));\n\n for (const file of files) {\n try {\n const raw = JSON.parse(\n fs.readFileSync(path.join(dir2, file), \"utf-8\") as string\n ) as AgentConfig;\n const lastWake = raw.lastWake\n ? `last wake: ${new Date(raw.lastWake).toLocaleString()}`\n : \"never woken\";\n console.log(\n info(` ${bold(raw.slug)} — ${raw.channel} · ${raw.wakeOn.join(\"+\")} · ${lastWake}`)\n );\n } catch {\n console.log(info(` ${file} (malformed)`));\n }\n }\n console.log(\"\");\n}\n\nexport async function runAgentRemove(slug: string, dataDir?: string): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const configPath = agentConfigPath(dir, slug);\n\n if (!fs.existsSync(configPath)) {\n console.error(error(`✗ No agent config found for '${slug}'.`));\n process.exit(1);\n }\n\n fs.unlinkSync(configPath);\n console.log(success(`✓ Agent removed: ${slug}`));\n}\n\nexport const agentCommand = new Command(\"agent\").description(\"Manage per-customer agents\");\n\nagentCommand\n .command(\"spawn <slug>\")\n .description(\"Spawn a wake-triggered agent for a customer\")\n .option(\"--channel <channel>\", \"Notification channel (telegram)\", \"telegram\")\n .option(\"--wake-on-email\", \"Wake agent on new email (default: on)\")\n .option(\"--chat-id <chatId>\", \"Telegram chat ID override\")\n .action((slug: string, opts: { channel?: string; wakeOnEmail?: boolean; chatId?: string }) =>\n runAgentSpawn(slug, opts, process.env[\"DXCRM_DATA_DIR\"])\n );\n\nagentCommand\n .command(\"status\")\n .description(\"Show all configured agents\")\n .action(() => runAgentStatus(process.env[\"DXCRM_DATA_DIR\"]));\n\nagentCommand\n .command(\"remove <slug>\")\n .description(\"Remove agent config for a customer\")\n .action((slug: string) => runAgentRemove(slug, process.env[\"DXCRM_DATA_DIR\"]));\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { createHash } from \"crypto\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport { appendInteraction, InteractionDedup } from \"../fs/interactions-writer.js\";\nimport { writeFileAtomic } from \"../fs/atomic-write.js\";\nimport { writeJsonFile } from \"../fs/json-store.js\";\n\ninterface ImportResult {\n customersCreated: number;\n interactionsImported: number;\n skipped: number;\n errors: string[];\n dealsImported?: number;\n leadsImported?: number;\n eventsImported?: number;\n casesImported?: number;\n quotesImported?: number;\n notesImported?: number;\n campaignsImported?: number;\n}\n\n/** Map a Salesforce StageName to opencrm's fixed pipeline stage enum. */\nfunction mapSalesforceStage(\n stageName?: string\n): \"lead\" | \"qualified\" | \"proposal\" | \"negotiation\" | \"won\" | \"lost\" {\n const s = (stageName ?? \"\").toLowerCase();\n if (s.includes(\"won\")) return \"won\";\n if (s.includes(\"lost\")) return \"lost\";\n if (s.includes(\"negoti\")) return \"negotiation\";\n if (s.includes(\"propos\") || s.includes(\"quote\")) return \"proposal\";\n if (s.includes(\"qualif\")) return \"qualified\";\n return \"lead\";\n}\n\n/** Map a Salesforce Case Status to opencrm's ticket status enum. */\nfunction mapCaseStatus(\n status?: string\n): \"open\" | \"in-progress\" | \"waiting\" | \"resolved\" | \"closed\" {\n const s = (status ?? \"\").toLowerCase();\n if (s.includes(\"closed\")) return \"closed\";\n if (s.includes(\"resolved\")) return \"resolved\";\n if (s.includes(\"escalat\") || s.includes(\"wait\") || s.includes(\"hold\")) return \"waiting\";\n if (s.includes(\"working\") || s.includes(\"progress\")) return \"in-progress\";\n return \"open\";\n}\n\n/** Map a Salesforce Case Priority to opencrm's ticket priority enum. */\nfunction mapCasePriority(priority?: string): \"urgent\" | \"high\" | \"normal\" | \"low\" {\n const p = (priority ?? \"\").toLowerCase();\n if (p.includes(\"urgent\") || p.includes(\"critical\")) return \"urgent\";\n if (p.includes(\"high\")) return \"high\";\n if (p.includes(\"low\")) return \"low\";\n return \"normal\";\n}\n\nfunction hashRow(row: Record<string, string>): string {\n return createHash(\"sha256\").update(JSON.stringify(row)).digest(\"hex\").slice(0, 16);\n}\n\nfunction slugify(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 60);\n}\n\nfunction parseCSV(content: string): Array<Record<string, string>> {\n const lines = content.trim().split(\"\\n\");\n if (lines.length < 2) return [];\n const headers = (lines[0] ?? \"\").split(\",\").map((h) => h.trim().replace(/^\"|\"$/g, \"\"));\n return lines.slice(1).map((line) => {\n const values = line.split(\",\").map((v) => v.trim().replace(/^\"|\"$/g, \"\"));\n const row: Record<string, string> = {};\n headers.forEach((h, i) => {\n row[h] = values[i] ?? \"\";\n });\n return row;\n });\n}\n\nconst IMPORT_TARGET_FIELDS = [\n \"name\",\n \"email\",\n \"domain\",\n \"notes\",\n \"date\",\n \"activityType\",\n \"sourceId\",\n] as const;\n\nfunction ensureCustomer(\n dataDir: string,\n name: string,\n domain: string,\n email: string,\n dryRun: boolean\n): { slug: string; created: boolean } {\n const slug = slugify(name || \"unknown\");\n const customerDir = path.join(dataDir, \"customers\", slug);\n const mainFactsPath = path.join(customerDir, \"main_facts.md\");\n\n if (fs.existsSync(mainFactsPath)) return { slug, created: false };\n if (dryRun) return { slug, created: true };\n\n fs.mkdirSync(customerDir, { recursive: true });\n\n const today = new Date().toISOString().slice(0, 10);\n const frontmatter = [\n \"---\",\n `name: ${name}`,\n domain ? `domain: ${domain}` : null,\n email ? `email: ${email}` : null,\n \"relationship_stage: prospect\",\n `created: ${today}`,\n `updated: ${today}`,\n `last_touchpoint: ${today}`,\n \"tags: []\",\n \"---\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n writeFileAtomic(mainFactsPath, `${frontmatter}\\n\\n# Customer: ${name}\\n`);\n writeFileAtomic(path.join(customerDir, \"interactions.md\"), `# Interactions — ${name}\\n\\n`);\n writeFileAtomic(path.join(customerDir, \"pipeline.md\"), `# Pipeline — ${name}\\n\\n`);\n writeJsonFile(path.join(customerDir, \"sources.json\"), {\n gmail: {\n query: domain\n ? `from:${domain} OR to:${domain}`\n : email\n ? `from:${email} OR to:${email}`\n : \"\",\n enabled: true,\n },\n transcripts: { paths: [], extensions: [\".txt\", \".vtt\"], enabled: false },\n });\n\n return { slug, created: true };\n}\n\nfunction readCsvFromDirectory(dirPath: string, filename: string): string | null {\n const variants = [filename, filename.toLowerCase(), filename.toUpperCase()];\n for (const name of variants) {\n const p = path.join(dirPath, name);\n if (fs.existsSync(p)) return fs.readFileSync(p, \"utf-8\") as string;\n }\n const files = fs.readdirSync(dirPath);\n const match = files.find((f) => f.toLowerCase() === filename.toLowerCase());\n if (match) return fs.readFileSync(path.join(dirPath, match), \"utf-8\") as string;\n return null;\n}\n\nasync function extractZip(zipPath: string): Promise<string> {\n const AdmZip = (await import(\"adm-zip\")).default;\n const zip = new AdmZip(zipPath);\n const tmpDir = `${zipPath}.extracted`;\n fs.mkdirSync(tmpDir, { recursive: true });\n zip.extractAllTo(tmpDir, true);\n return tmpDir;\n}\n\nasync function runSalesforceFileImport(\n sourcePath: string,\n opts: { dryRun?: boolean },\n dir: string\n): Promise<ImportResult> {\n const result: ImportResult = {\n customersCreated: 0,\n interactionsImported: 0,\n skipped: 0,\n errors: [],\n };\n\n let dataDir = sourcePath;\n let tmpDir: string | null = null;\n\n if (sourcePath.endsWith(\".zip\")) {\n tmpDir = await extractZip(sourcePath);\n dataDir = tmpDir;\n }\n\n if (!fs.statSync(dataDir).isDirectory()) {\n result.errors.push(\"Salesforce file import requires a directory or .zip file\");\n return result;\n }\n\n const accountsCsv =\n readCsvFromDirectory(dataDir, \"Accounts.csv\") ?? readCsvFromDirectory(dataDir, \"accounts.csv\");\n const activitiesCsv =\n readCsvFromDirectory(dataDir, \"Activities.csv\") ??\n readCsvFromDirectory(dataDir, \"activities.csv\") ??\n readCsvFromDirectory(dataDir, \"Tasks.csv\") ??\n readCsvFromDirectory(dataDir, \"tasks.csv\");\n\n if (!accountsCsv) {\n result.errors.push(\"Could not find Accounts.csv in Salesforce export\");\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true });\n return result;\n }\n\n const accounts = parseCSV(accountsCsv);\n const activities = activitiesCsv ? parseCSV(activitiesCsv) : [];\n\n if (opts.dryRun) {\n console.log(\n info(\n `Dry run — ${accounts.length} accounts, ${activities.length} activities from Salesforce export`\n )\n );\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true });\n return result;\n }\n\n const slugMap = new Map<string, string>();\n for (const row of accounts) {\n const name = (row[\"Name\"] ?? row[\"Account Name\"] ?? \"\").trim();\n if (!name) continue;\n const domain = (row[\"Website\"] ?? \"\").replace(/^https?:\\/\\//, \"\");\n const email = row[\"Email\"] ?? \"\";\n try {\n const { slug, created } = ensureCustomer(dir, name, domain, email, false);\n if (row[\"Id\"]) slugMap.set(row[\"Id\"], slug);\n slugMap.set(name.toLowerCase(), slug);\n if (created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Account '${name}': ${(err as Error).message}`);\n }\n }\n\n const dedup = new InteractionDedup(dir);\n for (const row of activities) {\n const accountId = row[\"AccountId\"] ?? row[\"WhatId\"] ?? \"\";\n const slug = accountId ? slugMap.get(accountId) : undefined;\n if (!slug) continue;\n\n const id = row[\"Id\"] ?? hashRow(row);\n const sourceRef = `salesforce://row/${id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date = row[\"ActivityDate\"] ?? row[\"CreatedDate\"] ?? new Date().toISOString().slice(0, 10);\n const notes = (row[\"Description\"] ?? row[\"Subject\"] ?? \"\").slice(0, 500);\n const t = (row[\"Type\"] ?? \"\").toLowerCase();\n const type = t.includes(\"call\")\n ? (\"Call\" as const)\n : t.includes(\"email\")\n ? (\"Email\" as const)\n : t.includes(\"meeting\")\n ? (\"Meeting\" as const)\n : (\"Note\" as const);\n\n try {\n await appendInteraction(dir, slug, {\n date,\n type,\n with: slug,\n summary: notes,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.interactionsImported++;\n } catch (err) {\n result.errors.push(`Activity ${id}: ${(err as Error).message}`);\n }\n }\n\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true });\n return result;\n}\n\nasync function runPipedriveFileImport(\n sourcePath: string,\n opts: { dryRun?: boolean },\n dir: string\n): Promise<ImportResult> {\n const result: ImportResult = {\n customersCreated: 0,\n interactionsImported: 0,\n skipped: 0,\n errors: [],\n };\n\n let dataDir = sourcePath;\n let tmpDir: string | null = null;\n\n if (sourcePath.endsWith(\".zip\")) {\n tmpDir = await extractZip(sourcePath);\n dataDir = tmpDir;\n }\n\n if (!fs.statSync(dataDir).isDirectory()) {\n result.errors.push(\"Pipedrive file import requires a directory or .zip file\");\n return result;\n }\n\n const orgsCsv =\n readCsvFromDirectory(dataDir, \"organizations.csv\") ??\n readCsvFromDirectory(dataDir, \"Organizations.csv\");\n const activitiesCsv =\n readCsvFromDirectory(dataDir, \"activities.csv\") ??\n readCsvFromDirectory(dataDir, \"Activities.csv\");\n\n if (!orgsCsv) {\n result.errors.push(\"Could not find organizations.csv in Pipedrive export\");\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true });\n return result;\n }\n\n const orgs = parseCSV(orgsCsv);\n const activities = activitiesCsv ? parseCSV(activitiesCsv) : [];\n\n if (opts.dryRun) {\n console.log(\n info(\n `Dry run — ${orgs.length} organizations, ${activities.length} activities from Pipedrive export`\n )\n );\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true });\n return result;\n }\n\n const slugMap = new Map<string, string>();\n for (const row of orgs) {\n const name = (row[\"name\"] ?? row[\"Name\"] ?? \"\").trim();\n if (!name) continue;\n const id = row[\"id\"] ?? row[\"ID\"] ?? \"\";\n try {\n const { slug, created } = ensureCustomer(dir, name, \"\", \"\", false);\n if (id) slugMap.set(id, slug);\n slugMap.set(name.toLowerCase(), slug);\n if (created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Organization '${name}': ${(err as Error).message}`);\n }\n }\n\n const dedup = new InteractionDedup(dir);\n for (const row of activities) {\n const orgId = row[\"org_id\"] ?? row[\"organization_id\"] ?? \"\";\n const slug = orgId ? slugMap.get(orgId) : undefined;\n if (!slug) continue;\n\n const id = row[\"id\"] ?? hashRow(row);\n const sourceRef = `pipedrive://row/${id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date =\n row[\"due_date\"] ?? row[\"add_time\"]?.slice(0, 10) ?? new Date().toISOString().slice(0, 10);\n const notes = (row[\"note\"] ?? row[\"subject\"] ?? \"\").slice(0, 500);\n const t = (row[\"type\"] ?? \"\").toLowerCase();\n const type =\n t === \"call\"\n ? (\"Call\" as const)\n : t === \"email\"\n ? (\"Email\" as const)\n : t === \"meeting\"\n ? (\"Meeting\" as const)\n : (\"Note\" as const);\n\n try {\n await appendInteraction(dir, slug, {\n date,\n type,\n with: slug,\n summary: notes,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.interactionsImported++;\n } catch (err) {\n result.errors.push(`Activity ${id}: ${(err as Error).message}`);\n }\n }\n\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true });\n return result;\n}\n\nexport async function runImport(\n sourcePath: string,\n opts: {\n from: string;\n dryRun?: boolean;\n mode?: string;\n token?: string;\n url?: string;\n ownerMap?: Record<string, string>;\n resume?: boolean;\n },\n dataDir?: string\n): Promise<ImportResult> {\n const dir = dataDir ?? process.cwd();\n const result: ImportResult = {\n customersCreated: 0,\n interactionsImported: 0,\n skipped: 0,\n errors: [],\n };\n\n // API import modes — bypass file reading\n if (opts.from === \"salesforce\" && opts.mode === \"api\") {\n return runSalesforceApiImport(opts, dir);\n }\n if (opts.from === \"pipedrive\" && opts.mode === \"api\") {\n return runPipedriveApiImport(opts, dir);\n }\n\n // HubSpot multi-file export directory: route to dedicated importer\n // Single-file HubSpot CSV falls through to generic LLM-mapping flow below\n if (\n opts.from === \"hubspot\" &&\n sourcePath &&\n fs.existsSync(sourcePath) &&\n fs.statSync(sourcePath).isDirectory()\n ) {\n const { runHubSpotCsvImport } = await import(\"./import-hubspot.js\");\n const r = await runHubSpotCsvImport(sourcePath, dir, {\n ...(opts.dryRun ? { dryRun: true } : {}),\n ...(opts.resume ? { resume: true } : {}),\n ownerMap: opts.ownerMap ?? {},\n });\n if (r.customPropertiesSaved > 0) {\n console.error(`[import] Custom properties saved: ${r.customPropertiesSaved}`);\n }\n if (r.ownersResolved > 0) {\n console.error(`[import] Owners resolved: ${r.ownersResolved}`);\n }\n return {\n customersCreated: r.companiesProcessed,\n interactionsImported: r.engagementsImported + r.dealsImported + r.contactsImported,\n skipped: 0,\n errors: r.errors,\n };\n }\n if (opts.from === \"salesforce\" && sourcePath) {\n return runSalesforceFileImport(sourcePath, opts, dir);\n }\n if (opts.from === \"pipedrive\" && sourcePath) {\n return runPipedriveFileImport(sourcePath, opts, dir);\n }\n\n if (!fs.existsSync(sourcePath)) {\n console.error(error(`✗ File not found: ${sourcePath}`));\n process.exit(1);\n }\n\n const content = fs.readFileSync(sourcePath, \"utf-8\");\n const rows = parseCSV(content);\n\n if (rows.length === 0) {\n console.log(info(\"No rows found in CSV.\"));\n return result;\n }\n\n const headers = Object.keys(rows[0]!);\n const { mapCsvFields } = await import(\"../core/llm.js\");\n const mapping = await mapCsvFields(headers, [...IMPORT_TARGET_FIELDS]);\n\n if (opts.dryRun) {\n console.log(info(`Dry run — ${rows.length} rows, field mapping:`));\n Object.entries(mapping).forEach(([k, v]) => v && console.log(info(` ${k} ← \"${v}\"`)));\n console.log(info(`\\nWould create up to ${rows.length} customers and interaction entries.`));\n return result;\n }\n\n // Pass 1: Create customers\n const customerRows = rows.filter((r) => {\n const name = r[mapping.name ?? \"\"] ?? \"\";\n return name.trim().length > 0;\n });\n\n const slugMap = new Map<string, string>();\n\n for (const row of customerRows) {\n const name = (row[mapping.name ?? \"\"] ?? \"\").trim();\n if (!name) continue;\n\n const domain = (row[mapping.domain ?? \"\"] ?? \"\").trim();\n const email = (row[mapping.email ?? \"\"] ?? \"\").trim();\n\n try {\n const { slug, created } = ensureCustomer(dir, name, domain, email, opts.dryRun ?? false);\n slugMap.set(name.toLowerCase(), slug);\n if (created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Customer '${name}': ${(err as Error).message}`);\n }\n }\n\n // Pass 2: Import activities/notes\n const dedup = new InteractionDedup(dir);\n for (const row of rows) {\n const activityType = (row[mapping[\"activityType\"] ?? \"\"] ?? \"\").trim();\n const notes = (row[mapping[\"notes\"] ?? \"\"] ?? \"\").trim();\n const activityDate = (row[mapping[\"date\"] ?? \"\"] ?? \"\").trim();\n const sourceIdVal = (row[mapping[\"sourceId\"] ?? \"\"] ?? \"\").trim();\n const name = (row[mapping[\"name\"] ?? \"\"] ?? \"\").trim();\n\n if (!notes && !activityType) continue;\n\n const slug = slugMap.get(name.toLowerCase());\n if (!slug) continue;\n\n const rowHash = hashRow(row);\n const prefix = opts.from === \"hubspot\" ? \"hubspot\" : \"csv\";\n const sourceRef = sourceIdVal\n ? `${prefix}://activity/${sourceIdVal}`\n : `${prefix}://row/${rowHash}`;\n\n const date = activityDate\n ? (() => {\n try {\n return new Date(activityDate).toISOString().slice(0, 10);\n } catch {\n return new Date().toISOString().slice(0, 10);\n }\n })()\n : new Date().toISOString().slice(0, 10);\n\n const type = (() => {\n const t = activityType.toLowerCase();\n if (t.includes(\"call\")) return \"Call\" as const;\n if (t.includes(\"meeting\") || t.includes(\"demo\")) return \"Meeting\" as const;\n if (t.includes(\"email\")) return \"Email\" as const;\n if (t.includes(\"note\")) return \"Note\" as const;\n return \"Note\" as const;\n })();\n\n try {\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n await appendInteraction(dir, slug, {\n date,\n type,\n with: name,\n summary: notes.slice(0, 500),\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n\n result.interactionsImported++;\n } catch (err) {\n result.errors.push(`Activity for '${name}': ${(err as Error).message}`);\n }\n }\n\n return result;\n}\n\nasync function runSalesforceApiImport(\n opts: { token?: string; url?: string; dryRun?: boolean },\n dir: string\n): Promise<ImportResult> {\n const result: ImportResult = {\n customersCreated: 0,\n interactionsImported: 0,\n skipped: 0,\n errors: [],\n };\n const token = opts.token ?? process.env[\"SFDC_TOKEN\"] ?? \"\";\n const instanceUrl = opts.url ?? process.env[\"SFDC_URL\"] ?? \"\";\n\n if (!token || !instanceUrl) {\n console.error(\n error(\"✗ Salesforce API mode requires --token and --url (or SFDC_TOKEN + SFDC_URL env vars)\")\n );\n process.exit(1);\n }\n\n const {\n fetchSalesforceContacts,\n fetchSalesforceTasks,\n fetchSalesforceOpportunities,\n fetchSalesforceLeads,\n fetchSalesforceEvents,\n fetchSalesforceCases,\n fetchSalesforceLineItems,\n fetchSalesforceNotes,\n fetchSalesforceCampaignMembers,\n } = await import(\"../sync/salesforce-client.js\");\n\n let contacts: Awaited<ReturnType<typeof fetchSalesforceContacts>>;\n let tasks: Awaited<ReturnType<typeof fetchSalesforceTasks>>;\n let opportunities: Awaited<ReturnType<typeof fetchSalesforceOpportunities>>;\n let leads: Awaited<ReturnType<typeof fetchSalesforceLeads>>;\n let events: Awaited<ReturnType<typeof fetchSalesforceEvents>>;\n let cases: Awaited<ReturnType<typeof fetchSalesforceCases>>;\n let lineItems: Awaited<ReturnType<typeof fetchSalesforceLineItems>>;\n let notes: Awaited<ReturnType<typeof fetchSalesforceNotes>>;\n let campaignMembers: Awaited<ReturnType<typeof fetchSalesforceCampaignMembers>>;\n\n try {\n contacts = await fetchSalesforceContacts(instanceUrl, token);\n tasks = await fetchSalesforceTasks(instanceUrl, token);\n opportunities = (await fetchSalesforceOpportunities(instanceUrl, token)) ?? [];\n leads = (await fetchSalesforceLeads(instanceUrl, token)) ?? [];\n events = (await fetchSalesforceEvents(instanceUrl, token)) ?? [];\n cases = (await fetchSalesforceCases(instanceUrl, token)) ?? [];\n lineItems = (await fetchSalesforceLineItems(instanceUrl, token)) ?? [];\n notes = (await fetchSalesforceNotes(instanceUrl, token)) ?? [];\n campaignMembers = (await fetchSalesforceCampaignMembers(instanceUrl, token)) ?? [];\n } catch (err) {\n result.errors.push(`Salesforce API: ${(err as Error).message}`);\n return result;\n }\n\n if (opts.dryRun) {\n console.log(\n info(\n `Dry run — ${contacts.length} contacts, ${tasks.length} tasks, ${opportunities.length} opportunities, ${leads.length} leads, ${events.length} events, ${cases.length} cases from Salesforce`\n )\n );\n return result;\n }\n\n // Pass 1: contacts → customers\n const slugMap = new Map<string, string>();\n for (const contact of contacts) {\n const name = contact.Name?.trim();\n if (!name) continue;\n const domain = contact.Account?.Website?.replace(/^https?:\\/\\//, \"\") ?? \"\";\n const email = contact.Email ?? \"\";\n try {\n const { slug, created } = ensureCustomer(dir, name, domain, email, false);\n slugMap.set(contact.Id, slug);\n slugMap.set(name.toLowerCase(), slug);\n if (created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Contact '${name}': ${(err as Error).message}`);\n }\n }\n\n // Pass 2: tasks → interactions\n const dedup = new InteractionDedup(dir);\n for (const task of tasks) {\n const slug = task.WhoId ? slugMap.get(task.WhoId) : undefined;\n if (!slug) continue;\n\n const sourceRef = `salesforce://task/${task.Id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date = task.ActivityDate ?? new Date().toISOString().slice(0, 10);\n const notes = (task.Description ?? task.Subject ?? \"\").slice(0, 500);\n const t = (task.Type ?? \"\").toLowerCase();\n const type = t.includes(\"call\")\n ? (\"Call\" as const)\n : t.includes(\"email\")\n ? (\"Email\" as const)\n : t.includes(\"meeting\")\n ? (\"Meeting\" as const)\n : (\"Note\" as const);\n\n try {\n await appendInteraction(dir, slug, {\n date,\n type,\n with: slug,\n summary: notes,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.interactionsImported++;\n } catch (err) {\n result.errors.push(`Task ${task.Id}: ${(err as Error).message}`);\n }\n }\n\n // Pass 3: opportunities → pipeline deals\n const { upsertDeal } = await import(\"../fs/pipeline-writer.js\");\n const today = new Date().toISOString().slice(0, 10);\n const oppSlugById = new Map<string, { slug: string; dealName: string }>();\n for (const opp of opportunities) {\n const accountName = opp.Account?.Name?.trim();\n if (!opp.Name || !accountName) continue;\n\n let slug = slugMap.get(accountName.toLowerCase());\n if (!slug) {\n const domain = opp.Account?.Website?.replace(/^https?:\\/\\//, \"\") ?? \"\";\n try {\n const r = ensureCustomer(dir, accountName, domain, \"\", false);\n slug = r.slug;\n slugMap.set(accountName.toLowerCase(), slug);\n if (r.created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Opportunity '${opp.Name}': ${(err as Error).message}`);\n continue;\n }\n }\n oppSlugById.set(opp.Id, { slug, dealName: opp.Name });\n\n try {\n await upsertDeal(dir, slug, {\n name: opp.Name,\n stage: mapSalesforceStage(opp.StageName),\n currency: \"EUR\",\n updated: today,\n notes: `Imported from Salesforce (${opp.StageName ?? \"unknown stage\"})`,\n ...(typeof opp.Amount === \"number\" ? { value: opp.Amount } : {}),\n ...(typeof opp.Probability === \"number\" ? { probability: opp.Probability } : {}),\n ...(opp.CloseDate ? { close_date: opp.CloseDate } : {}),\n });\n result.dealsImported = (result.dealsImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`Opportunity '${opp.Name}': ${(err as Error).message}`);\n }\n }\n\n // Pass 4: leads → customers (+ a lead interaction capturing status/title)\n for (const lead of leads) {\n const name = lead.Company?.trim() || lead.Name?.trim();\n if (!name) continue;\n\n const domain = lead.Website?.replace(/^https?:\\/\\//, \"\") ?? lead.Email?.split(\"@\")[1] ?? \"\";\n let slug: string;\n try {\n const r = ensureCustomer(dir, name, domain, lead.Email ?? \"\", false);\n slug = r.slug;\n slugMap.set(name.toLowerCase(), slug);\n if (r.created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Lead '${name}': ${(err as Error).message}`);\n continue;\n }\n\n const sourceRef = `salesforce://lead/${lead.Id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const contactPart = lead.Title ? `${lead.Name}, ${lead.Title}` : lead.Name;\n try {\n await appendInteraction(dir, slug, {\n date: new Date().toISOString().slice(0, 10),\n type: \"Note\",\n with: lead.Name,\n summary: `Salesforce Lead imported (status: ${lead.Status ?? \"n/a\"}; contact: ${contactPart})`,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.leadsImported = (result.leadsImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`Lead ${lead.Id}: ${(err as Error).message}`);\n }\n }\n\n // Pass 5: events (calendar) → Meeting interactions, linked by WhoId/WhatId\n for (const event of events) {\n const slug = event.WhoId\n ? slugMap.get(event.WhoId)\n : event.WhatId\n ? slugMap.get(event.WhatId)\n : undefined;\n if (!slug) {\n result.skipped++;\n continue;\n }\n\n const sourceRef = `salesforce://event/${event.Id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date = (event.StartDateTime ?? event.ActivityDate ?? new Date().toISOString()).slice(\n 0,\n 10\n );\n try {\n await appendInteraction(dir, slug, {\n date,\n type: \"Meeting\",\n with: slug,\n subject: event.Subject ?? \"Salesforce Event\",\n summary: (event.Description ?? event.Subject ?? \"\").slice(0, 500),\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.eventsImported = (result.eventsImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`Event ${event.Id}: ${(err as Error).message}`);\n }\n }\n\n // Pass 6: cases → tickets (status/priority mapped, SLA computed, deduped by case ref)\n const { readTickets, upsertTicket, nextTicketId } = await import(\"../fs/ticket-writer.js\");\n const { calcSlaDue, loadSlaRules } = await import(\"../core/sla-engine.js\");\n const slaRules = loadSlaRules(dir);\n for (const c of cases) {\n const accountName = c.Account?.Name?.trim();\n if (!accountName) {\n result.skipped++;\n continue;\n }\n let slug = slugMap.get(accountName.toLowerCase());\n if (!slug) {\n try {\n const r = ensureCustomer(dir, accountName, \"\", \"\", false);\n slug = r.slug;\n slugMap.set(accountName.toLowerCase(), slug);\n if (r.created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Case '${c.Id}': ${(err as Error).message}`);\n continue;\n }\n }\n // Make the account/contact reachable for note linking (Pass 8)\n if (c.AccountId) slugMap.set(c.AccountId, slug);\n if (c.ContactId) slugMap.set(c.ContactId, slug);\n\n const caseRef = `salesforce://case/${c.Id}`;\n const existingTickets = await readTickets(dir, slug);\n if (existingTickets.some((t) => (t.description ?? \"\").includes(caseRef))) {\n result.skipped++;\n continue;\n }\n\n const created = (c.CreatedDate ?? new Date().toISOString()).slice(0, 10);\n const status = mapCaseStatus(c.Status);\n const priority = mapCasePriority(c.Priority);\n const isDone = status === \"closed\" || status === \"resolved\";\n try {\n await upsertTicket(dir, slug, {\n id: nextTicketId(existingTickets),\n title: c.Subject ?? `Case ${c.CaseNumber ?? c.Id}`,\n status,\n priority,\n created,\n slaDue: calcSlaDue(created, priority, slaRules),\n description: `${c.Description ?? \"\"}\\n\\n[${caseRef}]`.trim(),\n ...(isDone ? { resolved: (c.ClosedDate ?? created).slice(0, 10) } : {}),\n });\n result.casesImported = (result.casesImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`Case ${c.Id}: ${(err as Error).message}`);\n }\n }\n\n // Pass 7: opportunity line items → one quote per opportunity\n if (lineItems.length > 0 && oppSlugById.size > 0) {\n const { generateQuote, listQuotes } = await import(\"../core/quote-generator.js\");\n const byOpp = new Map<string, typeof lineItems>();\n for (const li of lineItems) {\n if (!li.OpportunityId) continue;\n const arr = byOpp.get(li.OpportunityId) ?? [];\n arr.push(li);\n byOpp.set(li.OpportunityId, arr);\n }\n for (const [oppId, items] of byOpp) {\n const opp = oppSlugById.get(oppId);\n if (!opp) continue;\n // Dedup: skip if a quote for this deal already exists for the customer.\n if (listQuotes(dir, opp.slug).some((q) => q.dealName === opp.dealName)) {\n result.skipped++;\n continue;\n }\n const quoteLineItems = items.map((li) => {\n const quantity = typeof li.Quantity === \"number\" && li.Quantity > 0 ? li.Quantity : 1;\n const unitPrice =\n typeof li.UnitPrice === \"number\"\n ? li.UnitPrice\n : typeof li.TotalPrice === \"number\"\n ? li.TotalPrice / quantity\n : 0;\n return {\n description: li.Product2?.Name ?? li.Description ?? \"Line item\",\n quantity,\n unitPrice,\n };\n });\n try {\n await generateQuote(dir, {\n slug: opp.slug,\n dealName: opp.dealName,\n lineItems: quoteLineItems,\n });\n result.quotesImported = (result.quotesImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`LineItems for '${opp.dealName}': ${(err as Error).message}`);\n }\n }\n }\n\n // Pass 8: notes → Note interactions, linked by ParentId (account/contact/opp)\n for (const note of notes) {\n const slug = note.ParentId ? slugMap.get(note.ParentId) : undefined;\n if (!slug) {\n result.skipped++;\n continue;\n }\n const sourceRef = `salesforce://note/${note.Id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n const date = (note.CreatedDate ?? new Date().toISOString()).slice(0, 10);\n const title = note.Title ?? \"Salesforce Note\";\n try {\n await appendInteraction(dir, slug, {\n date,\n type: \"Note\",\n with: slug,\n subject: title,\n summary: `${title}${note.Body ? `: ${note.Body}` : \"\"}`.slice(0, 500),\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.notesImported = (result.notesImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`Note ${note.Id}: ${(err as Error).message}`);\n }\n }\n\n // Pass 9: campaign members → Note interactions, linked by ContactId/LeadId\n for (const cm of campaignMembers) {\n const slug = cm.ContactId\n ? slugMap.get(cm.ContactId)\n : cm.LeadId\n ? slugMap.get(cm.LeadId)\n : undefined;\n if (!slug) {\n result.skipped++;\n continue;\n }\n const sourceRef = `salesforce://campaignmember/${cm.Id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n const campaignName = cm.Campaign?.Name ?? cm.CampaignId ?? \"Unknown campaign\";\n try {\n await appendInteraction(dir, slug, {\n date: (cm.CreatedDate ?? new Date().toISOString()).slice(0, 10),\n type: \"Note\",\n with: slug,\n subject: `Campaign: ${campaignName}`,\n summary: `Salesforce Campaign: ${campaignName} (status: ${cm.Status ?? \"n/a\"})`,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.campaignsImported = (result.campaignsImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`CampaignMember ${cm.Id}: ${(err as Error).message}`);\n }\n }\n\n return result;\n}\n\nexport async function runPipedriveApiImport(\n opts: { token?: string; url?: string; dryRun?: boolean },\n dir: string = process.cwd()\n): Promise<ImportResult> {\n const result: ImportResult = {\n customersCreated: 0,\n interactionsImported: 0,\n skipped: 0,\n errors: [],\n };\n const token = opts.token ?? process.env[\"PIPEDRIVE_TOKEN\"] ?? \"\";\n const instanceUrl = opts.url ?? process.env[\"PIPEDRIVE_URL\"] ?? \"\";\n\n if (!token || !instanceUrl) {\n result.errors.push(\n \"Pipedrive API mode requires --token and --url (or PIPEDRIVE_TOKEN + PIPEDRIVE_URL env vars)\"\n );\n return result;\n }\n\n const { fetchPipedrivePersons, fetchPipedriveActivities } =\n await import(\"../sync/pipedrive-client.js\");\n\n let persons: Awaited<ReturnType<typeof fetchPipedrivePersons>>;\n let activities: Awaited<ReturnType<typeof fetchPipedriveActivities>>;\n\n try {\n [persons, activities] = await Promise.all([\n fetchPipedrivePersons(instanceUrl, token),\n fetchPipedriveActivities(instanceUrl, token),\n ]);\n } catch (err) {\n result.errors.push(`Pipedrive API: ${(err as Error).message}`);\n return result;\n }\n\n if (opts.dryRun) {\n console.log(\n info(`Dry run — ${persons.length} persons, ${activities.length} activities from Pipedrive`)\n );\n return result;\n }\n\n // Pass 1: persons → customers\n const slugByPersonId = new Map<number, string>();\n const slugByOrgId = new Map<number, string>();\n\n for (const person of persons) {\n const name = (person.org_name ?? person.name ?? \"\").trim();\n if (!name) continue;\n const email = person.primary_email ?? \"\";\n try {\n const { slug, created } = ensureCustomer(dir, name, \"\", email, false);\n if (person.id) slugByPersonId.set(person.id, slug);\n if (person.org_id?.value) slugByOrgId.set(person.org_id.value, slug);\n if (created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Person '${name}': ${(err as Error).message}`);\n }\n }\n\n // Pass 2: activities → interactions\n const dedup = new InteractionDedup(dir);\n for (const activity of activities) {\n const slug =\n (activity.person_id && slugByPersonId.get(activity.person_id)) ??\n (activity.org_id && slugByOrgId.get(activity.org_id)) ??\n undefined;\n if (!slug) continue;\n\n const sourceRef = `pipedrive://activity/${activity.id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date = activity.due_date ?? new Date().toISOString().slice(0, 10);\n const notes = (activity.note ?? activity.subject ?? \"\").slice(0, 500);\n const t = (activity.type ?? \"\").toLowerCase();\n const type =\n t === \"call\"\n ? (\"Call\" as const)\n : t === \"email\"\n ? (\"Email\" as const)\n : t === \"meeting\"\n ? (\"Meeting\" as const)\n : (\"Note\" as const);\n\n try {\n await appendInteraction(dir, slug, {\n date,\n type,\n with: slug,\n summary: `${activity.subject ?? type}: ${notes}`,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.interactionsImported++;\n } catch (err) {\n result.errors.push(`Activity ${activity.id}: ${(err as Error).message}`);\n }\n }\n\n return result;\n}\n\nexport const importCommand = new Command(\"import\")\n .description(\"Import customers and interactions from HubSpot, Salesforce, Pipedrive, or CSV\")\n .argument(\"[path]\", \"Path to export file or directory\")\n .option(\"--from <source>\", \"Source CRM: hubspot | csv | salesforce | pipedrive\", \"csv\")\n .option(\"--dry-run\", \"Preview what would be imported without writing\")\n .option(\"--mode <mode>\", \"Import mode: file | api\")\n .option(\"--token <token>\", \"API token (Salesforce, Pipedrive, HubSpot)\")\n .option(\"--url <url>\", \"Instance URL (e.g. https://myco.salesforce.com)\")\n .option(\"--analyze\", \"Analyze export and show what would be imported (no write)\")\n .option(\"--resume\", \"Resume a previously interrupted import\")\n .option(\n \"--owner-map <mapping>\",\n 'Map HubSpot owner emails to reps: \"alice@hs.com=alice,bob@hs.com=bob\"'\n )\n .action(\n async (\n sourcePath: string,\n opts: {\n from: string;\n dryRun?: boolean;\n mode?: string;\n token?: string;\n url?: string;\n analyze?: boolean;\n resume?: boolean;\n ownerMap?: string;\n }\n ) => {\n const dryRun = opts.dryRun ?? false;\n\n // Parse owner map\n const ownerMap: Record<string, string> = {};\n if (opts.ownerMap) {\n for (const pair of opts.ownerMap.split(\",\")) {\n const [hs, rep] = pair.split(\"=\");\n if (hs && rep) ownerMap[hs.trim()] = rep.trim();\n }\n }\n\n // HubSpot analyze mode\n if (opts.analyze && opts.from === \"hubspot\" && sourcePath) {\n const { analyzeHubSpotExport } = await import(\"./import-hubspot.js\");\n const analysis = await analyzeHubSpotExport(sourcePath);\n console.log(bold(\"\\nDatasynxOpenCRM — HubSpot Import Analysis\"));\n console.log(\"==========================================\");\n console.log(info(`Companies: ${analysis.companiesFound}`));\n console.log(\n info(\n `Contacts: ${analysis.contactsFound} (${analysis.unmappedContacts} unmapped companies)`\n )\n );\n console.log(info(`Deals: ${analysis.dealsFound}`));\n console.log(info(`Engagements: ${analysis.engagementsFound}`));\n if (analysis.customPropertiesDetected.length > 0) {\n console.log(\n info(`\\nCustom Properties: ${analysis.customPropertiesDetected.length} detected`)\n );\n console.log(\n ` ${analysis.customPropertiesDetected.slice(0, 10).join(\", \")}${analysis.customPropertiesDetected.length > 10 ? \" ...\" : \"\"}`\n );\n }\n if (analysis.ownersDetected.length > 0) {\n console.log(info(`\\nOwners detected: ${analysis.ownersDetected.join(\", \")}`));\n console.log(\n ` Use --owner-map \"${analysis.ownersDetected.map((o) => `${o}=<rep>`).join(\",\")}\"`\n );\n }\n if (analysis.unknownStages.length > 0) {\n console.log(\n info(`\\nUnknown stages (→ \"qualified\"): ${analysis.unknownStages.join(\", \")}`)\n );\n }\n console.log(info(`\\nEstimated import time: ~${analysis.estimatedMinutes} min`));\n console.log(info(`\\nRun without --analyze to start import.`));\n return;\n }\n\n if (!dryRun) {\n console.log(info(`Importing from ${bold(opts.from)}: ${sourcePath}`));\n }\n\n const result = await runImport(\n sourcePath,\n {\n from: opts.from,\n ...(dryRun ? { dryRun: true } : {}),\n ...(opts.mode ? { mode: opts.mode } : {}),\n ...(opts.token ? { token: opts.token } : {}),\n ...(opts.url ? { url: opts.url } : {}),\n ...(opts.resume ? { resume: true } : {}),\n ownerMap,\n },\n process.env[\"DXCRM_DATA_DIR\"]\n );\n\n if (!dryRun) {\n console.log(success(`✓ Import complete:`));\n console.log(info(` Customers created: ${result.customersCreated}`));\n console.log(info(` Interactions imported: ${result.interactionsImported}`));\n console.log(info(` Skipped (duplicates): ${result.skipped}`));\n if (result.errors.length > 0) {\n console.log(error(` Errors (${result.errors.length}):`));\n result.errors.slice(0, 5).forEach((e) => console.log(error(` ${e}`)));\n }\n }\n }\n );\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { spawn } from \"child_process\";\nimport { success, info } from \"../ui/colors.js\";\n\nfunction getPidFile(dataDir: string): string {\n return path.join(dataDir, \".agentic\", \"server.pid\");\n}\n\nexport async function runServerStart(\n opts: { port?: string; data?: string },\n dataDir?: string\n): Promise<void> {\n const port = parseInt(opts.port ?? \"3847\", 10);\n const dir = opts.data ?? dataDir ?? process.cwd();\n\n // Set env var if --data provided\n if (opts.data) {\n process.env[\"DXCRM_DATA_DIR\"] = opts.data;\n }\n\n const pidFile = getPidFile(dir);\n\n // Check if already running\n if (fs.existsSync(pidFile)) {\n const existing = parseInt(fs.readFileSync(pidFile, \"utf-8\").trim(), 10);\n if (!isNaN(existing)) {\n try {\n process.kill(existing, 0);\n console.log(info(`Server already running (PID ${existing})`));\n return;\n } catch {\n // stale PID file — continue\n }\n }\n }\n\n // Spawn the MCP HTTP server process\n const serverEntry = path.resolve(\n path.dirname(new URL(import.meta.url).pathname),\n \"../../dist/mcp/server.js\"\n );\n\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n DXCRM_MCP_MODE: \"http\",\n DXCRM_MCP_PORT: String(port),\n };\n\n if (opts.data) {\n env[\"DXCRM_DATA_DIR\"] = opts.data;\n }\n\n const child = spawn(process.execPath, [serverEntry], {\n detached: true,\n stdio: \"ignore\",\n env,\n });\n child.unref();\n\n // Write PID file\n fs.mkdirSync(path.dirname(pidFile), { recursive: true });\n fs.writeFileSync(pidFile, String(child.pid), \"utf-8\");\n\n const hostname = os.hostname();\n\n console.log(success(`DatasynxOpenCRM server running on http://0.0.0.0:${port}/mcp`));\n console.log(info(`Data dir: ${dir}`));\n console.log(info(`Add to your AI framework config: url: http://${hostname}:${port}/mcp`));\n}\n\nexport function runServerStatus(dataDir?: string): void {\n const dir = process.env[\"DXCRM_DATA_DIR\"] ?? dataDir ?? process.cwd();\n const pidFile = getPidFile(dir);\n\n if (!fs.existsSync(pidFile)) {\n console.log(info(\"Server: not running.\"));\n return;\n }\n\n const pid = parseInt(fs.readFileSync(pidFile, \"utf-8\").trim(), 10);\n if (isNaN(pid)) {\n console.log(info(\"Server: not running (invalid PID file).\"));\n return;\n }\n\n try {\n process.kill(pid, 0);\n console.log(success(`Server: running (PID ${pid})`));\n } catch {\n console.log(info(\"Server: not running (stale PID file).\"));\n try {\n fs.unlinkSync(pidFile);\n } catch {\n // ignore\n }\n }\n}\n\nexport const serverCommand = new Command(\"server\").description(\n \"Start the shared HTTP MCP server for team use\"\n);\n\nserverCommand\n .command(\"start\")\n .description(\"Start the DatasynxOpenCRM HTTP MCP server\")\n .option(\"--port <port>\", \"HTTP port (default 3847)\", \"3847\")\n .option(\"--data <dir>\", \"Data directory (sets DXCRM_DATA_DIR)\")\n .action((opts: { port: string; data?: string }) => runServerStart(opts));\n\nserverCommand\n .command(\"status\")\n .description(\"Check if the server is running\")\n .action(() => runServerStatus());\n","import { Command } from \"commander\";\nimport { readAuditLog, filterAuditLog } from \"../fs/audit-log.js\";\n\nconst SEP = \"─\".repeat(70);\n\nexport async function runAudit(\n opts: {\n slug?: string;\n actor?: string;\n limit?: number;\n tail?: boolean;\n },\n dataDir?: string\n): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const limit = opts.limit ?? 20;\n\n const allEntries = readAuditLog(dir);\n const entries = filterAuditLog(allEntries, {\n ...(opts.slug !== undefined ? { slug: opts.slug } : {}),\n ...(opts.actor !== undefined ? { actor: opts.actor } : {}),\n limit,\n });\n\n console.log(SEP);\n console.log(\" DatasynxOpenCRM — Audit Trail\");\n\n if (opts.slug) console.log(` Customer: ${opts.slug}`);\n if (opts.actor) console.log(` Actor: ${opts.actor}`);\n\n console.log(SEP);\n\n if (entries.length === 0) {\n console.log(\" No audit entries found.\");\n console.log(SEP);\n return;\n }\n\n for (const entry of entries) {\n console.log(\n ` ${entry.timestamp} ${entry.actor.padEnd(12)} ${entry.tool.padEnd(20)} ${entry.slug.padEnd(20)} ${entry.summary}`\n );\n }\n\n console.log(SEP);\n console.log(` ${entries.length} entr${entries.length === 1 ? \"y\" : \"ies\"} shown`);\n console.log(SEP);\n}\n\nexport const auditCommand = new Command(\"audit\")\n .description(\"Show CRM audit trail — who changed what and when\")\n .option(\"--slug <slug>\", \"Filter by customer slug\")\n .option(\"--actor <actor>\", \"Filter by actor\")\n .option(\"--limit <n>\", \"Number of entries to show (default: 20)\", parseInt)\n .option(\"--tail\", \"Show all new entries (simplified: shows current entries)\")\n .action((opts: { slug?: string; actor?: string; limit?: number; tail?: boolean }) =>\n runAudit(opts, process.env[\"DXCRM_DATA_DIR\"])\n );\n","import { Command } from \"commander\";\nimport { info, warning, error, success, bold } from \"../ui/colors.js\";\nimport type { LogLevel, LogQuery } from \"../core/logger.js\";\n\nconst LEVELS = [\"debug\", \"info\", \"warn\", \"error\"];\n\nfunction paintLevel(level: LogLevel, text: string): string {\n if (level === \"error\") return error(text);\n if (level === \"warn\") return warning(text);\n if (level === \"info\") return info(text);\n return text;\n}\n\nfunction buildQuery(opts: {\n level?: string;\n component?: string;\n since?: string;\n contains?: string;\n limit?: number;\n}): LogQuery {\n return {\n ...(opts.level && LEVELS.includes(opts.level) ? { level: opts.level as LogLevel } : {}),\n ...(opts.component !== undefined ? { component: opts.component } : {}),\n ...(opts.since !== undefined ? { since: opts.since } : {}),\n ...(opts.contains !== undefined ? { contains: opts.contains } : {}),\n limit: opts.limit ?? 50,\n };\n}\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const logsCommand = new Command(\"logs\")\n .description(\"View and analyze the structured application log\")\n .option(\"--level <level>\", \"Minimum level: debug | info | warn | error\")\n .option(\"--component <name>\", \"Filter by component (e.g. gmail-sync, lancedb)\")\n .option(\"--since <iso>\", \"Only entries at or after this ISO timestamp\")\n .option(\"--contains <text>\", \"Filter by message substring\")\n .option(\"--limit <n>\", \"Max entries to show (default: 50)\", parseInt)\n .option(\"--summary\", \"Show aggregated counts (by level + component) instead of entries\")\n .action(\n async (opts: {\n level?: string;\n component?: string;\n since?: string;\n contains?: string;\n limit?: number;\n summary?: boolean;\n }) => {\n const query = buildQuery(opts);\n\n if (opts.summary) {\n const { summarizeLogs } = await import(\"../core/logger.js\");\n const s = summarizeLogs(dataDir(), query);\n console.log(bold(`Logs — ${s.total} entr${s.total === 1 ? \"y\" : \"ies\"}`));\n if (s.firstTs) console.log(info(` ${s.firstTs} → ${s.lastTs}`));\n console.log(\" By level:\");\n for (const lvl of LEVELS) {\n const n = s.byLevel[lvl as LogLevel];\n if (n > 0) console.log(` ${paintLevel(lvl as LogLevel, lvl.padEnd(6))} ${n}`);\n }\n console.log(\" By component:\");\n for (const [comp, n] of Object.entries(s.byComponent).sort((a, b) => b[1] - a[1])) {\n console.log(` ${comp.padEnd(22)} ${n}`);\n }\n if (s.recentErrors.length > 0) {\n console.log(error(\" Recent errors:\"));\n for (const e of s.recentErrors) console.log(` ${e.ts} [${e.component}] ${e.message}`);\n }\n return;\n }\n\n const { queryLogs } = await import(\"../core/logger.js\");\n const entries = queryLogs(dataDir(), query);\n if (entries.length === 0) {\n console.log(success(\"No matching log entries.\"));\n return;\n }\n for (const e of entries) {\n const ctx = e.context ? ` ${JSON.stringify(e.context)}` : \"\";\n console.log(\n `${e.ts} ${paintLevel(e.level, e.level.padEnd(5))} ${e.component.padEnd(18)} ${e.message}${ctx}`\n );\n }\n }\n );\n","import { Command } from \"commander\";\nimport { success, error, warning, bold } from \"../ui/colors.js\";\nimport type { CheckStatus } from \"../core/doctor.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nfunction icon(status: CheckStatus): string {\n if (status === \"ok\") return success(\"✓\");\n if (status === \"warn\") return warning(\"⚠\");\n return error(\"✗\");\n}\n\nexport const doctorCommand = new Command(\"doctor\")\n .description(\"Run self-diagnostics: data integrity, temp files, log errors, backup freshness\")\n .option(\"--fix\", \"Clean up safely-fixable issues (orphaned temp files)\")\n .action(async (opts: { fix?: boolean }) => {\n const { runDiagnostics, cleanupTempFiles } = await import(\"../core/doctor.js\");\n\n if (opts.fix) {\n const removed = cleanupTempFiles(dataDir());\n console.log(\n removed.length > 0\n ? success(`Removed ${removed.length} orphaned temp file(s).`)\n : warning(\"Nothing to fix.\")\n );\n }\n\n const report = await runDiagnostics(dataDir());\n\n console.log(bold(\"dxcrm doctor\"));\n for (const c of report.checks) {\n console.log(` ${icon(c.status)} ${c.name.padEnd(16)} ${c.detail}`);\n }\n\n if (report.ok) {\n const warns = report.checks.filter((c) => c.status === \"warn\").length;\n console.log(\n warns > 0 ? warning(`\\nHealthy, with ${warns} warning(s).`) : success(\"\\nAll healthy.\")\n );\n } else {\n console.log(error(\"\\nProblems found — see the ✗ checks above.\"));\n process.exitCode = 1;\n }\n });\n","import { Command } from \"commander\";\nimport { getRbacConfig, setActorRole, canWrite, type Role } from \"../core/rbac.js\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nconst ROLES: Role[] = [\"admin\", \"manager\", \"rep\"];\n\nexport async function runRbacSet(actor: string, role: string, dataDir?: string): Promise<void> {\n const dir = dataDir ?? process.cwd();\n if (!ROLES.includes(role as Role)) {\n console.error(error(`✗ Invalid role '${role}'. Must be: ${ROLES.join(\", \")}`));\n process.exit(1);\n }\n setActorRole(dir, actor, role as Role);\n console.log(success(`✓ ${bold(actor)} → ${bold(role)}`));\n}\n\nexport async function runRbacShow(dataDir?: string): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const config = getRbacConfig(dir);\n const entries = Object.entries(config.actors);\n\n if (entries.length === 0) {\n console.log(info(\"No RBAC roles configured. All actors default to 'rep'.\"));\n return;\n }\n\n console.log(bold(`\\n RBAC Roles\\n`));\n for (const [actor, role] of entries) {\n console.log(info(` ${bold(actor).padEnd(20)} ${role}`));\n }\n if (config.default) {\n console.log(info(`\\n Default: ${config.default}`));\n }\n console.log(\"\");\n}\n\nexport async function runRbacCheck(actor: string, tool: string, dataDir?: string): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const { getRole } = await import(\"../core/rbac.js\");\n const role = getRole(dir, actor);\n const allowed = canWrite(role, tool);\n if (allowed) {\n console.log(success(`✓ ${actor} (${role}) CAN use '${tool}'`));\n } else {\n console.log(error(`✗ ${actor} (${role}) CANNOT use '${tool}'`));\n }\n}\n\nexport const rbacCommand = new Command(\"rbac\").description(\"Manage role-based access control\");\n\nrbacCommand\n .command(\"set <actor> <role>\")\n .description(`Assign role to actor (roles: ${ROLES.join(\", \")})`)\n .action((actor: string, role: string) => runRbacSet(actor, role, process.env[\"DXCRM_DATA_DIR\"]));\n\nrbacCommand\n .command(\"show\")\n .alias(\"list\")\n .description(\"List all RBAC role assignments\")\n .action(() => runRbacShow(process.env[\"DXCRM_DATA_DIR\"]));\n\nrbacCommand\n .command(\"check <actor> <tool>\")\n .description(\"Check if an actor can use a specific tool\")\n .action((actor: string, tool: string) =>\n runRbacCheck(actor, tool, process.env[\"DXCRM_DATA_DIR\"])\n );\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { writeJsonFile } from \"../fs/json-store.js\";\nimport { success, info, bold } from \"../ui/colors.js\";\nimport { writeAuditEntry, getActor } from \"../fs/audit-log.js\";\nimport { withJsonFile } from \"../core/file-lock.js\";\n\ninterface ErasureRecord {\n slug: string;\n erasedAt: string;\n erasedBy: string;\n reason: string;\n}\n\nfunction erasuresPath(dataDir: string): string {\n return path.join(dataDir, \".agentic\", \"gdpr-erasures.json\");\n}\n\nfunction readErasures(dataDir: string): ErasureRecord[] {\n const p = erasuresPath(dataDir);\n if (!fs.existsSync(p)) return [];\n try {\n return JSON.parse(fs.readFileSync(p, \"utf-8\") as string) as ErasureRecord[];\n } catch {\n return [];\n }\n}\n\nfunction appendErasure(dataDir: string, record: ErasureRecord): void {\n const p = erasuresPath(dataDir);\n fs.mkdirSync(path.dirname(p), { recursive: true });\n const existing = readErasures(dataDir);\n existing.push(record);\n writeJsonFile(p, existing);\n}\n\nexport async function runGdprErase(\n slug: string,\n opts: { confirm?: boolean },\n dataDir?: string\n): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const customerDir = path.join(dir, \"customers\", slug);\n\n if (!opts.confirm) {\n console.log(info(`Dry run — would permanently erase: ${bold(slug)}`));\n console.log(info(` Directory: ${customerDir}`));\n console.log(info(` Audit log entry will be written to .agentic/audit.log`));\n console.log(info(` Erasure record will be added to .agentic/gdpr-erasures.json`));\n console.log(info(`\\n To proceed: dxcrm gdpr erase ${slug} --confirm`));\n return;\n }\n\n if (!fs.existsSync(customerDir)) {\n console.warn(info(` Customer '${slug}' directory not found — may already be erased.`));\n } else {\n fs.rmSync(customerDir, { recursive: true, force: true });\n try {\n const { dropCustomerTable } = await import(\"../core/lancedb.js\");\n await dropCustomerTable(dir, slug);\n } catch {\n // non-critical — lancedb cleanup failure should not block erasure\n }\n }\n\n // Clean up .agentic/-level references to this slug\n\n // 1. Remove tasks for this slug from the global agent queue\n const globalQueuePath = path.join(dir, \".agentic\", \"agent-queue.json\");\n if (fs.existsSync(globalQueuePath)) {\n await withJsonFile<unknown[]>(globalQueuePath, (tasks) =>\n (Array.isArray(tasks) ? tasks : []).filter((t) => (t as { slug?: string }).slug !== slug)\n );\n }\n\n // 2. Remove goal sub-goals referencing this slug\n const goalsPath = path.join(dir, \".agentic\", \"goals.json\");\n if (fs.existsSync(goalsPath)) {\n const { readGoals, writeGoals } = await import(\"../core/goal-engine.js\");\n const goals = readGoals(dir);\n const cleaned = goals.map((g) => ({\n ...g,\n decomposition: {\n ...g.decomposition,\n subGoals: g.decomposition.subGoals.filter((sg) => sg.slug !== slug),\n },\n }));\n writeGoals(dir, cleaned);\n }\n\n // 3. Revoke push subscriptions for this slug\n const { readSubscriptions, writeSubscriptions } = await import(\"../sync/push-manager.js\");\n const subs = await readSubscriptions(dir);\n const remaining = subs.filter((s) => s.slug !== slug);\n if (remaining.length !== subs.length) {\n await writeSubscriptions(dir, remaining);\n }\n\n const actor = getActor();\n const now = new Date().toISOString();\n\n writeAuditEntry(dir, {\n timestamp: now,\n actor,\n tool: \"gdpr_erase\",\n slug,\n summary: \"Customer data permanently erased\",\n });\n\n appendErasure(dir, {\n slug,\n erasedAt: now,\n erasedBy: actor,\n reason: \"GDPR Art. 17 request\",\n });\n\n console.log(success(`✓ Customer '${bold(slug)}' erased.`));\n console.log(info(` Deletion logged to .agentic/audit.log`));\n console.log(info(` Record added to .agentic/gdpr-erasures.json`));\n}\n\nexport async function runGdprListErasures(dataDir?: string): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const records = readErasures(dir);\n\n if (records.length === 0) {\n console.log(info(\"No erasures on record.\"));\n return;\n }\n\n console.log(bold(`\\n GDPR Erasures (${records.length})\\n`));\n for (const r of records) {\n console.log(info(` ${r.erasedAt} ${r.erasedBy.padEnd(12)} ${r.slug} — ${r.reason}`));\n }\n console.log(\"\");\n}\n\nexport const gdprCommand = new Command(\"gdpr\").description(\"GDPR compliance tools\");\n\ngdprCommand\n .command(\"erase <slug>\")\n .description(\"Permanently erase all data for a customer (Art. 17 right to erasure)\")\n .option(\"--confirm\", \"Confirm permanent deletion (required)\")\n .action((slug: string, opts: { confirm?: boolean }) =>\n runGdprErase(slug, opts, process.env[\"DXCRM_DATA_DIR\"])\n );\n\ngdprCommand\n .command(\"list-erasures\")\n .description(\"Show history of GDPR erasures\")\n .action(() => runGdprListErasures(process.env[\"DXCRM_DATA_DIR\"]));\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { success } from \"../ui/colors.js\";\n\nconst REPORT = `# DatasynxOpenCRM — Security Report\n\nGenerated: ${new Date().toISOString().slice(0, 10)}\n\n## 1. Data Storage\n\n- **Location**: Local filesystem only. All data lives in \\`customers/\\` and \\`.agentic/\\` directories on your infrastructure.\n- **External transmission**: None by default. Data is never sent to Datasynx servers.\n- **Cloud dependencies**: None for core functionality. Optional integrations (Gmail, Anthropic API) are explicitly configured.\n\n## 2. Authentication & Authorization\n\n- **Phase 3**: No authentication on HTTP MCP server. Restrict access via firewall or VPN (port 3847 should be on private network only).\n- **Phase 4 (RBAC)**: Role-based access control via \\`.agentic/rbac.json\\`. Roles: admin, manager, rep. Enforced per MCP tool call.\n- **Actor identity**: \\`DXCRM_ACTOR\\` environment variable. No cryptographic identity in Phase 3.\n\n## 3. Encryption\n\n- **At rest**: Not encrypted at application level. Use OS-level disk encryption (LUKS on Linux, FileVault on macOS).\n- **In transit**: HTTP (no TLS) in Phase 3. Use a reverse proxy (nginx + Let's Encrypt) or VPN for TLS.\n- **Recommendation**: Deploy behind Tailscale or WireGuard for team access.\n\n## 4. Audit Trail\n\n- **File**: \\`.agentic/audit.log\\` — append-only, one line per entry.\n- **Format**: \\`timestamp | actor | tool | customer | summary\\`\n- **Coverage**: All write operations (\\`log_interaction\\`, \\`update_deal\\`, \\`gdpr_erase\\`).\n- **Tamper evidence**: Phase 3: none. Phase 4+: hash chaining planned.\n- **Retention**: Indefinite (append-only, never deleted by the application).\n\n## 5. Network Calls\n\nThe following external services are contacted when configured:\n\n| Service | When | Data sent |\n|---|---|---|\n| Gmail API | Gmail sync enabled + credentials configured | Email headers + snippets |\n| Anthropic API | \\`ANTHROPIC_API_KEY\\` set | Email/transcript content for summarization |\n| Telegram Bot API | Agent notifications enabled + token set | Customer slug + context excerpt (≤800 chars) |\n| Microsoft Graph | Microsoft sync configured | Email headers + snippets |\n\n**No telemetry, no analytics, no usage data is sent to Datasynx.**\n\n## 6. Data Residency\n\nDatasynxOpenCRM runs entirely on customer-controlled infrastructure. Data never leaves the deployment environment without explicit integration configuration.\n\nThis makes EU data residency guarantees straightforward — a key differentiator vs cloud CRMs.\n\n## 7. GDPR Compliance\n\n- **Right to erasure (Art. 17)**: \\`dxcrm gdpr erase <slug> --confirm\\` permanently deletes all customer data.\n- **Erasure log**: \\`.agentic/gdpr-erasures.json\\` records what was deleted, when, and by whom.\n- **Audit trail**: Every write operation is attributed to an actor.\n- **Data portability (Art. 20)**: \\`dxcrm export <slug>\\` exports all data as JSON or Markdown.\n\n## 8. SOC 2 Readiness\n\n- **Audit log**: Available from Phase 3 (audit trail covers all write operations).\n- **SOC 2 Type 2**: Requires 6 months of consistent audit logs. Apply after Phase 4 completion.\n- **Security review questionnaire**: This document serves as the primary answer document.\n\n## 9. Dependencies (Key Packages)\n\n| Package | Purpose | Cloud dependency? |\n|---|---|---|\n| \\`@modelcontextprotocol/sdk\\` | MCP server | No |\n| \\`@googleapis/gmail\\`, \\`@googleapis/calendar\\` | Gmail/Calendar sync | Optional — only if configured |\n| \\`@anthropic-ai/sdk\\` | LLM summarization | Optional — only if API key set |\n| \\`lancedb\\` | Local vector search | No — embedded DB |\n| \\`gray-matter\\` | Markdown frontmatter | No |\n| \\`commander\\` | CLI framework | No |\n| \\`zod\\` | Schema validation | No |\n| \\`cron\\` | Background sync | No |\n\n## 10. Incident Response\n\n- **Data breach**: Filesystem-only — scope is limited to the deployment host.\n- **Revoke access**: Remove actor from \\`.agentic/rbac.json\\`, rotate \\`DXCRM_ACTOR\\` env var.\n- **Audit**: \\`dxcrm audit --actor <actor>\\` shows all actions by a specific user.\n`;\n\nexport async function runSecurityReport(\n opts: { output?: string },\n _dataDir?: string\n): Promise<void> {\n const report = REPORT;\n\n if (opts.output) {\n const outputPath = path.resolve(opts.output);\n fs.writeFileSync(outputPath, report, \"utf-8\");\n console.log(success(`✓ Security report written to: ${outputPath}`));\n } else {\n console.log(report);\n }\n}\n\nexport const securityReportCommand = new Command(\"security-report\")\n .description(\"Generate security questionnaire answer document for enterprise reviews\")\n .option(\"--output <file>\", \"Write report to file instead of stdout\")\n .action((opts: { output?: string }) => runSecurityReport(opts, process.env[\"DXCRM_DATA_DIR\"]));\n","import { Command } from \"commander\";\nimport {\n getPipelineStages,\n setPipelineStage,\n deletePipelineStage,\n resetToDefaults,\n type PipelineStage,\n} from \"../core/pipeline-stages.js\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nfunction printStagesTable(stages: PipelineStage[]): void {\n console.log(bold(\"\\n Pipeline Stages\\n\"));\n console.log(\n info(\n ` ${\"ID\".padEnd(20)} ${\"Label\".padEnd(20)} ${\"Order\".padEnd(8)} ${\"Prob%\".padEnd(8)} ${\"Final\".padEnd(6)} Color`\n )\n );\n console.log(info(` ${\"─\".repeat(72)}`));\n for (const s of stages) {\n const prob = s.probability !== undefined ? String(s.probability) : \"-\";\n const isFinal = s.isFinal ? \"yes\" : \"no\";\n const color = s.color ?? \"-\";\n console.log(\n info(\n ` ${s.id.padEnd(20)} ${s.label.padEnd(20)} ${String(s.order).padEnd(8)} ${prob.padEnd(8)} ${isFinal.padEnd(6)} ${color}`\n )\n );\n }\n console.log(\"\");\n}\n\nexport const stagesCommand = new Command(\"stages\").description(\"Manage custom pipeline stages\");\n\nstagesCommand\n .command(\"list\")\n .description(\"List all configured pipeline stages\")\n .action(() => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const stages = getPipelineStages(dataDir);\n printStagesTable(stages);\n });\n\nstagesCommand\n .command(\"set <id> <label>\")\n .description(\"Create or update a pipeline stage\")\n .option(\"--order <n>\", \"Sort order (number)\", \"1\")\n .option(\"--probability <n>\", \"Default win probability 0-100\")\n .option(\"--color <hex>\", \"Hex color code (e.g. #3B82F6)\")\n .option(\"--final\", \"Mark as final stage (won/lost)\")\n .action(\n (\n id: string,\n label: string,\n opts: { order: string; probability?: string; color?: string; final?: boolean }\n ) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const stage: PipelineStage = {\n id,\n label,\n order: parseInt(opts.order, 10),\n ...(opts.probability !== undefined ? { probability: parseInt(opts.probability, 10) } : {}),\n ...(opts.color ? { color: opts.color } : {}),\n ...(opts.final ? { isFinal: true } : {}),\n };\n setPipelineStage(dataDir, stage);\n console.log(success(`✓ Stage '${id}' saved`));\n }\n );\n\nstagesCommand\n .command(\"delete <id>\")\n .description(\"Delete a pipeline stage by ID\")\n .action((id: string) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const existing = getPipelineStages(dataDir);\n if (!existing.find((s) => s.id === id)) {\n console.error(error(`✗ Stage '${id}' not found`));\n process.exit(1);\n }\n deletePipelineStage(dataDir, id);\n console.log(success(`✓ Stage '${id}' deleted`));\n });\n\nstagesCommand\n .command(\"reset\")\n .description(\"Reset pipeline stages to defaults\")\n .action(() => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n resetToDefaults(dataDir);\n console.log(success(\"✓ Pipeline stages reset to defaults\"));\n });\n","export interface DxcrmPlugin {\n name: string;\n version: string;\n description?: string;\n onInstall?(): Promise<void>;\n onUninstall?(): Promise<void>;\n mcpTools?: string[]; // names of MCP tools this plugin registers\n}\n\nconst _plugins = new Map<string, DxcrmPlugin>();\n\nexport function registerPlugin(plugin: DxcrmPlugin): void {\n if (_plugins.has(plugin.name)) {\n throw new Error(`Plugin '${plugin.name}' is already registered`);\n }\n _plugins.set(plugin.name, plugin);\n}\n\nexport function getPlugin(name: string): DxcrmPlugin | undefined {\n return _plugins.get(name);\n}\n\nexport function listPlugins(): DxcrmPlugin[] {\n return Array.from(_plugins.values());\n}\n\nexport function unregisterPlugin(name: string): boolean {\n return _plugins.delete(name);\n}\n","import { Command } from \"commander\";\nimport { listPlugins, getPlugin } from \"../core/plugin-registry.js\";\nimport { info, bold, error } from \"../ui/colors.js\";\n\nexport const pluginCommand = new Command(\"plugin\").description(\"Manage dxcrm plugins\");\n\npluginCommand\n .command(\"list\")\n .description(\"List all registered plugins\")\n .action(() => {\n const plugins = listPlugins();\n if (plugins.length === 0) {\n console.log(info(\"No plugins registered.\"));\n return;\n }\n console.log(bold(`\\n dxcrm Plugins (${plugins.length})\\n`));\n for (const p of plugins) {\n console.log(info(` ${p.name.padEnd(20)} v${p.version} ${p.description ?? \"\"}`));\n }\n console.log(\"\");\n });\n\npluginCommand\n .command(\"info <name>\")\n .description(\"Show info about a registered plugin\")\n .action((name: string) => {\n const plugin = getPlugin(name);\n if (!plugin) {\n console.log(error(`Plugin '${name}' not found.`));\n process.exit(1);\n }\n console.log(bold(`\\n Plugin: ${plugin.name}\\n`));\n console.log(info(` Version: ${plugin.version}`));\n if (plugin.description) console.log(info(` Description: ${plugin.description}`));\n if (plugin.mcpTools?.length) {\n console.log(info(` MCP Tools: ${plugin.mcpTools.join(\", \")}`));\n }\n console.log(\"\");\n });\n","import { Command } from \"commander\";\nimport { pursueGoal, getActiveGoals, updateGoalProgress, cancelGoal } from \"../core/goal-engine.js\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nexport async function runGoalSet(\n description: string,\n options: { deadline: string }\n): Promise<void> {\n const dir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const goal = await pursueGoal(dir, { description, deadline: options.deadline });\n console.log(success(`✓ Goal created: ${bold(goal.id)}`));\n console.log(info(` Description : ${goal.description}`));\n console.log(info(` Target : €${goal.target.toLocaleString()}`));\n console.log(info(` Deadline : ${goal.deadline}`));\n console.log(info(` Pipeline P50: €${goal.decomposition.currentPipeline.toLocaleString()}`));\n console.log(info(` Gap : €${goal.decomposition.gap.toLocaleString()}`));\n if (goal.decomposition.subGoals.length > 0) {\n console.log(bold(\"\\n Action Plan:\"));\n for (const sg of goal.decomposition.subGoals) {\n console.log(info(` ${sg.priority}. ${sg.action}`));\n console.log(info(` → ${sg.nextStep}`));\n }\n }\n}\n\nexport async function runGoalStatus(): Promise<void> {\n const dir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const goals = getActiveGoals(dir);\n if (goals.length === 0) {\n console.log(info(\"No active goals. Use `dxcrm goal set` to create one.\"));\n return;\n }\n console.log(bold(`\\n Active Goals (${goals.length})\\n`));\n for (const g of goals) {\n const bar =\n \"█\".repeat(Math.round(g.progress / 10)) + \"░\".repeat(10 - Math.round(g.progress / 10));\n const deadlineMs = new Date(g.deadline).getTime() - Date.now();\n const daysLeft = Math.max(0, Math.ceil(deadlineMs / 86_400_000));\n console.log(bold(` ${g.id}`));\n console.log(info(` ${g.description}`));\n console.log(\n info(\n ` [${bar}] ${g.progress}% | €${g.target.toLocaleString()} by ${g.deadline} (${daysLeft}d left)`\n )\n );\n console.log(\"\");\n }\n}\n\nexport async function runGoalUpdate(goalId: string, options: { progress: string }): Promise<void> {\n const dir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const progress = parseInt(options.progress, 10);\n if (isNaN(progress) || progress < 0 || progress > 100) {\n console.error(error(\"✗ --progress must be a number 0–100\"));\n process.exit(1);\n }\n const updated = await updateGoalProgress(dir, goalId, progress);\n if (!updated) {\n console.error(error(`✗ Goal '${goalId}' not found`));\n process.exit(1);\n }\n console.log(success(`✓ Goal ${bold(goalId)} progress updated to ${bold(String(progress))}%`));\n}\n\nexport async function runGoalCancel(goalId: string): Promise<void> {\n const dir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const cancelled = await cancelGoal(dir, goalId);\n if (!cancelled) {\n console.error(error(`✗ Goal '${goalId}' not found`));\n process.exit(1);\n }\n console.log(success(`✓ Goal ${bold(goalId)} cancelled`));\n}\n\nexport const goalCommand = new Command(\"goal\").description(\"Manage goals and action plans\");\n\ngoalCommand\n .command(\"set <description>\")\n .description(\"Set a new goal and get a decomposed action plan\")\n .requiredOption(\"--deadline <date>\", \"Target deadline (YYYY-MM-DD)\")\n .action((description: string, opts: { deadline: string }) => runGoalSet(description, opts));\n\ngoalCommand\n .command(\"status\")\n .description(\"Show all active goals with progress\")\n .action(() => runGoalStatus());\n\ngoalCommand\n .command(\"update <goalId>\")\n .description(\"Update goal progress percentage\")\n .requiredOption(\"--progress <n>\", \"Progress 0–100\")\n .action((goalId: string, opts: { progress: string }) => runGoalUpdate(goalId, opts));\n\ngoalCommand\n .command(\"cancel <goalId>\")\n .description(\"Cancel an active goal\")\n .action((goalId: string) => runGoalCancel(goalId));\n","import { Command } from \"commander\";\nimport {\n register,\n readSubscriptions,\n revoke,\n renewExpiringSubscriptions,\n} from \"../sync/push-manager.js\";\nimport type { PushProvider } from \"../sync/push-manager.js\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nexport async function runPushRegister(\n slug: string,\n options: {\n provider: PushProvider;\n webhookUrl: string;\n topicName?: string;\n clientState?: string;\n resource?: string;\n teamId?: string;\n channelId?: string;\n }\n): Promise<void> {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const providerData: Record<string, string> = {};\n if (options.topicName) providerData[\"gmailTopicName\"] = options.topicName;\n if (options.clientState) providerData[\"microsoftClientState\"] = options.clientState;\n if (options.resource) providerData[\"microsoftResource\"] = options.resource;\n if (options.teamId) providerData[\"slackTeamId\"] = options.teamId;\n if (options.channelId) providerData[\"slackChannelId\"] = options.channelId;\n\n const sub = await register(dataDir, options.provider, slug, {\n webhookUrl: options.webhookUrl,\n providerData,\n });\n\n console.log(success(`✓ Push subscription registered: ${bold(sub.id)}`));\n console.log(info(` Provider : ${sub.provider}`));\n console.log(info(` Slug : ${sub.slug}`));\n console.log(info(` Webhook : ${sub.webhookUrl}`));\n console.log(info(` Expires : ${sub.expiresAt ?? \"never\"}`));\n\n if (options.webhookUrl.includes(\"localhost\")) {\n console.log(info(` ⚠ Warning: localhost URLs cannot be reached by external providers.`));\n console.log(info(` Use a tunnel: ngrok http 3847`));\n }\n}\n\nexport async function runPushStatus(options: { slug?: string; provider?: string }): Promise<void> {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n let subs = await readSubscriptions(dataDir);\n\n if (options.slug) subs = subs.filter((s) => s.slug === options.slug);\n if (options.provider) subs = subs.filter((s) => s.provider === options.provider);\n\n if (subs.length === 0) {\n console.log(info(\"No push subscriptions registered. Use `dxcrm push register` to add one.\"));\n return;\n }\n\n const now = Date.now();\n console.log(bold(`\\n Push Subscriptions (${subs.length})\\n`));\n for (const s of subs) {\n const expiresIn = s.expiresAt\n ? Math.round((new Date(s.expiresAt).getTime() - now) / (60 * 60 * 1000))\n : null;\n const expiryStr = expiresIn !== null ? `${expiresIn}h remaining` : \"no expiry\";\n const needsRenewal =\n s.expiresAt !== null && new Date(s.expiresAt).getTime() - now < 24 * 60 * 60 * 1000;\n\n console.log(bold(` ${s.id}`));\n console.log(info(` ${s.provider} → ${s.slug} [${s.status}]`));\n console.log(\n info(\n ` Events: ${s.eventsProcessed} | Expires: ${expiryStr}${needsRenewal ? \" ⚠ RENEW SOON\" : \"\"}`\n )\n );\n console.log(info(` Last event: ${s.lastEventAt ?? \"—\"}`));\n console.log(\"\");\n }\n}\n\nexport async function runPushRevoke(id: string): Promise<void> {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n try {\n await revoke(dataDir, id);\n console.log(success(`✓ Subscription ${bold(id)} revoked`));\n } catch {\n console.error(error(`✗ Subscription not found: ${id}`));\n process.exit(1);\n }\n}\n\nexport async function runPushRenew(options: { all?: boolean; id?: string }): Promise<void> {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n if (options.id) {\n const subs = await readSubscriptions(dataDir);\n const sub = subs.find((s) => s.id === options.id);\n if (!sub) {\n console.error(error(`✗ Subscription not found: ${options.id}`));\n process.exit(1);\n }\n console.log(info(` Renewal for ${sub.id} requires provider-specific logic.`));\n console.log(info(` Use the daemon's automatic renewal (daily 06:00) or re-register.`));\n return;\n }\n const result = await renewExpiringSubscriptions(\n dataDir,\n async () => {\n throw new Error(\"No default renew function — use provider-specific tooling\");\n },\n 24\n );\n console.log(info(` Renewed: ${result.renewed.length} | Errors: ${result.errors.length}`));\n if (result.renewed.length > 0) console.log(success(`✓ Renewed: ${result.renewed.join(\", \")}`));\n if (result.errors.length > 0) console.log(error(`✗ Errors: ${result.errors.join(\", \")}`));\n}\n\nexport const pushCommand = new Command(\"push\").description(\n \"Manage real-time push subscriptions (Gmail Pub/Sub, MS Graph, Slack Events)\"\n);\n\npushCommand\n .command(\"register <slug>\")\n .description(\"Register a push subscription for a customer\")\n .requiredOption(\"--provider <provider>\", \"Provider: gmail | microsoft-graph | slack\")\n .requiredOption(\"--webhook-url <url>\", \"Public HTTPS URL for provider callbacks\")\n .option(\"--topic-name <topic>\", \"Gmail: Cloud Pub/Sub topic name\")\n .option(\"--client-state <secret>\", \"MS Graph: client state secret\")\n .option(\"--resource <path>\", \"MS Graph: resource path\")\n .option(\"--team-id <id>\", \"Slack: workspace team ID\")\n .option(\"--channel-id <id>\", \"Slack: optional channel ID\")\n .action(\n async (\n slug: string,\n opts: {\n provider: PushProvider;\n webhookUrl: string;\n topicName?: string;\n clientState?: string;\n resource?: string;\n teamId?: string;\n channelId?: string;\n }\n ) => {\n await runPushRegister(slug, opts);\n }\n );\n\npushCommand\n .command(\"status\")\n .description(\"Show all push subscriptions\")\n .option(\"--slug <slug>\", \"Filter by customer slug\")\n .option(\"--provider <provider>\", \"Filter by provider\")\n .action(async (opts: { slug?: string; provider?: string }) => {\n await runPushStatus(opts);\n });\n\npushCommand\n .command(\"revoke <id>\")\n .description(\"Revoke a push subscription by ID\")\n .action(async (id: string) => {\n await runPushRevoke(id);\n });\n\npushCommand\n .command(\"renew\")\n .description(\"Renew expiring push subscriptions\")\n .option(\"--all\", \"Renew all expiring subscriptions\")\n .option(\"--id <id>\", \"Renew a specific subscription by ID\")\n .action(async (opts: { all?: boolean; id?: string }) => {\n await runPushRenew(opts);\n });\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nexport async function runAttach(\n slug: string,\n filePath: string,\n dataDir?: string\n): Promise<{ attached: string } | { error: string }> {\n const dir = dataDir ?? process.cwd();\n const customerDir = path.join(dir, \"customers\", slug);\n\n if (!fs.existsSync(customerDir)) {\n const msg = `Customer '${slug}' not found.`;\n console.error(error(msg));\n return { error: msg };\n }\n\n if (!fs.existsSync(filePath)) {\n const msg = `File not found: ${filePath}`;\n console.error(error(msg));\n return { error: msg };\n }\n\n const attachmentsDir = path.join(customerDir, \"attachments\");\n fs.mkdirSync(attachmentsDir, { recursive: true });\n\n const filename = path.basename(filePath);\n const dest = path.join(attachmentsDir, filename);\n\n if (fs.existsSync(dest)) {\n const msg = `Attachment already exists: ${filename}`;\n console.log(info(msg));\n return { attached: dest };\n }\n\n fs.copyFileSync(filePath, dest);\n console.log(success(`Attached ${bold(filename)} to ${bold(slug)}`));\n return { attached: dest };\n}\n\nexport async function runListAttachments(slug: string, dataDir?: string): Promise<string[]> {\n const dir = dataDir ?? process.cwd();\n const attachmentsDir = path.join(dir, \"customers\", slug, \"attachments\");\n\n if (!fs.existsSync(attachmentsDir)) return [];\n\n try {\n return fs.readdirSync(attachmentsDir).filter((f) => {\n try {\n return fs.statSync(path.join(attachmentsDir, f)).isFile();\n } catch {\n return false;\n }\n });\n } catch {\n return [];\n }\n}\n\nexport const attachCommand = new Command(\"attach\")\n .description(\"Attach a file to a customer (copies to customers/<slug>/attachments/)\")\n .argument(\"<slug>\", \"Customer slug\")\n .argument(\"<file>\", \"Path to the file to attach\")\n .action(async (slug: string, file: string) => {\n await runAttach(slug, file, process.env[\"DXCRM_DATA_DIR\"]);\n });\n","import { Command } from \"commander\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport { listTemplates, getTemplate, writeTemplate, deleteTemplate } from \"../fs/template-store.js\";\nimport { interpolate, buildVariablesFromCustomer } from \"../core/template-engine.js\";\nimport type { EmailTemplate } from \"../schemas/email-template.js\";\n\nexport const templateCommand = new Command(\"template\").description(\"Manage email templates\");\n\ntemplateCommand\n .command(\"list\")\n .option(\"--category <category>\", \"Filter by category\")\n .action((opts: { category?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const templates = listTemplates(dataDir, opts.category ? { category: opts.category } : {});\n if (templates.length === 0) {\n console.log(info(\"No templates found.\"));\n return;\n }\n for (const t of templates) {\n console.log(` ${bold(t.id)} [${t.category}] ${t.subject}`);\n }\n });\n\ntemplateCommand.command(\"get <id>\").action((id: string) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const tmpl = getTemplate(dataDir, id);\n if (!tmpl) {\n console.error(error(`Template '${id}' not found`));\n process.exit(1);\n }\n console.log(bold(`Subject: ${tmpl.subject}`));\n console.log(`Category: ${tmpl.category} Language: ${tmpl.language}`);\n console.log(`Variables: ${tmpl.variables.join(\", \") || \"(none defined)\"}`);\n console.log(\"\\n\" + tmpl.body);\n});\n\ntemplateCommand\n .command(\"preview <id>\")\n .option(\"--slug <slug>\", \"Customer slug to preview with\")\n .action(async (id: string, opts: { slug?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const tmpl = getTemplate(dataDir, id);\n if (!tmpl) {\n console.error(error(`Template '${id}' not found`));\n process.exit(1);\n }\n const vars = opts.slug ? await buildVariablesFromCustomer(dataDir, opts.slug) : {};\n console.log(bold(`Subject: ${interpolate(tmpl.subject, vars)}`));\n console.log(interpolate(tmpl.body, vars));\n });\n\ntemplateCommand\n .command(\"create <id>\")\n .option(\"--category <category>\", \"Category\", \"general\")\n .option(\"--subject <subject>\", \"Subject line\")\n .action((id: string, opts: { category: string; subject?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const existing = getTemplate(dataDir, id);\n if (existing) {\n console.error(error(`Template '${id}' already exists`));\n process.exit(1);\n }\n const tmpl: EmailTemplate = {\n id,\n subject: opts.subject ?? `Subject for ${id}`,\n category: opts.category,\n variables: [],\n language: \"de\",\n createdAt: new Date().toISOString(),\n body: `Hi {{firstName}},\\n\\n[your message here]\\n\\nBest regards,\\n{{senderName}}`,\n };\n writeTemplate(dataDir, tmpl);\n console.log(success(`✓ Template '${id}' created in category '${opts.category}'`));\n });\n\ntemplateCommand.command(\"delete <id>\").action((id: string) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const deleted = deleteTemplate(dataDir, id);\n if (deleted) {\n console.log(success(`✓ Template '${id}' deleted`));\n } else {\n console.error(error(`Template '${id}' not found`));\n process.exit(1);\n }\n});\n","import { Command } from \"commander\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport {\n listSequences,\n getSequence,\n writeSequence,\n readEnrollments,\n writeEnrollment,\n} from \"../fs/sequence-store.js\";\nimport { runSequenceCycle } from \"../core/sequence-engine.js\";\nimport type { Sequence } from \"../schemas/sequence.js\";\n\nexport const sequenceCommand = new Command(\"sequence\").description(\"Manage email sequences\");\n\nsequenceCommand\n .command(\"list\")\n .description(\"List all sequences\")\n .action(() => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const sequences = listSequences(dataDir);\n const enrollments = readEnrollments(dataDir);\n\n if (sequences.length === 0) {\n console.log(info(\"No sequences found.\"));\n return;\n }\n\n for (const seq of sequences) {\n const count = enrollments.filter((e) => e.sequenceId === seq.id).length;\n console.log(` ${bold(seq.id)} \"${seq.name}\" ${seq.steps.length} steps ${count} enrolled`);\n }\n });\n\nsequenceCommand\n .command(\"create <id>\")\n .description(\"Create a new sequence skeleton\")\n .option(\"--name <name>\", \"Sequence display name\")\n .action((id: string, opts: { name?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n\n const existing = getSequence(dataDir, id);\n if (existing) {\n console.error(error(`Sequence '${id}' already exists`));\n process.exit(1);\n }\n\n const seq: Sequence = {\n id,\n name: opts.name ?? id,\n steps: [\n { day: 0, templateId: \"intro\", skipIfReplied: true },\n { day: 3, templateId: \"followup-1\", skipIfReplied: true },\n { day: 7, templateId: \"followup-2\", skipIfReplied: true },\n ],\n createdAt: new Date().toISOString(),\n };\n\n writeSequence(dataDir, seq);\n console.log(success(`✓ Sequence '${id}' created with ${seq.steps.length} steps`));\n console.log(info(`Edit .agentic/sequences/${id}.yaml to customize steps and templates`));\n });\n\nsequenceCommand\n .command(\"enroll <slug>\")\n .description(\"Enroll a customer contact in a sequence\")\n .requiredOption(\"--email <email>\", \"Contact email address\")\n .requiredOption(\"--sequence <id>\", \"Sequence ID\")\n .action(async (slug: string, opts: { email: string; sequence: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n\n const seq = getSequence(dataDir, opts.sequence);\n if (!seq) {\n console.error(error(`Sequence '${opts.sequence}' not found`));\n process.exit(1);\n }\n\n const enrollmentId = `enroll_${Date.now()}_${Math.random().toString(16).slice(2, 8)}`;\n const now = new Date().toISOString();\n\n await writeEnrollment(dataDir, {\n id: enrollmentId,\n sequenceId: opts.sequence,\n slug,\n contactEmail: opts.email,\n enrolledAt: now,\n status: \"active\",\n currentStep: 0,\n stepsCompleted: [],\n });\n\n console.log(success(`✓ Enrolled ${opts.email} in sequence '${seq.name}'`));\n console.log(info(`Enrollment ID: ${enrollmentId}`));\n });\n\nsequenceCommand\n .command(\"status\")\n .description(\"Show enrollment status\")\n .option(\"--slug <slug>\", \"Filter by customer slug\")\n .action((opts: { slug?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n let enrollments = readEnrollments(dataDir);\n\n if (opts.slug) {\n enrollments = enrollments.filter((e) => e.slug === opts.slug);\n }\n\n if (enrollments.length === 0) {\n console.log(info(\"No enrollments found.\"));\n return;\n }\n\n for (const e of enrollments) {\n const stepInfo = `step ${e.currentStep}`;\n const lastSent = e.lastSentAt ? ` last sent ${e.lastSentAt.slice(0, 10)}` : \"\";\n console.log(\n ` ${bold(e.id)} ${e.slug} <${e.contactEmail}> seq:${e.sequenceId} [${e.status}] ${stepInfo}${lastSent}`\n );\n }\n });\n\nsequenceCommand\n .command(\"run\")\n .description(\"Run the sequence cycle (send due emails)\")\n .option(\"--dry-run\", \"Show what would be sent without sending\")\n .action(async (opts: { dryRun?: boolean }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const today = new Date().toISOString().slice(0, 10);\n\n if (opts.dryRun) {\n const enrollments = readEnrollments(dataDir).filter((e) => e.status === \"active\");\n console.log(info(`Dry run — ${enrollments.length} active enrollments for ${today}`));\n for (const e of enrollments) {\n console.log(` Would process: ${e.id} (${e.contactEmail}, step ${e.currentStep})`);\n }\n return;\n }\n\n const result = await runSequenceCycle(dataDir, today);\n console.log(\n success(\n `✓ Cycle complete: ${result.sent} sent, ${result.completed} completed, ${result.errors.length} errors`\n )\n );\n if (result.errors.length > 0) {\n for (const e of result.errors) {\n console.error(error(` Error: ${e}`));\n }\n }\n });\n","import { Command } from \"commander\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport { generateQuote, listQuotes, readQuote } from \"../core/quote-generator.js\";\n\nexport const quoteCommand = new Command(\"quote\").description(\"Manage customer quotes\");\n\nquoteCommand\n .command(\"generate <slug>\")\n .description(\"Generate a quote for a customer\")\n .requiredOption(\"--deal <name>\", \"Deal name\")\n .option(\n \"--items <items>\",\n 'Line items: \"Description Qty Price,...\" (e.g. \"Consulting 1 5000,Support 12 500\")'\n )\n .option(\"--vat <percent>\", \"VAT percent\", \"19\")\n .option(\"--valid <days>\", \"Valid for N days\", \"30\")\n .action(\n async (slug: string, opts: { deal: string; items?: string; vat: string; valid: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n\n const lineItems = (opts.items ?? \"Service 1 1000\")\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean)\n .map((item) => {\n const parts = item.split(/\\s+/);\n const unitPrice = parseFloat(parts[parts.length - 1] ?? \"0\");\n const quantity = parseFloat(parts[parts.length - 2] ?? \"1\");\n const description = parts.slice(0, -2).join(\" \") || item;\n return { description, quantity, unitPrice };\n });\n\n try {\n const quote = await generateQuote(dataDir, {\n slug,\n dealName: opts.deal,\n lineItems,\n vatPercent: parseFloat(opts.vat),\n validUntilDays: parseInt(opts.valid, 10),\n });\n console.log(success(`✓ Quote ${bold(quote.quoteNumber)} generated`));\n console.log(info(` Total: ${quote.total.toFixed(2)} ${quote.currency}`));\n console.log(info(` Valid until: ${quote.validUntil}`));\n console.log(info(` HTML: ${quote.htmlPath}`));\n } catch (err) {\n console.error(error(`Failed to generate quote: ${(err as Error).message}`));\n process.exit(1);\n }\n }\n );\n\nquoteCommand\n .command(\"list\")\n .description(\"List quotes\")\n .option(\"--slug <slug>\", \"Filter by customer slug\")\n .action((opts: { slug?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const quotes = listQuotes(dataDir, opts.slug);\n\n if (quotes.length === 0) {\n console.log(info(\"No quotes found.\"));\n return;\n }\n\n for (const q of quotes) {\n console.log(\n ` ${bold(q.quoteNumber)} ${q.slug} ${q.dealName} ${q.total.toFixed(2)} ${q.currency} [${q.status}] ${q.validUntil}`\n );\n }\n });\n\nquoteCommand\n .command(\"get <quoteNumber>\")\n .description(\"Show quote details\")\n .action((quoteNumber: string) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const quote = readQuote(dataDir, quoteNumber);\n\n if (!quote) {\n console.error(error(`Quote '${quoteNumber}' not found`));\n process.exit(1);\n }\n\n console.log(bold(`Quote: ${quote.quoteNumber}`));\n console.log(`Customer: ${quote.slug} Deal: ${quote.dealName}`);\n console.log(`Status: ${quote.status} Valid until: ${quote.validUntil}`);\n console.log(\n `Subtotal: ${quote.subtotal.toFixed(2)} VAT: ${quote.vat.toFixed(2)} Total: ${quote.total.toFixed(2)} ${quote.currency}`\n );\n for (const item of quote.lineItems) {\n console.log(` - ${item.description}: ${item.quantity} × ${item.unitPrice} = ${item.total}`);\n }\n });\n","import { Command } from \"commander\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport { readTickets, listAllTickets, nextTicketId, upsertTicket } from \"../fs/ticket-writer.js\";\nimport { calcSlaDue, loadSlaRules } from \"../core/sla-engine.js\";\nimport type { Ticket } from \"../schemas/ticket.js\";\n\nexport const ticketCommand = new Command(\"ticket\").description(\"Manage support tickets\");\n\nticketCommand\n .command(\"list\")\n .description(\"List tickets\")\n .option(\"--slug <slug>\", \"Filter by customer slug\")\n .option(\"--status <status>\", \"Filter by status\")\n .option(\"--priority <priority>\", \"Filter by priority\")\n .action(async (opts: { slug?: string; status?: string; priority?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const tickets = await listAllTickets(dataDir, {\n ...(opts.slug ? { slug: opts.slug } : {}),\n ...(opts.status ? { status: opts.status } : {}),\n ...(opts.priority ? { priority: opts.priority } : {}),\n });\n\n if (tickets.length === 0) {\n console.log(info(\"No tickets found.\"));\n return;\n }\n\n for (const { slug, ticket: t } of tickets) {\n const breach =\n t.slaDue &&\n t.slaDue < new Date().toISOString().slice(0, 10) &&\n t.status !== \"resolved\" &&\n t.status !== \"closed\";\n const flag = breach ? \" ⚠ SLA\" : \"\";\n console.log(\n ` ${bold(t.id)} [${slug}] ${t.title} [${t.status}/${t.priority}]${t.assignee ? ` @${t.assignee}` : \"\"}${flag}`\n );\n }\n });\n\nticketCommand\n .command(\"create <slug>\")\n .description(\"Create a ticket for a customer\")\n .requiredOption(\"--title <title>\", \"Ticket title\")\n .option(\"--description <desc>\", \"Description\")\n .option(\"--priority <priority>\", \"Priority: urgent|high|normal|low\", \"normal\")\n .option(\"--assignee <name>\", \"Assignee\")\n .action(\n async (\n slug: string,\n opts: { title: string; description?: string; priority: string; assignee?: string }\n ) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const today = new Date().toISOString().slice(0, 10);\n const rules = loadSlaRules(dataDir);\n const priority = (opts.priority as Ticket[\"priority\"]) ?? \"normal\";\n const existing = await readTickets(dataDir, slug);\n const id = nextTicketId(existing);\n\n const ticket: Ticket = {\n id,\n title: opts.title,\n status: \"open\",\n priority,\n ...(opts.assignee ? { assignee: opts.assignee } : {}),\n created: today,\n slaDue: calcSlaDue(today, priority, rules),\n ...(opts.description ? { description: opts.description } : {}),\n };\n\n await upsertTicket(dataDir, slug, ticket);\n console.log(success(`✓ Ticket ${bold(id)} created for ${slug}`));\n console.log(info(` SLA due: ${ticket.slaDue}`));\n }\n );\n\nticketCommand\n .command(\"update <ticketId>\")\n .description(\"Update a ticket\")\n .requiredOption(\"--slug <slug>\", \"Customer slug\")\n .option(\"--status <status>\", \"New status\")\n .option(\"--assignee <name>\", \"New assignee\")\n .action(async (ticketId: string, opts: { slug: string; status?: string; assignee?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const tickets = await readTickets(dataDir, opts.slug);\n const ticket = tickets.find((t) => t.id === ticketId);\n\n if (!ticket) {\n console.error(error(`Ticket '${ticketId}' not found`));\n process.exit(1);\n }\n\n const today = new Date().toISOString().slice(0, 10);\n const updated: Ticket = {\n ...ticket,\n ...(opts.status ? { status: opts.status as Ticket[\"status\"] } : {}),\n ...(opts.assignee !== undefined ? { assignee: opts.assignee } : {}),\n ...(opts.status === \"resolved\" && !ticket.resolved ? { resolved: today } : {}),\n };\n\n await upsertTicket(dataDir, opts.slug, updated);\n console.log(success(`✓ Ticket ${bold(ticketId)} updated`));\n });\n\nticketCommand\n .command(\"close <ticketId>\")\n .description(\"Close a ticket\")\n .requiredOption(\"--slug <slug>\", \"Customer slug\")\n .option(\"--resolution <text>\", \"Resolution notes\")\n .action(async (ticketId: string, opts: { slug: string; resolution?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const tickets = await readTickets(dataDir, opts.slug);\n const ticket = tickets.find((t) => t.id === ticketId);\n\n if (!ticket) {\n console.error(error(`Ticket '${ticketId}' not found`));\n process.exit(1);\n }\n\n const today = new Date().toISOString().slice(0, 10);\n const updated: Ticket = { ...ticket, status: \"closed\", resolved: ticket.resolved ?? today };\n await upsertTicket(dataDir, opts.slug, updated);\n console.log(success(`✓ Ticket ${bold(ticketId)} closed`));\n });\n","import { Command } from \"commander\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport {\n getSurvey,\n writeSurvey,\n listSurveys,\n loadSurveyResponses,\n calcNpsScore,\n generateSurveyToken,\n savePendingSurvey,\n} from \"../core/survey-engine.js\";\nimport type { SurveyDefinition } from \"../schemas/survey.js\";\n\nexport const surveyCommand = new Command(\"survey\").description(\"Manage NPS/CSAT surveys\");\n\nsurveyCommand\n .command(\"list\")\n .description(\"List all survey definitions\")\n .action(() => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const surveys = listSurveys(dataDir);\n if (surveys.length === 0) {\n console.log(info(\"No surveys found.\"));\n return;\n }\n for (const s of surveys) {\n console.log(` ${bold(s.id)} [${s.type}] ${s.question.slice(0, 60)}`);\n }\n });\n\nsurveyCommand\n .command(\"create <id>\")\n .description(\"Create a new survey definition\")\n .option(\"--type <type>\", \"Survey type: nps|csat|ces\", \"nps\")\n .option(\"--question <q>\", \"Survey question\")\n .action((id: string, opts: { type: string; question?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const survey: SurveyDefinition = {\n id,\n type: (opts.type as SurveyDefinition[\"type\"]) ?? \"nps\",\n question: opts.question ?? \"How likely are you to recommend us? (0–10)\",\n scale: { min: 0, max: 10 },\n includeComment: true,\n commentPrompt: \"What's the main reason for your score?\",\n createdAt: new Date().toISOString(),\n };\n writeSurvey(dataDir, survey);\n console.log(success(`✓ Survey '${id}' created`));\n });\n\nsurveyCommand\n .command(\"send <surveyId>\")\n .description(\"Generate survey token for a contact\")\n .requiredOption(\"--slug <slug>\", \"Customer slug\")\n .requiredOption(\"--email <email>\", \"Contact email\")\n .option(\n \"--server <url>\",\n \"Server URL\",\n process.env[\"DXCRM_SERVER_URL\"] ?? \"http://localhost:3456\"\n )\n .action(async (surveyId: string, opts: { slug: string; email: string; server: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const survey = getSurvey(dataDir, surveyId);\n if (!survey) {\n console.error(error(`Survey '${surveyId}' not found`));\n process.exit(1);\n }\n const token = generateSurveyToken(opts.slug, opts.email, surveyId);\n await savePendingSurvey(dataDir, surveyId, opts.slug, opts.email, token);\n console.log(success(`✓ Survey token generated`));\n console.log(info(` URL: ${opts.server}/survey/respond?token=${token}`));\n });\n\nsurveyCommand\n .command(\"results <surveyId>\")\n .description(\"Show survey results and NPS score\")\n .option(\"--slug <slug>\", \"Filter by customer slug\")\n .action((surveyId: string, opts: { slug?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const responses = loadSurveyResponses(dataDir, surveyId, opts.slug);\n const nps = calcNpsScore(responses);\n const promoters = responses.filter((r) => r.score >= 9).length;\n const detractors = responses.filter((r) => r.score <= 6).length;\n\n console.log(bold(`Survey: ${surveyId}`));\n console.log(\n info(\n `Responses: ${responses.length} NPS: ${nps} Promoters: ${promoters} Detractors: ${detractors}`\n )\n );\n for (const r of responses) {\n console.log(\n ` ${r.slug} <${r.contactEmail}> score=${r.score}${r.comment ? ` \"${r.comment.slice(0, 80)}\"` : \"\"}`\n );\n }\n });\n","import { Command } from \"commander\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport {\n listKbArticles,\n getKbArticle,\n writeKbArticle,\n deleteKbArticle,\n searchKbSimple,\n} from \"../fs/knowledge-base.js\";\nimport type { KbArticle } from \"../schemas/kb-article.js\";\n\nexport const kbCommand = new Command(\"kb\").description(\"Manage the knowledge base\");\n\nkbCommand\n .command(\"list\")\n .description(\"List all KB articles\")\n .option(\"--category <cat>\", \"Filter by category\")\n .option(\"--public\", \"Show only public articles\")\n .action((opts: { category?: string; public?: boolean }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const articles = listKbArticles(dataDir, {\n ...(opts.category ? { category: opts.category } : {}),\n ...(opts.public ? { publicOnly: true } : {}),\n });\n if (articles.length === 0) {\n console.log(info(\"No articles found.\"));\n return;\n }\n for (const a of articles) {\n const pub = a.public ? \" [public]\" : \"\";\n console.log(` ${bold(a.id)} [${a.category}] ${a.title}${pub}`);\n }\n });\n\nkbCommand\n .command(\"get <id>\")\n .description(\"Get a KB article\")\n .action((id: string) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const article = getKbArticle(dataDir, id);\n if (!article) {\n console.error(error(`Article '${id}' not found`));\n process.exit(1);\n }\n console.log(bold(article.title));\n console.log(`Category: ${article.category} Tags: ${article.tags.join(\", \") || \"(none)\"}`);\n console.log(\"\\n\" + article.body);\n });\n\nkbCommand\n .command(\"search <query>\")\n .description(\"Search KB articles\")\n .option(\"--public\", \"Search only public articles\")\n .action((query: string, opts: { public?: boolean }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const results = searchKbSimple(dataDir, query, opts.public ? { publicOnly: true } : {});\n if (results.length === 0) {\n console.log(info(\"No results.\"));\n return;\n }\n for (const a of results) {\n console.log(` ${bold(a.id)} ${a.title}`);\n console.log(` ${a.body.slice(0, 120).replace(/\\n/g, \" \")}...`);\n }\n });\n\nkbCommand\n .command(\"create <id>\")\n .description(\"Create a KB article (opens editor-ready template)\")\n .requiredOption(\"--title <title>\", \"Article title\")\n .option(\"--category <cat>\", \"Category\", \"general\")\n .option(\"--ticket <id>\", \"Source ticket ID\")\n .action((id: string, opts: { title: string; category: string; ticket?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const now = new Date().toISOString();\n const article: KbArticle = {\n id,\n title: opts.title,\n category: opts.category,\n tags: [],\n public: false,\n createdAt: now,\n updatedAt: now,\n ...(opts.ticket ? { sourceTicketId: opts.ticket } : {}),\n body: `## Problem\\n\\n[Describe the problem]\\n\\n## Solution\\n\\n[Describe the solution]`,\n };\n writeKbArticle(dataDir, article);\n console.log(success(`✓ Article '${id}' created in category '${opts.category}'`));\n console.log(info(`Edit: .agentic/knowledge-base/${opts.category}/${id}.md`));\n });\n\nkbCommand\n .command(\"delete <id>\")\n .description(\"Delete a KB article\")\n .action((id: string) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n if (deleteKbArticle(dataDir, id)) {\n console.log(success(`✓ Article '${id}' deleted`));\n } else {\n console.error(error(`Article '${id}' not found`));\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { info, success, error } from \"../ui/colors.js\";\nimport type { CustomFieldType, FieldDefinition } from \"../core/custom-fields.js\";\n\nconst VALID_TYPES = [\"text\", \"number\", \"boolean\", \"date\", \"select\"];\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nfunction collect(value: string, prev: string[]): string[] {\n return [...prev, value];\n}\n\n/** Parse a `--field name:type[:opt1|opt2]` spec into a FieldDefinition. */\nfunction parseFieldSpec(spec: string): FieldDefinition | null {\n const [name, type, opts] = spec.split(\":\");\n if (!name || !type || !VALID_TYPES.includes(type)) return null;\n return {\n name,\n type: type as CustomFieldType,\n ...(opts ? { options: opts.split(\"|\").map((s) => s.trim()) } : {}),\n };\n}\n\nexport const fieldsCommand = new Command(\"fields\").description(\n \"Manage custom fields (metadata-driven extensibility)\"\n);\n\nfieldsCommand\n .command(\"list\")\n .description(\"List defined custom fields\")\n .action(async () => {\n const { loadFieldDefinitions } = await import(\"../core/custom-fields.js\");\n const defs = loadFieldDefinitions(dataDir());\n if (defs.length === 0) {\n console.log(info(\"No custom fields defined. Add one with: dxcrm fields add <name> <type>\"));\n return;\n }\n for (const d of defs) {\n const opts = d.options ? ` [${d.options.join(\", \")}]` : \"\";\n console.log(`${d.name} (${d.type})${opts}${d.label ? ` — ${d.label}` : \"\"}`);\n }\n });\n\nfieldsCommand\n .command(\"add <name> <type>\")\n .description(\"Define a custom field (type: text|number|boolean|date|select)\")\n .option(\"--label <label>\", \"Human-readable label\")\n .option(\"--options <csv>\", \"Comma-separated options (for select)\")\n .action(async (name: string, type: string, opts: { label?: string; options?: string }) => {\n if (!VALID_TYPES.includes(type)) {\n console.error(error(`Invalid type '${type}'. Use one of: ${VALID_TYPES.join(\", \")}`));\n process.exitCode = 1;\n return;\n }\n const { defineCustomField } = await import(\"../core/custom-fields.js\");\n defineCustomField(dataDir(), {\n name,\n type: type as CustomFieldType,\n ...(opts.label ? { label: opts.label } : {}),\n ...(opts.options ? { options: opts.options.split(\",\").map((s) => s.trim()) } : {}),\n });\n console.log(success(`Custom field '${name}' (${type}) defined.`));\n });\n\nexport const objectCommand = new Command(\"object\").description(\n \"Manage custom objects (runtime-defined entities, no-migration)\"\n);\n\nobjectCommand\n .command(\"define <name>\")\n .description(\"Define a custom object with fields (--field name:type[:opt1|opt2])\")\n .option(\"--label <label>\", \"Human-readable label\")\n .option(\"--field <spec>\", \"Field spec, repeatable\", collect, [] as string[])\n .action(async (name: string, opts: { label?: string; field: string[] }) => {\n const fields: FieldDefinition[] = [];\n for (const spec of opts.field) {\n const f = parseFieldSpec(spec);\n if (!f) {\n console.error(error(`Invalid --field spec '${spec}' (use name:type[:a|b])`));\n process.exitCode = 1;\n return;\n }\n fields.push(f);\n }\n const { defineCustomObject } = await import(\"../core/custom-objects.js\");\n defineCustomObject(dataDir(), { name, ...(opts.label ? { label: opts.label } : {}), fields });\n console.log(success(`Custom object '${name}' defined with ${fields.length} field(s).`));\n });\n\nobjectCommand\n .command(\"add <name>\")\n .description(\"Create a record (--set key=value, repeatable)\")\n .option(\"--set <kv>\", \"key=value, repeatable\", collect, [] as string[])\n .action(async (name: string, opts: { set: string[] }) => {\n const values: Record<string, string> = {};\n for (const kv of opts.set) {\n const eq = kv.indexOf(\"=\");\n if (eq < 0) continue;\n values[kv.slice(0, eq).trim()] = kv.slice(eq + 1).trim();\n }\n const { createRecord } = await import(\"../core/custom-objects.js\");\n const res = createRecord(dataDir(), name, values);\n if (!res.ok) {\n console.error(error(`Could not create record: ${(res.errors ?? []).join(\"; \")}`));\n process.exitCode = 1;\n return;\n }\n console.log(success(`Created ${name} record ${res.record!.id}`));\n });\n\nobjectCommand\n .command(\"list <name>\")\n .description(\"List records of a custom object\")\n .action(async (name: string) => {\n const { listRecords } = await import(\"../core/custom-objects.js\");\n const records = listRecords(dataDir(), name);\n if (records.length === 0) {\n console.log(info(`No records for '${name}'.`));\n return;\n }\n for (const r of records) console.log(`${r.id} ${JSON.stringify(r.values)}`);\n });\n","import { Command } from \"commander\";\nimport { info, success, error } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const webhookCommand = new Command(\"webhook\").description(\n \"Manage outbound webhooks (event-driven integrations)\"\n);\n\nwebhookCommand\n .command(\"add <url>\")\n .description(\"Subscribe a URL to events (--events record.created,deal.updated or '*')\")\n .option(\"--events <csv>\", \"Comma-separated event patterns\", \"*\")\n .option(\"--secret <secret>\", \"HMAC secret for X-DXCRM-Signature\")\n .action(async (url: string, opts: { events: string; secret?: string }) => {\n const { addWebhook } = await import(\"../core/webhooks.js\");\n const events = opts.events\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n const sub = addWebhook(dataDir(), url, events, opts.secret);\n console.log(success(`Webhook ${sub.id} → ${url} [${events.join(\", \")}]`));\n });\n\nwebhookCommand\n .command(\"list\")\n .description(\"List webhook subscriptions\")\n .action(async () => {\n const { loadWebhooks } = await import(\"../core/webhooks.js\");\n const subs = loadWebhooks(dataDir());\n if (subs.length === 0) {\n console.log(info(\"No webhooks configured.\"));\n return;\n }\n for (const s of subs) console.log(`${s.id} ${s.url} [${s.events.join(\", \")}]`);\n });\n\nwebhookCommand\n .command(\"remove <id>\")\n .description(\"Remove a webhook subscription\")\n .action(async (id: string) => {\n const { removeWebhook } = await import(\"../core/webhooks.js\");\n if (removeWebhook(dataDir(), id)) console.log(success(`Removed ${id}`));\n else {\n console.error(error(`Not found: ${id}`));\n process.exitCode = 1;\n }\n });\n\nwebhookCommand\n .command(\"retry\")\n .description(\"Re-attempt failed webhook deliveries (replay store)\")\n .action(async () => {\n const { retryFailures } = await import(\"../core/webhooks.js\");\n const r = await retryFailures(dataDir());\n console.log(info(`Retried ${r.retried}, still failing ${r.stillFailing}.`));\n });\n","import { Command } from \"commander\";\nimport { info, success, error } from \"../ui/colors.js\";\nimport type { SegmentCriteria } from \"../core/segments.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const segmentCommand = new Command(\"segment\").description(\n \"Manage customer segments (marketing lists)\"\n);\n\nsegmentCommand\n .command(\"define <name>\")\n .description(\"Define a segment by criteria\")\n .option(\"--stage <stage>\", \"relationship_stage (prospect|active|churned|paused)\")\n .option(\"--tags <csv>\", \"Comma-separated tags (all must match)\")\n .option(\"--min-deal-value <n>\", \"Minimum deal value\")\n .option(\"--stale-days <n>\", \"Days since last update (staleness)\")\n .action(\n async (\n name: string,\n opts: { stage?: string; tags?: string; minDealValue?: string; staleDays?: string }\n ) => {\n const criteria: SegmentCriteria = {\n ...(opts.stage ? { stage: opts.stage } : {}),\n ...(opts.tags ? { tags: opts.tags.split(\",\").map((s) => s.trim()) } : {}),\n ...(opts.minDealValue ? { minDealValue: Number(opts.minDealValue) } : {}),\n ...(opts.staleDays ? { staleDays: Number(opts.staleDays) } : {}),\n };\n const { defineSegment } = await import(\"../core/segments.js\");\n defineSegment(dataDir(), name, criteria);\n console.log(success(`Segment '${name}' defined: ${JSON.stringify(criteria)}`));\n }\n );\n\nsegmentCommand\n .command(\"list\")\n .description(\"List defined segments\")\n .action(async () => {\n const { loadSegments } = await import(\"../core/segments.js\");\n const segs = loadSegments(dataDir());\n if (segs.length === 0) {\n console.log(info(\"No segments defined.\"));\n return;\n }\n for (const s of segs) console.log(`${s.name} ${JSON.stringify(s.criteria)}`);\n });\n\nsegmentCommand\n .command(\"members <name>\")\n .description(\"List customers matching a segment\")\n .action(async (name: string) => {\n const { loadSegments, evaluateSegment } = await import(\"../core/segments.js\");\n const seg = loadSegments(dataDir()).find((s) => s.name === name);\n if (!seg) {\n console.error(error(`Segment not found: ${name}`));\n process.exitCode = 1;\n return;\n }\n const members = await evaluateSegment(dataDir(), seg.criteria);\n console.log(info(`${members.length} member(s):`));\n for (const slug of members) console.log(slug);\n });\n","import { Command } from \"commander\";\nimport { info } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const identityCommand = new Command(\"identity\").description(\n \"Identity resolution / deduplication (CDP)\"\n);\n\nidentityCommand\n .command(\"duplicates\")\n .description(\"Find clusters of likely-duplicate customers (by canonical domain)\")\n .action(async () => {\n const { findDuplicateClusters } = await import(\"../core/identity.js\");\n const clusters = await findDuplicateClusters(dataDir());\n if (clusters.length === 0) {\n console.log(info(\"No duplicate clusters found.\"));\n return;\n }\n console.log(info(`${clusters.length} duplicate cluster(s):`));\n for (const c of clusters) console.log(`${c.key}: ${c.slugs.join(\", \")}`);\n });\n","import { Command } from \"commander\";\nimport { info, bold } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const metricsCommand = new Command(\"metrics\")\n .description(\"Command-center metrics from the audit trail\")\n .action(async () => {\n const { computeAuditMetrics } = await import(\"../core/metrics.js\");\n const m = computeAuditMetrics(dataDir());\n console.log(bold(\"Command Center\"));\n console.log(`Total operations: ${m.totalOperations}`);\n console.log(`Customers touched: ${m.customersTouched}`);\n console.log(`Automation rate: ${(m.automationRate * 100).toFixed(0)}%`);\n console.log(info(\"By tool:\"));\n for (const [tool, n] of Object.entries(m.byTool).sort((a, b) => b[1] - a[1])) {\n console.log(` ${tool}: ${n}`);\n }\n console.log(info(\"By actor:\"));\n for (const [actor, n] of Object.entries(m.byActor).sort((a, b) => b[1] - a[1])) {\n console.log(` ${actor}: ${n}`);\n }\n });\n","import { Command } from \"commander\";\nimport { info, bold } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const usageCommand = new Command(\"usage\")\n .description(\"LLM token usage & cost (per customer)\")\n .option(\"--slug <slug>\", \"Filter by customer\")\n .action(async (opts: { slug?: string }) => {\n const { aggregateUsage } = await import(\"../core/usage.js\");\n const agg = aggregateUsage(dataDir(), opts.slug ? { slug: opts.slug } : {});\n console.log(bold(\"LLM Usage\"));\n console.log(`Calls: ${agg.calls}`);\n console.log(`Input tokens: ${agg.totalInputTokens}`);\n console.log(`Output tokens: ${agg.totalOutputTokens}`);\n console.log(`Cost (USD): $${agg.totalCostUsd.toFixed(4)}`);\n if (!opts.slug) {\n console.log(info(\"By customer:\"));\n for (const [slug, b] of Object.entries(agg.bySlug).sort(\n (a, b) => b[1].costUsd - a[1].costUsd\n )) {\n console.log(` ${slug}: $${b.costUsd.toFixed(4)} (${b.calls} calls)`);\n }\n }\n });\n","import { Command } from \"commander\";\nimport { info, success, error } from \"../ui/colors.js\";\nimport type { Policy } from \"../core/approvals.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const approvalsCommand = new Command(\"approvals\").description(\n \"Human-in-the-loop approval queue\"\n);\n\napprovalsCommand\n .command(\"list\")\n .description(\"List approvals (default: pending)\")\n .option(\"--status <status>\", \"pending | approved | rejected\", \"pending\")\n .action(async (opts: { status: string }) => {\n const { listApprovals } = await import(\"../core/approvals.js\");\n const list = listApprovals(dataDir(), opts.status as \"pending\" | \"approved\" | \"rejected\");\n if (list.length === 0) {\n console.log(info(`No ${opts.status} approvals.`));\n return;\n }\n for (const a of list) console.log(`${a.id} ${a.tool} ${a.slug ?? \"-\"} ${a.requestedAt}`);\n });\n\napprovalsCommand\n .command(\"approve <id>\")\n .description(\"Approve a pending action\")\n .action(async (id: string) => {\n const { decideApproval } = await import(\"../core/approvals.js\");\n if (decideApproval(dataDir(), id, \"approved\")) console.log(success(`Approved ${id}`));\n else {\n console.error(error(`Not found: ${id}`));\n process.exitCode = 1;\n }\n });\n\napprovalsCommand\n .command(\"reject <id>\")\n .description(\"Reject a pending action\")\n .action(async (id: string) => {\n const { decideApproval } = await import(\"../core/approvals.js\");\n if (decideApproval(dataDir(), id, \"rejected\")) console.log(success(`Rejected ${id}`));\n else {\n console.error(error(`Not found: ${id}`));\n process.exitCode = 1;\n }\n });\n\nexport const policyCommand = new Command(\"policy\").description(\n \"Autonomy policy per tool/customer (auto|approve|block)\"\n);\n\npolicyCommand\n .command(\"set <tool> <policy>\")\n .description(\"Set autonomy policy for a tool (optionally per --slug)\")\n .option(\"--slug <slug>\", \"Customer slug (per-customer override)\")\n .action(async (tool: string, policy: string, opts: { slug?: string }) => {\n if (![\"auto\", \"approve\", \"block\"].includes(policy)) {\n console.error(error(\"policy must be auto | approve | block\"));\n process.exitCode = 1;\n return;\n }\n const { setPolicy } = await import(\"../core/approvals.js\");\n setPolicy(dataDir(), tool, policy as Policy, opts.slug);\n console.log(success(`Policy ${tool}${opts.slug ? `@${opts.slug}` : \"\"} = ${policy}`));\n });\n","import { Command } from \"commander\";\nimport { info, success } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const hygieneCommand = new Command(\"hygiene\").description(\"Data-quality scanning\");\n\nhygieneCommand\n .command(\"scan\")\n .description(\"Scan customers for data-quality issues (missing/malformed/duplicate)\")\n .action(async () => {\n const { scanHygiene } = await import(\"../core/hygiene.js\");\n const issues = await scanHygiene(dataDir());\n if (issues.length === 0) {\n console.log(success(\"✓ No data-quality issues found.\"));\n return;\n }\n console.log(info(`${issues.length} issue(s):`));\n for (const i of issues) {\n const fix = i.suggestedFix ? ` → fix: ${i.suggestedFix}` : \"\";\n console.log(` [${i.type}] ${i.slug}: ${i.detail}${fix}`);\n }\n });\n","import { Command } from \"commander\";\nimport { info, success } from \"../ui/colors.js\";\nimport type { MemoryType } from \"../core/memory.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\nconst TYPES = [\"fact\", \"preference\", \"learning\", \"instruction\"];\n\nexport const memoryCommand = new Command(\"memory\").description(\n \"Agent memories (per customer + global)\"\n);\n\nmemoryCommand\n .command(\"add <text>\")\n .description(\"Add a memory (global unless --slug given)\")\n .option(\"--type <type>\", \"fact | preference | learning | instruction\", \"fact\")\n .option(\"--slug <slug>\", \"Customer slug (omit for global)\")\n .action(async (text: string, opts: { type: string; slug?: string }) => {\n const type = (TYPES.includes(opts.type) ? opts.type : \"fact\") as MemoryType;\n const { addMemory } = await import(\"../core/memory.js\");\n const m = addMemory(dataDir(), {\n scope: opts.slug ? \"customer\" : \"global\",\n ...(opts.slug ? { slug: opts.slug } : {}),\n type,\n text,\n });\n console.log(success(`Memory ${m.id} stored (${m.scope}${opts.slug ? `:${opts.slug}` : \"\"}).`));\n });\n\nmemoryCommand\n .command(\"list\")\n .description(\"List memories (global + customer if --slug)\")\n .option(\"--slug <slug>\", \"Customer slug\")\n .action(async (opts: { slug?: string }) => {\n const { loadMemories } = await import(\"../core/memory.js\");\n const mems = loadMemories(dataDir(), opts.slug);\n if (mems.length === 0) {\n console.log(info(\"No memories.\"));\n return;\n }\n for (const m of mems) console.log(`[${m.scope}/${m.type}] ${m.text}`);\n });\n\nmemoryCommand\n .command(\"search <query>\")\n .description(\"Search memories by relevance\")\n .option(\"--slug <slug>\", \"Customer slug\")\n .action(async (query: string, opts: { slug?: string }) => {\n const { searchMemory } = await import(\"../core/memory.js\");\n const hits = await searchMemory(dataDir(), query, opts.slug);\n if (hits.length === 0) {\n console.log(info(\"No matching memories.\"));\n return;\n }\n for (const m of hits) console.log(`[${m.scope}/${m.type}] ${m.text}`);\n });\n","import { Command } from \"commander\";\nimport { info, success } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const sopCommand = new Command(\"sop\").description(\n \"Standard Operating Procedures (global / per customer)\"\n);\n\nsopCommand\n .command(\"add <title>\")\n .description(\"Add an SOP (global unless --slug given)\")\n .option(\"--triggers <csv>\", \"Comma-separated trigger keywords\", \"\")\n .option(\"--body <text>\", \"SOP body / steps\", \"\")\n .option(\"--slug <slug>\", \"Customer slug (omit for global)\")\n .action(async (title: string, opts: { triggers: string; body: string; slug?: string }) => {\n const { addSop } = await import(\"../core/sop.js\");\n const triggers = opts.triggers\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n const s = addSop(dataDir(), {\n scope: opts.slug ? \"customer\" : \"global\",\n ...(opts.slug ? { slug: opts.slug } : {}),\n title,\n triggers,\n body: opts.body,\n });\n console.log(success(`SOP ${s.id} added (${s.scope}${opts.slug ? `:${opts.slug}` : \"\"}).`));\n });\n\nsopCommand\n .command(\"list\")\n .description(\"List SOPs (global + customer if --slug)\")\n .option(\"--slug <slug>\", \"Customer slug\")\n .action(async (opts: { slug?: string }) => {\n const { loadSops } = await import(\"../core/sop.js\");\n const sops = loadSops(dataDir(), opts.slug);\n if (sops.length === 0) {\n console.log(info(\"No SOPs.\"));\n return;\n }\n for (const s of sops) console.log(`[${s.scope}] ${s.title} (${s.triggers.join(\", \")})`);\n });\n\nsopCommand\n .command(\"find <query>\")\n .description(\"Find SOPs relevant to a task\")\n .option(\"--slug <slug>\", \"Customer slug\")\n .action(async (query: string, opts: { slug?: string }) => {\n const { findSops } = await import(\"../core/sop.js\");\n const hits = await findSops(dataDir(), query, opts.slug);\n if (hits.length === 0) {\n console.log(info(\"No matching SOPs.\"));\n return;\n }\n for (const s of hits) console.log(`[${s.scope}] ${s.title}`);\n });\n","import { Command } from \"commander\";\nimport { info, success } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const toneCommand = new Command(\"tone\").description(\n \"Customer tonality profiles (per customer + global)\"\n);\n\ntoneCommand\n .command(\"set\")\n .description(\"Set tone profile (global unless --slug given)\")\n .option(\"--formality <v>\", \"formal | casual | friendly\")\n .option(\"--language <v>\", \"Language code, e.g. de | en\")\n .option(\"--do <csv>\", \"Comma-separated phrases to prefer\")\n .option(\"--dont <csv>\", \"Comma-separated phrases to avoid\")\n .option(\"--slug <slug>\", \"Customer slug (omit for global)\")\n .action(\n async (opts: {\n formality?: string;\n language?: string;\n do?: string;\n dont?: string;\n slug?: string;\n }) => {\n const { setTone } = await import(\"../core/tone.js\");\n setTone(\n dataDir(),\n {\n ...(opts.formality ? { formality: opts.formality } : {}),\n ...(opts.language ? { language: opts.language } : {}),\n ...(opts.do ? { dos: opts.do.split(\",\").map((s) => s.trim()) } : {}),\n ...(opts.dont ? { donts: opts.dont.split(\",\").map((s) => s.trim()) } : {}),\n },\n opts.slug\n );\n console.log(\n success(`Tone profile saved (${opts.slug ? `customer:${opts.slug}` : \"global\"}).`)\n );\n }\n );\n\ntoneCommand\n .command(\"show\")\n .description(\"Show the effective tone profile\")\n .option(\"--slug <slug>\", \"Customer slug\")\n .action(async (opts: { slug?: string }) => {\n const { resolveTone, toneInstruction } = await import(\"../core/tone.js\");\n const profile = resolveTone(dataDir(), opts.slug);\n console.log(info(JSON.stringify(profile)));\n console.log(`instruction: ${toneInstruction(profile) || \"(none)\"}`);\n });\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport { info, error } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const autofillCommand = new Command(\"autofill\")\n .description(\"Extract structured CRM fields from a transcript file\")\n .argument(\"<file>\", \"Path to transcript file\")\n .option(\"--slug <slug>\", \"Customer slug (for usage attribution)\")\n .action(async (file: string, opts: { slug?: string }) => {\n if (!fs.existsSync(file)) {\n console.error(error(`File not found: ${file}`));\n process.exitCode = 1;\n return;\n }\n const transcript = fs.readFileSync(file, \"utf-8\") as string;\n const { extractAutofill } = await import(\"../core/autofill.js\");\n const result = await extractAutofill(transcript, opts.slug ? { slug: opts.slug } : {});\n console.log(info(\"Extracted fields (review before applying):\"));\n console.log(JSON.stringify(result, null, 2));\n void dataDir;\n });\n","import { Command } from \"commander\";\nimport { info, bold } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const askCommand = new Command(\"ask\")\n .description(\"Ask your CRM a natural-language question\")\n .argument(\"<question>\", \"The question\")\n .option(\"--slug <slug>\", \"Scope to a customer\")\n .action(async (question: string, opts: { slug?: string }) => {\n const { askCrm } = await import(\"../core/ask.js\");\n const res = await askCrm(dataDir(), question, opts.slug);\n if (res.answer) {\n console.log(bold(\"Answer:\"));\n console.log(res.answer);\n }\n if (res.sources.length === 0) {\n console.log(info(\"No relevant data found.\"));\n return;\n }\n console.log(info(\"Sources:\"));\n res.sources.forEach((s, i) => console.log(` [${i + 1}] ${s.text.slice(0, 120)}`));\n });\n","import { Command } from \"commander\";\nimport { info } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const nbaCommand = new Command(\"nba\")\n .description(\"Next-best-action recommendations for a customer\")\n .argument(\"<slug>\", \"Customer slug\")\n .action(async (slug: string) => {\n const { nextBestAction } = await import(\"../core/nba.js\");\n const actions = await nextBestAction(dataDir(), slug);\n if (actions.length === 0) {\n console.log(info(\"No recommendations.\"));\n return;\n }\n for (const a of actions) console.log(`[${a.priority}] ${a.action} — ${a.reason}`);\n });\n","import { Command } from \"commander\";\nimport { info, success, error } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\n/** Master key from the environment only — never a flag (avoids shell history). */\nfunction masterKey(): string {\n const key = process.env[\"DXCRM_VAULT_KEY\"];\n if (!key) {\n console.error(error(\"DXCRM_VAULT_KEY is not set. Export your vault master key first.\"));\n process.exit(1);\n }\n return key;\n}\n\n/** Run a vault action, turning decryption/IO failures into a clean exit. */\nasync function guard(fn: () => Promise<void> | void): Promise<void> {\n try {\n await fn();\n } catch (e) {\n console.error(error((e as Error).message));\n process.exit(1);\n }\n}\n\nexport const vaultCommand = new Command(\"vault\").description(\n \"Local encrypted credential vault (AES-256-GCM)\"\n);\n\nvaultCommand\n .command(\"set <name> <value>\")\n .description(\"Store (or overwrite) a secret\")\n .action((name: string, value: string) =>\n guard(async () => {\n const { setSecret } = await import(\"../core/vault.js\");\n setSecret(dataDir(), masterKey(), name, value);\n console.log(success(`Secret '${name}' stored.`));\n })\n );\n\nvaultCommand\n .command(\"get <name>\")\n .description(\"Retrieve a secret\")\n .action((name: string) =>\n guard(async () => {\n const { getSecret } = await import(\"../core/vault.js\");\n const value = getSecret(dataDir(), masterKey(), name);\n if (value === undefined) {\n console.log(info(`No secret named '${name}'.`));\n return;\n }\n console.log(value);\n })\n );\n\nvaultCommand\n .command(\"list\")\n .description(\"List secret names (values stay encrypted)\")\n .action(() =>\n guard(async () => {\n const { listSecretKeys } = await import(\"../core/vault.js\");\n const names = listSecretKeys(dataDir(), masterKey());\n if (names.length === 0) {\n console.log(info(\"Vault is empty.\"));\n return;\n }\n for (const n of names.sort()) console.log(n);\n })\n );\n\nvaultCommand\n .command(\"rm <name>\")\n .description(\"Remove a secret\")\n .action((name: string) =>\n guard(async () => {\n const { removeSecret } = await import(\"../core/vault.js\");\n const removed = removeSecret(dataDir(), masterKey(), name);\n console.log(\n removed ? success(`Secret '${name}' removed.`) : info(`No secret named '${name}'.`)\n );\n })\n );\n","import { Command } from \"commander\";\nimport { info, success, warning, error } from \"../ui/colors.js\";\nimport type { ChurnLevel } from \"../core/churn.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nfunction paint(level: ChurnLevel, text: string): string {\n if (level === \"high\") return error(text);\n if (level === \"medium\") return warning(text);\n return success(text);\n}\n\nexport const churnCommand = new Command(\"churn\").description(\n \"Churn early-warning (relationship-health based)\"\n);\n\nchurnCommand\n .command(\"assess <slug>\")\n .description(\"Assess churn risk for one customer\")\n .action(async (slug: string) => {\n const { assessChurn } = await import(\"../core/churn.js\");\n const r = assessChurn(dataDir(), slug);\n console.log(paint(r.level, `${slug}: ${r.level.toUpperCase()} risk (${r.riskScore}/100)`));\n for (const s of r.signals) console.log(` • ${s}`);\n });\n\nchurnCommand\n .command(\"scan\")\n .description(\"Rank all customers by churn risk (highest first)\")\n .action(async () => {\n const { scanChurn } = await import(\"../core/churn.js\");\n const ranked = scanChurn(dataDir());\n if (ranked.length === 0) {\n console.log(info(\"No customers to assess.\"));\n return;\n }\n for (const r of ranked) {\n console.log(\n paint(r.level, `${r.riskScore.toString().padStart(3)} ${r.level.padEnd(6)} ${r.slug}`)\n );\n }\n });\n","import { Command } from \"commander\";\nimport { info, success, warning } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const leadscoreCommand = new Command(\"leadscore\").description(\n \"Predictive lead scoring (logistic regression on won/lost history)\"\n);\n\nleadscoreCommand\n .command(\"train\")\n .description(\"Train the model from won/lost history and persist it\")\n .action(async () => {\n const { buildLeadModel, saveLeadModel } = await import(\"../core/lead-model.js\");\n const model = buildLeadModel(dataDir());\n if (!model.sufficient) {\n console.log(\n warning(\n `Not enough closed history to train (${model.trainedOn} deals, need ≥4 with both outcomes).`\n )\n );\n console.log(info(\"Predictions fall back to the deterministic heuristic until then.\"));\n return;\n }\n saveLeadModel(dataDir(), model);\n console.log(success(`Trained on ${model.trainedOn} closed deals. Model saved.`));\n });\n\nleadscoreCommand\n .command(\"predict <slug>\")\n .description(\"Score a customer's open deals with the trained model\")\n .action(async (slug: string) => {\n const { loadLeadModel, buildLeadModel, predictWin } = await import(\"../core/lead-model.js\");\n const { readPipelineSync } = await import(\"../fs/pipeline-writer.js\");\n const model = loadLeadModel(dataDir()) ?? buildLeadModel(dataDir());\n const open = readPipelineSync(dataDir(), slug).filter(\n (d) => d.stage !== \"won\" && d.stage !== \"lost\"\n );\n if (open.length === 0) {\n console.log(info(`No open deals for ${slug}.`));\n return;\n }\n const source = model.sufficient ? \"model\" : \"heuristic\";\n console.log(info(`Win-probability for ${slug} (${source}):`));\n for (const d of open) {\n const p = Math.round(predictWin(model, d) * 100);\n console.log(` ${String(p).padStart(3)}% ${d.name} (${d.stage})`);\n }\n });\n\nexport default leadscoreCommand;\n","import { Command } from \"commander\";\nimport { info, success } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const enrichCommand = new Command(\"enrich\")\n .description(\"Enrich a customer's facts (offline domain-from-email + plugins)\")\n .argument(\"<slug>\", \"Customer slug\")\n .option(\"--write\", \"Write newly-derived fields back to main_facts.md\")\n .action(async (slug: string, opts: { write?: boolean }) => {\n const { enrichCustomer } = await import(\"../core/enrichment.js\");\n const res = await enrichCustomer(dataDir(), slug, { write: opts.write ?? false });\n const applied = Object.entries(res.applied);\n if (applied.length === 0) {\n console.log(info(`Nothing new to enrich for ${slug}.`));\n return;\n }\n for (const [k, v] of applied) console.log(` ${k}: ${String(v)}`);\n console.log(\n res.written\n ? success(`Applied ${applied.length} field(s) to ${slug}.`)\n : info(`Found ${applied.length} field(s) — re-run with --write to apply.`)\n );\n });\n","import fs from \"fs\";\nimport { Command } from \"commander\";\nimport { info, success } from \"../ui/colors.js\";\n\nexport const coachCommand = new Command(\"coach\")\n .description(\"Conversation-intelligence: analyze a call transcript\")\n .argument(\"<file>\", 'Path to a speaker-labelled transcript (\"Rep: ...\" / \"Customer: ...\")')\n .option(\n \"--rep <labels>\",\n \"Comma-separated speaker labels treated as the rep\",\n \"rep,sales,ae,me,agent\"\n )\n .action(async (file: string, opts: { rep: string }) => {\n if (!fs.existsSync(file)) {\n console.error(`Transcript not found: ${file}`);\n process.exit(1);\n }\n const transcript = fs.readFileSync(file, \"utf-8\") as string;\n const { analyzeConversation } = await import(\"../core/conversation-intel.js\");\n const labels = opts.rep\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n const a = analyzeConversation(transcript, labels);\n\n console.log(success(`Conversation analysis (${a.turns} turns)`));\n console.log(` Talk ratio (rep): ${Math.round(a.talkRatio * 100)}%`);\n console.log(` Questions asked: ${a.questionsAsked}`);\n console.log(` Longest monologue: ${a.longestMonologue} words`);\n if (a.objections.length > 0) {\n console.log(info(\" Objections:\"));\n for (const o of a.objections) console.log(` • ${o}`);\n }\n console.log(info(\" Coaching:\"));\n for (const c of a.coaching) console.log(` → ${c}`);\n });\n","import { Command } from \"commander\";\nimport { info, success, warning } from \"../ui/colors.js\";\n\nexport const complianceCommand = new Command(\"compliance\").description(\n \"Privacy/compliance posture (AI-Act Art. 50, local-LLM, PII, guardrails)\"\n);\n\ncomplianceCommand\n .command(\"status\", { isDefault: true })\n .description(\"Show the active compliance configuration\")\n .action(async () => {\n const { complianceConfig, aiDisclosure } = await import(\"../core/compliance.js\");\n const cfg = complianceConfig();\n const onOff = (b: boolean): string => (b ? success(\"on\") : warning(\"off\"));\n\n console.log(info(\"Compliance posture\"));\n console.log(` LLM provider: ${cfg.provider}`);\n if (cfg.local) {\n console.log(` Local endpoint: ${cfg.local.baseUrl}`);\n console.log(` Local model: ${cfg.local.model}`);\n console.log(success(\" → Customer data stays on-machine (data-residency moat).\"));\n }\n console.log(` AI-Act Art.50 label: ${onOff(cfg.aiDisclosure)}`);\n console.log(` PII masking: ${onOff(cfg.piiMasking)}`);\n console.log(` Prompt guardrails: ${onOff(cfg.guardrails)}`);\n if (cfg.aiDisclosure) console.log(info(` Disclosure: \"${aiDisclosure()}\"`));\n });\n","// Single source of truth for the dxcrm command set.\n// Both the CLI entrypoint (src/cli.ts) and the docs generator\n// (scripts/generate-docs.ts) consume this array, so the published\n// CLI reference can never drift from the commands that actually ship.\nimport type { Command } from \"commander\";\nimport { createCommand } from \"./create.js\";\nimport { listCommand } from \"./list.js\";\nimport { validateCommand } from \"./validate.js\";\nimport { sessionCommand } from \"./session.js\";\nimport { guideCommand, mcpCommand } from \"./guide.js\";\nimport { initCommand } from \"./init.js\";\nimport { syncCommand } from \"./sync.js\";\nimport { backupCommand, restoreCommand } from \"./backup.js\";\nimport { daemonCommand } from \"./daemon.js\";\nimport { statusCommand } from \"./status.js\";\nimport { agentCommand } from \"./agent.js\";\nimport { importCommand } from \"./import.js\";\nimport { serverCommand } from \"./server.js\";\nimport { auditCommand } from \"./audit.js\";\nimport { logsCommand } from \"./logs.js\";\nimport { doctorCommand } from \"./doctor.js\";\nimport { rbacCommand } from \"./rbac.js\";\nimport { gdprCommand } from \"./gdpr.js\";\nimport { securityReportCommand } from \"./security-report.js\";\nimport { stagesCommand } from \"./pipeline-stages.js\";\nimport { pluginCommand } from \"./plugin.js\";\nimport { goalCommand } from \"./goal.js\";\nimport { pushCommand } from \"./push.js\";\nimport { attachCommand } from \"./attach.js\";\nimport { templateCommand } from \"./template.js\";\nimport { sequenceCommand } from \"./sequence.js\";\nimport { quoteCommand } from \"./quote.js\";\nimport { ticketCommand } from \"./ticket.js\";\nimport { surveyCommand } from \"./survey.js\";\nimport { kbCommand } from \"./kb.js\";\nimport { fieldsCommand, objectCommand } from \"./fields.js\";\nimport { webhookCommand } from \"./webhook.js\";\nimport { segmentCommand } from \"./segment.js\";\nimport { identityCommand } from \"./identity.js\";\nimport { metricsCommand } from \"./metrics.js\";\nimport { usageCommand } from \"./usage.js\";\nimport { approvalsCommand, policyCommand } from \"./approvals.js\";\nimport { hygieneCommand } from \"./hygiene.js\";\nimport { memoryCommand } from \"./memory.js\";\nimport { sopCommand } from \"./sop.js\";\nimport { toneCommand } from \"./tone.js\";\nimport { autofillCommand } from \"./autofill.js\";\nimport { askCommand } from \"./ask.js\";\nimport { nbaCommand } from \"./nba.js\";\nimport { vaultCommand } from \"./vault.js\";\nimport { churnCommand } from \"./churn.js\";\nimport { leadscoreCommand } from \"./leadscore.js\";\nimport { enrichCommand } from \"./enrich.js\";\nimport { coachCommand } from \"./coach.js\";\nimport { complianceCommand } from \"./compliance.js\";\n\n/** Every top-level `dxcrm` command, in display order. */\nexport const ALL_COMMANDS: readonly Command[] = [\n initCommand,\n createCommand,\n listCommand,\n validateCommand,\n sessionCommand,\n guideCommand,\n mcpCommand,\n syncCommand,\n backupCommand,\n restoreCommand,\n daemonCommand,\n statusCommand,\n agentCommand,\n importCommand,\n serverCommand,\n auditCommand,\n logsCommand,\n doctorCommand,\n rbacCommand,\n gdprCommand,\n securityReportCommand,\n stagesCommand,\n pluginCommand,\n goalCommand,\n pushCommand,\n attachCommand,\n templateCommand,\n sequenceCommand,\n quoteCommand,\n ticketCommand,\n surveyCommand,\n kbCommand,\n fieldsCommand,\n objectCommand,\n webhookCommand,\n segmentCommand,\n identityCommand,\n metricsCommand,\n usageCommand,\n approvalsCommand,\n policyCommand,\n hygieneCommand,\n memoryCommand,\n sopCommand,\n toneCommand,\n autofillCommand,\n askCommand,\n nbaCommand,\n vaultCommand,\n churnCommand,\n leadscoreCommand,\n enrichCommand,\n coachCommand,\n complianceCommand,\n];\n","#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { ALL_COMMANDS } from \"./commands/registry.js\";\n\nconst program = new Command();\nprogram\n .name(\"dxcrm\")\n .description(\"DatasynxOpenCRM — local-first, MCP-native CRM\")\n .version(\"0.1.0\")\n .exitOverride(); // for testability\n\nfor (const command of ALL_COMMANDS) {\n program.addCommand(command);\n}\n\nawait program.parseAsync(process.argv);\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":["HOME","HOME","HOME","HOME","HOME","HOME","HOME","getPidFile","slugify","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir","dataDir"],"sources":["../src/commands/create.ts","../src/ui/table.ts","../src/commands/list.ts","../src/commands/validate.ts","../src/commands/guide.ts","../src/setup/harness-content.ts","../src/setup/adapters/claude-code.ts","../src/setup/adapters/claude-desktop.ts","../src/setup/adapters/codex.ts","../src/setup/adapters/openclaw.ts","../src/setup/adapters/hermes.ts","../src/setup/adapters/antigravity.ts","../src/setup/adapters/cursor.ts","../src/setup/adapters/windsurf.ts","../src/setup/adapters/cline.ts","../src/setup/adapters/grok.ts","../src/setup/framework-registry.ts","../src/commands/init.ts","../src/commands/sync.ts","../src/commands/daemon.ts","../src/commands/status.ts","../src/commands/agent.ts","../src/commands/import.ts","../src/commands/server.ts","../src/commands/audit.ts","../src/commands/logs.ts","../src/commands/doctor.ts","../src/commands/rbac.ts","../src/commands/gdpr.ts","../src/commands/security-report.ts","../src/commands/pipeline-stages.ts","../src/core/plugin-registry.ts","../src/commands/plugin.ts","../src/commands/goal.ts","../src/commands/push.ts","../src/commands/attach.ts","../src/commands/template.ts","../src/commands/sequence.ts","../src/commands/quote.ts","../src/commands/ticket.ts","../src/commands/survey.ts","../src/commands/kb.ts","../src/commands/fields.ts","../src/commands/webhook.ts","../src/commands/segment.ts","../src/commands/identity.ts","../src/commands/metrics.ts","../src/commands/usage.ts","../src/commands/approvals.ts","../src/commands/hygiene.ts","../src/commands/memory.ts","../src/commands/sop.ts","../src/commands/tone.ts","../src/commands/autofill.ts","../src/commands/ask.ts","../src/commands/nba.ts","../src/commands/vault.ts","../src/commands/churn.ts","../src/commands/leadscore.ts","../src/commands/enrich.ts","../src/commands/coach.ts","../src/commands/compliance.ts","../src/commands/mailbox.ts","../src/commands/registry.ts","../src/cli.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport slugify from \"slug\";\nimport { ensureCustomerDir, writeMainFacts } from \"../fs/customer-dir.js\";\nimport { writeFileAtomic } from \"../fs/atomic-write.js\";\nimport { writeJsonFile } from \"../fs/json-store.js\";\nimport { success, error, bold } from \"../ui/colors.js\";\n\nexport async function createCustomer(opts: {\n name: string;\n domain?: string;\n email?: string;\n dataDir?: string;\n}): Promise<{ id: string; dir: string }> {\n const id = slugify(opts.name, { lower: true });\n const dataDir = opts.dataDir ?? process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n await ensureCustomerDir(dataDir, id);\n const dir = path.join(dataDir, \"customers\", id);\n\n // Write main_facts.md\n const today = new Date().toISOString().slice(0, 10);\n await writeMainFacts(dataDir, id, {\n name: opts.name,\n domain: opts.domain,\n email: opts.email,\n relationship_stage: \"prospect\",\n tags: [],\n currency: \"EUR\",\n created: today,\n updated: today,\n });\n\n // Create interactions.md\n const interactionsPath = path.join(dir, \"interactions.md\");\n if (!fs.existsSync(interactionsPath)) {\n writeFileAtomic(interactionsPath, `# Interactions — ${opts.name}\\n\\n`);\n }\n\n // Create pipeline.md\n const pipelinePath = path.join(dir, \"pipeline.md\");\n if (!fs.existsSync(pipelinePath)) {\n writeFileAtomic(\n pipelinePath,\n `# Pipeline — ${opts.name}\\n\\n| Deal | Stage | Value | Currency | Probability | Close Date | Updated | Notes |\\n|---|---|---|---|---|---|---|---|\\n`\n );\n }\n\n // Create sources.json\n const sourcesPath = path.join(dir, \"sources.json\");\n if (!fs.existsSync(sourcesPath)) {\n const gmailQuery = opts.domain\n ? `from:${opts.domain} OR to:${opts.domain}`\n : opts.email\n ? `from:${opts.email} OR to:${opts.email}`\n : \"\";\n const sources = {\n gmail: {\n type: \"gmail\",\n query: gmailQuery,\n enabled: true,\n },\n version: 1,\n created: new Date().toISOString(),\n };\n writeJsonFile(sourcesPath, sources);\n }\n\n return { id, dir };\n}\n\nexport const createCommand = new Command(\"create\")\n .description(\"Create a new customer\")\n .argument(\"<name>\", \"Customer name\")\n .option(\"--domain <domain>\", \"Primary domain (for Gmail sync)\")\n .option(\"--email <email>\", \"Primary contact email\")\n .action(async (name: string, opts: { domain?: string; email?: string }) => {\n try {\n const { id, dir } = await createCustomer({ name, ...opts });\n console.log(success(`✓ Created customer: ${bold(id)}`));\n console.log(` Dir: ${dir}`);\n console.log(` Files: main_facts.md, interactions.md, pipeline.md, sources.json`);\n } catch (err) {\n console.error(error(`✗ ${(err as Error).message}`));\n process.exit(1);\n }\n });\n","import Table from \"cli-table3\";\nimport type { MainFacts } from \"../schemas/main-facts.js\";\nimport type { PipelineDeal } from \"../schemas/pipeline.js\";\n\nexport interface CustomerRow {\n slug: string;\n facts: MainFacts;\n lastTouchpoint?: string;\n}\n\nexport function renderCustomerTable(customers: CustomerRow[]): string {\n const table = new Table({\n head: [\"Slug\", \"Name\", \"Stage\", \"Industry\", \"Tags\", \"Updated\"],\n style: { head: [\"cyan\"] },\n colWidths: [20, 25, 15, 15, 20, 12],\n wordWrap: true,\n });\n\n for (const { slug, facts } of customers) {\n table.push([\n slug,\n facts.name,\n facts.relationship_stage,\n facts.industry ?? \"—\",\n facts.tags.join(\", \") || \"—\",\n facts.updated,\n ]);\n }\n\n return table.toString();\n}\n\nexport function renderPipelineTable(deals: PipelineDeal[]): string {\n const table = new Table({\n head: [\"Name\", \"Stage\", \"Value\", \"Prob%\", \"Close Date\", \"Updated\"],\n style: { head: [\"cyan\"] },\n colWidths: [30, 15, 12, 8, 12, 12],\n wordWrap: true,\n });\n\n for (const deal of deals) {\n const valueStr =\n deal.value !== undefined ? `${deal.value.toLocaleString()} ${deal.currency}` : \"—\";\n const probStr = deal.probability !== undefined ? `${deal.probability}%` : \"—\";\n table.push([deal.name, deal.stage, valueStr, probStr, deal.close_date ?? \"—\", deal.updated]);\n }\n\n return table.toString();\n}\n","import { Command } from \"commander\";\nimport { readMainFacts, listCustomerSlugs } from \"../fs/customer-dir.js\";\nimport { renderCustomerTable } from \"../ui/table.js\";\nimport type { MainFacts } from \"../schemas/main-facts.js\";\n\nexport const listCommand = new Command(\"list\")\n .description(\"List all customers\")\n .option(\"--filter <query>\", \"Filter by name or slug\")\n .action(async (opts: { filter?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const slugs = listCustomerSlugs(dataDir);\n\n if (slugs.length === 0) {\n console.log('No customers yet. Run: dxcrm create \"Customer Name\"');\n return;\n }\n\n const customers: Array<{\n slug: string;\n facts: MainFacts;\n }> = [];\n\n for (const slug of slugs) {\n try {\n const facts = await readMainFacts(dataDir, slug);\n if (opts.filter) {\n const q = opts.filter.toLowerCase();\n if (\n !facts.name.toLowerCase().includes(q) &&\n !slug.includes(q) &&\n !(facts.relationship_stage ?? \"\").toLowerCase().includes(q)\n )\n continue;\n }\n customers.push({ slug, facts });\n } catch {\n /* skip invalid */\n }\n }\n\n if (customers.length === 0) {\n console.log(opts.filter ? `No customers matching \"${opts.filter}\"` : \"No customers yet.\");\n return;\n }\n\n console.log(renderCustomerTable(customers));\n });\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { MainFactsSchema } from \"../schemas/main-facts.js\";\nimport { listCustomerSlugs } from \"../fs/customer-dir.js\";\nimport matter from \"gray-matter\";\nimport { success, error, warning, info } from \"../ui/colors.js\";\n\nconst RECOVERABLE_DEFAULTS: Record<string, unknown> = {\n tags: [],\n currency: \"EUR\",\n};\n\nexport function applyFix(\n factsPath: string,\n content: string,\n data: Record<string, unknown>\n): { fixed: string[]; content: string } | null {\n const fixed: string[] = [];\n const patched = { ...data };\n\n for (const [field, defaultValue] of Object.entries(RECOVERABLE_DEFAULTS)) {\n if (patched[field] === undefined || patched[field] === null) {\n patched[field] = defaultValue;\n fixed.push(`${field} → ${JSON.stringify(defaultValue)}`);\n }\n }\n\n if (patched[\"updated\"] === undefined && patched[\"created\"]) {\n patched[\"updated\"] = patched[\"created\"];\n fixed.push(`updated → ${String(patched[\"created\"])}`);\n }\n\n if (fixed.length === 0) return null;\n\n const parsed = matter(content);\n const newContent = matter.stringify(parsed.content, patched);\n fs.writeFileSync(factsPath, newContent);\n return { fixed, content: newContent };\n}\n\nexport async function runValidate(opts: { fix?: boolean }, dataDir: string): Promise<void> {\n const customersDir = path.join(dataDir, \"customers\");\n\n if (!fs.existsSync(customersDir)) {\n console.log(warning(\"⚠ No customers directory found.\"));\n return;\n }\n\n const slugs = listCustomerSlugs(dataDir);\n\n let errorCount = 0;\n let fixedCount = 0;\n\n for (const slug of slugs) {\n const factsPath = path.join(customersDir, slug, \"main_facts.md\");\n const interactionsPath = path.join(customersDir, slug, \"interactions.md\");\n\n if (!fs.existsSync(factsPath)) {\n console.log(error(`✗ ${slug}: missing main_facts.md`));\n errorCount++;\n continue;\n }\n\n try {\n let content = fs.readFileSync(factsPath, \"utf-8\") as string;\n let parsed = matter(content);\n\n if (opts.fix) {\n const result = applyFix(factsPath, content, parsed.data as Record<string, unknown>);\n if (result) {\n content = result.content;\n parsed = matter(content); // only re-parse when a fix actually rewrote content\n fixedCount++;\n console.log(info(`⚙ ${slug}: fixed ${result.fixed.join(\", \")}`));\n }\n }\n\n MainFactsSchema.parse(parsed.data);\n\n if (!fs.existsSync(interactionsPath)) {\n console.log(warning(`⚠ ${slug}: missing interactions.md`));\n } else {\n console.log(success(`✓ ${slug}`));\n }\n } catch (err) {\n console.log(error(`✗ ${slug}: ${(err as Error).message}`));\n errorCount++;\n }\n }\n\n if (opts.fix && fixedCount > 0) {\n console.log(info(`\\n⚙ Fixed ${fixedCount} customer(s).`));\n }\n\n if (errorCount > 0) {\n console.error(error(`\\n${errorCount} error(s) found.`));\n process.exit(1);\n } else {\n console.log(success(\"\\n✓ All customers valid.\"));\n }\n}\n\nexport const validateCommand = new Command(\"validate\")\n .description(\"Validate all customer data against schemas\")\n .option(\"--fix\", \"Auto-fix recoverable issues\")\n .action(async (opts: { fix?: boolean }) => {\n await runValidate(opts, process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd());\n });\n","import { Command } from \"commander\";\nimport { CAPABILITIES_TEXT } from \"../mcp/capabilities.js\";\nimport { info } from \"../ui/colors.js\";\n\nexport const guideCommand = new Command(\"guide\")\n .description(\"Full CRM documentation in terminal\")\n .action(() => {\n console.log(CAPABILITIES_TEXT);\n });\n\nexport const mcpCommand = new Command(\"mcp\").description(\"MCP server management and documentation\");\n\nmcpCommand.command(\"docs\").action(() => {\n console.log(CAPABILITIES_TEXT);\n});\n\nmcpCommand\n .command(\"token\")\n .description(\"Mint a bearer token for the HTTP MCP server (printed once)\")\n .requiredOption(\"--actor <actor>\", \"Actor/user the token authenticates as\")\n .option(\"--role <role>\", \"RBAC role: admin | manager | rep\", \"rep\")\n .option(\"--label <label>\", \"Optional label (e.g. device name)\")\n .action(async (opts: { actor: string; role: string; label?: string }) => {\n const role = [\"admin\", \"manager\", \"rep\"].includes(opts.role)\n ? (opts.role as \"admin\" | \"manager\" | \"rep\")\n : \"rep\";\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const { createMcpToken } = await import(\"../mcp/auth.js\");\n const token = createMcpToken(dataDir, opts.actor, role, opts.label);\n console.log(info(\"MCP bearer token (store it now — it is not shown again):\"));\n console.log(token);\n console.log(info(`actor=${opts.actor} role=${role} — HTTP /mcp now requires this token.`));\n });\n\nmcpCommand\n .command(\"start\")\n .description(\"Start MCP server (stdio by default)\")\n .option(\"--http\", \"Use HTTP transport instead of stdio\")\n .option(\"--port <port>\", \"HTTP port (default 3847)\", \"3847\")\n .action(async (opts: { http?: boolean; port: string }) => {\n if (opts.http) {\n const port = parseInt(opts.port, 10);\n console.error(info(`Starting MCP server in HTTP mode on port ${port}...`));\n const { startHttp } = await import(\"../mcp/server.js\");\n await startHttp(port);\n } else {\n const { startStdio } = await import(\"../mcp/server.js\");\n await startStdio();\n }\n });\n","// src/setup/harness-content.ts\n// Single Source of Truth for all harness file content — v2 (see TOOL_COUNT below).\n\n// All registered MCP tools — keep in sync with src/mcp/server.ts\nconst ALL_TOOLS = [\n // Core v1\n \"get_capabilities\",\n \"get_active_session\",\n \"get_customer_context\",\n \"search_customer_knowledge\",\n \"list_customers\",\n \"log_interaction\",\n \"update_deal\",\n \"export_customer\",\n \"update_customer_facts\",\n \"get_deal_health\",\n \"get_pipeline_forecast\",\n \"summarize_meeting\",\n \"get_pipeline_stages\",\n \"get_market_intelligence\",\n // Graph & Health (D11/D12)\n \"get_relationship_graph\",\n \"get_relationship_health\",\n // Autonomous Agent (D13)\n \"run_deal_agent\",\n \"approve_agent_action\",\n // Revenue Intelligence (D14/D18)\n \"simulate_revenue\",\n \"get_org_intelligence\",\n // Playbooks (D15)\n \"get_playbook\",\n \"create_playbook\",\n \"list_playbooks\",\n \"distill_playbook\",\n // Goals (D16)\n \"pursue_goal\",\n \"get_goal_status\",\n // Push (D17)\n \"register_push_subscription\",\n \"get_push_status\",\n // Proactive & Deal Room (D19/D20)\n \"open_deal_room\",\n \"get_proactive_briefing\",\n // Email Templates (H2)\n \"list_email_templates\",\n \"get_email_template\",\n \"draft_email\",\n // Email Sequences (H1)\n \"enroll_in_sequence\",\n \"list_sequence_enrollments\",\n \"unenroll_from_sequence\",\n \"list_sequences\",\n // Quote Generator (H4)\n \"generate_quote\",\n \"get_quote_status\",\n // Calendly Scheduler (H3)\n \"get_booking_link\",\n // Ticket Management (H6)\n \"create_ticket\",\n \"update_ticket\",\n \"list_tickets\",\n \"close_ticket\",\n // NPS/CSAT Survey (H7)\n \"send_nps_survey\",\n \"get_survey_results\",\n // Knowledge Base (H8)\n \"search_knowledge_base\",\n \"create_kb_article\",\n // Backup (Enterprise)\n \"backup_now\",\n \"list_backups\",\n // Sync & Audit (Enterprise)\n \"trigger_sync\",\n \"get_audit_log\",\n \"get_logs\",\n \"get_diagnostics\",\n // Metadata / custom objects (Platform)\n \"define_custom_object\",\n \"create_record\",\n \"list_records\",\n \"list_custom_objects\",\n] as const;\n\nexport type McpToolName = (typeof ALL_TOOLS)[number];\nexport { ALL_TOOLS };\nexport const TOOL_COUNT = ALL_TOOLS.length; // 58\n\n/** Claude Code: CLAUDE.md in CRM dataDir */\nexport function buildClaudeMd(dataDir: string): string {\n return `# DatasynxOpenCRM v2 — Agent Instructions (${TOOL_COUNT} MCP Tools)\n\n## Proactive — Act Without Being Asked\nAt the start of every session, before the user says anything:\n1. \\`get_proactive_briefing()\\` — today's urgent items, forecast, top action\n2. \\`get_goal_status()\\` — if active goals exist, show progress\n\n## Before Every Deal Conversation\nUse \\`open_deal_room({ slug, dealName })\\` — not \\`get_customer_context()\\`.\nIt combines graph, health, revenue simulation, playbook, and org intelligence in one call (~3–5s).\n\n## Standard Workflow\n| Trigger | Tool |\n|---|---|\n| Customer mentioned | \\`get_customer_context(slug)\\` or \\`open_deal_room(slug, dealName)\\` |\n| After call/meeting/email | \\`log_interaction(slug, type, summary, nextSteps)\\` |\n| Deal stage changes | \\`update_deal(slug, dealName, { stage, probability, value })\\` |\n| Historical question | \\`search_customer_knowledge(slug, query)\\` |\n| \"What should I do today?\" | \\`get_proactive_briefing()\\` |\n| \"Close €X this quarter\" | \\`pursue_goal(goal, deadline)\\` |\n\n## Autonomy Patterns\n\n**User says \"Look at Acme Corp\":**\n1. \\`open_deal_room({ slug: \"acme-corp\", dealName: \"<active deal>\" })\\`\n2. Summarize in 3 bullets, recommend 1 action\n\n**User says \"What do I need to do today?\":**\n1. \\`get_proactive_briefing()\\`\n2. \\`get_goal_status()\\` if goals are active\n3. Reply with prioritized actions\n\n**User says \"Deal is stalled\":**\n1. \\`run_deal_agent({ slug, dealName, autonomyLevel: \"suggest\" })\\`\n2. Present the plan, ask for approval before acting\n\n## All ${TOOL_COUNT} MCP Tools\n\n### Foundation\n- \\`get_capabilities()\\` — complete tool reference with schemas\n- \\`get_active_session()\\` — which customer is currently open\n- \\`get_customer_context(slug?)\\` — full briefing, triggers background Gmail sync\n- \\`search_customer_knowledge(slug, query)\\` — semantic vector search across emails + transcripts\n- \\`list_customers(filter?)\\` — all customers with health score and last touchpoint\n- \\`log_interaction(slug, type, summary, nextSteps?)\\` — write to CRM; auto-updates graph + health\n- \\`update_deal(slug, dealName, fields)\\` — pipeline stage, value, probability, close date\n- \\`export_customer(slug, format?)\\` — export as JSON or Markdown ZIP\n- \\`update_customer_facts(slug, fields)\\` — name, domain, email, primary_contact, tags\n- \\`get_deal_health(slug)\\` — health score A–F with warnings per deal\n- \\`get_pipeline_forecast()\\` — weighted pipeline total and deal list\n- \\`summarize_meeting(transcript)\\` — LLM meeting analysis → structured notes\n- \\`get_pipeline_stages()\\` — configured stages with default probabilities\n- \\`get_market_intelligence(slug)\\` — competitor mentions and market context\n\n### Graph & Relationship (D11/D12)\n- \\`get_relationship_graph(slug)\\` — stakeholder graph: champions, blockers, economic buyers, warm intro paths\n- \\`get_relationship_health(slug)\\` — contact health scores A–F, decay detection, risk flags\n\n### Autonomous Deal Agent (D13)\n- \\`run_deal_agent({ slug, dealName, autonomyLevel })\\` — AI deal analysis + action plan; autonomyLevel: \"observe\" | \"suggest\" | \"act\"\n- \\`approve_agent_action({ actionId, approved })\\` — approve or reject a queued agent action\n\n### Revenue Intelligence (D14/D18)\n- \\`simulate_revenue({ horizon })\\` — Monte Carlo P10/P50/P90 forecast over full pipeline\n- \\`get_org_intelligence({ slug, dealName })\\` — stakeholder map, missing roles, external signals (funding, news)\n\n### Playbooks (D15)\n- \\`get_playbook({ slug, situation })\\` — matching playbook for current deal situation\n- \\`create_playbook({ name, trigger, content })\\` — save a new playbook\n- \\`list_playbooks()\\` — all available playbooks\n- \\`distill_playbook({ slug, dealName, outcome })\\` — learn from a won/lost deal\n\n### Goals (D16)\n- \\`pursue_goal({ goal, deadline, context? })\\` — decompose a revenue goal into prioritized sub-actions\n- \\`get_goal_status()\\` — progress of all active goals\n\n### Push (D17)\n- \\`register_push_subscription({ provider, webhookUrl })\\` — gmail | microsoft-graph | slack real-time push\n- \\`get_push_status()\\` — active subscriptions and expiry dates\n\n### Intelligence Synthesis (D19/D20)\n- \\`open_deal_room({ slug, dealName })\\` — orchestrates 7 sub-tools; returns complete deal brief in one call\n- \\`get_proactive_briefing({ date? })\\` — AI-generated daily briefing: urgent items, opportunities, forecast\n\n### Email Templates (H2)\n- \\`list_email_templates({ category? })\\` — list templates; filter by category (outreach, followup, support)\n- \\`get_email_template({ id })\\` — get full template with auto-detected variables\n- \\`draft_email({ slug, templateId, overrides? })\\` — draft personalized email from template + customer facts\n\n### Email Sequences (H1)\n- \\`enroll_in_sequence({ slug, contactEmail, sequenceId })\\` — enroll contact in automated email sequence\n- \\`list_sequence_enrollments({ slug?, status? })\\` — list enrollments; filter by slug or status\n- \\`unenroll_from_sequence({ enrollmentId })\\` — pause an active enrollment\n- \\`list_sequences()\\` — all sequences with step count and enrollment count\n\n### Quotes & Invoices (H4)\n- \\`generate_quote({ slug, dealName, lineItems, vatPercent?, validUntilDays? })\\` — create HTML quote with auto-numbering Q-YYYY-NNN\n- \\`get_quote_status({ quoteNumber?, slug? })\\` — get quote or list all quotes for customer\n\n### Meeting Scheduler (H3)\n- \\`get_booking_link({ slug, eventType?, prefillName? })\\` — get Calendly booking URL, optionally pre-filled with customer name/email\n\n### Ticket Management (H6)\n- \\`create_ticket({ slug, title, priority?, assignee? })\\` — open support ticket with auto-SLA due date\n- \\`update_ticket({ slug, ticketId, status?, assignee? })\\` — update ticket status or assignee\n- \\`list_tickets({ slug?, status?, priority?, assignee? })\\` — list tickets sorted by priority\n- \\`close_ticket({ slug, ticketId, resolution? })\\` — close ticket and optionally log resolution\n\n### NPS/CSAT Surveys (H7)\n- \\`send_nps_survey({ slug, contactEmail, surveyId, serverUrl? })\\` — generate survey token and email body for NPS/CSAT survey\n- \\`get_survey_results({ surveyId, slug? })\\` — NPS score, promoters/passives/detractors, all responses\n\n### Knowledge Base (H8)\n- \\`search_knowledge_base({ query, publicOnly? })\\` — full-text search across KB articles\n- \\`create_kb_article({ id, title, body, category?, tags?, public?, sourceTicketId? })\\` — create or update KB article\n\n### Backup (Enterprise)\n- \\`backup_now({ remote?, note? })\\` — trigger immediate backup of customers/ + .agentic/ with manifest + integrity check\n- \\`list_backups({ limit? })\\` — list available backups with date, size, verification status, customer count\n\n### Sync & Audit (Enterprise)\n- \\`trigger_sync({ slug?, since? })\\` — force immediate Gmail sync for one or all customers (bypasses 30-min daemon cycle)\n- \\`get_audit_log({ slug?, actor?, limit? })\\` — read append-only audit log of all write operations\n- \\`get_logs({ level?, component?, since?, contains?, limit?, summary? })\\` — query/aggregate the structured application log\n- \\`get_diagnostics({ fix? })\\` — self-diagnostic health check (data integrity, temp files, log errors, backups)\n\n### Custom Objects (Platform / metadata)\n- \\`define_custom_object({ name, label?, fields })\\` — define a runtime entity type with typed fields (no migration), admin\n- \\`create_record({ object, values })\\` — create a record of a custom object, validated against its schema, rep+\n- \\`list_records({ object })\\` — list records of a custom object\n- \\`list_custom_objects()\\` — list all defined custom objects and their schemas\n\n## Rules\n- Never discuss a customer without first loading their context\n- Always log interactions — calls, emails, Slack, demos, proposals\n- Never invent information — if uncertain, use search_customer_knowledge\n- Use open_deal_room before any deal conversation, not get_customer_context\n\n## Data Directory\n${dataDir}`.trim();\n}\n\n/** OpenClaw / Hermes: SOUL.md */\nexport function buildSoulMd(framework: \"openclaw\" | \"hermes\"): string {\n return `# Identity\nI am a CRM-integrated AI assistant powered by DatasynxOpenCRM v2 (${TOOL_COUNT} MCP tools).\nMy purpose is to help manage customer relationships proactively — acting before being asked.\n\n# Core Behaviors\n- **Proactive first.** At session start I call \\`get_proactive_briefing()\\` without being asked.\n- **Context before action.** Before any customer discussion: \\`open_deal_room()\\` or \\`get_customer_context()\\`.\n- **Log everything.** Every interaction — calls, emails, meetings, Slack — goes into the CRM via \\`log_interaction()\\`.\n- **Cite sources.** All customer information is cited: gmail://, file://, transcript://.\n- **Glass-box reasoning.** When using \\`run_deal_agent()\\`, I surface the trace so the user can inspect my reasoning.\n\n# Tool Hierarchy\n1. \\`open_deal_room()\\` — for deal conversations (combines 7 sub-tools)\n2. \\`get_proactive_briefing()\\` — for morning / session start\n3. \\`get_customer_context()\\` — for general customer questions\n4. \\`run_deal_agent()\\` — when a deal needs AI-driven analysis\n\n# Boundaries\n- I do not invent customer data. I search or sync first.\n- I do not skip logging — even quick Slack messages deserve a \\`log_interaction()\\`.\n- I do not act autonomously beyond \"suggest\" level without explicit human approval via \\`approve_agent_action()\\`.\n- I do not discuss a customer without context loaded.\n\n# Communication\nDirect. Action-oriented. Lead with the most important insight.\nBullet points for next steps. End every deal summary with: \"What do you want to do first?\"\n\n# Framework\n${framework === \"openclaw\" ? \"OpenClaw — tool prefix: datasynx_opencrm:\" : \"Hermes — skill: datasynx-crm\"}`.trim();\n}\n\n/** Hermes SOUL.md is same as OpenClaw */\nexport const buildHermesSoulMd = buildSoulMd;\n\n/** Codex / OpenClaw / Antigravity: AGENTS.md in dataDir */\nexport function buildAgentsMd(dataDir: string): string {\n return `# DatasynxOpenCRM v2 — Agent Instructions (${TOOL_COUNT} MCP Tools)\n\n## Role\nYou are a proactive CRM AI assistant. You act before being asked.\nAt every session start: call \\`get_proactive_briefing()\\`.\n\n## Priority Tool Order\n1. \\`open_deal_room(slug, dealName)\\` — before any deal conversation\n2. \\`get_proactive_briefing()\\` — at session start, or when asked \"what should I do?\"\n3. \\`get_customer_context(slug)\\` — for general customer questions\n4. \\`run_deal_agent(slug, dealName, \"suggest\")\\` — when a deal is stalled\n\n## Core Workflow\n- Customer mentioned → \\`get_customer_context(slug)\\` immediately\n- Deal conversation → \\`open_deal_room(slug, dealName)\\` first\n- After interaction → \\`log_interaction(slug, type, summary, nextSteps)\\`\n- Deal stage change → \\`update_deal(slug, dealName, { stage, probability })\\`\n- Revenue goal → \\`pursue_goal(goal, deadline)\\`\n\n## Available Tools (${TOOL_COUNT})\n**Foundation:** get_capabilities · get_active_session · get_customer_context ·\nsearch_customer_knowledge · list_customers · log_interaction · update_deal ·\nexport_customer · update_customer_facts · get_deal_health · get_pipeline_forecast ·\nsummarize_meeting · get_pipeline_stages · get_market_intelligence\n\n**Graph & Health (D11/D12):** get_relationship_graph · get_relationship_health\n\n**Autonomous Agent (D13):** run_deal_agent · approve_agent_action\n\n**Revenue (D14/D18):** simulate_revenue · get_org_intelligence\n\n**Playbooks (D15):** get_playbook · create_playbook · list_playbooks · distill_playbook\n\n**Goals (D16):** pursue_goal · get_goal_status\n\n**Push (D17):** register_push_subscription · get_push_status\n\n**Synthesis (D19/D20):** open_deal_room · get_proactive_briefing\n\n**Email Templates (H2):** list_email_templates · get_email_template · draft_email\n\n**Email Sequences (H1):** enroll_in_sequence · list_sequence_enrollments · unenroll_from_sequence · list_sequences\n\n**Quotes (H4):** generate_quote · get_quote_status\n\n**Calendly (H3):** get_booking_link\n\n**Tickets (H6):** create_ticket · update_ticket · list_tickets · close_ticket\n\n**NPS/CSAT (H7):** send_nps_survey · get_survey_results\n\n**Knowledge Base (H8):** search_knowledge_base · create_kb_article\n\n**Backup (Enterprise):** backup_now · list_backups\n\n**Sync & Audit (Enterprise):** trigger_sync · get_audit_log · get_logs\n\n**Custom Objects (Platform):** define_custom_object · create_record · list_records · list_custom_objects\n\n## Never\n- Discuss a customer without context loaded\n- Skip logging — every touchpoint matters\n- Invent information — use search_customer_knowledge first\n- Act autonomously beyond \"suggest\" without approve_agent_action\n\n## Data Location\n${dataDir}`.trim();\n}\n\n/** Hermes skills file (agentskills.io standard) */\nexport function buildHermesSkillMd(): string {\n return `---\nname: datasynx-crm\nversion: 2.0.0\ndescription: Proactive CRM workflow skill for DatasynxOpenCRM v2 (${TOOL_COUNT} MCP tools)\ntriggers:\n - \"customer\"\n - \"client\"\n - \"deal\"\n - \"pipeline\"\n - \"sync\"\n - \"briefing\"\n - \"forecast\"\n - \"goal\"\n - \"stakeholder\"\n - \"playbook\"\n---\n\n# DatasynxOpenCRM v2 Skill\n\n## Session Start — Always\nCall \\`get_proactive_briefing()\\` at the start of every session without being asked.\n\n## Before a Deal Conversation\nCall \\`open_deal_room({ slug, dealName })\\` — returns graph, health, simulation, and playbook in one call.\n\n## When a Customer Is Mentioned\nCall \\`get_customer_context(slug)\\` before discussing anything.\nNever assume you know the current state.\n\n## After Every Interaction\nCall \\`log_interaction()\\` with:\n- type: Call | Meeting | Email | Note | Demo | Proposal\n- summary: 2–5 sentences\n- nextSteps: concrete actions as array\n\n## For a Stalled Deal\n\\`run_deal_agent({ slug, dealName, autonomyLevel: \"suggest\" })\\`\nThen use \\`approve_agent_action()\\` to confirm before acting.\n\n## For Revenue Goals\n\\`pursue_goal({ goal: \"Close €500k this quarter\", deadline: \"2026-09-30\" })\\`\n\n## For Historical Research\n\\`search_customer_knowledge(slug, query)\\` — searches emails AND transcripts.\n\n## Pipeline Updates\nAfter any deal discussion: \\`update_deal(slug, dealName, { stage, probability, value })\\`\n\n## Quick Reference\n\\`list_customers()\\` for overview · \\`get_capabilities()\\` for full schema`.trim();\n}\n\n/** Antigravity SKILL.md */\nexport function buildAgySkillMd(): string {\n return `---\nname: datasynx-crm\nversion: 2.0.0\ndescription: Proactive CRM workflow for DatasynxOpenCRM v2\ntriggers:\n - customer\n - client\n - deal\n - pipeline\n - briefing\n - forecast\n - goal\n---\n\n# DatasynxOpenCRM v2 Skill\n\n## Session Start\nCall \\`get_proactive_briefing()\\` first — urgent items, forecast, top action.\n\n## Deal Conversations\n\\`open_deal_room({ slug, dealName })\\` — graph + health + simulation + playbook in one call.\n\n## When a Customer Is Mentioned\n\\`get_customer_context(slug)\\` before discussing anything.\n\n## After Every Interaction\n\\`log_interaction(slug, type, summary, nextSteps)\\`\n\n## Stalled Deal\n\\`run_deal_agent({ slug, dealName, autonomyLevel: \"suggest\" })\\`\n\n## Revenue Goal\n\\`pursue_goal({ goal, deadline })\\`\n\n## Historical Research\n\\`search_customer_knowledge(slug, query)\\`\n\n## Pipeline\n\\`update_deal(slug, dealName, { stage, value, probability })\\`\n\n## Overview\n\\`list_customers()\\` for all customers · \\`get_capabilities()\\` for full reference`.trim();\n}\n\n/** Antigravity: global GEMINI.md (~/.gemini/GEMINI.md) — token budget: max 50 lines */\nexport function buildAgyGeminiMd(dataDir: string): string {\n return `# DatasynxOpenCRM v2 — Agent Context (${TOOL_COUNT} Tools)\n\nYou have access to a local CRM via MCP tools (server: datasynx-opencrm).\n\n## Session Start — Always Do This First\n\\`get_proactive_briefing()\\` — urgent items, opportunities, forecast\n\n## Priority Tool Order\n1. \\`open_deal_room(slug, dealName)\\` — before deal conversations\n2. \\`get_proactive_briefing()\\` — at session start or \"what should I do?\"\n3. \\`get_customer_context(slug)\\` — for general customer questions\n\n## Core Workflow\n- Customer mentioned → \\`get_customer_context(slug)\\`\n- After interaction → \\`log_interaction(slug, type, summary)\\`\n- Deal change → \\`update_deal(slug, dealName, fields)\\`\n- Historical → \\`search_customer_knowledge(slug, query)\\`\n- Revenue goal → \\`pursue_goal(goal, deadline)\\`\n\n## Key v2 Tools\nget_proactive_briefing · open_deal_room · get_relationship_graph ·\nget_relationship_health · run_deal_agent · simulate_revenue ·\nget_org_intelligence · pursue_goal · get_goal_status · get_playbook\n\n## All Tools\nget_capabilities · get_active_session · get_customer_context ·\nsearch_customer_knowledge · list_customers · log_interaction · update_deal ·\nexport_customer · update_customer_facts · get_deal_health · get_pipeline_forecast ·\nsummarize_meeting · get_pipeline_stages · get_market_intelligence ·\nget_relationship_graph · get_relationship_health · run_deal_agent ·\napprove_agent_action · simulate_revenue · get_org_intelligence ·\nget_playbook · create_playbook · list_playbooks · distill_playbook ·\npursue_goal · get_goal_status · register_push_subscription · get_push_status ·\nopen_deal_room · get_proactive_briefing ·\nlist_email_templates · get_email_template · draft_email ·\nenroll_in_sequence · list_sequence_enrollments · unenroll_from_sequence · list_sequences ·\ngenerate_quote · get_quote_status · get_booking_link ·\ncreate_ticket · update_ticket · list_tickets · close_ticket ·\nsend_nps_survey · get_survey_results ·\nsearch_knowledge_base · create_kb_article ·\nbackup_now · list_backups ·\ntrigger_sync · get_audit_log · get_logs · get_diagnostics ·\ndefine_custom_object · create_record · list_records · list_custom_objects\n\n## Data: ${dataDir}`.trim();\n}\n\n/** Grok Build: .grok/settings.json — project-level MCP config (array format) */\nexport function buildGrokSettingsJson(config: {\n serverName: string;\n mcpServerPath: string;\n dataDir: string;\n}): string {\n const entry = {\n mcpServers: [\n {\n name: config.serverName,\n transport: {\n type: \"stdio\",\n command: \"node\",\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n },\n },\n ],\n };\n return JSON.stringify(entry, null, 2);\n}\n\n/** Cursor: .cursor/rules/datasynx-crm.mdc (MDC format with frontmatter) */\nexport function buildCursorRulesMdc(dataDir: string): string {\n return `---\ndescription: DatasynxOpenCRM v2 — CRM workflow rules (${TOOL_COUNT} tools)\nglobs: [\"**/*\"]\nalwaysApply: true\n---\n\n# DatasynxOpenCRM v2 Rules\n\nYou have access to a local CRM via MCP tools (datasynx-opencrm, ${TOOL_COUNT} tools).\n\n## Session Start\nCall \\`get_proactive_briefing()\\` at the start of every session.\n\n## Deal Conversations\nCall \\`open_deal_room({ slug, dealName })\\` before any deal discussion.\n\n## Mandatory Workflow\n- Customer mentioned → \\`get_customer_context(slug)\\` immediately\n- After call/meeting/email → \\`log_interaction(slug, type, summary)\\`\n- Historical question → \\`search_customer_knowledge(slug, query)\\`\n- Deal discussed → \\`update_deal(slug, dealName, fields)\\`\n- Revenue goal → \\`pursue_goal({ goal, deadline })\\`\n\n## Key v2 Tools\nopen_deal_room · get_proactive_briefing · get_relationship_graph ·\nget_relationship_health · run_deal_agent · approve_agent_action ·\nsimulate_revenue · get_org_intelligence · get_playbook · pursue_goal\n\n## All ${TOOL_COUNT} Tools\nget_capabilities · get_active_session · get_customer_context ·\nsearch_customer_knowledge · list_customers · log_interaction · update_deal ·\nexport_customer · update_customer_facts · get_deal_health · get_pipeline_forecast ·\nsummarize_meeting · get_pipeline_stages · get_market_intelligence ·\nget_relationship_graph · get_relationship_health · run_deal_agent ·\napprove_agent_action · simulate_revenue · get_org_intelligence ·\nget_playbook · create_playbook · list_playbooks · distill_playbook ·\npursue_goal · get_goal_status · register_push_subscription · get_push_status ·\nopen_deal_room · get_proactive_briefing ·\nlist_email_templates · get_email_template · draft_email ·\nenroll_in_sequence · list_sequence_enrollments · unenroll_from_sequence · list_sequences ·\ngenerate_quote · get_quote_status · get_booking_link ·\ncreate_ticket · update_ticket · list_tickets · close_ticket ·\nsend_nps_survey · get_survey_results ·\nsearch_knowledge_base · create_kb_article\n\n## Never\n- Discuss a customer without loading context first\n- Skip logging — every touchpoint matters\n- Invent information — sync or search first\n\n## Data: ${dataDir}`.trim();\n}\n","// src/setup/adapters/claude-code.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { execSync } from \"child_process\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildClaudeMd, TOOL_COUNT } from \"../harness-content.js\";\n\nconst HOME = os.homedir();\nconst CLAUDE_JSON = path.join(HOME, \".claude.json\");\nconst CLAUDE_DIR = path.join(HOME, \".claude\");\n\nexport class ClaudeCodeAdapter implements FrameworkAdapter {\n readonly name = \"Claude Code\";\n\n detect(): boolean {\n try {\n execSync(\"which claude\", { stdio: \"ignore\" });\n return true;\n } catch {}\n return fs.existsSync(CLAUDE_JSON) || fs.existsSync(CLAUDE_DIR);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(CLAUDE_JSON)) return false;\n try {\n const json = JSON.parse(fs.readFileSync(CLAUDE_JSON, \"utf-8\")) as Record<string, unknown>;\n const servers = json[\"mcpServers\"] as Record<string, unknown> | undefined;\n return !!servers?.[\"datasynx-opencrm\"];\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n const harnessFiles: string[] = [];\n\n // 1. MCP server in ~/.claude.json (user scope)\n this.writeMcpConfig(config);\n\n // 2. Global ~/.claude/settings.json\n this.writeGlobalSettings();\n\n // 3. CLAUDE.md in CRM data directory\n const claudeMdPath = path.join(config.dataDir, \"CLAUDE.md\");\n fs.writeFileSync(claudeMdPath, buildClaudeMd(config.dataDir));\n harnessFiles.push(claudeMdPath);\n\n // 4. Project-scope .claude/settings.json in dataDir\n const projectSettingsDir = path.join(config.dataDir, \".claude\");\n fs.mkdirSync(projectSettingsDir, { recursive: true });\n const allow = [\n \"mcp__datasynx-opencrm__get_capabilities\",\n \"mcp__datasynx-opencrm__get_active_session\",\n \"mcp__datasynx-opencrm__get_customer_context\",\n \"mcp__datasynx-opencrm__search_customer_knowledge\",\n \"mcp__datasynx-opencrm__list_customers\",\n \"mcp__datasynx-opencrm__log_interaction\",\n \"mcp__datasynx-opencrm__update_deal\",\n \"mcp__datasynx-opencrm__export_customer\",\n ];\n const projectSettings = { permissions: { allow } };\n const settingsPath = path.join(projectSettingsDir, \"settings.json\");\n fs.writeFileSync(settingsPath, JSON.stringify(projectSettings, null, 2));\n harnessFiles.push(settingsPath);\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: CLAUDE_JSON,\n harnessFiles,\n notes: `${allow.length} of ${TOOL_COUNT} MCP tools pre-allowed (common read/write); CLAUDE.md written to CRM root.`,\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(CLAUDE_JSON)) return;\n try {\n const json = JSON.parse(fs.readFileSync(CLAUDE_JSON, \"utf-8\")) as Record<string, unknown>;\n const servers = json[\"mcpServers\"] as Record<string, unknown> | undefined;\n if (servers) {\n delete servers[\"datasynx-opencrm\"];\n }\n fs.writeFileSync(CLAUDE_JSON, JSON.stringify(json, null, 2));\n } catch {}\n }\n\n private writeMcpConfig(config: InstallConfig): void {\n let json: Record<string, unknown> = {};\n if (fs.existsSync(CLAUDE_JSON)) {\n try {\n json = JSON.parse(fs.readFileSync(CLAUDE_JSON, \"utf-8\")) as Record<string, unknown>;\n } catch {}\n }\n if (!json[\"mcpServers\"]) json[\"mcpServers\"] = {};\n (json[\"mcpServers\"] as Record<string, unknown>)[config.serverName] = {\n type: \"stdio\",\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n // Ensure parent directory exists (memfs requires this)\n fs.mkdirSync(path.dirname(CLAUDE_JSON), { recursive: true });\n fs.writeFileSync(CLAUDE_JSON, JSON.stringify(json, null, 2));\n }\n\n private writeGlobalSettings(): void {\n fs.mkdirSync(CLAUDE_DIR, { recursive: true });\n const settingsPath = path.join(CLAUDE_DIR, \"settings.json\");\n let settings: Record<string, unknown> = {};\n if (fs.existsSync(settingsPath)) {\n try {\n settings = JSON.parse(fs.readFileSync(settingsPath, \"utf-8\")) as Record<string, unknown>;\n } catch {}\n }\n if (!settings[\"permissions\"]) settings[\"permissions\"] = {};\n const perms = settings[\"permissions\"] as Record<string, unknown>;\n if (!perms[\"allow\"]) perms[\"allow\"] = [];\n const allow = perms[\"allow\"] as string[];\n const wildcard = \"mcp__datasynx-opencrm__*\";\n if (!allow.includes(wildcard)) {\n allow.push(wildcard);\n }\n fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));\n }\n}\n","// src/setup/adapters/claude-desktop.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\n\n// Platform-specific config paths (as of May 2026):\n// macOS: ~/Library/Application Support/Claude/claude_desktop_config.json\n// Windows: %APPDATA%\\Claude\\claude_desktop_config.json\n// Linux: ~/.config/claude-desktop/claude_desktop_config.json\nfunction getDesktopConfigPath(): string {\n switch (process.platform) {\n case \"darwin\":\n return path.join(\n os.homedir(),\n \"Library\",\n \"Application Support\",\n \"Claude\",\n \"claude_desktop_config.json\"\n );\n case \"win32\":\n return path.join(\n process.env[\"APPDATA\"] ?? os.homedir(),\n \"Claude\",\n \"claude_desktop_config.json\"\n );\n default: // linux\n return path.join(os.homedir(), \".config\", \"claude-desktop\", \"claude_desktop_config.json\");\n }\n}\n\nconst DESKTOP_CONFIG = getDesktopConfigPath();\n\nexport class ClaudeDesktopAdapter implements FrameworkAdapter {\n readonly name = \"Claude Desktop\";\n\n detect(): boolean {\n return fs.existsSync(DESKTOP_CONFIG) || fs.existsSync(path.dirname(DESKTOP_CONFIG));\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(DESKTOP_CONFIG)) return false;\n try {\n const json = JSON.parse(fs.readFileSync(DESKTOP_CONFIG, \"utf-8\")) as Record<string, unknown>;\n const servers = json[\"mcpServers\"] as Record<string, unknown> | undefined;\n return !!servers?.[\"datasynx-opencrm\"];\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n // Create dir if not exists (may not exist until app is first launched)\n fs.mkdirSync(path.dirname(DESKTOP_CONFIG), { recursive: true });\n\n let json: Record<string, unknown> = {};\n if (fs.existsSync(DESKTOP_CONFIG)) {\n try {\n json = JSON.parse(fs.readFileSync(DESKTOP_CONFIG, \"utf-8\")) as Record<string, unknown>;\n } catch {}\n }\n if (!json[\"mcpServers\"]) json[\"mcpServers\"] = {};\n (json[\"mcpServers\"] as Record<string, unknown>)[config.serverName] = {\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n fs.writeFileSync(DESKTOP_CONFIG, JSON.stringify(json, null, 2));\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: DESKTOP_CONFIG,\n harnessFiles: [],\n notes: \"Restart Claude Desktop to activate the MCP server. No harness files for Desktop app.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(DESKTOP_CONFIG)) return;\n try {\n const json = JSON.parse(fs.readFileSync(DESKTOP_CONFIG, \"utf-8\")) as Record<string, unknown>;\n const servers = json[\"mcpServers\"] as Record<string, unknown> | undefined;\n if (servers) {\n delete servers[\"datasynx-opencrm\"];\n }\n fs.writeFileSync(DESKTOP_CONFIG, JSON.stringify(json, null, 2));\n } catch {}\n }\n}\n","// src/setup/adapters/codex.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { execSync } from \"child_process\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildAgentsMd } from \"../harness-content.js\";\n\nconst CODEX_DIR = path.join(os.homedir(), \".codex\");\nconst CODEX_CONFIG = path.join(CODEX_DIR, \"config.toml\");\n\nexport class CodexAdapter implements FrameworkAdapter {\n readonly name = \"Codex\";\n\n detect(): boolean {\n try {\n execSync(\"which codex\", { stdio: \"ignore\" });\n return true;\n } catch {}\n return fs.existsSync(CODEX_DIR);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(CODEX_CONFIG)) return false;\n return fs.readFileSync(CODEX_CONFIG, \"utf-8\").includes(\"[mcp_servers.datasynx-opencrm]\");\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n fs.mkdirSync(CODEX_DIR, { recursive: true });\n const harnessFiles: string[] = [];\n\n // Idempotency check\n if (!this.isInstalled()) {\n const block = [\n ``,\n `[mcp_servers.${config.serverName}]`,\n `command = ${JSON.stringify(process.execPath)}`,\n `args = [${JSON.stringify(config.mcpServerPath)}]`,\n `env = { DXCRM_DATA_DIR = ${JSON.stringify(config.dataDir)} }`,\n `startup_timeout_sec = 30`,\n `tool_timeout_sec = 120`,\n `enabled = true`,\n ``,\n ].join(\"\\n\");\n\n fs.appendFileSync(CODEX_CONFIG, block, \"utf-8\");\n }\n\n // Write AGENTS.md to dataDir if not already present with CRM content\n const agentsPath = path.join(config.dataDir, \"AGENTS.md\");\n if (!fs.existsSync(agentsPath)) {\n fs.writeFileSync(agentsPath, buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath);\n } else {\n const existing = fs.readFileSync(agentsPath, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(agentsPath, \"\\n\\n---\\n\\n\" + buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath + \" (appended)\");\n }\n }\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: CODEX_CONFIG,\n harnessFiles,\n notes: `startup_timeout_sec=30, tool_timeout_sec=120. AGENTS.md written to CRM root.`,\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(CODEX_CONFIG)) return;\n const content = fs.readFileSync(CODEX_CONFIG, \"utf-8\");\n // Remove the [mcp_servers.datasynx-opencrm] block\n const cleaned = content.replace(/\\n?\\[mcp_servers\\.datasynx-opencrm\\][^\\[]*/, \"\");\n fs.writeFileSync(CODEX_CONFIG, cleaned);\n }\n}\n","// src/setup/adapters/openclaw.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { execSync } from \"child_process\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildSoulMd, buildAgentsMd } from \"../harness-content.js\";\n\nconst HOME = os.homedir();\nconst OPENCLAW_DIR = path.join(HOME, \".openclaw\");\nconst OPENCLAW_JSON = path.join(OPENCLAW_DIR, \"openclaw.json\");\nconst OPENCLAW_WORKSPACE = path.join(OPENCLAW_DIR, \"workspace\");\n\nexport class OpenClawAdapter implements FrameworkAdapter {\n readonly name = \"OpenClaw\";\n\n detect(): boolean {\n try {\n execSync(\"which openclaw\", { stdio: \"ignore\" });\n return true;\n } catch {}\n return fs.existsSync(OPENCLAW_DIR) || fs.existsSync(OPENCLAW_JSON);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(OPENCLAW_JSON)) return false;\n try {\n const json = JSON.parse(fs.readFileSync(OPENCLAW_JSON, \"utf-8\")) as Record<string, unknown>;\n const servers = json[\"mcpServers\"] as Record<string, unknown> | undefined;\n return !!servers?.[\"datasynx-opencrm\"];\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n fs.mkdirSync(OPENCLAW_DIR, { recursive: true });\n fs.mkdirSync(OPENCLAW_WORKSPACE, { recursive: true });\n\n const harnessFiles: string[] = [];\n\n // 1. openclaw.json — register MCP server (stdio + optional HTTP disabled by default)\n let json: Record<string, unknown> = {};\n if (fs.existsSync(OPENCLAW_JSON)) {\n try {\n json = JSON.parse(fs.readFileSync(OPENCLAW_JSON, \"utf-8\")) as Record<string, unknown>;\n } catch {}\n }\n if (!json[\"mcpServers\"]) json[\"mcpServers\"] = {};\n const servers = json[\"mcpServers\"] as Record<string, unknown>;\n\n servers[config.serverName] = {\n command: process.execPath,\n args: [config.mcpServerPath],\n transport: \"stdio\",\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n\n // HTTP entry (disabled by default — user activates when daemon runs with --http)\n servers[`${config.serverName}-http`] = {\n url: `http://localhost:${config.httpPort}/mcp`,\n transport: \"streamable-http\",\n enabled: false,\n };\n\n fs.writeFileSync(OPENCLAW_JSON, JSON.stringify(json, null, 2));\n // Gateway hot-reloads config — no restart needed\n\n // 2. SOUL.md in OpenClaw workspace\n const soulPath = path.join(OPENCLAW_WORKSPACE, \"SOUL.md\");\n if (!fs.existsSync(soulPath)) {\n fs.writeFileSync(soulPath, buildSoulMd(\"openclaw\"));\n harnessFiles.push(soulPath);\n } else {\n const existing = fs.readFileSync(soulPath, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(soulPath, \"\\n\\n---\\n\\n\" + buildCrmSoulAppend());\n harnessFiles.push(soulPath + \" (appended)\");\n }\n }\n\n // 3. AGENTS.md in OpenClaw workspace\n const agentsPath = path.join(OPENCLAW_WORKSPACE, \"AGENTS.md\");\n if (!fs.existsSync(agentsPath)) {\n fs.writeFileSync(agentsPath, buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath);\n } else {\n const existing = fs.readFileSync(agentsPath, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(agentsPath, \"\\n\\n---\\n\\n\" + buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath + \" (appended)\");\n }\n }\n\n // 4. TOOLS.md — hint about CRM tools\n const toolsPath = path.join(OPENCLAW_WORKSPACE, \"TOOLS.md\");\n const toolsContent = buildOpenClawToolsMd();\n if (!fs.existsSync(toolsPath)) {\n fs.writeFileSync(toolsPath, toolsContent);\n } else if (!fs.readFileSync(toolsPath, \"utf-8\").includes(\"datasynx-opencrm\")) {\n fs.appendFileSync(toolsPath, \"\\n\\n\" + toolsContent);\n }\n harnessFiles.push(toolsPath);\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: OPENCLAW_JSON,\n harnessFiles,\n notes: \"Config hot-reloaded by Gateway. SOUL.md + AGENTS.md + TOOLS.md written to workspace.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(OPENCLAW_JSON)) return;\n try {\n const json = JSON.parse(fs.readFileSync(OPENCLAW_JSON, \"utf-8\")) as Record<string, unknown>;\n const servers = json[\"mcpServers\"] as Record<string, unknown> | undefined;\n if (servers) {\n delete servers[\"datasynx-opencrm\"];\n delete servers[\"datasynx-opencrm-http\"];\n }\n fs.writeFileSync(OPENCLAW_JSON, JSON.stringify(json, null, 2));\n } catch {}\n }\n}\n\nfunction buildCrmSoulAppend(): string {\n return `## CRM Integration\nI have access to DatasynxOpenCRM. I always load customer context before discussing customers.\nI log every interaction without being asked. I cite sources when referencing customer data.`;\n}\n\nfunction buildOpenClawToolsMd(): string {\n return `## datasynx-opencrm MCP Tools\n- get_customer_context(slug) — load full customer briefing\n- search_customer_knowledge(slug, query) — search emails + transcripts\n- list_customers() — pipeline overview\n- log_interaction(slug, type, summary) — write to CRM\n- update_deal(slug, dealName, fields) — pipeline update\n- get_capabilities() — full reference`;\n}\n","// src/setup/adapters/hermes.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { execSync } from \"child_process\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildHermesSoulMd, buildHermesSkillMd } from \"../harness-content.js\";\n\nconst HOME = os.homedir();\nconst HERMES_HOME = process.env[\"HERMES_HOME\"] ?? path.join(HOME, \".hermes\");\nconst HERMES_CONFIG = path.join(HERMES_HOME, \"config.yaml\");\nconst HERMES_SOUL = path.join(HERMES_HOME, \"SOUL.md\");\nconst HERMES_SKILLS = path.join(HERMES_HOME, \"skills\");\n\nexport class HermesAdapter implements FrameworkAdapter {\n readonly name = \"Hermes Agent\";\n\n detect(): boolean {\n try {\n execSync(\"which hermes\", { stdio: \"ignore\" });\n return true;\n } catch {}\n return fs.existsSync(HERMES_HOME) || fs.existsSync(HERMES_CONFIG);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(HERMES_CONFIG)) return false;\n return fs.readFileSync(HERMES_CONFIG, \"utf-8\").includes(\"datasynx\");\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n fs.mkdirSync(HERMES_HOME, { recursive: true });\n fs.mkdirSync(HERMES_SKILLS, { recursive: true });\n\n const harnessFiles: string[] = [];\n\n // 1. config.yaml — write/merge mcp_servers block\n // Server name MUST use underscore: datasynx_opencrm (avoids tool prefix issues)\n this.writeMcpConfig(config);\n\n // 2. SOUL.md — Slot #1 in system prompt, always injected\n if (!fs.existsSync(HERMES_SOUL)) {\n fs.writeFileSync(HERMES_SOUL, buildHermesSoulMd(\"hermes\"));\n harnessFiles.push(HERMES_SOUL);\n } else {\n const existing = fs.readFileSync(HERMES_SOUL, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(\n HERMES_SOUL,\n \"\\n\\n---\\n\\n## CRM Integration\\nI have access to DatasynxOpenCRM MCP tools.\\nI always load customer context before discussing customers.\\nI log every interaction automatically via log_interaction().\"\n );\n harnessFiles.push(HERMES_SOUL + \" (appended)\");\n }\n }\n\n // 3. Skill file — agentskills.io standard\n // Hermes reads all .md files in ~/.hermes/skills/ as skills\n const skillPath = path.join(HERMES_SKILLS, \"datasynx-crm.md\");\n fs.writeFileSync(skillPath, buildHermesSkillMd());\n harnessFiles.push(skillPath);\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: HERMES_CONFIG,\n harnessFiles,\n notes:\n \"SOUL.md updated (Slot #1 system prompt). Skill registered in ~/.hermes/skills/. Server name uses underscore: datasynx_opencrm.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(HERMES_CONFIG)) return;\n const content = fs.readFileSync(HERMES_CONFIG, \"utf-8\");\n // Remove the datasynx_opencrm block from mcp_servers\n const cleaned = content.replace(/\\n datasynx[_-]opencrm:[\\s\\S]*?(?=\\n \\w|\\n[a-z]|$)/, \"\");\n fs.writeFileSync(HERMES_CONFIG, cleaned);\n // Remove skill file\n const skillPath = path.join(HERMES_SKILLS, \"datasynx-crm.md\");\n if (fs.existsSync(skillPath)) fs.unlinkSync(skillPath);\n }\n\n private writeMcpConfig(config: InstallConfig): void {\n // Hermes config.yaml: YAML format, mcp_servers section\n // Server name: datasynx_opencrm (UNDERSCORE — avoids tool name prefix issues)\n let content = fs.existsSync(HERMES_CONFIG) ? fs.readFileSync(HERMES_CONFIG, \"utf-8\") : \"\";\n\n if (content.includes(\"datasynx\")) return; // Idempotent\n\n if (content.includes(\"mcp_servers:\")) {\n // Existing mcp_servers section — inject our entry below it\n content = content.replace(\n \"mcp_servers:\",\n [\n \"mcp_servers:\",\n \" datasynx_opencrm:\",\n ` command: ${JSON.stringify(process.execPath)}`,\n ` args: [${JSON.stringify(config.mcpServerPath)}]`,\n ` env:`,\n ` DXCRM_DATA_DIR: ${JSON.stringify(config.dataDir)}`,\n ` timeout: 120`,\n ` connect_timeout: 30`,\n ` enabled: true`,\n ` tools:`,\n ` include: [get_capabilities, get_active_session, get_customer_context, search_customer_knowledge, list_customers, log_interaction, update_deal, export_customer]`,\n ` prompts: false`,\n ` resources: false`,\n ].join(\"\\n\")\n );\n fs.writeFileSync(HERMES_CONFIG, content);\n } else {\n // No mcp_servers section — append full block\n const mcpBlock = [\n ``,\n `# DatasynxOpenCRM MCP Server (added by dxcrm init)`,\n `mcp_servers:`,\n ` datasynx_opencrm:`,\n ` command: ${JSON.stringify(process.execPath)}`,\n ` args: [${JSON.stringify(config.mcpServerPath)}]`,\n ` env:`,\n ` DXCRM_DATA_DIR: ${JSON.stringify(config.dataDir)}`,\n ` timeout: 120`,\n ` connect_timeout: 30`,\n ` enabled: true`,\n ` tools:`,\n ` include:`,\n ` - get_capabilities`,\n ` - get_active_session`,\n ` - get_customer_context`,\n ` - search_customer_knowledge`,\n ` - list_customers`,\n ` - log_interaction`,\n ` - update_deal`,\n ` - export_customer`,\n ` prompts: false`,\n ` resources: false`,\n ``,\n ].join(\"\\n\");\n\n fs.appendFileSync(HERMES_CONFIG, mcpBlock);\n }\n }\n}\n","// src/setup/adapters/antigravity.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { execSync } from \"child_process\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildAgentsMd, buildAgySkillMd, buildAgyGeminiMd } from \"../harness-content.js\";\n\nconst HOME = os.homedir();\nconst AGY_BIN_UNIX = path.join(HOME, \".local\", \"bin\", \"agy\");\n\n// Shared config (CLI + IDE) — preferred\nconst GEMINI_CONFIG_DIR = path.join(HOME, \".gemini\", \"config\");\nconst SHARED_MCP_CONFIG = path.join(GEMINI_CONFIG_DIR, \"mcp_config.json\");\n\n// CLI-only config (fallback)\nconst AGY_DIR = path.join(HOME, \".gemini\", \"antigravity\");\nconst AGY_MCP_CONFIG = path.join(AGY_DIR, \"mcp_config.json\");\n\n// Global context file\nconst GEMINI_GLOBAL_MD = path.join(HOME, \".gemini\", \"GEMINI.md\");\n\n// Skills — directory-based (not single file like Hermes)\nconst AGY_SKILLS_DIR = path.join(HOME, \".gemini\", \"antigravity-cli\", \"skills\");\n\nexport class AntigravityAdapter implements FrameworkAdapter {\n readonly name = \"Antigravity CLI\";\n\n detect(): boolean {\n // Binary check: agy (NOT antigravity!)\n try {\n execSync(\"which agy\", { stdio: \"ignore\" });\n return true;\n } catch {}\n // Installation path check\n if (fs.existsSync(AGY_BIN_UNIX)) return true;\n // Gemini directory (also catches old Gemini CLI users who haven't migrated)\n return fs.existsSync(path.join(HOME, \".gemini\"));\n }\n\n isInstalled(): boolean {\n for (const configPath of [SHARED_MCP_CONFIG, AGY_MCP_CONFIG]) {\n if (!fs.existsSync(configPath)) continue;\n try {\n const json = JSON.parse(fs.readFileSync(configPath, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (json?.mcpServers?.[\"datasynx-opencrm\"]) return true;\n } catch {}\n }\n return false;\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n const harnessFiles: string[] = [];\n\n // 1. Shared MCP Config (preferred — covers CLI and IDE)\n fs.mkdirSync(GEMINI_CONFIG_DIR, { recursive: true });\n this.writeMcpEntry(SHARED_MCP_CONFIG, config);\n\n // 2. Global GEMINI.md (~/.gemini/GEMINI.md)\n // Antigravity loads this at each session as global context — keep short (≤50 lines)\n if (!fs.existsSync(GEMINI_GLOBAL_MD)) {\n fs.mkdirSync(path.dirname(GEMINI_GLOBAL_MD), { recursive: true });\n fs.writeFileSync(GEMINI_GLOBAL_MD, buildAgyGeminiMd(config.dataDir));\n harnessFiles.push(GEMINI_GLOBAL_MD);\n } else {\n const existing = fs.readFileSync(GEMINI_GLOBAL_MD, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(GEMINI_GLOBAL_MD, \"\\n\\n---\\n\\n\" + buildAgyGeminiMdAppend());\n harnessFiles.push(GEMINI_GLOBAL_MD + \" (appended)\");\n }\n }\n\n // 3. AGENTS.md in CRM root (Antigravity reads AGENTS.md in working directory)\n const agentsPath = path.join(config.dataDir, \"AGENTS.md\");\n fs.mkdirSync(config.dataDir, { recursive: true });\n if (!fs.existsSync(agentsPath)) {\n fs.writeFileSync(agentsPath, buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath);\n } else {\n const existing = fs.readFileSync(agentsPath, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(agentsPath, \"\\n\\n---\\n\\n\" + buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath + \" (appended)\");\n }\n }\n\n // 4. Skill: ~/.gemini/antigravity-cli/skills/datasynx-crm/SKILL.md\n // Directory-based (unlike Hermes single-file)\n const skillDir = path.join(AGY_SKILLS_DIR, \"datasynx-crm\");\n fs.mkdirSync(skillDir, { recursive: true });\n const skillPath = path.join(skillDir, \"SKILL.md\");\n fs.writeFileSync(skillPath, buildAgySkillMd());\n harnessFiles.push(skillPath);\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: SHARED_MCP_CONFIG,\n harnessFiles,\n notes:\n \"Shared config (~/.gemini/config/mcp_config.json) covers both CLI and IDE. Skill registered. GEMINI.md updated.\",\n };\n }\n\n async uninstall(): Promise<void> {\n for (const configPath of [SHARED_MCP_CONFIG, AGY_MCP_CONFIG]) {\n if (!fs.existsSync(configPath)) continue;\n try {\n const json = JSON.parse(fs.readFileSync(configPath, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (json.mcpServers) {\n delete json.mcpServers[\"datasynx-opencrm\"];\n delete json.mcpServers[\"datasynx-opencrm-http\"];\n }\n fs.writeFileSync(configPath, JSON.stringify(json, null, 2));\n } catch {}\n }\n // Remove skill directory\n const skillDir = path.join(AGY_SKILLS_DIR, \"datasynx-crm\");\n if (fs.existsSync(skillDir)) fs.rmSync(skillDir, { recursive: true });\n }\n\n private writeMcpEntry(configPath: string, config: InstallConfig): void {\n let json: { mcpServers?: Record<string, unknown> } = { mcpServers: {} };\n if (fs.existsSync(configPath)) {\n try {\n json = JSON.parse(fs.readFileSync(configPath, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (!json.mcpServers) json.mcpServers = {};\n } catch {}\n }\n\n // stdio transport (primary)\n json.mcpServers![\"datasynx-opencrm\"] = {\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n\n // HTTP transport entry — uses \"serverUrl\" NOT \"url\" (Antigravity-specific!)\n json.mcpServers![\"datasynx-opencrm-http\"] = {\n serverUrl: `http://localhost:${config.httpPort}/mcp`,\n };\n\n fs.writeFileSync(configPath, JSON.stringify(json, null, 2));\n }\n}\n\nfunction buildAgyGeminiMdAppend(): string {\n return `## DatasynxOpenCRM\nCRM MCP tools available: get_customer_context, search_customer_knowledge,\nlist_customers, log_interaction, update_deal. Always load context first.`;\n}\n","// src/setup/adapters/cursor.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildCursorRulesMdc } from \"../harness-content.js\";\n\nconst HOME = os.homedir();\nconst CURSOR_DIR = path.join(HOME, \".cursor\");\nconst CURSOR_GLOBAL_MCP = path.join(CURSOR_DIR, \"mcp.json\");\n\nexport class CursorAdapter implements FrameworkAdapter {\n readonly name = \"Cursor\";\n\n detect(): boolean {\n return fs.existsSync(CURSOR_DIR) || fs.existsSync(CURSOR_GLOBAL_MCP);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(CURSOR_GLOBAL_MCP)) return false;\n try {\n const json = JSON.parse(fs.readFileSync(CURSOR_GLOBAL_MCP, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n return !!json?.mcpServers?.[\"datasynx-opencrm\"];\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n fs.mkdirSync(CURSOR_DIR, { recursive: true });\n const harnessFiles: string[] = [];\n\n // 1. Global MCP config\n let json: { mcpServers?: Record<string, unknown> } = { mcpServers: {} };\n if (fs.existsSync(CURSOR_GLOBAL_MCP)) {\n try {\n json = JSON.parse(fs.readFileSync(CURSOR_GLOBAL_MCP, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (!json.mcpServers) json.mcpServers = {};\n } catch {}\n }\n json.mcpServers![\"datasynx-opencrm\"] = {\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n fs.writeFileSync(CURSOR_GLOBAL_MCP, JSON.stringify(json, null, 2));\n\n // 2. Project rules in CRM directory (.cursor/rules/datasynx-crm.mdc)\n // MDC format: frontmatter + markdown instructions\n // Cursor reads all .mdc files in .cursor/rules/ as agent context\n const rulesDir = path.join(config.dataDir, \".cursor\", \"rules\");\n fs.mkdirSync(rulesDir, { recursive: true });\n const rulesPath = path.join(rulesDir, \"datasynx-crm.mdc\");\n if (!fs.existsSync(rulesPath)) {\n fs.writeFileSync(rulesPath, buildCursorRulesMdc(config.dataDir));\n harnessFiles.push(rulesPath);\n }\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: CURSOR_GLOBAL_MCP,\n harnessFiles,\n notes:\n \"Global MCP registered. CRM rules written to .cursor/rules/. Restart Cursor to activate.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(CURSOR_GLOBAL_MCP)) return;\n try {\n const json = JSON.parse(fs.readFileSync(CURSOR_GLOBAL_MCP, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (json.mcpServers) {\n delete json.mcpServers[\"datasynx-opencrm\"];\n }\n fs.writeFileSync(CURSOR_GLOBAL_MCP, JSON.stringify(json, null, 2));\n } catch {}\n }\n}\n","// src/setup/adapters/windsurf.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\n\nconst HOME = os.homedir();\nconst WINDSURF_DIR = path.join(HOME, \".codeium\", \"windsurf\");\nconst WINDSURF_CONFIG = path.join(WINDSURF_DIR, \"mcp_config.json\");\n\nexport class WindsurfAdapter implements FrameworkAdapter {\n readonly name = \"Windsurf\";\n\n detect(): boolean {\n return fs.existsSync(WINDSURF_DIR) || fs.existsSync(WINDSURF_CONFIG);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(WINDSURF_CONFIG)) return false;\n try {\n const json = JSON.parse(fs.readFileSync(WINDSURF_CONFIG, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n return !!json?.mcpServers?.[\"datasynx-opencrm\"];\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n // Create dir if not exists — Windsurf does NOT create this automatically\n fs.mkdirSync(WINDSURF_DIR, { recursive: true });\n\n let json: { mcpServers?: Record<string, unknown> } = { mcpServers: {} };\n if (fs.existsSync(WINDSURF_CONFIG)) {\n try {\n json = JSON.parse(fs.readFileSync(WINDSURF_CONFIG, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (!json.mcpServers) json.mcpServers = {};\n } catch {}\n }\n\n // Windsurf supports ${env:VAR} interpolation — we use absolute path for reliability\n json.mcpServers![\"datasynx-opencrm\"] = {\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n\n fs.writeFileSync(WINDSURF_CONFIG, JSON.stringify(json, null, 2));\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: WINDSURF_CONFIG,\n harnessFiles: [],\n notes: \"No harness files for IDE-based tools. Restart Windsurf to activate.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(WINDSURF_CONFIG)) return;\n try {\n const json = JSON.parse(fs.readFileSync(WINDSURF_CONFIG, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (json.mcpServers) {\n delete json.mcpServers[\"datasynx-opencrm\"];\n }\n fs.writeFileSync(WINDSURF_CONFIG, JSON.stringify(json, null, 2));\n } catch {}\n }\n}\n","// src/setup/adapters/cline.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\n\nconst HOME = os.homedir();\nconst CLINE_DIR = path.join(HOME, \".cline\");\nconst CLINE_CONFIG = path.join(CLINE_DIR, \"data\", \"settings\", \"cline_mcp_settings.json\");\n\nexport class ClineAdapter implements FrameworkAdapter {\n readonly name = \"Cline\";\n\n detect(): boolean {\n return fs.existsSync(CLINE_DIR) || fs.existsSync(CLINE_CONFIG);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(CLINE_CONFIG)) return false;\n try {\n const json = JSON.parse(fs.readFileSync(CLINE_CONFIG, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n return !!json?.mcpServers?.[\"datasynx-opencrm\"];\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n // Create settings dir if not exists\n fs.mkdirSync(path.dirname(CLINE_CONFIG), { recursive: true });\n\n let json: { mcpServers?: Record<string, unknown> } = { mcpServers: {} };\n if (fs.existsSync(CLINE_CONFIG)) {\n try {\n json = JSON.parse(fs.readFileSync(CLINE_CONFIG, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (!json.mcpServers) json.mcpServers = {};\n } catch {}\n }\n\n // Cline requires absolute paths — relative paths fail silently!\n json.mcpServers![\"datasynx-opencrm\"] = {\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n };\n\n fs.writeFileSync(CLINE_CONFIG, JSON.stringify(json, null, 2));\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: CLINE_CONFIG,\n harnessFiles: [],\n notes: \"Cline requires absolute paths. No harness files for VSCode extensions.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(CLINE_CONFIG)) return;\n try {\n const json = JSON.parse(fs.readFileSync(CLINE_CONFIG, \"utf-8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n if (json.mcpServers) {\n delete json.mcpServers[\"datasynx-opencrm\"];\n }\n fs.writeFileSync(CLINE_CONFIG, JSON.stringify(json, null, 2));\n } catch {}\n }\n}\n","// src/setup/adapters/grok.ts\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { execSync } from \"child_process\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"../framework-adapter.js\";\nimport { buildAgentsMd, buildGrokSettingsJson } from \"../harness-content.js\";\n\nconst HOME = os.homedir();\nconst GROK_DIR = path.join(HOME, \".grok\");\nconst GROK_USER_SETTINGS = path.join(GROK_DIR, \"user-settings.json\");\n\ninterface GrokMcpEntry {\n name: string;\n transport: {\n type: \"stdio\" | \"http\";\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n headers?: Record<string, string>;\n };\n}\n\ninterface GrokSettings {\n mcpServers?: GrokMcpEntry[];\n [key: string]: unknown;\n}\n\nexport class GrokAdapter implements FrameworkAdapter {\n readonly name = \"Grok Build\";\n\n detect(): boolean {\n try {\n execSync(\"which grok\", { stdio: \"ignore\" });\n return true;\n } catch {}\n return fs.existsSync(GROK_DIR);\n }\n\n isInstalled(): boolean {\n if (!fs.existsSync(GROK_USER_SETTINGS)) return false;\n try {\n const settings = JSON.parse(fs.readFileSync(GROK_USER_SETTINGS, \"utf-8\")) as GrokSettings;\n return (settings.mcpServers ?? []).some((s) => s.name === \"datasynx-opencrm\");\n } catch {\n return false;\n }\n }\n\n async install(config: InstallConfig): Promise<InstallResult> {\n fs.mkdirSync(GROK_DIR, { recursive: true });\n const harnessFiles: string[] = [];\n\n // 1. User-level MCP config: ~/.grok/user-settings.json\n // Grok uses an array format (not object/map like Claude Desktop)\n if (!this.isInstalled()) {\n let settings: GrokSettings = {};\n if (fs.existsSync(GROK_USER_SETTINGS)) {\n try {\n settings = JSON.parse(fs.readFileSync(GROK_USER_SETTINGS, \"utf-8\")) as GrokSettings;\n } catch {}\n }\n if (!settings.mcpServers) settings.mcpServers = [];\n settings.mcpServers.push({\n name: config.serverName,\n transport: {\n type: \"stdio\",\n command: process.execPath,\n args: [config.mcpServerPath],\n env: { DXCRM_DATA_DIR: config.dataDir },\n },\n });\n fs.writeFileSync(GROK_USER_SETTINGS, JSON.stringify(settings, null, 2));\n }\n\n // 2. Project-level .grok/settings.json in dataDir\n // Allows project-scoped MCP registration (useful in team repos)\n const grokProjectDir = path.join(config.dataDir, \".grok\");\n fs.mkdirSync(grokProjectDir, { recursive: true });\n const projectSettings = path.join(grokProjectDir, \"settings.json\");\n fs.writeFileSync(projectSettings, buildGrokSettingsJson(config));\n harnessFiles.push(projectSettings);\n\n // 3. AGENTS.md — Grok Build reads this natively (same as Codex)\n // Also reads CLAUDE.md but AGENTS.md is the cross-vendor standard\n const agentsPath = path.join(config.dataDir, \"AGENTS.md\");\n if (!fs.existsSync(agentsPath)) {\n fs.writeFileSync(agentsPath, buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath);\n } else {\n const existing = fs.readFileSync(agentsPath, \"utf-8\");\n if (!existing.includes(\"DatasynxOpenCRM\")) {\n fs.appendFileSync(agentsPath, \"\\n\\n---\\n\\n\" + buildAgentsMd(config.dataDir));\n harnessFiles.push(agentsPath + \" (appended)\");\n }\n }\n\n return {\n framework: this.name,\n success: true,\n transport: \"stdio\",\n configPath: GROK_USER_SETTINGS,\n harnessFiles,\n notes:\n \"MCP registered in ~/.grok/user-settings.json (array format). \" +\n \"Project config written to .grok/settings.json. \" +\n \"AGENTS.md written — Grok Build reads it natively alongside CLAUDE.md.\",\n };\n }\n\n async uninstall(): Promise<void> {\n if (!fs.existsSync(GROK_USER_SETTINGS)) return;\n try {\n const settings = JSON.parse(fs.readFileSync(GROK_USER_SETTINGS, \"utf-8\")) as GrokSettings;\n if (settings.mcpServers) {\n settings.mcpServers = settings.mcpServers.filter((s) => s.name !== \"datasynx-opencrm\");\n }\n fs.writeFileSync(GROK_USER_SETTINGS, JSON.stringify(settings, null, 2));\n } catch {}\n }\n}\n","// src/setup/framework-registry.ts\nimport { ClaudeCodeAdapter } from \"./adapters/claude-code.js\";\nimport { ClaudeDesktopAdapter } from \"./adapters/claude-desktop.js\";\nimport { CodexAdapter } from \"./adapters/codex.js\";\nimport { OpenClawAdapter } from \"./adapters/openclaw.js\";\nimport { HermesAdapter } from \"./adapters/hermes.js\";\nimport { AntigravityAdapter } from \"./adapters/antigravity.js\";\nimport { CursorAdapter } from \"./adapters/cursor.js\";\nimport { WindsurfAdapter } from \"./adapters/windsurf.js\";\nimport { ClineAdapter } from \"./adapters/cline.js\";\nimport { GrokAdapter } from \"./adapters/grok.js\";\nimport type { FrameworkAdapter, InstallConfig, InstallResult } from \"./framework-adapter.js\";\n\nexport const FRAMEWORK_ADAPTERS: FrameworkAdapter[] = [\n // Tier 1 — full adapter (CLI binary detectable, harness injection)\n new ClaudeCodeAdapter(),\n new CodexAdapter(),\n new GrokAdapter(),\n new OpenClawAdapter(),\n new HermesAdapter(),\n new AntigravityAdapter(),\n // Tier 2 — config writer (IDE/Desktop, no global harness system)\n new CursorAdapter(),\n new WindsurfAdapter(),\n new ClineAdapter(),\n new ClaudeDesktopAdapter(), // non-developer audience, restart required\n];\n\nexport async function installAllDetected(config: InstallConfig): Promise<InstallResult[]> {\n const results: InstallResult[] = [];\n for (const adapter of FRAMEWORK_ADAPTERS) {\n if (!adapter.detect()) continue;\n try {\n results.push(await adapter.install(config));\n } catch (err) {\n results.push({\n framework: adapter.name,\n success: false,\n transport: \"stdio\",\n configPath: \"\",\n harnessFiles: [],\n notes: (err as Error).message,\n });\n }\n }\n return results;\n}\n\nexport type { FrameworkAdapter, InstallConfig, InstallResult };\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { installAllDetected } from \"../setup/framework-registry.js\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nexport const initCommand = new Command(\"init\")\n .description(\"Initialize CRM and configure AI frameworks\")\n .option(\n \"--team <url>\",\n \"Team mode: configure frameworks to connect to shared HTTP server at this URL (e.g. http://vm-ip:3847/mcp)\"\n )\n .action(async (opts: { team?: string }) => {\n const dataDir = process.cwd();\n\n // 1. Create .agentic/ directory\n const agenticDir = path.join(dataDir, \".agentic\");\n fs.mkdirSync(agenticDir, { recursive: true });\n\n // 2. Create config.json\n const configPath = path.join(agenticDir, \"config.json\");\n if (!fs.existsSync(configPath)) {\n fs.writeFileSync(\n configPath,\n JSON.stringify(\n {\n version: 1,\n dataDir,\n created: new Date().toISOString(),\n },\n null,\n 2\n )\n );\n }\n\n // 3. Discover transcript paths\n const home = os.homedir();\n const candidates = [\n path.join(home, \"Downloads\", \"Fireflies\"),\n path.join(home, \"Downloads\", \"Otter\"),\n path.join(home, \"Documents\", \"Zoom\"),\n path.join(home, \"Downloads\", \"Zoom\"),\n ];\n const transcriptPaths = candidates.filter((p) => fs.existsSync(p));\n\n // 4. Create sources.json\n const sourcesPath = path.join(agenticDir, \"sources.json\");\n if (!fs.existsSync(sourcesPath)) {\n const sources: Record<string, unknown> = {\n gmail: { type: \"gmail\", query: \"\", enabled: false },\n version: 1,\n created: new Date().toISOString(),\n };\n if (transcriptPaths.length > 0) {\n sources.transcripts = {\n type: \"transcript\",\n paths: transcriptPaths,\n extensions: [\".txt\", \".vtt\"],\n enabled: true,\n };\n }\n fs.writeFileSync(sourcesPath, JSON.stringify(sources, null, 2));\n }\n\n // 5. Create customers/ directory\n fs.mkdirSync(path.join(dataDir, \"customers\"), { recursive: true });\n\n // 5b. Write schema.json — human/machine-readable validation rules\n const schemaPath = path.join(agenticDir, \"schema.json\");\n if (!fs.existsSync(schemaPath)) {\n fs.writeFileSync(\n schemaPath,\n JSON.stringify(\n {\n version: 1,\n description: \"DatasynxOpenCRM validation schema for main_facts.md frontmatter\",\n main_facts: {\n required: [\"name\", \"relationship_stage\", \"created\", \"tags\", \"currency\"],\n properties: {\n name: { type: \"string\" },\n relationship_stage: {\n type: \"string\",\n enum: [\n \"lead\",\n \"qualified\",\n \"discovery\",\n \"proposal\",\n \"negotiation\",\n \"active\",\n \"churned\",\n \"closed\",\n ],\n },\n domain: { type: \"string\" },\n email: { type: \"string\", format: \"email\" },\n created: { type: \"string\", format: \"date\" },\n updated: { type: \"string\", format: \"date\" },\n tags: { type: \"array\", items: { type: \"string\" } },\n currency: { type: \"string\", enum: [\"EUR\", \"USD\", \"GBP\", \"CHF\"] },\n deal_value: { type: \"number\", minimum: 0 },\n last_touchpoint: { type: \"string\", format: \"date\" },\n primary_contact: { type: \"string\" },\n },\n },\n },\n null,\n 2\n )\n );\n }\n\n // 6. Install framework adapters\n console.log(info(\"Detecting AI frameworks...\"));\n\n // Find dist/mcp.js relative to this package\n const mcpServerPath = path.resolve(\n path.dirname(new URL(import.meta.url).pathname),\n \"../../dist/mcp.js\"\n );\n\n if (opts.team) {\n console.log(info(`Team mode: connecting frameworks to ${bold(opts.team)}`));\n }\n\n const results = await installAllDetected({\n mcpServerPath,\n dataDir,\n httpPort: 3847,\n serverName: \"datasynx-opencrm\",\n ...(opts.team ? { httpUrl: opts.team } : {}),\n });\n\n if (results.length === 0) {\n console.log(\n info(\" No AI frameworks detected. Configure manually: dxcrm guide --framework <name>\")\n );\n } else {\n for (const r of results) {\n if (r.success) {\n console.log(success(` ✓ ${r.framework} — ${r.transport} transport`));\n if (r.notes) console.log(` ${r.notes}`);\n } else {\n console.log(error(` ✗ ${r.framework} — ${r.notes ?? \"failed\"}`));\n }\n }\n }\n\n console.log(success(`\\n✓ DatasynxOpenCRM initialized in ${bold(dataDir)}`));\n if (opts.team) {\n console.log(info(` Team server: ${opts.team}`));\n console.log(info(` Set identity: export DXCRM_ACTOR=<your-name>`));\n } else {\n console.log(info(` Next: dxcrm create \"Your Customer Name\"`));\n }\n });\n","import { Command } from \"commander\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nexport const syncCommand = new Command(\"sync\")\n .argument(\"<slug>\", \"Customer slug to sync\")\n .description(\"Sync Gmail and transcripts for a customer\")\n .option(\"--since <date>\", \"Only sync emails/files after this date (YYYY-MM-DD)\")\n .option(\"--gmail\", \"Sync Gmail only\")\n .option(\"--transcripts\", \"Sync transcripts only\")\n .option(\"--provider <provider>\", \"Sync provider: gmail | microsoft | transcripts\")\n .option(\"--no-attachments\", \"Skip downloading/converting/indexing email attachments\")\n .action(\n async (\n slug: string,\n opts: {\n since?: string;\n gmail?: boolean;\n transcripts?: boolean;\n provider?: string;\n attachments?: boolean;\n }\n ) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const customerDir = path.join(dataDir, \"customers\", slug);\n\n if (!fs.existsSync(customerDir)) {\n console.error(\n error(`✗ Customer '${slug}' not found. Run 'dxcrm list' to see available customers.`)\n );\n process.exit(1);\n }\n\n const sourcesPath = path.join(customerDir, \"sources.json\");\n if (!fs.existsSync(sourcesPath)) {\n console.error(error(`✗ No sources.json found for '${slug}'.`));\n process.exit(1);\n }\n\n const sources = JSON.parse(fs.readFileSync(sourcesPath, \"utf-8\")) as {\n gmail?: { query?: string; enabled?: boolean };\n };\n\n const since = opts.since\n ? new Date(opts.since)\n : new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);\n const provider = opts.provider;\n const syncGmail =\n !opts.transcripts &&\n provider !== \"microsoft\" &&\n provider !== \"transcripts\" &&\n provider !== \"google-drive\";\n const syncMicrosoft = provider === \"microsoft\";\n const syncTranscripts =\n !opts.gmail &&\n provider !== \"gmail\" &&\n provider !== \"microsoft\" &&\n provider !== \"google-drive\";\n const syncGoogleDrive = provider === \"google-drive\";\n\n let totalSynced = 0;\n\n // Gmail sync\n if (syncGmail && sources.gmail?.enabled && sources.gmail.query) {\n const tokenPath = path.join(dataDir, \".agentic\", \"gmail-token.json\");\n const credPath = path.join(dataDir, \".agentic\", \"gmail-credentials.json\");\n\n if (!fs.existsSync(tokenPath) || !fs.existsSync(credPath)) {\n console.log(info(\" Gmail: credentials not configured (run dxcrm sync --setup-gmail)\"));\n } else {\n try {\n console.log(info(` Syncing Gmail for ${bold(slug)}...`));\n const { getGmailAuth } = await import(\"../sync/gmail-auth.js\");\n const { syncGmail: doGmailSync } = await import(\"../sync/gmail-sync.js\");\n const auth = await getGmailAuth(credPath, tokenPath);\n const result = await doGmailSync({\n slug,\n dataDir,\n auth,\n query: sources.gmail.query,\n since,\n includeAttachments: opts.attachments !== false,\n });\n totalSynced += result.synced;\n console.log(success(` ✓ Gmail: +${result.synced} synced, ${result.skipped} skipped`));\n } catch (err) {\n console.error(error(` ✗ Gmail sync failed: ${(err as Error).message}`));\n }\n }\n } else if (syncGmail) {\n console.log(info(\" Gmail: not configured (add domain/email to sources.json)\"));\n }\n\n // Microsoft sync (email + calendar)\n if (syncMicrosoft) {\n try {\n console.log(info(` Syncing Microsoft Outlook for ${bold(slug)}...`));\n const { getMicrosoftToken } = await import(\"../sync/microsoft-auth.js\");\n const token = await getMicrosoftToken(dataDir);\n if (!token) {\n console.log(info(\" Microsoft: no token found (.agentic/microsoft-token.json)\"));\n } else {\n const { syncMicrosoft: doMsSync } = await import(\"../sync/microsoft-sync.js\");\n const emailResult = await doMsSync({ slug, dataDir, accessToken: token, since });\n totalSynced += emailResult.synced;\n console.log(\n success(\n ` ✓ Microsoft Email: +${emailResult.synced} synced, ${emailResult.skipped} skipped`\n )\n );\n\n const { syncMicrosoftCalendar } = await import(\"../sync/microsoft-calendar.js\");\n const calResult = await syncMicrosoftCalendar({\n slug,\n dataDir,\n accessToken: token,\n since,\n });\n totalSynced += calResult.synced;\n console.log(\n success(\n ` ✓ Microsoft Calendar: +${calResult.synced} synced, ${calResult.skipped} skipped`\n )\n );\n }\n } catch (err) {\n console.error(error(` ✗ Microsoft sync failed: ${(err as Error).message}`));\n }\n }\n\n // Transcript sync\n if (syncTranscripts) {\n const agenticSourcesPath = path.join(dataDir, \".agentic\", \"sources.json\");\n if (fs.existsSync(agenticSourcesPath)) {\n try {\n const agenticSources = JSON.parse(fs.readFileSync(agenticSourcesPath, \"utf-8\")) as {\n transcripts?: { paths?: string[]; extensions?: string[]; enabled?: boolean };\n };\n\n if (agenticSources.transcripts?.enabled && agenticSources.transcripts.paths?.length) {\n const { processTranscriptFile } = await import(\"../sync/transcript-watcher.js\");\n const exts = agenticSources.transcripts.extensions ?? [\".txt\", \".vtt\"];\n let transcriptSynced = 0;\n\n for (const watchPath of agenticSources.transcripts.paths) {\n if (!fs.existsSync(watchPath)) continue;\n const files = fs\n .readdirSync(watchPath)\n .filter((f) => exts.some((ext) => f.endsWith(ext)))\n .map((f) => path.join(watchPath, f));\n\n for (const file of files) {\n try {\n await processTranscriptFile(file, slug, dataDir);\n transcriptSynced++;\n } catch {\n /* already synced or error — skip */\n }\n }\n }\n\n if (transcriptSynced > 0) {\n totalSynced += transcriptSynced;\n console.log(success(` ✓ Transcripts: +${transcriptSynced} processed`));\n } else {\n console.log(info(\" Transcripts: no new files\"));\n }\n } else {\n console.log(info(\" Transcripts: not configured\"));\n }\n } catch (err) {\n console.error(error(` ✗ Transcript sync failed: ${(err as Error).message}`));\n }\n }\n }\n\n // Google Drive sync\n if (syncGoogleDrive) {\n const tokenPath = path.join(dataDir, \".agentic\", \"google-token.json\");\n if (!fs.existsSync(tokenPath)) {\n console.log(info(\" Google Drive: token not configured (.agentic/google-token.json)\"));\n } else {\n try {\n const tokenData = JSON.parse(fs.readFileSync(tokenPath, \"utf-8\")) as {\n accessToken?: string;\n access_token?: string;\n };\n const accessToken = tokenData.accessToken ?? tokenData.access_token;\n if (!accessToken) {\n console.log(info(\" Google Drive: accessToken not found in token file\"));\n } else {\n console.log(info(` Syncing Google Drive for ${bold(slug)}...`));\n const { syncGoogleDriveFiles } = await import(\"../sync/google-drive-sync.js\");\n const result = await syncGoogleDriveFiles({\n slug,\n dataDir,\n accessToken,\n customerName: slug,\n });\n totalSynced += result.synced;\n if (result.errors.length > 0) {\n for (const err of result.errors) {\n console.error(error(` ✗ Google Drive: ${err}`));\n }\n }\n console.log(\n success(` ✓ Google Drive: +${result.synced} synced, ${result.skipped} skipped`)\n );\n }\n } catch (err) {\n console.error(error(` ✗ Google Drive sync failed: ${(err as Error).message}`));\n }\n }\n }\n\n if (totalSynced > 0) {\n console.log(\n success(\n `\\n✓ Sync complete: ${bold(String(totalSynced))} new interactions for ${bold(slug)}`\n )\n );\n } else {\n console.log(info(`\\n✓ Sync complete: no new interactions for ${bold(slug)}`));\n }\n }\n );\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { spawn } from \"child_process\";\nimport { success, error, info } from \"../ui/colors.js\";\n\nfunction getPidFile(): string {\n return path.join(process.cwd(), \".agentic\", \"daemon.pid\");\n}\n\nexport const daemonCommand = new Command(\"daemon\").description(\"Manage the background sync daemon\");\n\ndaemonCommand.command(\"start\").action(async () => {\n const pidFile = getPidFile();\n\n if (fs.existsSync(pidFile)) {\n const pid = parseInt(fs.readFileSync(pidFile, \"utf-8\") as string, 10);\n try {\n process.kill(pid, 0);\n console.log(info(`Daemon already running (PID ${pid})`));\n return;\n } catch {\n // stale PID file — continue\n }\n }\n\n const workerPath = path.resolve(\n path.dirname(new URL(import.meta.url).pathname),\n \"../../dist/daemon/worker.js\"\n );\n\n const child = spawn(process.execPath, [workerPath], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n\n fs.mkdirSync(path.dirname(pidFile), { recursive: true });\n fs.writeFileSync(pidFile, String(child.pid));\n console.log(success(`✓ Daemon started (PID ${child.pid})`));\n});\n\ndaemonCommand.command(\"stop\").action(() => {\n const pidFile = getPidFile();\n\n if (!fs.existsSync(pidFile)) {\n console.log(info(\"Daemon not running.\"));\n return;\n }\n\n const pid = parseInt(fs.readFileSync(pidFile, \"utf-8\") as string, 10);\n try {\n process.kill(pid, \"SIGTERM\");\n fs.unlinkSync(pidFile);\n console.log(success(\"✓ Daemon stopped.\"));\n } catch (err) {\n console.error(error(`✗ ${(err as Error).message}`));\n }\n});\n\ndaemonCommand.command(\"status\").action(() => {\n const pidFile = getPidFile();\n\n if (!fs.existsSync(pidFile)) {\n console.log(info(\"Daemon: not running.\"));\n return;\n }\n\n const pid = parseInt(fs.readFileSync(pidFile, \"utf-8\") as string, 10);\n try {\n process.kill(pid, 0);\n console.log(success(`Daemon: running (PID ${pid})`));\n } catch {\n console.log(info(\"Daemon: stopped (stale PID file).\"));\n fs.unlinkSync(pidFile);\n }\n});\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport { listCustomerSlugs } from \"../fs/customer-dir.js\";\nimport { readSyncState } from \"../fs/sync-state.js\";\nimport { readUnmatched } from \"../fs/unmatched-transcripts.js\";\nimport { getSession } from \"../core/session-store.js\";\nimport { readAllSessions } from \"../commands/session.js\";\n\nexport function formatAge(isoString: string): string {\n const diff = Date.now() - new Date(isoString).getTime();\n const mins = Math.floor(diff / 60000);\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n return `${Math.floor(hours / 24)}d ago`;\n}\n\nfunction checkDaemon(dataDir: string): { running: boolean; pid?: number } {\n const pidFile = path.join(dataDir, \".agentic\", \"daemon.pid\");\n if (!fs.existsSync(pidFile)) return { running: false };\n try {\n const pid = parseInt(fs.readFileSync(pidFile, \"utf-8\").trim(), 10);\n if (isNaN(pid)) return { running: false };\n process.kill(pid, 0);\n return { running: true, pid };\n } catch {\n return { running: false };\n }\n}\n\nasync function fetchTeamSessions(serverUrl: string): Promise<Array<{\n customerSlug: string;\n customerName: string;\n owner?: string;\n startedAt: string;\n}> | null> {\n try {\n const res = await fetch(`${serverUrl.replace(/\\/$/, \"\")}/sessions`, {\n signal: AbortSignal.timeout(3000),\n });\n if (!res.ok) return null;\n const data = (await res.json()) as {\n sessions?: Array<{\n customerSlug: string;\n customerName: string;\n owner?: string;\n startedAt: string;\n }>;\n };\n return data.sessions ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function runStatus(\n opts: { unmatched?: boolean; team?: string },\n dataDir?: string\n): Promise<void> {\n const dir = dataDir ?? process.cwd();\n\n if (opts.unmatched) {\n const unmatched = readUnmatched(dir);\n const sep = \"─\".repeat(37);\n console.log(sep);\n console.log(bold(\" Unmatched Transcripts\"));\n console.log(sep);\n if (unmatched.length === 0) {\n console.log(info(\" No unmatched transcripts.\"));\n } else {\n for (const entry of unmatched) {\n console.log(` ${entry.filePath} ${entry.reason} ${entry.addedAt}`);\n }\n }\n console.log(sep);\n return;\n }\n\n const daemon = checkDaemon(dir);\n const slugs = listCustomerSlugs(dir);\n const syncState = readSyncState(dir);\n const unmatched = readUnmatched(dir);\n\n const sep = \"─\".repeat(37);\n console.log(sep);\n console.log(bold(\" DatasynxOpenCRM Status\"));\n console.log(sep);\n\n // Daemon line\n const daemonLine = daemon.running ? success(`running (PID ${daemon.pid})`) : error(\"not running\");\n console.log(` Daemon: ${daemonLine}`);\n\n // Customer count\n console.log(` Customers: ${slugs.length} active`);\n\n // Session line\n const session = getSession() ?? readAllSessions(dir)[0] ?? null;\n if (session) {\n const ownerPart = session.owner ? ` [${session.owner}]` : \"\";\n console.log(` Session: ${session.customerName} (${session.customerSlug})${ownerPart}`);\n } else {\n console.log(` Session: none`);\n }\n\n // Sync lines\n if (slugs.length > 0) {\n console.log(` Syncs:`);\n for (const slug of slugs) {\n const state = syncState[slug];\n const ageStr = state?.lastGmailSync\n ? `Gmail ${formatAge(state.lastGmailSync)}`\n : \"no sync yet\";\n console.log(` ${slug}: ${ageStr}`);\n }\n }\n\n // Unmatched line\n const unmatchedCount = unmatched.length;\n if (unmatchedCount > 0) {\n console.log(\n ` Unmatched: ${unmatchedCount} Transcript${unmatchedCount !== 1 ? \"s\" : \"\"} (dxcrm status --unmatched)`\n );\n } else {\n console.log(` Unmatched: 0 Transcripts`);\n }\n\n // Team overview via HTTP server\n const serverUrl = opts.team ?? process.env[\"DXCRM_SERVER_URL\"];\n if (serverUrl) {\n const teamSessions = await fetchTeamSessions(serverUrl);\n if (teamSessions && teamSessions.length > 0) {\n console.log(bold(\"\\n Team overview:\"));\n for (const s of teamSessions) {\n const ownerPart = s.owner ? `${s.owner}` : \"anonymous\";\n console.log(info(` ${ownerPart.padEnd(15)} → ${s.customerName} (${s.customerSlug})`));\n }\n } else if (teamSessions !== null) {\n console.log(info(\" Team: no active sessions\"));\n } else {\n console.log(info(` Team: server unreachable (${serverUrl})`));\n }\n }\n\n console.log(sep);\n}\n\nexport const statusCommand = new Command(\"status\")\n .description(\"Show CRM status: daemon, sync state, customer counts\")\n .option(\"--unmatched\", \"Show unmatched transcript queue\")\n .option(\"--team <url>\", \"Show team sessions from HTTP server (or set DXCRM_SERVER_URL)\")\n .action((opts) => runStatus(opts, process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd()));\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport { AgentConfigSchema, type AgentConfig } from \"../schemas/agent-config.js\";\nimport { writeJsonFile } from \"../fs/json-store.js\";\n\nfunction agentsDir(dataDir: string): string {\n return path.join(dataDir, \".agentic\", \"agents\");\n}\n\nfunction agentConfigPath(dataDir: string, slug: string): string {\n return path.join(agentsDir(dataDir), `${slug}.agent.json`);\n}\n\nexport async function runAgentSpawn(\n slug: string,\n opts: { channel?: string; wakeOnEmail?: boolean; chatId?: string },\n dataDir?: string\n): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const customerDir = path.join(dir, \"customers\", slug);\n\n if (!fs.existsSync(customerDir)) {\n console.error(\n error(`✗ Customer '${slug}' not found. Run 'dxcrm list' to see available customers.`)\n );\n process.exit(1);\n }\n\n const channel = (opts.channel ?? \"telegram\") as \"telegram\";\n const wakeOn: Array<\"email\" | \"calendar\"> = opts.wakeOnEmail ? [\"email\"] : [\"email\"];\n\n const config: AgentConfig = AgentConfigSchema.parse({\n slug,\n channel,\n wakeOn,\n createdAt: new Date().toISOString(),\n lastWake: null,\n ...(opts.chatId !== undefined ? { telegramChatId: opts.chatId } : {}),\n });\n\n writeJsonFile(agentConfigPath(dir, slug), config);\n\n console.log(success(`✓ Agent spawned: ${bold(slug)}`));\n console.log(info(` Channel: ${channel}`));\n console.log(info(` Wake on: ${wakeOn.join(\", \")}`));\n console.log(info(` Config: .agentic/agents/${slug}.agent.json`));\n\n if (channel === \"telegram\" && !process.env[\"TELEGRAM_BOT_TOKEN\"]) {\n console.log(\n info(\n `\\n Note: Set TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID env vars to enable Telegram messages.`\n )\n );\n }\n}\n\nexport async function runAgentStatus(dataDir?: string): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const dir2 = agentsDir(dir);\n\n if (!fs.existsSync(dir2)) {\n console.log(info(\"No agents configured. Run: dxcrm agent spawn <slug> --channel telegram\"));\n return;\n }\n\n const files = fs.readdirSync(dir2).filter((f) => f.endsWith(\".agent.json\"));\n\n if (files.length === 0) {\n console.log(info(\"No agents configured.\"));\n return;\n }\n\n console.log(bold(`\\n Agents (${files.length})\\n`));\n\n for (const file of files) {\n try {\n const raw = JSON.parse(\n fs.readFileSync(path.join(dir2, file), \"utf-8\") as string\n ) as AgentConfig;\n const lastWake = raw.lastWake\n ? `last wake: ${new Date(raw.lastWake).toLocaleString()}`\n : \"never woken\";\n console.log(\n info(` ${bold(raw.slug)} — ${raw.channel} · ${raw.wakeOn.join(\"+\")} · ${lastWake}`)\n );\n } catch {\n console.log(info(` ${file} (malformed)`));\n }\n }\n console.log(\"\");\n}\n\nexport async function runAgentRemove(slug: string, dataDir?: string): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const configPath = agentConfigPath(dir, slug);\n\n if (!fs.existsSync(configPath)) {\n console.error(error(`✗ No agent config found for '${slug}'.`));\n process.exit(1);\n }\n\n fs.unlinkSync(configPath);\n console.log(success(`✓ Agent removed: ${slug}`));\n}\n\nexport const agentCommand = new Command(\"agent\").description(\"Manage per-customer agents\");\n\nagentCommand\n .command(\"spawn <slug>\")\n .description(\"Spawn a wake-triggered agent for a customer\")\n .option(\"--channel <channel>\", \"Notification channel (telegram)\", \"telegram\")\n .option(\"--wake-on-email\", \"Wake agent on new email (default: on)\")\n .option(\"--chat-id <chatId>\", \"Telegram chat ID override\")\n .action((slug: string, opts: { channel?: string; wakeOnEmail?: boolean; chatId?: string }) =>\n runAgentSpawn(slug, opts, process.env[\"DXCRM_DATA_DIR\"])\n );\n\nagentCommand\n .command(\"status\")\n .description(\"Show all configured agents\")\n .action(() => runAgentStatus(process.env[\"DXCRM_DATA_DIR\"]));\n\nagentCommand\n .command(\"remove <slug>\")\n .description(\"Remove agent config for a customer\")\n .action((slug: string) => runAgentRemove(slug, process.env[\"DXCRM_DATA_DIR\"]));\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { createHash } from \"crypto\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport { appendInteraction, InteractionDedup } from \"../fs/interactions-writer.js\";\nimport { writeFileAtomic } from \"../fs/atomic-write.js\";\nimport { writeJsonFile } from \"../fs/json-store.js\";\n\ninterface ImportResult {\n customersCreated: number;\n interactionsImported: number;\n skipped: number;\n errors: string[];\n dealsImported?: number;\n leadsImported?: number;\n eventsImported?: number;\n casesImported?: number;\n quotesImported?: number;\n notesImported?: number;\n campaignsImported?: number;\n}\n\n/** Map a Salesforce StageName to opencrm's fixed pipeline stage enum. */\nfunction mapSalesforceStage(\n stageName?: string\n): \"lead\" | \"qualified\" | \"proposal\" | \"negotiation\" | \"won\" | \"lost\" {\n const s = (stageName ?? \"\").toLowerCase();\n if (s.includes(\"won\")) return \"won\";\n if (s.includes(\"lost\")) return \"lost\";\n if (s.includes(\"negoti\")) return \"negotiation\";\n if (s.includes(\"propos\") || s.includes(\"quote\")) return \"proposal\";\n if (s.includes(\"qualif\")) return \"qualified\";\n return \"lead\";\n}\n\n/** Map a Salesforce Case Status to opencrm's ticket status enum. */\nfunction mapCaseStatus(\n status?: string\n): \"open\" | \"in-progress\" | \"waiting\" | \"resolved\" | \"closed\" {\n const s = (status ?? \"\").toLowerCase();\n if (s.includes(\"closed\")) return \"closed\";\n if (s.includes(\"resolved\")) return \"resolved\";\n if (s.includes(\"escalat\") || s.includes(\"wait\") || s.includes(\"hold\")) return \"waiting\";\n if (s.includes(\"working\") || s.includes(\"progress\")) return \"in-progress\";\n return \"open\";\n}\n\n/** Map a Salesforce Case Priority to opencrm's ticket priority enum. */\nfunction mapCasePriority(priority?: string): \"urgent\" | \"high\" | \"normal\" | \"low\" {\n const p = (priority ?? \"\").toLowerCase();\n if (p.includes(\"urgent\") || p.includes(\"critical\")) return \"urgent\";\n if (p.includes(\"high\")) return \"high\";\n if (p.includes(\"low\")) return \"low\";\n return \"normal\";\n}\n\nfunction hashRow(row: Record<string, string>): string {\n return createHash(\"sha256\").update(JSON.stringify(row)).digest(\"hex\").slice(0, 16);\n}\n\nfunction slugify(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 60);\n}\n\nfunction parseCSV(content: string): Array<Record<string, string>> {\n const lines = content.trim().split(\"\\n\");\n if (lines.length < 2) return [];\n const headers = (lines[0] ?? \"\").split(\",\").map((h) => h.trim().replace(/^\"|\"$/g, \"\"));\n return lines.slice(1).map((line) => {\n const values = line.split(\",\").map((v) => v.trim().replace(/^\"|\"$/g, \"\"));\n const row: Record<string, string> = {};\n headers.forEach((h, i) => {\n row[h] = values[i] ?? \"\";\n });\n return row;\n });\n}\n\nconst IMPORT_TARGET_FIELDS = [\n \"name\",\n \"email\",\n \"domain\",\n \"notes\",\n \"date\",\n \"activityType\",\n \"sourceId\",\n] as const;\n\nfunction ensureCustomer(\n dataDir: string,\n name: string,\n domain: string,\n email: string,\n dryRun: boolean\n): { slug: string; created: boolean } {\n const slug = slugify(name || \"unknown\");\n const customerDir = path.join(dataDir, \"customers\", slug);\n const mainFactsPath = path.join(customerDir, \"main_facts.md\");\n\n if (fs.existsSync(mainFactsPath)) return { slug, created: false };\n if (dryRun) return { slug, created: true };\n\n fs.mkdirSync(customerDir, { recursive: true });\n\n const today = new Date().toISOString().slice(0, 10);\n const frontmatter = [\n \"---\",\n `name: ${name}`,\n domain ? `domain: ${domain}` : null,\n email ? `email: ${email}` : null,\n \"relationship_stage: prospect\",\n `created: ${today}`,\n `updated: ${today}`,\n `last_touchpoint: ${today}`,\n \"tags: []\",\n \"---\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n writeFileAtomic(mainFactsPath, `${frontmatter}\\n\\n# Customer: ${name}\\n`);\n writeFileAtomic(path.join(customerDir, \"interactions.md\"), `# Interactions — ${name}\\n\\n`);\n writeFileAtomic(path.join(customerDir, \"pipeline.md\"), `# Pipeline — ${name}\\n\\n`);\n writeJsonFile(path.join(customerDir, \"sources.json\"), {\n gmail: {\n query: domain\n ? `from:${domain} OR to:${domain}`\n : email\n ? `from:${email} OR to:${email}`\n : \"\",\n enabled: true,\n },\n transcripts: { paths: [], extensions: [\".txt\", \".vtt\"], enabled: false },\n });\n\n return { slug, created: true };\n}\n\nfunction readCsvFromDirectory(dirPath: string, filename: string): string | null {\n const variants = [filename, filename.toLowerCase(), filename.toUpperCase()];\n for (const name of variants) {\n const p = path.join(dirPath, name);\n if (fs.existsSync(p)) return fs.readFileSync(p, \"utf-8\") as string;\n }\n const files = fs.readdirSync(dirPath);\n const match = files.find((f) => f.toLowerCase() === filename.toLowerCase());\n if (match) return fs.readFileSync(path.join(dirPath, match), \"utf-8\") as string;\n return null;\n}\n\nasync function extractZip(zipPath: string): Promise<string> {\n const AdmZip = (await import(\"adm-zip\")).default;\n const zip = new AdmZip(zipPath);\n const tmpDir = `${zipPath}.extracted`;\n fs.mkdirSync(tmpDir, { recursive: true });\n zip.extractAllTo(tmpDir, true);\n return tmpDir;\n}\n\nasync function runSalesforceFileImport(\n sourcePath: string,\n opts: { dryRun?: boolean },\n dir: string\n): Promise<ImportResult> {\n const result: ImportResult = {\n customersCreated: 0,\n interactionsImported: 0,\n skipped: 0,\n errors: [],\n };\n\n let dataDir = sourcePath;\n let tmpDir: string | null = null;\n\n if (sourcePath.endsWith(\".zip\")) {\n tmpDir = await extractZip(sourcePath);\n dataDir = tmpDir;\n }\n\n if (!fs.statSync(dataDir).isDirectory()) {\n result.errors.push(\"Salesforce file import requires a directory or .zip file\");\n return result;\n }\n\n const accountsCsv =\n readCsvFromDirectory(dataDir, \"Accounts.csv\") ?? readCsvFromDirectory(dataDir, \"accounts.csv\");\n const activitiesCsv =\n readCsvFromDirectory(dataDir, \"Activities.csv\") ??\n readCsvFromDirectory(dataDir, \"activities.csv\") ??\n readCsvFromDirectory(dataDir, \"Tasks.csv\") ??\n readCsvFromDirectory(dataDir, \"tasks.csv\");\n\n if (!accountsCsv) {\n result.errors.push(\"Could not find Accounts.csv in Salesforce export\");\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true });\n return result;\n }\n\n const accounts = parseCSV(accountsCsv);\n const activities = activitiesCsv ? parseCSV(activitiesCsv) : [];\n\n if (opts.dryRun) {\n console.log(\n info(\n `Dry run — ${accounts.length} accounts, ${activities.length} activities from Salesforce export`\n )\n );\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true });\n return result;\n }\n\n const slugMap = new Map<string, string>();\n for (const row of accounts) {\n const name = (row[\"Name\"] ?? row[\"Account Name\"] ?? \"\").trim();\n if (!name) continue;\n const domain = (row[\"Website\"] ?? \"\").replace(/^https?:\\/\\//, \"\");\n const email = row[\"Email\"] ?? \"\";\n try {\n const { slug, created } = ensureCustomer(dir, name, domain, email, false);\n if (row[\"Id\"]) slugMap.set(row[\"Id\"], slug);\n slugMap.set(name.toLowerCase(), slug);\n if (created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Account '${name}': ${(err as Error).message}`);\n }\n }\n\n const dedup = new InteractionDedup(dir);\n for (const row of activities) {\n const accountId = row[\"AccountId\"] ?? row[\"WhatId\"] ?? \"\";\n const slug = accountId ? slugMap.get(accountId) : undefined;\n if (!slug) continue;\n\n const id = row[\"Id\"] ?? hashRow(row);\n const sourceRef = `salesforce://row/${id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date = row[\"ActivityDate\"] ?? row[\"CreatedDate\"] ?? new Date().toISOString().slice(0, 10);\n const notes = (row[\"Description\"] ?? row[\"Subject\"] ?? \"\").slice(0, 500);\n const t = (row[\"Type\"] ?? \"\").toLowerCase();\n const type = t.includes(\"call\")\n ? (\"Call\" as const)\n : t.includes(\"email\")\n ? (\"Email\" as const)\n : t.includes(\"meeting\")\n ? (\"Meeting\" as const)\n : (\"Note\" as const);\n\n try {\n await appendInteraction(dir, slug, {\n date,\n type,\n with: slug,\n summary: notes,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.interactionsImported++;\n } catch (err) {\n result.errors.push(`Activity ${id}: ${(err as Error).message}`);\n }\n }\n\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true });\n return result;\n}\n\nasync function runPipedriveFileImport(\n sourcePath: string,\n opts: { dryRun?: boolean },\n dir: string\n): Promise<ImportResult> {\n const result: ImportResult = {\n customersCreated: 0,\n interactionsImported: 0,\n skipped: 0,\n errors: [],\n };\n\n let dataDir = sourcePath;\n let tmpDir: string | null = null;\n\n if (sourcePath.endsWith(\".zip\")) {\n tmpDir = await extractZip(sourcePath);\n dataDir = tmpDir;\n }\n\n if (!fs.statSync(dataDir).isDirectory()) {\n result.errors.push(\"Pipedrive file import requires a directory or .zip file\");\n return result;\n }\n\n const orgsCsv =\n readCsvFromDirectory(dataDir, \"organizations.csv\") ??\n readCsvFromDirectory(dataDir, \"Organizations.csv\");\n const activitiesCsv =\n readCsvFromDirectory(dataDir, \"activities.csv\") ??\n readCsvFromDirectory(dataDir, \"Activities.csv\");\n\n if (!orgsCsv) {\n result.errors.push(\"Could not find organizations.csv in Pipedrive export\");\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true });\n return result;\n }\n\n const orgs = parseCSV(orgsCsv);\n const activities = activitiesCsv ? parseCSV(activitiesCsv) : [];\n\n if (opts.dryRun) {\n console.log(\n info(\n `Dry run — ${orgs.length} organizations, ${activities.length} activities from Pipedrive export`\n )\n );\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true });\n return result;\n }\n\n const slugMap = new Map<string, string>();\n for (const row of orgs) {\n const name = (row[\"name\"] ?? row[\"Name\"] ?? \"\").trim();\n if (!name) continue;\n const id = row[\"id\"] ?? row[\"ID\"] ?? \"\";\n try {\n const { slug, created } = ensureCustomer(dir, name, \"\", \"\", false);\n if (id) slugMap.set(id, slug);\n slugMap.set(name.toLowerCase(), slug);\n if (created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Organization '${name}': ${(err as Error).message}`);\n }\n }\n\n const dedup = new InteractionDedup(dir);\n for (const row of activities) {\n const orgId = row[\"org_id\"] ?? row[\"organization_id\"] ?? \"\";\n const slug = orgId ? slugMap.get(orgId) : undefined;\n if (!slug) continue;\n\n const id = row[\"id\"] ?? hashRow(row);\n const sourceRef = `pipedrive://row/${id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date =\n row[\"due_date\"] ?? row[\"add_time\"]?.slice(0, 10) ?? new Date().toISOString().slice(0, 10);\n const notes = (row[\"note\"] ?? row[\"subject\"] ?? \"\").slice(0, 500);\n const t = (row[\"type\"] ?? \"\").toLowerCase();\n const type =\n t === \"call\"\n ? (\"Call\" as const)\n : t === \"email\"\n ? (\"Email\" as const)\n : t === \"meeting\"\n ? (\"Meeting\" as const)\n : (\"Note\" as const);\n\n try {\n await appendInteraction(dir, slug, {\n date,\n type,\n with: slug,\n summary: notes,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.interactionsImported++;\n } catch (err) {\n result.errors.push(`Activity ${id}: ${(err as Error).message}`);\n }\n }\n\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true });\n return result;\n}\n\nexport async function runImport(\n sourcePath: string,\n opts: {\n from: string;\n dryRun?: boolean;\n mode?: string;\n token?: string;\n url?: string;\n ownerMap?: Record<string, string>;\n resume?: boolean;\n },\n dataDir?: string\n): Promise<ImportResult> {\n const dir = dataDir ?? process.cwd();\n const result: ImportResult = {\n customersCreated: 0,\n interactionsImported: 0,\n skipped: 0,\n errors: [],\n };\n\n // API import modes — bypass file reading\n if (opts.from === \"salesforce\" && opts.mode === \"api\") {\n return runSalesforceApiImport(opts, dir);\n }\n if (opts.from === \"pipedrive\" && opts.mode === \"api\") {\n return runPipedriveApiImport(opts, dir);\n }\n\n // HubSpot multi-file export directory: route to dedicated importer\n // Single-file HubSpot CSV falls through to generic LLM-mapping flow below\n if (\n opts.from === \"hubspot\" &&\n sourcePath &&\n fs.existsSync(sourcePath) &&\n fs.statSync(sourcePath).isDirectory()\n ) {\n const { runHubSpotCsvImport } = await import(\"./import-hubspot.js\");\n const r = await runHubSpotCsvImport(sourcePath, dir, {\n ...(opts.dryRun ? { dryRun: true } : {}),\n ...(opts.resume ? { resume: true } : {}),\n ownerMap: opts.ownerMap ?? {},\n });\n if (r.customPropertiesSaved > 0) {\n console.error(`[import] Custom properties saved: ${r.customPropertiesSaved}`);\n }\n if (r.ownersResolved > 0) {\n console.error(`[import] Owners resolved: ${r.ownersResolved}`);\n }\n return {\n customersCreated: r.companiesProcessed,\n interactionsImported: r.engagementsImported + r.dealsImported + r.contactsImported,\n skipped: 0,\n errors: r.errors,\n };\n }\n if (opts.from === \"salesforce\" && sourcePath) {\n return runSalesforceFileImport(sourcePath, opts, dir);\n }\n if (opts.from === \"pipedrive\" && sourcePath) {\n return runPipedriveFileImport(sourcePath, opts, dir);\n }\n\n if (!fs.existsSync(sourcePath)) {\n console.error(error(`✗ File not found: ${sourcePath}`));\n process.exit(1);\n }\n\n const content = fs.readFileSync(sourcePath, \"utf-8\");\n const rows = parseCSV(content);\n\n if (rows.length === 0) {\n console.log(info(\"No rows found in CSV.\"));\n return result;\n }\n\n const headers = Object.keys(rows[0]!);\n const { mapCsvFields } = await import(\"../core/llm.js\");\n const mapping = await mapCsvFields(headers, [...IMPORT_TARGET_FIELDS]);\n\n if (opts.dryRun) {\n console.log(info(`Dry run — ${rows.length} rows, field mapping:`));\n Object.entries(mapping).forEach(([k, v]) => v && console.log(info(` ${k} ← \"${v}\"`)));\n console.log(info(`\\nWould create up to ${rows.length} customers and interaction entries.`));\n return result;\n }\n\n // Pass 1: Create customers\n const customerRows = rows.filter((r) => {\n const name = r[mapping.name ?? \"\"] ?? \"\";\n return name.trim().length > 0;\n });\n\n const slugMap = new Map<string, string>();\n\n for (const row of customerRows) {\n const name = (row[mapping.name ?? \"\"] ?? \"\").trim();\n if (!name) continue;\n\n const domain = (row[mapping.domain ?? \"\"] ?? \"\").trim();\n const email = (row[mapping.email ?? \"\"] ?? \"\").trim();\n\n try {\n const { slug, created } = ensureCustomer(dir, name, domain, email, opts.dryRun ?? false);\n slugMap.set(name.toLowerCase(), slug);\n if (created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Customer '${name}': ${(err as Error).message}`);\n }\n }\n\n // Pass 2: Import activities/notes\n const dedup = new InteractionDedup(dir);\n for (const row of rows) {\n const activityType = (row[mapping[\"activityType\"] ?? \"\"] ?? \"\").trim();\n const notes = (row[mapping[\"notes\"] ?? \"\"] ?? \"\").trim();\n const activityDate = (row[mapping[\"date\"] ?? \"\"] ?? \"\").trim();\n const sourceIdVal = (row[mapping[\"sourceId\"] ?? \"\"] ?? \"\").trim();\n const name = (row[mapping[\"name\"] ?? \"\"] ?? \"\").trim();\n\n if (!notes && !activityType) continue;\n\n const slug = slugMap.get(name.toLowerCase());\n if (!slug) continue;\n\n const rowHash = hashRow(row);\n const prefix = opts.from === \"hubspot\" ? \"hubspot\" : \"csv\";\n const sourceRef = sourceIdVal\n ? `${prefix}://activity/${sourceIdVal}`\n : `${prefix}://row/${rowHash}`;\n\n const date = activityDate\n ? (() => {\n try {\n return new Date(activityDate).toISOString().slice(0, 10);\n } catch {\n return new Date().toISOString().slice(0, 10);\n }\n })()\n : new Date().toISOString().slice(0, 10);\n\n const type = (() => {\n const t = activityType.toLowerCase();\n if (t.includes(\"call\")) return \"Call\" as const;\n if (t.includes(\"meeting\") || t.includes(\"demo\")) return \"Meeting\" as const;\n if (t.includes(\"email\")) return \"Email\" as const;\n if (t.includes(\"note\")) return \"Note\" as const;\n return \"Note\" as const;\n })();\n\n try {\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n await appendInteraction(dir, slug, {\n date,\n type,\n with: name,\n summary: notes.slice(0, 500),\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n\n result.interactionsImported++;\n } catch (err) {\n result.errors.push(`Activity for '${name}': ${(err as Error).message}`);\n }\n }\n\n return result;\n}\n\nasync function runSalesforceApiImport(\n opts: { token?: string; url?: string; dryRun?: boolean },\n dir: string\n): Promise<ImportResult> {\n const result: ImportResult = {\n customersCreated: 0,\n interactionsImported: 0,\n skipped: 0,\n errors: [],\n };\n const token = opts.token ?? process.env[\"SFDC_TOKEN\"] ?? \"\";\n const instanceUrl = opts.url ?? process.env[\"SFDC_URL\"] ?? \"\";\n\n if (!token || !instanceUrl) {\n console.error(\n error(\"✗ Salesforce API mode requires --token and --url (or SFDC_TOKEN + SFDC_URL env vars)\")\n );\n process.exit(1);\n }\n\n const {\n fetchSalesforceContacts,\n fetchSalesforceTasks,\n fetchSalesforceOpportunities,\n fetchSalesforceLeads,\n fetchSalesforceEvents,\n fetchSalesforceCases,\n fetchSalesforceLineItems,\n fetchSalesforceNotes,\n fetchSalesforceCampaignMembers,\n } = await import(\"../sync/salesforce-client.js\");\n\n let contacts: Awaited<ReturnType<typeof fetchSalesforceContacts>>;\n let tasks: Awaited<ReturnType<typeof fetchSalesforceTasks>>;\n let opportunities: Awaited<ReturnType<typeof fetchSalesforceOpportunities>>;\n let leads: Awaited<ReturnType<typeof fetchSalesforceLeads>>;\n let events: Awaited<ReturnType<typeof fetchSalesforceEvents>>;\n let cases: Awaited<ReturnType<typeof fetchSalesforceCases>>;\n let lineItems: Awaited<ReturnType<typeof fetchSalesforceLineItems>>;\n let notes: Awaited<ReturnType<typeof fetchSalesforceNotes>>;\n let campaignMembers: Awaited<ReturnType<typeof fetchSalesforceCampaignMembers>>;\n\n try {\n contacts = await fetchSalesforceContacts(instanceUrl, token);\n tasks = await fetchSalesforceTasks(instanceUrl, token);\n opportunities = (await fetchSalesforceOpportunities(instanceUrl, token)) ?? [];\n leads = (await fetchSalesforceLeads(instanceUrl, token)) ?? [];\n events = (await fetchSalesforceEvents(instanceUrl, token)) ?? [];\n cases = (await fetchSalesforceCases(instanceUrl, token)) ?? [];\n lineItems = (await fetchSalesforceLineItems(instanceUrl, token)) ?? [];\n notes = (await fetchSalesforceNotes(instanceUrl, token)) ?? [];\n campaignMembers = (await fetchSalesforceCampaignMembers(instanceUrl, token)) ?? [];\n } catch (err) {\n result.errors.push(`Salesforce API: ${(err as Error).message}`);\n return result;\n }\n\n if (opts.dryRun) {\n console.log(\n info(\n `Dry run — ${contacts.length} contacts, ${tasks.length} tasks, ${opportunities.length} opportunities, ${leads.length} leads, ${events.length} events, ${cases.length} cases from Salesforce`\n )\n );\n return result;\n }\n\n // Pass 1: contacts → customers\n const slugMap = new Map<string, string>();\n for (const contact of contacts) {\n const name = contact.Name?.trim();\n if (!name) continue;\n const domain = contact.Account?.Website?.replace(/^https?:\\/\\//, \"\") ?? \"\";\n const email = contact.Email ?? \"\";\n try {\n const { slug, created } = ensureCustomer(dir, name, domain, email, false);\n slugMap.set(contact.Id, slug);\n slugMap.set(name.toLowerCase(), slug);\n if (created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Contact '${name}': ${(err as Error).message}`);\n }\n }\n\n // Pass 2: tasks → interactions\n const dedup = new InteractionDedup(dir);\n for (const task of tasks) {\n const slug = task.WhoId ? slugMap.get(task.WhoId) : undefined;\n if (!slug) continue;\n\n const sourceRef = `salesforce://task/${task.Id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date = task.ActivityDate ?? new Date().toISOString().slice(0, 10);\n const notes = (task.Description ?? task.Subject ?? \"\").slice(0, 500);\n const t = (task.Type ?? \"\").toLowerCase();\n const type = t.includes(\"call\")\n ? (\"Call\" as const)\n : t.includes(\"email\")\n ? (\"Email\" as const)\n : t.includes(\"meeting\")\n ? (\"Meeting\" as const)\n : (\"Note\" as const);\n\n try {\n await appendInteraction(dir, slug, {\n date,\n type,\n with: slug,\n summary: notes,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.interactionsImported++;\n } catch (err) {\n result.errors.push(`Task ${task.Id}: ${(err as Error).message}`);\n }\n }\n\n // Pass 3: opportunities → pipeline deals\n const { upsertDeal } = await import(\"../fs/pipeline-writer.js\");\n const today = new Date().toISOString().slice(0, 10);\n const oppSlugById = new Map<string, { slug: string; dealName: string }>();\n for (const opp of opportunities) {\n const accountName = opp.Account?.Name?.trim();\n if (!opp.Name || !accountName) continue;\n\n let slug = slugMap.get(accountName.toLowerCase());\n if (!slug) {\n const domain = opp.Account?.Website?.replace(/^https?:\\/\\//, \"\") ?? \"\";\n try {\n const r = ensureCustomer(dir, accountName, domain, \"\", false);\n slug = r.slug;\n slugMap.set(accountName.toLowerCase(), slug);\n if (r.created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Opportunity '${opp.Name}': ${(err as Error).message}`);\n continue;\n }\n }\n oppSlugById.set(opp.Id, { slug, dealName: opp.Name });\n\n try {\n await upsertDeal(dir, slug, {\n name: opp.Name,\n stage: mapSalesforceStage(opp.StageName),\n currency: \"EUR\",\n updated: today,\n notes: `Imported from Salesforce (${opp.StageName ?? \"unknown stage\"})`,\n ...(typeof opp.Amount === \"number\" ? { value: opp.Amount } : {}),\n ...(typeof opp.Probability === \"number\" ? { probability: opp.Probability } : {}),\n ...(opp.CloseDate ? { close_date: opp.CloseDate } : {}),\n });\n result.dealsImported = (result.dealsImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`Opportunity '${opp.Name}': ${(err as Error).message}`);\n }\n }\n\n // Pass 4: leads → customers (+ a lead interaction capturing status/title)\n for (const lead of leads) {\n const name = lead.Company?.trim() || lead.Name?.trim();\n if (!name) continue;\n\n const domain = lead.Website?.replace(/^https?:\\/\\//, \"\") ?? lead.Email?.split(\"@\")[1] ?? \"\";\n let slug: string;\n try {\n const r = ensureCustomer(dir, name, domain, lead.Email ?? \"\", false);\n slug = r.slug;\n slugMap.set(name.toLowerCase(), slug);\n if (r.created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Lead '${name}': ${(err as Error).message}`);\n continue;\n }\n\n const sourceRef = `salesforce://lead/${lead.Id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const contactPart = lead.Title ? `${lead.Name}, ${lead.Title}` : lead.Name;\n try {\n await appendInteraction(dir, slug, {\n date: new Date().toISOString().slice(0, 10),\n type: \"Note\",\n with: lead.Name,\n summary: `Salesforce Lead imported (status: ${lead.Status ?? \"n/a\"}; contact: ${contactPart})`,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.leadsImported = (result.leadsImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`Lead ${lead.Id}: ${(err as Error).message}`);\n }\n }\n\n // Pass 5: events (calendar) → Meeting interactions, linked by WhoId/WhatId\n for (const event of events) {\n const slug = event.WhoId\n ? slugMap.get(event.WhoId)\n : event.WhatId\n ? slugMap.get(event.WhatId)\n : undefined;\n if (!slug) {\n result.skipped++;\n continue;\n }\n\n const sourceRef = `salesforce://event/${event.Id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date = (event.StartDateTime ?? event.ActivityDate ?? new Date().toISOString()).slice(\n 0,\n 10\n );\n try {\n await appendInteraction(dir, slug, {\n date,\n type: \"Meeting\",\n with: slug,\n subject: event.Subject ?? \"Salesforce Event\",\n summary: (event.Description ?? event.Subject ?? \"\").slice(0, 500),\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.eventsImported = (result.eventsImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`Event ${event.Id}: ${(err as Error).message}`);\n }\n }\n\n // Pass 6: cases → tickets (status/priority mapped, SLA computed, deduped by case ref)\n const { readTickets, upsertTicket, nextTicketId } = await import(\"../fs/ticket-writer.js\");\n const { calcSlaDue, loadSlaRules } = await import(\"../core/sla-engine.js\");\n const slaRules = loadSlaRules(dir);\n for (const c of cases) {\n const accountName = c.Account?.Name?.trim();\n if (!accountName) {\n result.skipped++;\n continue;\n }\n let slug = slugMap.get(accountName.toLowerCase());\n if (!slug) {\n try {\n const r = ensureCustomer(dir, accountName, \"\", \"\", false);\n slug = r.slug;\n slugMap.set(accountName.toLowerCase(), slug);\n if (r.created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Case '${c.Id}': ${(err as Error).message}`);\n continue;\n }\n }\n // Make the account/contact reachable for note linking (Pass 8)\n if (c.AccountId) slugMap.set(c.AccountId, slug);\n if (c.ContactId) slugMap.set(c.ContactId, slug);\n\n const caseRef = `salesforce://case/${c.Id}`;\n const existingTickets = await readTickets(dir, slug);\n if (existingTickets.some((t) => (t.description ?? \"\").includes(caseRef))) {\n result.skipped++;\n continue;\n }\n\n const created = (c.CreatedDate ?? new Date().toISOString()).slice(0, 10);\n const status = mapCaseStatus(c.Status);\n const priority = mapCasePriority(c.Priority);\n const isDone = status === \"closed\" || status === \"resolved\";\n try {\n await upsertTicket(dir, slug, {\n id: nextTicketId(existingTickets),\n title: c.Subject ?? `Case ${c.CaseNumber ?? c.Id}`,\n status,\n priority,\n created,\n slaDue: calcSlaDue(created, priority, slaRules),\n description: `${c.Description ?? \"\"}\\n\\n[${caseRef}]`.trim(),\n ...(isDone ? { resolved: (c.ClosedDate ?? created).slice(0, 10) } : {}),\n });\n result.casesImported = (result.casesImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`Case ${c.Id}: ${(err as Error).message}`);\n }\n }\n\n // Pass 7: opportunity line items → one quote per opportunity\n if (lineItems.length > 0 && oppSlugById.size > 0) {\n const { generateQuote, listQuotes } = await import(\"../core/quote-generator.js\");\n const byOpp = new Map<string, typeof lineItems>();\n for (const li of lineItems) {\n if (!li.OpportunityId) continue;\n const arr = byOpp.get(li.OpportunityId) ?? [];\n arr.push(li);\n byOpp.set(li.OpportunityId, arr);\n }\n for (const [oppId, items] of byOpp) {\n const opp = oppSlugById.get(oppId);\n if (!opp) continue;\n // Dedup: skip if a quote for this deal already exists for the customer.\n if (listQuotes(dir, opp.slug).some((q) => q.dealName === opp.dealName)) {\n result.skipped++;\n continue;\n }\n const quoteLineItems = items.map((li) => {\n const quantity = typeof li.Quantity === \"number\" && li.Quantity > 0 ? li.Quantity : 1;\n const unitPrice =\n typeof li.UnitPrice === \"number\"\n ? li.UnitPrice\n : typeof li.TotalPrice === \"number\"\n ? li.TotalPrice / quantity\n : 0;\n return {\n description: li.Product2?.Name ?? li.Description ?? \"Line item\",\n quantity,\n unitPrice,\n };\n });\n try {\n await generateQuote(dir, {\n slug: opp.slug,\n dealName: opp.dealName,\n lineItems: quoteLineItems,\n });\n result.quotesImported = (result.quotesImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`LineItems for '${opp.dealName}': ${(err as Error).message}`);\n }\n }\n }\n\n // Pass 8: notes → Note interactions, linked by ParentId (account/contact/opp)\n for (const note of notes) {\n const slug = note.ParentId ? slugMap.get(note.ParentId) : undefined;\n if (!slug) {\n result.skipped++;\n continue;\n }\n const sourceRef = `salesforce://note/${note.Id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n const date = (note.CreatedDate ?? new Date().toISOString()).slice(0, 10);\n const title = note.Title ?? \"Salesforce Note\";\n try {\n await appendInteraction(dir, slug, {\n date,\n type: \"Note\",\n with: slug,\n subject: title,\n summary: `${title}${note.Body ? `: ${note.Body}` : \"\"}`.slice(0, 500),\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.notesImported = (result.notesImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`Note ${note.Id}: ${(err as Error).message}`);\n }\n }\n\n // Pass 9: campaign members → Note interactions, linked by ContactId/LeadId\n for (const cm of campaignMembers) {\n const slug = cm.ContactId\n ? slugMap.get(cm.ContactId)\n : cm.LeadId\n ? slugMap.get(cm.LeadId)\n : undefined;\n if (!slug) {\n result.skipped++;\n continue;\n }\n const sourceRef = `salesforce://campaignmember/${cm.Id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n const campaignName = cm.Campaign?.Name ?? cm.CampaignId ?? \"Unknown campaign\";\n try {\n await appendInteraction(dir, slug, {\n date: (cm.CreatedDate ?? new Date().toISOString()).slice(0, 10),\n type: \"Note\",\n with: slug,\n subject: `Campaign: ${campaignName}`,\n summary: `Salesforce Campaign: ${campaignName} (status: ${cm.Status ?? \"n/a\"})`,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.campaignsImported = (result.campaignsImported ?? 0) + 1;\n } catch (err) {\n result.errors.push(`CampaignMember ${cm.Id}: ${(err as Error).message}`);\n }\n }\n\n return result;\n}\n\nexport async function runPipedriveApiImport(\n opts: { token?: string; url?: string; dryRun?: boolean },\n dir: string = process.cwd()\n): Promise<ImportResult> {\n const result: ImportResult = {\n customersCreated: 0,\n interactionsImported: 0,\n skipped: 0,\n errors: [],\n };\n const token = opts.token ?? process.env[\"PIPEDRIVE_TOKEN\"] ?? \"\";\n const instanceUrl = opts.url ?? process.env[\"PIPEDRIVE_URL\"] ?? \"\";\n\n if (!token || !instanceUrl) {\n result.errors.push(\n \"Pipedrive API mode requires --token and --url (or PIPEDRIVE_TOKEN + PIPEDRIVE_URL env vars)\"\n );\n return result;\n }\n\n const { fetchPipedrivePersons, fetchPipedriveActivities } =\n await import(\"../sync/pipedrive-client.js\");\n\n let persons: Awaited<ReturnType<typeof fetchPipedrivePersons>>;\n let activities: Awaited<ReturnType<typeof fetchPipedriveActivities>>;\n\n try {\n [persons, activities] = await Promise.all([\n fetchPipedrivePersons(instanceUrl, token),\n fetchPipedriveActivities(instanceUrl, token),\n ]);\n } catch (err) {\n result.errors.push(`Pipedrive API: ${(err as Error).message}`);\n return result;\n }\n\n if (opts.dryRun) {\n console.log(\n info(`Dry run — ${persons.length} persons, ${activities.length} activities from Pipedrive`)\n );\n return result;\n }\n\n // Pass 1: persons → customers\n const slugByPersonId = new Map<number, string>();\n const slugByOrgId = new Map<number, string>();\n\n for (const person of persons) {\n const name = (person.org_name ?? person.name ?? \"\").trim();\n if (!name) continue;\n const email = person.primary_email ?? \"\";\n try {\n const { slug, created } = ensureCustomer(dir, name, \"\", email, false);\n if (person.id) slugByPersonId.set(person.id, slug);\n if (person.org_id?.value) slugByOrgId.set(person.org_id.value, slug);\n if (created) result.customersCreated++;\n } catch (err) {\n result.errors.push(`Person '${name}': ${(err as Error).message}`);\n }\n }\n\n // Pass 2: activities → interactions\n const dedup = new InteractionDedup(dir);\n for (const activity of activities) {\n const slug =\n (activity.person_id && slugByPersonId.get(activity.person_id)) ??\n (activity.org_id && slugByOrgId.get(activity.org_id)) ??\n undefined;\n if (!slug) continue;\n\n const sourceRef = `pipedrive://activity/${activity.id}`;\n if (await dedup.seen(slug, sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date = activity.due_date ?? new Date().toISOString().slice(0, 10);\n const notes = (activity.note ?? activity.subject ?? \"\").slice(0, 500);\n const t = (activity.type ?? \"\").toLowerCase();\n const type =\n t === \"call\"\n ? (\"Call\" as const)\n : t === \"email\"\n ? (\"Email\" as const)\n : t === \"meeting\"\n ? (\"Meeting\" as const)\n : (\"Note\" as const);\n\n try {\n await appendInteraction(dir, slug, {\n date,\n type,\n with: slug,\n summary: `${activity.subject ?? type}: ${notes}`,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n });\n dedup.markAppended(slug, sourceRef);\n result.interactionsImported++;\n } catch (err) {\n result.errors.push(`Activity ${activity.id}: ${(err as Error).message}`);\n }\n }\n\n return result;\n}\n\nexport const importCommand = new Command(\"import\")\n .description(\"Import customers and interactions from HubSpot, Salesforce, Pipedrive, or CSV\")\n .argument(\"[path]\", \"Path to export file or directory\")\n .option(\"--from <source>\", \"Source CRM: hubspot | csv | salesforce | pipedrive\", \"csv\")\n .option(\"--dry-run\", \"Preview what would be imported without writing\")\n .option(\"--mode <mode>\", \"Import mode: file | api\")\n .option(\"--token <token>\", \"API token (Salesforce, Pipedrive, HubSpot)\")\n .option(\"--url <url>\", \"Instance URL (e.g. https://myco.salesforce.com)\")\n .option(\"--analyze\", \"Analyze export and show what would be imported (no write)\")\n .option(\"--resume\", \"Resume a previously interrupted import\")\n .option(\n \"--owner-map <mapping>\",\n 'Map HubSpot owner emails to reps: \"alice@hs.com=alice,bob@hs.com=bob\"'\n )\n .action(\n async (\n sourcePath: string,\n opts: {\n from: string;\n dryRun?: boolean;\n mode?: string;\n token?: string;\n url?: string;\n analyze?: boolean;\n resume?: boolean;\n ownerMap?: string;\n }\n ) => {\n const dryRun = opts.dryRun ?? false;\n\n // Parse owner map\n const ownerMap: Record<string, string> = {};\n if (opts.ownerMap) {\n for (const pair of opts.ownerMap.split(\",\")) {\n const [hs, rep] = pair.split(\"=\");\n if (hs && rep) ownerMap[hs.trim()] = rep.trim();\n }\n }\n\n // HubSpot analyze mode\n if (opts.analyze && opts.from === \"hubspot\" && sourcePath) {\n const { analyzeHubSpotExport } = await import(\"./import-hubspot.js\");\n const analysis = await analyzeHubSpotExport(sourcePath);\n console.log(bold(\"\\nDatasynxOpenCRM — HubSpot Import Analysis\"));\n console.log(\"==========================================\");\n console.log(info(`Companies: ${analysis.companiesFound}`));\n console.log(\n info(\n `Contacts: ${analysis.contactsFound} (${analysis.unmappedContacts} unmapped companies)`\n )\n );\n console.log(info(`Deals: ${analysis.dealsFound}`));\n console.log(info(`Engagements: ${analysis.engagementsFound}`));\n if (analysis.customPropertiesDetected.length > 0) {\n console.log(\n info(`\\nCustom Properties: ${analysis.customPropertiesDetected.length} detected`)\n );\n console.log(\n ` ${analysis.customPropertiesDetected.slice(0, 10).join(\", \")}${analysis.customPropertiesDetected.length > 10 ? \" ...\" : \"\"}`\n );\n }\n if (analysis.ownersDetected.length > 0) {\n console.log(info(`\\nOwners detected: ${analysis.ownersDetected.join(\", \")}`));\n console.log(\n ` Use --owner-map \"${analysis.ownersDetected.map((o) => `${o}=<rep>`).join(\",\")}\"`\n );\n }\n if (analysis.unknownStages.length > 0) {\n console.log(\n info(`\\nUnknown stages (→ \"qualified\"): ${analysis.unknownStages.join(\", \")}`)\n );\n }\n console.log(info(`\\nEstimated import time: ~${analysis.estimatedMinutes} min`));\n console.log(info(`\\nRun without --analyze to start import.`));\n return;\n }\n\n if (!dryRun) {\n console.log(info(`Importing from ${bold(opts.from)}: ${sourcePath}`));\n }\n\n const result = await runImport(\n sourcePath,\n {\n from: opts.from,\n ...(dryRun ? { dryRun: true } : {}),\n ...(opts.mode ? { mode: opts.mode } : {}),\n ...(opts.token ? { token: opts.token } : {}),\n ...(opts.url ? { url: opts.url } : {}),\n ...(opts.resume ? { resume: true } : {}),\n ownerMap,\n },\n process.env[\"DXCRM_DATA_DIR\"]\n );\n\n if (!dryRun) {\n console.log(success(`✓ Import complete:`));\n console.log(info(` Customers created: ${result.customersCreated}`));\n console.log(info(` Interactions imported: ${result.interactionsImported}`));\n console.log(info(` Skipped (duplicates): ${result.skipped}`));\n if (result.errors.length > 0) {\n console.log(error(` Errors (${result.errors.length}):`));\n result.errors.slice(0, 5).forEach((e) => console.log(error(` ${e}`)));\n }\n }\n }\n );\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { spawn } from \"child_process\";\nimport { success, info } from \"../ui/colors.js\";\n\nfunction getPidFile(dataDir: string): string {\n return path.join(dataDir, \".agentic\", \"server.pid\");\n}\n\nexport async function runServerStart(\n opts: { port?: string; data?: string },\n dataDir?: string\n): Promise<void> {\n const port = parseInt(opts.port ?? \"3847\", 10);\n const dir = opts.data ?? dataDir ?? process.cwd();\n\n // Set env var if --data provided\n if (opts.data) {\n process.env[\"DXCRM_DATA_DIR\"] = opts.data;\n }\n\n const pidFile = getPidFile(dir);\n\n // Check if already running\n if (fs.existsSync(pidFile)) {\n const existing = parseInt(fs.readFileSync(pidFile, \"utf-8\").trim(), 10);\n if (!isNaN(existing)) {\n try {\n process.kill(existing, 0);\n console.log(info(`Server already running (PID ${existing})`));\n return;\n } catch {\n // stale PID file — continue\n }\n }\n }\n\n // Spawn the MCP HTTP server process\n const serverEntry = path.resolve(\n path.dirname(new URL(import.meta.url).pathname),\n \"../../dist/mcp/server.js\"\n );\n\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n DXCRM_MCP_MODE: \"http\",\n DXCRM_MCP_PORT: String(port),\n };\n\n if (opts.data) {\n env[\"DXCRM_DATA_DIR\"] = opts.data;\n }\n\n const child = spawn(process.execPath, [serverEntry], {\n detached: true,\n stdio: \"ignore\",\n env,\n });\n child.unref();\n\n // Write PID file\n fs.mkdirSync(path.dirname(pidFile), { recursive: true });\n fs.writeFileSync(pidFile, String(child.pid), \"utf-8\");\n\n const hostname = os.hostname();\n\n console.log(success(`DatasynxOpenCRM server running on http://0.0.0.0:${port}/mcp`));\n console.log(info(`Data dir: ${dir}`));\n console.log(info(`Add to your AI framework config: url: http://${hostname}:${port}/mcp`));\n}\n\nexport function runServerStatus(dataDir?: string): void {\n const dir = process.env[\"DXCRM_DATA_DIR\"] ?? dataDir ?? process.cwd();\n const pidFile = getPidFile(dir);\n\n if (!fs.existsSync(pidFile)) {\n console.log(info(\"Server: not running.\"));\n return;\n }\n\n const pid = parseInt(fs.readFileSync(pidFile, \"utf-8\").trim(), 10);\n if (isNaN(pid)) {\n console.log(info(\"Server: not running (invalid PID file).\"));\n return;\n }\n\n try {\n process.kill(pid, 0);\n console.log(success(`Server: running (PID ${pid})`));\n } catch {\n console.log(info(\"Server: not running (stale PID file).\"));\n try {\n fs.unlinkSync(pidFile);\n } catch {\n // ignore\n }\n }\n}\n\nexport const serverCommand = new Command(\"server\").description(\n \"Start the shared HTTP MCP server for team use\"\n);\n\nserverCommand\n .command(\"start\")\n .description(\"Start the DatasynxOpenCRM HTTP MCP server\")\n .option(\"--port <port>\", \"HTTP port (default 3847)\", \"3847\")\n .option(\"--data <dir>\", \"Data directory (sets DXCRM_DATA_DIR)\")\n .action((opts: { port: string; data?: string }) => runServerStart(opts));\n\nserverCommand\n .command(\"status\")\n .description(\"Check if the server is running\")\n .action(() => runServerStatus());\n","import { Command } from \"commander\";\nimport { readAuditLog, filterAuditLog } from \"../fs/audit-log.js\";\n\nconst SEP = \"─\".repeat(70);\n\nexport async function runAudit(\n opts: {\n slug?: string;\n actor?: string;\n limit?: number;\n tail?: boolean;\n },\n dataDir?: string\n): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const limit = opts.limit ?? 20;\n\n const allEntries = readAuditLog(dir);\n const entries = filterAuditLog(allEntries, {\n ...(opts.slug !== undefined ? { slug: opts.slug } : {}),\n ...(opts.actor !== undefined ? { actor: opts.actor } : {}),\n limit,\n });\n\n console.log(SEP);\n console.log(\" DatasynxOpenCRM — Audit Trail\");\n\n if (opts.slug) console.log(` Customer: ${opts.slug}`);\n if (opts.actor) console.log(` Actor: ${opts.actor}`);\n\n console.log(SEP);\n\n if (entries.length === 0) {\n console.log(\" No audit entries found.\");\n console.log(SEP);\n return;\n }\n\n for (const entry of entries) {\n console.log(\n ` ${entry.timestamp} ${entry.actor.padEnd(12)} ${entry.tool.padEnd(20)} ${entry.slug.padEnd(20)} ${entry.summary}`\n );\n }\n\n console.log(SEP);\n console.log(` ${entries.length} entr${entries.length === 1 ? \"y\" : \"ies\"} shown`);\n console.log(SEP);\n}\n\nexport const auditCommand = new Command(\"audit\")\n .description(\"Show CRM audit trail — who changed what and when\")\n .option(\"--slug <slug>\", \"Filter by customer slug\")\n .option(\"--actor <actor>\", \"Filter by actor\")\n .option(\"--limit <n>\", \"Number of entries to show (default: 20)\", parseInt)\n .option(\"--tail\", \"Show all new entries (simplified: shows current entries)\")\n .action((opts: { slug?: string; actor?: string; limit?: number; tail?: boolean }) =>\n runAudit(opts, process.env[\"DXCRM_DATA_DIR\"])\n );\n","import { Command } from \"commander\";\nimport { info, warning, error, success, bold } from \"../ui/colors.js\";\nimport type { LogLevel, LogQuery } from \"../core/logger.js\";\n\nconst LEVELS = [\"debug\", \"info\", \"warn\", \"error\"];\n\nfunction paintLevel(level: LogLevel, text: string): string {\n if (level === \"error\") return error(text);\n if (level === \"warn\") return warning(text);\n if (level === \"info\") return info(text);\n return text;\n}\n\nfunction buildQuery(opts: {\n level?: string;\n component?: string;\n since?: string;\n contains?: string;\n limit?: number;\n}): LogQuery {\n return {\n ...(opts.level && LEVELS.includes(opts.level) ? { level: opts.level as LogLevel } : {}),\n ...(opts.component !== undefined ? { component: opts.component } : {}),\n ...(opts.since !== undefined ? { since: opts.since } : {}),\n ...(opts.contains !== undefined ? { contains: opts.contains } : {}),\n limit: opts.limit ?? 50,\n };\n}\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const logsCommand = new Command(\"logs\")\n .description(\"View and analyze the structured application log\")\n .option(\"--level <level>\", \"Minimum level: debug | info | warn | error\")\n .option(\"--component <name>\", \"Filter by component (e.g. gmail-sync, lancedb)\")\n .option(\"--since <iso>\", \"Only entries at or after this ISO timestamp\")\n .option(\"--contains <text>\", \"Filter by message substring\")\n .option(\"--limit <n>\", \"Max entries to show (default: 50)\", parseInt)\n .option(\"--summary\", \"Show aggregated counts (by level + component) instead of entries\")\n .action(\n async (opts: {\n level?: string;\n component?: string;\n since?: string;\n contains?: string;\n limit?: number;\n summary?: boolean;\n }) => {\n const query = buildQuery(opts);\n\n if (opts.summary) {\n const { summarizeLogs } = await import(\"../core/logger.js\");\n const s = summarizeLogs(dataDir(), query);\n console.log(bold(`Logs — ${s.total} entr${s.total === 1 ? \"y\" : \"ies\"}`));\n if (s.firstTs) console.log(info(` ${s.firstTs} → ${s.lastTs}`));\n console.log(\" By level:\");\n for (const lvl of LEVELS) {\n const n = s.byLevel[lvl as LogLevel];\n if (n > 0) console.log(` ${paintLevel(lvl as LogLevel, lvl.padEnd(6))} ${n}`);\n }\n console.log(\" By component:\");\n for (const [comp, n] of Object.entries(s.byComponent).sort((a, b) => b[1] - a[1])) {\n console.log(` ${comp.padEnd(22)} ${n}`);\n }\n if (s.recentErrors.length > 0) {\n console.log(error(\" Recent errors:\"));\n for (const e of s.recentErrors) console.log(` ${e.ts} [${e.component}] ${e.message}`);\n }\n return;\n }\n\n const { queryLogs } = await import(\"../core/logger.js\");\n const entries = queryLogs(dataDir(), query);\n if (entries.length === 0) {\n console.log(success(\"No matching log entries.\"));\n return;\n }\n for (const e of entries) {\n const ctx = e.context ? ` ${JSON.stringify(e.context)}` : \"\";\n console.log(\n `${e.ts} ${paintLevel(e.level, e.level.padEnd(5))} ${e.component.padEnd(18)} ${e.message}${ctx}`\n );\n }\n }\n );\n","import { Command } from \"commander\";\nimport { success, error, warning, bold } from \"../ui/colors.js\";\nimport type { CheckStatus } from \"../core/doctor.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nfunction icon(status: CheckStatus): string {\n if (status === \"ok\") return success(\"✓\");\n if (status === \"warn\") return warning(\"⚠\");\n return error(\"✗\");\n}\n\nexport const doctorCommand = new Command(\"doctor\")\n .description(\"Run self-diagnostics: data integrity, temp files, log errors, backup freshness\")\n .option(\"--fix\", \"Clean up safely-fixable issues (orphaned temp files)\")\n .action(async (opts: { fix?: boolean }) => {\n const { runDiagnostics, cleanupTempFiles } = await import(\"../core/doctor.js\");\n\n if (opts.fix) {\n const removed = cleanupTempFiles(dataDir());\n console.log(\n removed.length > 0\n ? success(`Removed ${removed.length} orphaned temp file(s).`)\n : warning(\"Nothing to fix.\")\n );\n }\n\n const report = await runDiagnostics(dataDir());\n\n console.log(bold(\"dxcrm doctor\"));\n for (const c of report.checks) {\n console.log(` ${icon(c.status)} ${c.name.padEnd(16)} ${c.detail}`);\n }\n\n if (report.ok) {\n const warns = report.checks.filter((c) => c.status === \"warn\").length;\n console.log(\n warns > 0 ? warning(`\\nHealthy, with ${warns} warning(s).`) : success(\"\\nAll healthy.\")\n );\n } else {\n console.log(error(\"\\nProblems found — see the ✗ checks above.\"));\n process.exitCode = 1;\n }\n });\n","import { Command } from \"commander\";\nimport { getRbacConfig, setActorRole, canWrite, type Role } from \"../core/rbac.js\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nconst ROLES: Role[] = [\"admin\", \"manager\", \"rep\"];\n\nexport async function runRbacSet(actor: string, role: string, dataDir?: string): Promise<void> {\n const dir = dataDir ?? process.cwd();\n if (!ROLES.includes(role as Role)) {\n console.error(error(`✗ Invalid role '${role}'. Must be: ${ROLES.join(\", \")}`));\n process.exit(1);\n }\n setActorRole(dir, actor, role as Role);\n console.log(success(`✓ ${bold(actor)} → ${bold(role)}`));\n}\n\nexport async function runRbacShow(dataDir?: string): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const config = getRbacConfig(dir);\n const entries = Object.entries(config.actors);\n\n if (entries.length === 0) {\n console.log(info(\"No RBAC roles configured. All actors default to 'rep'.\"));\n return;\n }\n\n console.log(bold(`\\n RBAC Roles\\n`));\n for (const [actor, role] of entries) {\n console.log(info(` ${bold(actor).padEnd(20)} ${role}`));\n }\n if (config.default) {\n console.log(info(`\\n Default: ${config.default}`));\n }\n console.log(\"\");\n}\n\nexport async function runRbacCheck(actor: string, tool: string, dataDir?: string): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const { getRole } = await import(\"../core/rbac.js\");\n const role = getRole(dir, actor);\n const allowed = canWrite(role, tool);\n if (allowed) {\n console.log(success(`✓ ${actor} (${role}) CAN use '${tool}'`));\n } else {\n console.log(error(`✗ ${actor} (${role}) CANNOT use '${tool}'`));\n }\n}\n\nexport const rbacCommand = new Command(\"rbac\").description(\"Manage role-based access control\");\n\nrbacCommand\n .command(\"set <actor> <role>\")\n .description(`Assign role to actor (roles: ${ROLES.join(\", \")})`)\n .action((actor: string, role: string) => runRbacSet(actor, role, process.env[\"DXCRM_DATA_DIR\"]));\n\nrbacCommand\n .command(\"show\")\n .alias(\"list\")\n .description(\"List all RBAC role assignments\")\n .action(() => runRbacShow(process.env[\"DXCRM_DATA_DIR\"]));\n\nrbacCommand\n .command(\"check <actor> <tool>\")\n .description(\"Check if an actor can use a specific tool\")\n .action((actor: string, tool: string) =>\n runRbacCheck(actor, tool, process.env[\"DXCRM_DATA_DIR\"])\n );\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { writeJsonFile } from \"../fs/json-store.js\";\nimport { success, info, bold } from \"../ui/colors.js\";\nimport { writeAuditEntry, getActor } from \"../fs/audit-log.js\";\nimport { withJsonFile } from \"../core/file-lock.js\";\n\ninterface ErasureRecord {\n slug: string;\n erasedAt: string;\n erasedBy: string;\n reason: string;\n}\n\nfunction erasuresPath(dataDir: string): string {\n return path.join(dataDir, \".agentic\", \"gdpr-erasures.json\");\n}\n\nfunction readErasures(dataDir: string): ErasureRecord[] {\n const p = erasuresPath(dataDir);\n if (!fs.existsSync(p)) return [];\n try {\n return JSON.parse(fs.readFileSync(p, \"utf-8\") as string) as ErasureRecord[];\n } catch {\n return [];\n }\n}\n\nfunction appendErasure(dataDir: string, record: ErasureRecord): void {\n const p = erasuresPath(dataDir);\n fs.mkdirSync(path.dirname(p), { recursive: true });\n const existing = readErasures(dataDir);\n existing.push(record);\n writeJsonFile(p, existing);\n}\n\nexport async function runGdprErase(\n slug: string,\n opts: { confirm?: boolean },\n dataDir?: string\n): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const customerDir = path.join(dir, \"customers\", slug);\n\n if (!opts.confirm) {\n console.log(info(`Dry run — would permanently erase: ${bold(slug)}`));\n console.log(info(` Directory: ${customerDir}`));\n console.log(info(` Audit log entry will be written to .agentic/audit.log`));\n console.log(info(` Erasure record will be added to .agentic/gdpr-erasures.json`));\n console.log(info(`\\n To proceed: dxcrm gdpr erase ${slug} --confirm`));\n return;\n }\n\n if (!fs.existsSync(customerDir)) {\n console.warn(info(` Customer '${slug}' directory not found — may already be erased.`));\n } else {\n fs.rmSync(customerDir, { recursive: true, force: true });\n try {\n const { dropCustomerTable } = await import(\"../core/lancedb.js\");\n await dropCustomerTable(dir, slug);\n } catch {\n // non-critical — lancedb cleanup failure should not block erasure\n }\n }\n\n // Clean up .agentic/-level references to this slug\n\n // 1. Remove tasks for this slug from the global agent queue\n const globalQueuePath = path.join(dir, \".agentic\", \"agent-queue.json\");\n if (fs.existsSync(globalQueuePath)) {\n await withJsonFile<unknown[]>(globalQueuePath, (tasks) =>\n (Array.isArray(tasks) ? tasks : []).filter((t) => (t as { slug?: string }).slug !== slug)\n );\n }\n\n // 2. Remove goal sub-goals referencing this slug\n const goalsPath = path.join(dir, \".agentic\", \"goals.json\");\n if (fs.existsSync(goalsPath)) {\n const { readGoals, writeGoals } = await import(\"../core/goal-engine.js\");\n const goals = readGoals(dir);\n const cleaned = goals.map((g) => ({\n ...g,\n decomposition: {\n ...g.decomposition,\n subGoals: g.decomposition.subGoals.filter((sg) => sg.slug !== slug),\n },\n }));\n writeGoals(dir, cleaned);\n }\n\n // 3. Revoke push subscriptions for this slug\n const { readSubscriptions, writeSubscriptions } = await import(\"../sync/push-manager.js\");\n const subs = await readSubscriptions(dir);\n const remaining = subs.filter((s) => s.slug !== slug);\n if (remaining.length !== subs.length) {\n await writeSubscriptions(dir, remaining);\n }\n\n const actor = getActor();\n const now = new Date().toISOString();\n\n writeAuditEntry(dir, {\n timestamp: now,\n actor,\n tool: \"gdpr_erase\",\n slug,\n summary: \"Customer data permanently erased\",\n });\n\n appendErasure(dir, {\n slug,\n erasedAt: now,\n erasedBy: actor,\n reason: \"GDPR Art. 17 request\",\n });\n\n console.log(success(`✓ Customer '${bold(slug)}' erased.`));\n console.log(info(` Deletion logged to .agentic/audit.log`));\n console.log(info(` Record added to .agentic/gdpr-erasures.json`));\n}\n\nexport async function runGdprListErasures(dataDir?: string): Promise<void> {\n const dir = dataDir ?? process.cwd();\n const records = readErasures(dir);\n\n if (records.length === 0) {\n console.log(info(\"No erasures on record.\"));\n return;\n }\n\n console.log(bold(`\\n GDPR Erasures (${records.length})\\n`));\n for (const r of records) {\n console.log(info(` ${r.erasedAt} ${r.erasedBy.padEnd(12)} ${r.slug} — ${r.reason}`));\n }\n console.log(\"\");\n}\n\nexport const gdprCommand = new Command(\"gdpr\").description(\"GDPR compliance tools\");\n\ngdprCommand\n .command(\"erase <slug>\")\n .description(\"Permanently erase all data for a customer (Art. 17 right to erasure)\")\n .option(\"--confirm\", \"Confirm permanent deletion (required)\")\n .action((slug: string, opts: { confirm?: boolean }) =>\n runGdprErase(slug, opts, process.env[\"DXCRM_DATA_DIR\"])\n );\n\ngdprCommand\n .command(\"list-erasures\")\n .description(\"Show history of GDPR erasures\")\n .action(() => runGdprListErasures(process.env[\"DXCRM_DATA_DIR\"]));\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { success } from \"../ui/colors.js\";\n\nconst REPORT = `# DatasynxOpenCRM — Security Report\n\nGenerated: ${new Date().toISOString().slice(0, 10)}\n\n## 1. Data Storage\n\n- **Location**: Local filesystem only. All data lives in \\`customers/\\` and \\`.agentic/\\` directories on your infrastructure.\n- **External transmission**: None by default. Data is never sent to Datasynx servers.\n- **Cloud dependencies**: None for core functionality. Optional integrations (Gmail, Anthropic API) are explicitly configured.\n\n## 2. Authentication & Authorization\n\n- **Phase 3**: No authentication on HTTP MCP server. Restrict access via firewall or VPN (port 3847 should be on private network only).\n- **Phase 4 (RBAC)**: Role-based access control via \\`.agentic/rbac.json\\`. Roles: admin, manager, rep. Enforced per MCP tool call.\n- **Actor identity**: \\`DXCRM_ACTOR\\` environment variable. No cryptographic identity in Phase 3.\n\n## 3. Encryption\n\n- **At rest**: Not encrypted at application level. Use OS-level disk encryption (LUKS on Linux, FileVault on macOS).\n- **In transit**: HTTP (no TLS) in Phase 3. Use a reverse proxy (nginx + Let's Encrypt) or VPN for TLS.\n- **Recommendation**: Deploy behind Tailscale or WireGuard for team access.\n\n## 4. Audit Trail\n\n- **File**: \\`.agentic/audit.log\\` — append-only, one line per entry.\n- **Format**: \\`timestamp | actor | tool | customer | summary\\`\n- **Coverage**: All write operations (\\`log_interaction\\`, \\`update_deal\\`, \\`gdpr_erase\\`).\n- **Tamper evidence**: Phase 3: none. Phase 4+: hash chaining planned.\n- **Retention**: Indefinite (append-only, never deleted by the application).\n\n## 5. Network Calls\n\nThe following external services are contacted when configured:\n\n| Service | When | Data sent |\n|---|---|---|\n| Gmail API | Gmail sync enabled + credentials configured | Email headers + snippets |\n| Anthropic API | \\`ANTHROPIC_API_KEY\\` set | Email/transcript content for summarization |\n| Telegram Bot API | Agent notifications enabled + token set | Customer slug + context excerpt (≤800 chars) |\n| Microsoft Graph | Microsoft sync configured | Email headers + snippets |\n\n**No telemetry, no analytics, no usage data is sent to Datasynx.**\n\n## 6. Data Residency\n\nDatasynxOpenCRM runs entirely on customer-controlled infrastructure. Data never leaves the deployment environment without explicit integration configuration.\n\nThis makes EU data residency guarantees straightforward — a key differentiator vs cloud CRMs.\n\n## 7. GDPR Compliance\n\n- **Right to erasure (Art. 17)**: \\`dxcrm gdpr erase <slug> --confirm\\` permanently deletes all customer data.\n- **Erasure log**: \\`.agentic/gdpr-erasures.json\\` records what was deleted, when, and by whom.\n- **Audit trail**: Every write operation is attributed to an actor.\n- **Data portability (Art. 20)**: \\`dxcrm export <slug>\\` exports all data as JSON or Markdown.\n\n## 8. SOC 2 Readiness\n\n- **Audit log**: Available from Phase 3 (audit trail covers all write operations).\n- **SOC 2 Type 2**: Requires 6 months of consistent audit logs. Apply after Phase 4 completion.\n- **Security review questionnaire**: This document serves as the primary answer document.\n\n## 9. Dependencies (Key Packages)\n\n| Package | Purpose | Cloud dependency? |\n|---|---|---|\n| \\`@modelcontextprotocol/sdk\\` | MCP server | No |\n| \\`@googleapis/gmail\\`, \\`@googleapis/calendar\\` | Gmail/Calendar sync | Optional — only if configured |\n| \\`@anthropic-ai/sdk\\` | LLM summarization | Optional — only if API key set |\n| \\`lancedb\\` | Local vector search | No — embedded DB |\n| \\`gray-matter\\` | Markdown frontmatter | No |\n| \\`commander\\` | CLI framework | No |\n| \\`zod\\` | Schema validation | No |\n| \\`cron\\` | Background sync | No |\n\n## 10. Incident Response\n\n- **Data breach**: Filesystem-only — scope is limited to the deployment host.\n- **Revoke access**: Remove actor from \\`.agentic/rbac.json\\`, rotate \\`DXCRM_ACTOR\\` env var.\n- **Audit**: \\`dxcrm audit --actor <actor>\\` shows all actions by a specific user.\n`;\n\nexport async function runSecurityReport(\n opts: { output?: string },\n _dataDir?: string\n): Promise<void> {\n const report = REPORT;\n\n if (opts.output) {\n const outputPath = path.resolve(opts.output);\n fs.writeFileSync(outputPath, report, \"utf-8\");\n console.log(success(`✓ Security report written to: ${outputPath}`));\n } else {\n console.log(report);\n }\n}\n\nexport const securityReportCommand = new Command(\"security-report\")\n .description(\"Generate security questionnaire answer document for enterprise reviews\")\n .option(\"--output <file>\", \"Write report to file instead of stdout\")\n .action((opts: { output?: string }) => runSecurityReport(opts, process.env[\"DXCRM_DATA_DIR\"]));\n","import { Command } from \"commander\";\nimport {\n getPipelineStages,\n setPipelineStage,\n deletePipelineStage,\n resetToDefaults,\n type PipelineStage,\n} from \"../core/pipeline-stages.js\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nfunction printStagesTable(stages: PipelineStage[]): void {\n console.log(bold(\"\\n Pipeline Stages\\n\"));\n console.log(\n info(\n ` ${\"ID\".padEnd(20)} ${\"Label\".padEnd(20)} ${\"Order\".padEnd(8)} ${\"Prob%\".padEnd(8)} ${\"Final\".padEnd(6)} Color`\n )\n );\n console.log(info(` ${\"─\".repeat(72)}`));\n for (const s of stages) {\n const prob = s.probability !== undefined ? String(s.probability) : \"-\";\n const isFinal = s.isFinal ? \"yes\" : \"no\";\n const color = s.color ?? \"-\";\n console.log(\n info(\n ` ${s.id.padEnd(20)} ${s.label.padEnd(20)} ${String(s.order).padEnd(8)} ${prob.padEnd(8)} ${isFinal.padEnd(6)} ${color}`\n )\n );\n }\n console.log(\"\");\n}\n\nexport const stagesCommand = new Command(\"stages\").description(\"Manage custom pipeline stages\");\n\nstagesCommand\n .command(\"list\")\n .description(\"List all configured pipeline stages\")\n .action(() => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const stages = getPipelineStages(dataDir);\n printStagesTable(stages);\n });\n\nstagesCommand\n .command(\"set <id> <label>\")\n .description(\"Create or update a pipeline stage\")\n .option(\"--order <n>\", \"Sort order (number)\", \"1\")\n .option(\"--probability <n>\", \"Default win probability 0-100\")\n .option(\"--color <hex>\", \"Hex color code (e.g. #3B82F6)\")\n .option(\"--final\", \"Mark as final stage (won/lost)\")\n .action(\n (\n id: string,\n label: string,\n opts: { order: string; probability?: string; color?: string; final?: boolean }\n ) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const stage: PipelineStage = {\n id,\n label,\n order: parseInt(opts.order, 10),\n ...(opts.probability !== undefined ? { probability: parseInt(opts.probability, 10) } : {}),\n ...(opts.color ? { color: opts.color } : {}),\n ...(opts.final ? { isFinal: true } : {}),\n };\n setPipelineStage(dataDir, stage);\n console.log(success(`✓ Stage '${id}' saved`));\n }\n );\n\nstagesCommand\n .command(\"delete <id>\")\n .description(\"Delete a pipeline stage by ID\")\n .action((id: string) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const existing = getPipelineStages(dataDir);\n if (!existing.find((s) => s.id === id)) {\n console.error(error(`✗ Stage '${id}' not found`));\n process.exit(1);\n }\n deletePipelineStage(dataDir, id);\n console.log(success(`✓ Stage '${id}' deleted`));\n });\n\nstagesCommand\n .command(\"reset\")\n .description(\"Reset pipeline stages to defaults\")\n .action(() => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n resetToDefaults(dataDir);\n console.log(success(\"✓ Pipeline stages reset to defaults\"));\n });\n","export interface DxcrmPlugin {\n name: string;\n version: string;\n description?: string;\n onInstall?(): Promise<void>;\n onUninstall?(): Promise<void>;\n mcpTools?: string[]; // names of MCP tools this plugin registers\n}\n\nconst _plugins = new Map<string, DxcrmPlugin>();\n\nexport function registerPlugin(plugin: DxcrmPlugin): void {\n if (_plugins.has(plugin.name)) {\n throw new Error(`Plugin '${plugin.name}' is already registered`);\n }\n _plugins.set(plugin.name, plugin);\n}\n\nexport function getPlugin(name: string): DxcrmPlugin | undefined {\n return _plugins.get(name);\n}\n\nexport function listPlugins(): DxcrmPlugin[] {\n return Array.from(_plugins.values());\n}\n\nexport function unregisterPlugin(name: string): boolean {\n return _plugins.delete(name);\n}\n","import { Command } from \"commander\";\nimport { listPlugins, getPlugin } from \"../core/plugin-registry.js\";\nimport { info, bold, error } from \"../ui/colors.js\";\n\nexport const pluginCommand = new Command(\"plugin\").description(\"Manage dxcrm plugins\");\n\npluginCommand\n .command(\"list\")\n .description(\"List all registered plugins\")\n .action(() => {\n const plugins = listPlugins();\n if (plugins.length === 0) {\n console.log(info(\"No plugins registered.\"));\n return;\n }\n console.log(bold(`\\n dxcrm Plugins (${plugins.length})\\n`));\n for (const p of plugins) {\n console.log(info(` ${p.name.padEnd(20)} v${p.version} ${p.description ?? \"\"}`));\n }\n console.log(\"\");\n });\n\npluginCommand\n .command(\"info <name>\")\n .description(\"Show info about a registered plugin\")\n .action((name: string) => {\n const plugin = getPlugin(name);\n if (!plugin) {\n console.log(error(`Plugin '${name}' not found.`));\n process.exit(1);\n }\n console.log(bold(`\\n Plugin: ${plugin.name}\\n`));\n console.log(info(` Version: ${plugin.version}`));\n if (plugin.description) console.log(info(` Description: ${plugin.description}`));\n if (plugin.mcpTools?.length) {\n console.log(info(` MCP Tools: ${plugin.mcpTools.join(\", \")}`));\n }\n console.log(\"\");\n });\n","import { Command } from \"commander\";\nimport { pursueGoal, getActiveGoals, updateGoalProgress, cancelGoal } from \"../core/goal-engine.js\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nexport async function runGoalSet(\n description: string,\n options: { deadline: string }\n): Promise<void> {\n const dir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const goal = await pursueGoal(dir, { description, deadline: options.deadline });\n console.log(success(`✓ Goal created: ${bold(goal.id)}`));\n console.log(info(` Description : ${goal.description}`));\n console.log(info(` Target : €${goal.target.toLocaleString()}`));\n console.log(info(` Deadline : ${goal.deadline}`));\n console.log(info(` Pipeline P50: €${goal.decomposition.currentPipeline.toLocaleString()}`));\n console.log(info(` Gap : €${goal.decomposition.gap.toLocaleString()}`));\n if (goal.decomposition.subGoals.length > 0) {\n console.log(bold(\"\\n Action Plan:\"));\n for (const sg of goal.decomposition.subGoals) {\n console.log(info(` ${sg.priority}. ${sg.action}`));\n console.log(info(` → ${sg.nextStep}`));\n }\n }\n}\n\nexport async function runGoalStatus(): Promise<void> {\n const dir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const goals = getActiveGoals(dir);\n if (goals.length === 0) {\n console.log(info(\"No active goals. Use `dxcrm goal set` to create one.\"));\n return;\n }\n console.log(bold(`\\n Active Goals (${goals.length})\\n`));\n for (const g of goals) {\n const bar =\n \"█\".repeat(Math.round(g.progress / 10)) + \"░\".repeat(10 - Math.round(g.progress / 10));\n const deadlineMs = new Date(g.deadline).getTime() - Date.now();\n const daysLeft = Math.max(0, Math.ceil(deadlineMs / 86_400_000));\n console.log(bold(` ${g.id}`));\n console.log(info(` ${g.description}`));\n console.log(\n info(\n ` [${bar}] ${g.progress}% | €${g.target.toLocaleString()} by ${g.deadline} (${daysLeft}d left)`\n )\n );\n console.log(\"\");\n }\n}\n\nexport async function runGoalUpdate(goalId: string, options: { progress: string }): Promise<void> {\n const dir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const progress = parseInt(options.progress, 10);\n if (isNaN(progress) || progress < 0 || progress > 100) {\n console.error(error(\"✗ --progress must be a number 0–100\"));\n process.exit(1);\n }\n const updated = await updateGoalProgress(dir, goalId, progress);\n if (!updated) {\n console.error(error(`✗ Goal '${goalId}' not found`));\n process.exit(1);\n }\n console.log(success(`✓ Goal ${bold(goalId)} progress updated to ${bold(String(progress))}%`));\n}\n\nexport async function runGoalCancel(goalId: string): Promise<void> {\n const dir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const cancelled = await cancelGoal(dir, goalId);\n if (!cancelled) {\n console.error(error(`✗ Goal '${goalId}' not found`));\n process.exit(1);\n }\n console.log(success(`✓ Goal ${bold(goalId)} cancelled`));\n}\n\nexport const goalCommand = new Command(\"goal\").description(\"Manage goals and action plans\");\n\ngoalCommand\n .command(\"set <description>\")\n .description(\"Set a new goal and get a decomposed action plan\")\n .requiredOption(\"--deadline <date>\", \"Target deadline (YYYY-MM-DD)\")\n .action((description: string, opts: { deadline: string }) => runGoalSet(description, opts));\n\ngoalCommand\n .command(\"status\")\n .description(\"Show all active goals with progress\")\n .action(() => runGoalStatus());\n\ngoalCommand\n .command(\"update <goalId>\")\n .description(\"Update goal progress percentage\")\n .requiredOption(\"--progress <n>\", \"Progress 0–100\")\n .action((goalId: string, opts: { progress: string }) => runGoalUpdate(goalId, opts));\n\ngoalCommand\n .command(\"cancel <goalId>\")\n .description(\"Cancel an active goal\")\n .action((goalId: string) => runGoalCancel(goalId));\n","import { Command } from \"commander\";\nimport {\n register,\n readSubscriptions,\n revoke,\n renewExpiringSubscriptions,\n} from \"../sync/push-manager.js\";\nimport type { PushProvider } from \"../sync/push-manager.js\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nexport async function runPushRegister(\n slug: string,\n options: {\n provider: PushProvider;\n webhookUrl: string;\n topicName?: string;\n clientState?: string;\n resource?: string;\n teamId?: string;\n channelId?: string;\n }\n): Promise<void> {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const providerData: Record<string, string> = {};\n if (options.topicName) providerData[\"gmailTopicName\"] = options.topicName;\n if (options.clientState) providerData[\"microsoftClientState\"] = options.clientState;\n if (options.resource) providerData[\"microsoftResource\"] = options.resource;\n if (options.teamId) providerData[\"slackTeamId\"] = options.teamId;\n if (options.channelId) providerData[\"slackChannelId\"] = options.channelId;\n\n const sub = await register(dataDir, options.provider, slug, {\n webhookUrl: options.webhookUrl,\n providerData,\n });\n\n console.log(success(`✓ Push subscription registered: ${bold(sub.id)}`));\n console.log(info(` Provider : ${sub.provider}`));\n console.log(info(` Slug : ${sub.slug}`));\n console.log(info(` Webhook : ${sub.webhookUrl}`));\n console.log(info(` Expires : ${sub.expiresAt ?? \"never\"}`));\n\n if (options.webhookUrl.includes(\"localhost\")) {\n console.log(info(` ⚠ Warning: localhost URLs cannot be reached by external providers.`));\n console.log(info(` Use a tunnel: ngrok http 3847`));\n }\n}\n\nexport async function runPushStatus(options: { slug?: string; provider?: string }): Promise<void> {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n let subs = await readSubscriptions(dataDir);\n\n if (options.slug) subs = subs.filter((s) => s.slug === options.slug);\n if (options.provider) subs = subs.filter((s) => s.provider === options.provider);\n\n if (subs.length === 0) {\n console.log(info(\"No push subscriptions registered. Use `dxcrm push register` to add one.\"));\n return;\n }\n\n const now = Date.now();\n console.log(bold(`\\n Push Subscriptions (${subs.length})\\n`));\n for (const s of subs) {\n const expiresIn = s.expiresAt\n ? Math.round((new Date(s.expiresAt).getTime() - now) / (60 * 60 * 1000))\n : null;\n const expiryStr = expiresIn !== null ? `${expiresIn}h remaining` : \"no expiry\";\n const needsRenewal =\n s.expiresAt !== null && new Date(s.expiresAt).getTime() - now < 24 * 60 * 60 * 1000;\n\n console.log(bold(` ${s.id}`));\n console.log(info(` ${s.provider} → ${s.slug} [${s.status}]`));\n console.log(\n info(\n ` Events: ${s.eventsProcessed} | Expires: ${expiryStr}${needsRenewal ? \" ⚠ RENEW SOON\" : \"\"}`\n )\n );\n console.log(info(` Last event: ${s.lastEventAt ?? \"—\"}`));\n console.log(\"\");\n }\n}\n\nexport async function runPushRevoke(id: string): Promise<void> {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n try {\n await revoke(dataDir, id);\n console.log(success(`✓ Subscription ${bold(id)} revoked`));\n } catch {\n console.error(error(`✗ Subscription not found: ${id}`));\n process.exit(1);\n }\n}\n\nexport async function runPushRenew(options: { all?: boolean; id?: string }): Promise<void> {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n if (options.id) {\n const subs = await readSubscriptions(dataDir);\n const sub = subs.find((s) => s.id === options.id);\n if (!sub) {\n console.error(error(`✗ Subscription not found: ${options.id}`));\n process.exit(1);\n }\n console.log(info(` Renewal for ${sub.id} requires provider-specific logic.`));\n console.log(info(` Use the daemon's automatic renewal (daily 06:00) or re-register.`));\n return;\n }\n const result = await renewExpiringSubscriptions(\n dataDir,\n async () => {\n throw new Error(\"No default renew function — use provider-specific tooling\");\n },\n 24\n );\n console.log(info(` Renewed: ${result.renewed.length} | Errors: ${result.errors.length}`));\n if (result.renewed.length > 0) console.log(success(`✓ Renewed: ${result.renewed.join(\", \")}`));\n if (result.errors.length > 0) console.log(error(`✗ Errors: ${result.errors.join(\", \")}`));\n}\n\nexport const pushCommand = new Command(\"push\").description(\n \"Manage real-time push subscriptions (Gmail Pub/Sub, MS Graph, Slack Events)\"\n);\n\npushCommand\n .command(\"register <slug>\")\n .description(\"Register a push subscription for a customer\")\n .requiredOption(\"--provider <provider>\", \"Provider: gmail | microsoft-graph | slack\")\n .requiredOption(\"--webhook-url <url>\", \"Public HTTPS URL for provider callbacks\")\n .option(\"--topic-name <topic>\", \"Gmail: Cloud Pub/Sub topic name\")\n .option(\"--client-state <secret>\", \"MS Graph: client state secret\")\n .option(\"--resource <path>\", \"MS Graph: resource path\")\n .option(\"--team-id <id>\", \"Slack: workspace team ID\")\n .option(\"--channel-id <id>\", \"Slack: optional channel ID\")\n .action(\n async (\n slug: string,\n opts: {\n provider: PushProvider;\n webhookUrl: string;\n topicName?: string;\n clientState?: string;\n resource?: string;\n teamId?: string;\n channelId?: string;\n }\n ) => {\n await runPushRegister(slug, opts);\n }\n );\n\npushCommand\n .command(\"status\")\n .description(\"Show all push subscriptions\")\n .option(\"--slug <slug>\", \"Filter by customer slug\")\n .option(\"--provider <provider>\", \"Filter by provider\")\n .action(async (opts: { slug?: string; provider?: string }) => {\n await runPushStatus(opts);\n });\n\npushCommand\n .command(\"revoke <id>\")\n .description(\"Revoke a push subscription by ID\")\n .action(async (id: string) => {\n await runPushRevoke(id);\n });\n\npushCommand\n .command(\"renew\")\n .description(\"Renew expiring push subscriptions\")\n .option(\"--all\", \"Renew all expiring subscriptions\")\n .option(\"--id <id>\", \"Renew a specific subscription by ID\")\n .action(async (opts: { all?: boolean; id?: string }) => {\n await runPushRenew(opts);\n });\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\n\nexport async function runAttach(\n slug: string,\n filePath: string,\n dataDir?: string\n): Promise<{ attached: string } | { error: string }> {\n const dir = dataDir ?? process.cwd();\n const customerDir = path.join(dir, \"customers\", slug);\n\n if (!fs.existsSync(customerDir)) {\n const msg = `Customer '${slug}' not found.`;\n console.error(error(msg));\n return { error: msg };\n }\n\n if (!fs.existsSync(filePath)) {\n const msg = `File not found: ${filePath}`;\n console.error(error(msg));\n return { error: msg };\n }\n\n const attachmentsDir = path.join(customerDir, \"attachments\");\n fs.mkdirSync(attachmentsDir, { recursive: true });\n\n const filename = path.basename(filePath);\n const dest = path.join(attachmentsDir, filename);\n\n if (fs.existsSync(dest)) {\n const msg = `Attachment already exists: ${filename}`;\n console.log(info(msg));\n return { attached: dest };\n }\n\n fs.copyFileSync(filePath, dest);\n console.log(success(`Attached ${bold(filename)} to ${bold(slug)}`));\n return { attached: dest };\n}\n\nexport async function runListAttachments(slug: string, dataDir?: string): Promise<string[]> {\n const dir = dataDir ?? process.cwd();\n const attachmentsDir = path.join(dir, \"customers\", slug, \"attachments\");\n\n if (!fs.existsSync(attachmentsDir)) return [];\n\n try {\n return fs.readdirSync(attachmentsDir).filter((f) => {\n try {\n return fs.statSync(path.join(attachmentsDir, f)).isFile();\n } catch {\n return false;\n }\n });\n } catch {\n return [];\n }\n}\n\nexport const attachCommand = new Command(\"attach\")\n .description(\"Attach a file to a customer (copies to customers/<slug>/attachments/)\")\n .argument(\"<slug>\", \"Customer slug\")\n .argument(\"<file>\", \"Path to the file to attach\")\n .action(async (slug: string, file: string) => {\n await runAttach(slug, file, process.env[\"DXCRM_DATA_DIR\"]);\n });\n","import { Command } from \"commander\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport { listTemplates, getTemplate, writeTemplate, deleteTemplate } from \"../fs/template-store.js\";\nimport { interpolate, buildVariablesFromCustomer } from \"../core/template-engine.js\";\nimport type { EmailTemplate } from \"../schemas/email-template.js\";\n\nexport const templateCommand = new Command(\"template\").description(\"Manage email templates\");\n\ntemplateCommand\n .command(\"list\")\n .option(\"--category <category>\", \"Filter by category\")\n .action((opts: { category?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const templates = listTemplates(dataDir, opts.category ? { category: opts.category } : {});\n if (templates.length === 0) {\n console.log(info(\"No templates found.\"));\n return;\n }\n for (const t of templates) {\n console.log(` ${bold(t.id)} [${t.category}] ${t.subject}`);\n }\n });\n\ntemplateCommand.command(\"get <id>\").action((id: string) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const tmpl = getTemplate(dataDir, id);\n if (!tmpl) {\n console.error(error(`Template '${id}' not found`));\n process.exit(1);\n }\n console.log(bold(`Subject: ${tmpl.subject}`));\n console.log(`Category: ${tmpl.category} Language: ${tmpl.language}`);\n console.log(`Variables: ${tmpl.variables.join(\", \") || \"(none defined)\"}`);\n console.log(\"\\n\" + tmpl.body);\n});\n\ntemplateCommand\n .command(\"preview <id>\")\n .option(\"--slug <slug>\", \"Customer slug to preview with\")\n .action(async (id: string, opts: { slug?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const tmpl = getTemplate(dataDir, id);\n if (!tmpl) {\n console.error(error(`Template '${id}' not found`));\n process.exit(1);\n }\n const vars = opts.slug ? await buildVariablesFromCustomer(dataDir, opts.slug) : {};\n console.log(bold(`Subject: ${interpolate(tmpl.subject, vars)}`));\n console.log(interpolate(tmpl.body, vars));\n });\n\ntemplateCommand\n .command(\"create <id>\")\n .option(\"--category <category>\", \"Category\", \"general\")\n .option(\"--subject <subject>\", \"Subject line\")\n .action((id: string, opts: { category: string; subject?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const existing = getTemplate(dataDir, id);\n if (existing) {\n console.error(error(`Template '${id}' already exists`));\n process.exit(1);\n }\n const tmpl: EmailTemplate = {\n id,\n subject: opts.subject ?? `Subject for ${id}`,\n category: opts.category,\n variables: [],\n language: \"de\",\n createdAt: new Date().toISOString(),\n body: `Hi {{firstName}},\\n\\n[your message here]\\n\\nBest regards,\\n{{senderName}}`,\n };\n writeTemplate(dataDir, tmpl);\n console.log(success(`✓ Template '${id}' created in category '${opts.category}'`));\n });\n\ntemplateCommand.command(\"delete <id>\").action((id: string) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const deleted = deleteTemplate(dataDir, id);\n if (deleted) {\n console.log(success(`✓ Template '${id}' deleted`));\n } else {\n console.error(error(`Template '${id}' not found`));\n process.exit(1);\n }\n});\n","import { Command } from \"commander\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport {\n listSequences,\n getSequence,\n writeSequence,\n readEnrollments,\n writeEnrollment,\n} from \"../fs/sequence-store.js\";\nimport { runSequenceCycle } from \"../core/sequence-engine.js\";\nimport type { Sequence } from \"../schemas/sequence.js\";\n\nexport const sequenceCommand = new Command(\"sequence\").description(\"Manage email sequences\");\n\nsequenceCommand\n .command(\"list\")\n .description(\"List all sequences\")\n .action(() => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const sequences = listSequences(dataDir);\n const enrollments = readEnrollments(dataDir);\n\n if (sequences.length === 0) {\n console.log(info(\"No sequences found.\"));\n return;\n }\n\n for (const seq of sequences) {\n const count = enrollments.filter((e) => e.sequenceId === seq.id).length;\n console.log(` ${bold(seq.id)} \"${seq.name}\" ${seq.steps.length} steps ${count} enrolled`);\n }\n });\n\nsequenceCommand\n .command(\"create <id>\")\n .description(\"Create a new sequence skeleton\")\n .option(\"--name <name>\", \"Sequence display name\")\n .action((id: string, opts: { name?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n\n const existing = getSequence(dataDir, id);\n if (existing) {\n console.error(error(`Sequence '${id}' already exists`));\n process.exit(1);\n }\n\n const seq: Sequence = {\n id,\n name: opts.name ?? id,\n steps: [\n { day: 0, templateId: \"intro\", skipIfReplied: true },\n { day: 3, templateId: \"followup-1\", skipIfReplied: true },\n { day: 7, templateId: \"followup-2\", skipIfReplied: true },\n ],\n createdAt: new Date().toISOString(),\n };\n\n writeSequence(dataDir, seq);\n console.log(success(`✓ Sequence '${id}' created with ${seq.steps.length} steps`));\n console.log(info(`Edit .agentic/sequences/${id}.yaml to customize steps and templates`));\n });\n\nsequenceCommand\n .command(\"enroll <slug>\")\n .description(\"Enroll a customer contact in a sequence\")\n .requiredOption(\"--email <email>\", \"Contact email address\")\n .requiredOption(\"--sequence <id>\", \"Sequence ID\")\n .action(async (slug: string, opts: { email: string; sequence: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n\n const seq = getSequence(dataDir, opts.sequence);\n if (!seq) {\n console.error(error(`Sequence '${opts.sequence}' not found`));\n process.exit(1);\n }\n\n const enrollmentId = `enroll_${Date.now()}_${Math.random().toString(16).slice(2, 8)}`;\n const now = new Date().toISOString();\n\n await writeEnrollment(dataDir, {\n id: enrollmentId,\n sequenceId: opts.sequence,\n slug,\n contactEmail: opts.email,\n enrolledAt: now,\n status: \"active\",\n currentStep: 0,\n stepsCompleted: [],\n });\n\n console.log(success(`✓ Enrolled ${opts.email} in sequence '${seq.name}'`));\n console.log(info(`Enrollment ID: ${enrollmentId}`));\n });\n\nsequenceCommand\n .command(\"status\")\n .description(\"Show enrollment status\")\n .option(\"--slug <slug>\", \"Filter by customer slug\")\n .action((opts: { slug?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n let enrollments = readEnrollments(dataDir);\n\n if (opts.slug) {\n enrollments = enrollments.filter((e) => e.slug === opts.slug);\n }\n\n if (enrollments.length === 0) {\n console.log(info(\"No enrollments found.\"));\n return;\n }\n\n for (const e of enrollments) {\n const stepInfo = `step ${e.currentStep}`;\n const lastSent = e.lastSentAt ? ` last sent ${e.lastSentAt.slice(0, 10)}` : \"\";\n console.log(\n ` ${bold(e.id)} ${e.slug} <${e.contactEmail}> seq:${e.sequenceId} [${e.status}] ${stepInfo}${lastSent}`\n );\n }\n });\n\nsequenceCommand\n .command(\"run\")\n .description(\"Run the sequence cycle (send due emails)\")\n .option(\"--dry-run\", \"Show what would be sent without sending\")\n .action(async (opts: { dryRun?: boolean }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const today = new Date().toISOString().slice(0, 10);\n\n if (opts.dryRun) {\n const enrollments = readEnrollments(dataDir).filter((e) => e.status === \"active\");\n console.log(info(`Dry run — ${enrollments.length} active enrollments for ${today}`));\n for (const e of enrollments) {\n console.log(` Would process: ${e.id} (${e.contactEmail}, step ${e.currentStep})`);\n }\n return;\n }\n\n const result = await runSequenceCycle(dataDir, today);\n console.log(\n success(\n `✓ Cycle complete: ${result.sent} sent, ${result.completed} completed, ${result.errors.length} errors`\n )\n );\n if (result.errors.length > 0) {\n for (const e of result.errors) {\n console.error(error(` Error: ${e}`));\n }\n }\n });\n","import { Command } from \"commander\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport { generateQuote, listQuotes, readQuote } from \"../core/quote-generator.js\";\n\nexport const quoteCommand = new Command(\"quote\").description(\"Manage customer quotes\");\n\nquoteCommand\n .command(\"generate <slug>\")\n .description(\"Generate a quote for a customer\")\n .requiredOption(\"--deal <name>\", \"Deal name\")\n .option(\n \"--items <items>\",\n 'Line items: \"Description Qty Price,...\" (e.g. \"Consulting 1 5000,Support 12 500\")'\n )\n .option(\"--vat <percent>\", \"VAT percent\", \"19\")\n .option(\"--valid <days>\", \"Valid for N days\", \"30\")\n .action(\n async (slug: string, opts: { deal: string; items?: string; vat: string; valid: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n\n const lineItems = (opts.items ?? \"Service 1 1000\")\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean)\n .map((item) => {\n const parts = item.split(/\\s+/);\n const unitPrice = parseFloat(parts[parts.length - 1] ?? \"0\");\n const quantity = parseFloat(parts[parts.length - 2] ?? \"1\");\n const description = parts.slice(0, -2).join(\" \") || item;\n return { description, quantity, unitPrice };\n });\n\n try {\n const quote = await generateQuote(dataDir, {\n slug,\n dealName: opts.deal,\n lineItems,\n vatPercent: parseFloat(opts.vat),\n validUntilDays: parseInt(opts.valid, 10),\n });\n console.log(success(`✓ Quote ${bold(quote.quoteNumber)} generated`));\n console.log(info(` Total: ${quote.total.toFixed(2)} ${quote.currency}`));\n console.log(info(` Valid until: ${quote.validUntil}`));\n console.log(info(` HTML: ${quote.htmlPath}`));\n } catch (err) {\n console.error(error(`Failed to generate quote: ${(err as Error).message}`));\n process.exit(1);\n }\n }\n );\n\nquoteCommand\n .command(\"list\")\n .description(\"List quotes\")\n .option(\"--slug <slug>\", \"Filter by customer slug\")\n .action((opts: { slug?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const quotes = listQuotes(dataDir, opts.slug);\n\n if (quotes.length === 0) {\n console.log(info(\"No quotes found.\"));\n return;\n }\n\n for (const q of quotes) {\n console.log(\n ` ${bold(q.quoteNumber)} ${q.slug} ${q.dealName} ${q.total.toFixed(2)} ${q.currency} [${q.status}] ${q.validUntil}`\n );\n }\n });\n\nquoteCommand\n .command(\"get <quoteNumber>\")\n .description(\"Show quote details\")\n .action((quoteNumber: string) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const quote = readQuote(dataDir, quoteNumber);\n\n if (!quote) {\n console.error(error(`Quote '${quoteNumber}' not found`));\n process.exit(1);\n }\n\n console.log(bold(`Quote: ${quote.quoteNumber}`));\n console.log(`Customer: ${quote.slug} Deal: ${quote.dealName}`);\n console.log(`Status: ${quote.status} Valid until: ${quote.validUntil}`);\n console.log(\n `Subtotal: ${quote.subtotal.toFixed(2)} VAT: ${quote.vat.toFixed(2)} Total: ${quote.total.toFixed(2)} ${quote.currency}`\n );\n for (const item of quote.lineItems) {\n console.log(` - ${item.description}: ${item.quantity} × ${item.unitPrice} = ${item.total}`);\n }\n });\n","import { Command } from \"commander\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport { readTickets, listAllTickets, nextTicketId, upsertTicket } from \"../fs/ticket-writer.js\";\nimport { calcSlaDue, loadSlaRules } from \"../core/sla-engine.js\";\nimport type { Ticket } from \"../schemas/ticket.js\";\n\nexport const ticketCommand = new Command(\"ticket\").description(\"Manage support tickets\");\n\nticketCommand\n .command(\"list\")\n .description(\"List tickets\")\n .option(\"--slug <slug>\", \"Filter by customer slug\")\n .option(\"--status <status>\", \"Filter by status\")\n .option(\"--priority <priority>\", \"Filter by priority\")\n .action(async (opts: { slug?: string; status?: string; priority?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const tickets = await listAllTickets(dataDir, {\n ...(opts.slug ? { slug: opts.slug } : {}),\n ...(opts.status ? { status: opts.status } : {}),\n ...(opts.priority ? { priority: opts.priority } : {}),\n });\n\n if (tickets.length === 0) {\n console.log(info(\"No tickets found.\"));\n return;\n }\n\n for (const { slug, ticket: t } of tickets) {\n const breach =\n t.slaDue &&\n t.slaDue < new Date().toISOString().slice(0, 10) &&\n t.status !== \"resolved\" &&\n t.status !== \"closed\";\n const flag = breach ? \" ⚠ SLA\" : \"\";\n console.log(\n ` ${bold(t.id)} [${slug}] ${t.title} [${t.status}/${t.priority}]${t.assignee ? ` @${t.assignee}` : \"\"}${flag}`\n );\n }\n });\n\nticketCommand\n .command(\"create <slug>\")\n .description(\"Create a ticket for a customer\")\n .requiredOption(\"--title <title>\", \"Ticket title\")\n .option(\"--description <desc>\", \"Description\")\n .option(\"--priority <priority>\", \"Priority: urgent|high|normal|low\", \"normal\")\n .option(\"--assignee <name>\", \"Assignee\")\n .action(\n async (\n slug: string,\n opts: { title: string; description?: string; priority: string; assignee?: string }\n ) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const today = new Date().toISOString().slice(0, 10);\n const rules = loadSlaRules(dataDir);\n const priority = (opts.priority as Ticket[\"priority\"]) ?? \"normal\";\n const existing = await readTickets(dataDir, slug);\n const id = nextTicketId(existing);\n\n const ticket: Ticket = {\n id,\n title: opts.title,\n status: \"open\",\n priority,\n ...(opts.assignee ? { assignee: opts.assignee } : {}),\n created: today,\n slaDue: calcSlaDue(today, priority, rules),\n ...(opts.description ? { description: opts.description } : {}),\n };\n\n await upsertTicket(dataDir, slug, ticket);\n console.log(success(`✓ Ticket ${bold(id)} created for ${slug}`));\n console.log(info(` SLA due: ${ticket.slaDue}`));\n }\n );\n\nticketCommand\n .command(\"update <ticketId>\")\n .description(\"Update a ticket\")\n .requiredOption(\"--slug <slug>\", \"Customer slug\")\n .option(\"--status <status>\", \"New status\")\n .option(\"--assignee <name>\", \"New assignee\")\n .action(async (ticketId: string, opts: { slug: string; status?: string; assignee?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const tickets = await readTickets(dataDir, opts.slug);\n const ticket = tickets.find((t) => t.id === ticketId);\n\n if (!ticket) {\n console.error(error(`Ticket '${ticketId}' not found`));\n process.exit(1);\n }\n\n const today = new Date().toISOString().slice(0, 10);\n const updated: Ticket = {\n ...ticket,\n ...(opts.status ? { status: opts.status as Ticket[\"status\"] } : {}),\n ...(opts.assignee !== undefined ? { assignee: opts.assignee } : {}),\n ...(opts.status === \"resolved\" && !ticket.resolved ? { resolved: today } : {}),\n };\n\n await upsertTicket(dataDir, opts.slug, updated);\n console.log(success(`✓ Ticket ${bold(ticketId)} updated`));\n });\n\nticketCommand\n .command(\"close <ticketId>\")\n .description(\"Close a ticket\")\n .requiredOption(\"--slug <slug>\", \"Customer slug\")\n .option(\"--resolution <text>\", \"Resolution notes\")\n .action(async (ticketId: string, opts: { slug: string; resolution?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const tickets = await readTickets(dataDir, opts.slug);\n const ticket = tickets.find((t) => t.id === ticketId);\n\n if (!ticket) {\n console.error(error(`Ticket '${ticketId}' not found`));\n process.exit(1);\n }\n\n const today = new Date().toISOString().slice(0, 10);\n const updated: Ticket = { ...ticket, status: \"closed\", resolved: ticket.resolved ?? today };\n await upsertTicket(dataDir, opts.slug, updated);\n console.log(success(`✓ Ticket ${bold(ticketId)} closed`));\n });\n","import { Command } from \"commander\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport {\n getSurvey,\n writeSurvey,\n listSurveys,\n loadSurveyResponses,\n calcNpsScore,\n generateSurveyToken,\n savePendingSurvey,\n} from \"../core/survey-engine.js\";\nimport type { SurveyDefinition } from \"../schemas/survey.js\";\n\nexport const surveyCommand = new Command(\"survey\").description(\"Manage NPS/CSAT surveys\");\n\nsurveyCommand\n .command(\"list\")\n .description(\"List all survey definitions\")\n .action(() => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const surveys = listSurveys(dataDir);\n if (surveys.length === 0) {\n console.log(info(\"No surveys found.\"));\n return;\n }\n for (const s of surveys) {\n console.log(` ${bold(s.id)} [${s.type}] ${s.question.slice(0, 60)}`);\n }\n });\n\nsurveyCommand\n .command(\"create <id>\")\n .description(\"Create a new survey definition\")\n .option(\"--type <type>\", \"Survey type: nps|csat|ces\", \"nps\")\n .option(\"--question <q>\", \"Survey question\")\n .action((id: string, opts: { type: string; question?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const survey: SurveyDefinition = {\n id,\n type: (opts.type as SurveyDefinition[\"type\"]) ?? \"nps\",\n question: opts.question ?? \"How likely are you to recommend us? (0–10)\",\n scale: { min: 0, max: 10 },\n includeComment: true,\n commentPrompt: \"What's the main reason for your score?\",\n createdAt: new Date().toISOString(),\n };\n writeSurvey(dataDir, survey);\n console.log(success(`✓ Survey '${id}' created`));\n });\n\nsurveyCommand\n .command(\"send <surveyId>\")\n .description(\"Generate survey token for a contact\")\n .requiredOption(\"--slug <slug>\", \"Customer slug\")\n .requiredOption(\"--email <email>\", \"Contact email\")\n .option(\n \"--server <url>\",\n \"Server URL\",\n process.env[\"DXCRM_SERVER_URL\"] ?? \"http://localhost:3456\"\n )\n .action(async (surveyId: string, opts: { slug: string; email: string; server: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const survey = getSurvey(dataDir, surveyId);\n if (!survey) {\n console.error(error(`Survey '${surveyId}' not found`));\n process.exit(1);\n }\n const token = generateSurveyToken(opts.slug, opts.email, surveyId);\n await savePendingSurvey(dataDir, surveyId, opts.slug, opts.email, token);\n console.log(success(`✓ Survey token generated`));\n console.log(info(` URL: ${opts.server}/survey/respond?token=${token}`));\n });\n\nsurveyCommand\n .command(\"results <surveyId>\")\n .description(\"Show survey results and NPS score\")\n .option(\"--slug <slug>\", \"Filter by customer slug\")\n .action((surveyId: string, opts: { slug?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const responses = loadSurveyResponses(dataDir, surveyId, opts.slug);\n const nps = calcNpsScore(responses);\n const promoters = responses.filter((r) => r.score >= 9).length;\n const detractors = responses.filter((r) => r.score <= 6).length;\n\n console.log(bold(`Survey: ${surveyId}`));\n console.log(\n info(\n `Responses: ${responses.length} NPS: ${nps} Promoters: ${promoters} Detractors: ${detractors}`\n )\n );\n for (const r of responses) {\n console.log(\n ` ${r.slug} <${r.contactEmail}> score=${r.score}${r.comment ? ` \"${r.comment.slice(0, 80)}\"` : \"\"}`\n );\n }\n });\n","import { Command } from \"commander\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport {\n listKbArticles,\n getKbArticle,\n writeKbArticle,\n deleteKbArticle,\n searchKbSimple,\n} from \"../fs/knowledge-base.js\";\nimport type { KbArticle } from \"../schemas/kb-article.js\";\n\nexport const kbCommand = new Command(\"kb\").description(\"Manage the knowledge base\");\n\nkbCommand\n .command(\"list\")\n .description(\"List all KB articles\")\n .option(\"--category <cat>\", \"Filter by category\")\n .option(\"--public\", \"Show only public articles\")\n .action((opts: { category?: string; public?: boolean }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const articles = listKbArticles(dataDir, {\n ...(opts.category ? { category: opts.category } : {}),\n ...(opts.public ? { publicOnly: true } : {}),\n });\n if (articles.length === 0) {\n console.log(info(\"No articles found.\"));\n return;\n }\n for (const a of articles) {\n const pub = a.public ? \" [public]\" : \"\";\n console.log(` ${bold(a.id)} [${a.category}] ${a.title}${pub}`);\n }\n });\n\nkbCommand\n .command(\"get <id>\")\n .description(\"Get a KB article\")\n .action((id: string) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const article = getKbArticle(dataDir, id);\n if (!article) {\n console.error(error(`Article '${id}' not found`));\n process.exit(1);\n }\n console.log(bold(article.title));\n console.log(`Category: ${article.category} Tags: ${article.tags.join(\", \") || \"(none)\"}`);\n console.log(\"\\n\" + article.body);\n });\n\nkbCommand\n .command(\"search <query>\")\n .description(\"Search KB articles\")\n .option(\"--public\", \"Search only public articles\")\n .action((query: string, opts: { public?: boolean }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const results = searchKbSimple(dataDir, query, opts.public ? { publicOnly: true } : {});\n if (results.length === 0) {\n console.log(info(\"No results.\"));\n return;\n }\n for (const a of results) {\n console.log(` ${bold(a.id)} ${a.title}`);\n console.log(` ${a.body.slice(0, 120).replace(/\\n/g, \" \")}...`);\n }\n });\n\nkbCommand\n .command(\"create <id>\")\n .description(\"Create a KB article (opens editor-ready template)\")\n .requiredOption(\"--title <title>\", \"Article title\")\n .option(\"--category <cat>\", \"Category\", \"general\")\n .option(\"--ticket <id>\", \"Source ticket ID\")\n .action((id: string, opts: { title: string; category: string; ticket?: string }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const now = new Date().toISOString();\n const article: KbArticle = {\n id,\n title: opts.title,\n category: opts.category,\n tags: [],\n public: false,\n createdAt: now,\n updatedAt: now,\n ...(opts.ticket ? { sourceTicketId: opts.ticket } : {}),\n body: `## Problem\\n\\n[Describe the problem]\\n\\n## Solution\\n\\n[Describe the solution]`,\n };\n writeKbArticle(dataDir, article);\n console.log(success(`✓ Article '${id}' created in category '${opts.category}'`));\n console.log(info(`Edit: .agentic/knowledge-base/${opts.category}/${id}.md`));\n });\n\nkbCommand\n .command(\"delete <id>\")\n .description(\"Delete a KB article\")\n .action((id: string) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n if (deleteKbArticle(dataDir, id)) {\n console.log(success(`✓ Article '${id}' deleted`));\n } else {\n console.error(error(`Article '${id}' not found`));\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { info, success, error } from \"../ui/colors.js\";\nimport type { CustomFieldType, FieldDefinition } from \"../core/custom-fields.js\";\n\nconst VALID_TYPES = [\"text\", \"number\", \"boolean\", \"date\", \"select\"];\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nfunction collect(value: string, prev: string[]): string[] {\n return [...prev, value];\n}\n\n/** Parse a `--field name:type[:opt1|opt2]` spec into a FieldDefinition. */\nfunction parseFieldSpec(spec: string): FieldDefinition | null {\n const [name, type, opts] = spec.split(\":\");\n if (!name || !type || !VALID_TYPES.includes(type)) return null;\n return {\n name,\n type: type as CustomFieldType,\n ...(opts ? { options: opts.split(\"|\").map((s) => s.trim()) } : {}),\n };\n}\n\nexport const fieldsCommand = new Command(\"fields\").description(\n \"Manage custom fields (metadata-driven extensibility)\"\n);\n\nfieldsCommand\n .command(\"list\")\n .description(\"List defined custom fields\")\n .action(async () => {\n const { loadFieldDefinitions } = await import(\"../core/custom-fields.js\");\n const defs = loadFieldDefinitions(dataDir());\n if (defs.length === 0) {\n console.log(info(\"No custom fields defined. Add one with: dxcrm fields add <name> <type>\"));\n return;\n }\n for (const d of defs) {\n const opts = d.options ? ` [${d.options.join(\", \")}]` : \"\";\n console.log(`${d.name} (${d.type})${opts}${d.label ? ` — ${d.label}` : \"\"}`);\n }\n });\n\nfieldsCommand\n .command(\"add <name> <type>\")\n .description(\"Define a custom field (type: text|number|boolean|date|select)\")\n .option(\"--label <label>\", \"Human-readable label\")\n .option(\"--options <csv>\", \"Comma-separated options (for select)\")\n .action(async (name: string, type: string, opts: { label?: string; options?: string }) => {\n if (!VALID_TYPES.includes(type)) {\n console.error(error(`Invalid type '${type}'. Use one of: ${VALID_TYPES.join(\", \")}`));\n process.exitCode = 1;\n return;\n }\n const { defineCustomField } = await import(\"../core/custom-fields.js\");\n defineCustomField(dataDir(), {\n name,\n type: type as CustomFieldType,\n ...(opts.label ? { label: opts.label } : {}),\n ...(opts.options ? { options: opts.options.split(\",\").map((s) => s.trim()) } : {}),\n });\n console.log(success(`Custom field '${name}' (${type}) defined.`));\n });\n\nexport const objectCommand = new Command(\"object\").description(\n \"Manage custom objects (runtime-defined entities, no-migration)\"\n);\n\nobjectCommand\n .command(\"define <name>\")\n .description(\"Define a custom object with fields (--field name:type[:opt1|opt2])\")\n .option(\"--label <label>\", \"Human-readable label\")\n .option(\"--field <spec>\", \"Field spec, repeatable\", collect, [] as string[])\n .action(async (name: string, opts: { label?: string; field: string[] }) => {\n const fields: FieldDefinition[] = [];\n for (const spec of opts.field) {\n const f = parseFieldSpec(spec);\n if (!f) {\n console.error(error(`Invalid --field spec '${spec}' (use name:type[:a|b])`));\n process.exitCode = 1;\n return;\n }\n fields.push(f);\n }\n const { defineCustomObject } = await import(\"../core/custom-objects.js\");\n defineCustomObject(dataDir(), { name, ...(opts.label ? { label: opts.label } : {}), fields });\n console.log(success(`Custom object '${name}' defined with ${fields.length} field(s).`));\n });\n\nobjectCommand\n .command(\"add <name>\")\n .description(\"Create a record (--set key=value, repeatable)\")\n .option(\"--set <kv>\", \"key=value, repeatable\", collect, [] as string[])\n .action(async (name: string, opts: { set: string[] }) => {\n const values: Record<string, string> = {};\n for (const kv of opts.set) {\n const eq = kv.indexOf(\"=\");\n if (eq < 0) continue;\n values[kv.slice(0, eq).trim()] = kv.slice(eq + 1).trim();\n }\n const { createRecord } = await import(\"../core/custom-objects.js\");\n const res = createRecord(dataDir(), name, values);\n if (!res.ok) {\n console.error(error(`Could not create record: ${(res.errors ?? []).join(\"; \")}`));\n process.exitCode = 1;\n return;\n }\n console.log(success(`Created ${name} record ${res.record!.id}`));\n });\n\nobjectCommand\n .command(\"list <name>\")\n .description(\"List records of a custom object\")\n .action(async (name: string) => {\n const { listRecords } = await import(\"../core/custom-objects.js\");\n const records = listRecords(dataDir(), name);\n if (records.length === 0) {\n console.log(info(`No records for '${name}'.`));\n return;\n }\n for (const r of records) console.log(`${r.id} ${JSON.stringify(r.values)}`);\n });\n","import { Command } from \"commander\";\nimport { info, success, error } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const webhookCommand = new Command(\"webhook\").description(\n \"Manage outbound webhooks (event-driven integrations)\"\n);\n\nwebhookCommand\n .command(\"add <url>\")\n .description(\"Subscribe a URL to events (--events record.created,deal.updated or '*')\")\n .option(\"--events <csv>\", \"Comma-separated event patterns\", \"*\")\n .option(\"--secret <secret>\", \"HMAC secret for X-DXCRM-Signature\")\n .action(async (url: string, opts: { events: string; secret?: string }) => {\n const { addWebhook } = await import(\"../core/webhooks.js\");\n const events = opts.events\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n const sub = addWebhook(dataDir(), url, events, opts.secret);\n console.log(success(`Webhook ${sub.id} → ${url} [${events.join(\", \")}]`));\n });\n\nwebhookCommand\n .command(\"list\")\n .description(\"List webhook subscriptions\")\n .action(async () => {\n const { loadWebhooks } = await import(\"../core/webhooks.js\");\n const subs = loadWebhooks(dataDir());\n if (subs.length === 0) {\n console.log(info(\"No webhooks configured.\"));\n return;\n }\n for (const s of subs) console.log(`${s.id} ${s.url} [${s.events.join(\", \")}]`);\n });\n\nwebhookCommand\n .command(\"remove <id>\")\n .description(\"Remove a webhook subscription\")\n .action(async (id: string) => {\n const { removeWebhook } = await import(\"../core/webhooks.js\");\n if (removeWebhook(dataDir(), id)) console.log(success(`Removed ${id}`));\n else {\n console.error(error(`Not found: ${id}`));\n process.exitCode = 1;\n }\n });\n\nwebhookCommand\n .command(\"retry\")\n .description(\"Re-attempt failed webhook deliveries (replay store)\")\n .action(async () => {\n const { retryFailures } = await import(\"../core/webhooks.js\");\n const r = await retryFailures(dataDir());\n console.log(info(`Retried ${r.retried}, still failing ${r.stillFailing}.`));\n });\n","import { Command } from \"commander\";\nimport { info, success, error } from \"../ui/colors.js\";\nimport type { SegmentCriteria } from \"../core/segments.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const segmentCommand = new Command(\"segment\").description(\n \"Manage customer segments (marketing lists)\"\n);\n\nsegmentCommand\n .command(\"define <name>\")\n .description(\"Define a segment by criteria\")\n .option(\"--stage <stage>\", \"relationship_stage (prospect|active|churned|paused)\")\n .option(\"--tags <csv>\", \"Comma-separated tags (all must match)\")\n .option(\"--min-deal-value <n>\", \"Minimum deal value\")\n .option(\"--stale-days <n>\", \"Days since last update (staleness)\")\n .action(\n async (\n name: string,\n opts: { stage?: string; tags?: string; minDealValue?: string; staleDays?: string }\n ) => {\n const criteria: SegmentCriteria = {\n ...(opts.stage ? { stage: opts.stage } : {}),\n ...(opts.tags ? { tags: opts.tags.split(\",\").map((s) => s.trim()) } : {}),\n ...(opts.minDealValue ? { minDealValue: Number(opts.minDealValue) } : {}),\n ...(opts.staleDays ? { staleDays: Number(opts.staleDays) } : {}),\n };\n const { defineSegment } = await import(\"../core/segments.js\");\n defineSegment(dataDir(), name, criteria);\n console.log(success(`Segment '${name}' defined: ${JSON.stringify(criteria)}`));\n }\n );\n\nsegmentCommand\n .command(\"list\")\n .description(\"List defined segments\")\n .action(async () => {\n const { loadSegments } = await import(\"../core/segments.js\");\n const segs = loadSegments(dataDir());\n if (segs.length === 0) {\n console.log(info(\"No segments defined.\"));\n return;\n }\n for (const s of segs) console.log(`${s.name} ${JSON.stringify(s.criteria)}`);\n });\n\nsegmentCommand\n .command(\"members <name>\")\n .description(\"List customers matching a segment\")\n .action(async (name: string) => {\n const { loadSegments, evaluateSegment } = await import(\"../core/segments.js\");\n const seg = loadSegments(dataDir()).find((s) => s.name === name);\n if (!seg) {\n console.error(error(`Segment not found: ${name}`));\n process.exitCode = 1;\n return;\n }\n const members = await evaluateSegment(dataDir(), seg.criteria);\n console.log(info(`${members.length} member(s):`));\n for (const slug of members) console.log(slug);\n });\n","import { Command } from \"commander\";\nimport { info } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const identityCommand = new Command(\"identity\").description(\n \"Identity resolution / deduplication (CDP)\"\n);\n\nidentityCommand\n .command(\"duplicates\")\n .description(\"Find clusters of likely-duplicate customers (by canonical domain)\")\n .action(async () => {\n const { findDuplicateClusters } = await import(\"../core/identity.js\");\n const clusters = await findDuplicateClusters(dataDir());\n if (clusters.length === 0) {\n console.log(info(\"No duplicate clusters found.\"));\n return;\n }\n console.log(info(`${clusters.length} duplicate cluster(s):`));\n for (const c of clusters) console.log(`${c.key}: ${c.slugs.join(\", \")}`);\n });\n","import { Command } from \"commander\";\nimport { info, bold } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const metricsCommand = new Command(\"metrics\")\n .description(\"Command-center metrics from the audit trail\")\n .action(async () => {\n const { computeAuditMetrics } = await import(\"../core/metrics.js\");\n const m = computeAuditMetrics(dataDir());\n console.log(bold(\"Command Center\"));\n console.log(`Total operations: ${m.totalOperations}`);\n console.log(`Customers touched: ${m.customersTouched}`);\n console.log(`Automation rate: ${(m.automationRate * 100).toFixed(0)}%`);\n console.log(info(\"By tool:\"));\n for (const [tool, n] of Object.entries(m.byTool).sort((a, b) => b[1] - a[1])) {\n console.log(` ${tool}: ${n}`);\n }\n console.log(info(\"By actor:\"));\n for (const [actor, n] of Object.entries(m.byActor).sort((a, b) => b[1] - a[1])) {\n console.log(` ${actor}: ${n}`);\n }\n });\n","import { Command } from \"commander\";\nimport { info, bold } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const usageCommand = new Command(\"usage\")\n .description(\"LLM token usage & cost (per customer)\")\n .option(\"--slug <slug>\", \"Filter by customer\")\n .action(async (opts: { slug?: string }) => {\n const { aggregateUsage } = await import(\"../core/usage.js\");\n const agg = aggregateUsage(dataDir(), opts.slug ? { slug: opts.slug } : {});\n console.log(bold(\"LLM Usage\"));\n console.log(`Calls: ${agg.calls}`);\n console.log(`Input tokens: ${agg.totalInputTokens}`);\n console.log(`Output tokens: ${agg.totalOutputTokens}`);\n console.log(`Cost (USD): $${agg.totalCostUsd.toFixed(4)}`);\n if (!opts.slug) {\n console.log(info(\"By customer:\"));\n for (const [slug, b] of Object.entries(agg.bySlug).sort(\n (a, b) => b[1].costUsd - a[1].costUsd\n )) {\n console.log(` ${slug}: $${b.costUsd.toFixed(4)} (${b.calls} calls)`);\n }\n }\n });\n","import { Command } from \"commander\";\nimport { info, success, error } from \"../ui/colors.js\";\nimport type { Policy } from \"../core/approvals.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const approvalsCommand = new Command(\"approvals\").description(\n \"Human-in-the-loop approval queue\"\n);\n\napprovalsCommand\n .command(\"list\")\n .description(\"List approvals (default: pending)\")\n .option(\"--status <status>\", \"pending | approved | rejected\", \"pending\")\n .action(async (opts: { status: string }) => {\n const { listApprovals } = await import(\"../core/approvals.js\");\n const list = listApprovals(dataDir(), opts.status as \"pending\" | \"approved\" | \"rejected\");\n if (list.length === 0) {\n console.log(info(`No ${opts.status} approvals.`));\n return;\n }\n for (const a of list) console.log(`${a.id} ${a.tool} ${a.slug ?? \"-\"} ${a.requestedAt}`);\n });\n\napprovalsCommand\n .command(\"approve <id>\")\n .description(\"Approve a pending action\")\n .action(async (id: string) => {\n const { decideApproval } = await import(\"../core/approvals.js\");\n if (decideApproval(dataDir(), id, \"approved\")) console.log(success(`Approved ${id}`));\n else {\n console.error(error(`Not found: ${id}`));\n process.exitCode = 1;\n }\n });\n\napprovalsCommand\n .command(\"reject <id>\")\n .description(\"Reject a pending action\")\n .action(async (id: string) => {\n const { decideApproval } = await import(\"../core/approvals.js\");\n if (decideApproval(dataDir(), id, \"rejected\")) console.log(success(`Rejected ${id}`));\n else {\n console.error(error(`Not found: ${id}`));\n process.exitCode = 1;\n }\n });\n\nexport const policyCommand = new Command(\"policy\").description(\n \"Autonomy policy per tool/customer (auto|approve|block)\"\n);\n\npolicyCommand\n .command(\"set <tool> <policy>\")\n .description(\"Set autonomy policy for a tool (optionally per --slug)\")\n .option(\"--slug <slug>\", \"Customer slug (per-customer override)\")\n .action(async (tool: string, policy: string, opts: { slug?: string }) => {\n if (![\"auto\", \"approve\", \"block\"].includes(policy)) {\n console.error(error(\"policy must be auto | approve | block\"));\n process.exitCode = 1;\n return;\n }\n const { setPolicy } = await import(\"../core/approvals.js\");\n setPolicy(dataDir(), tool, policy as Policy, opts.slug);\n console.log(success(`Policy ${tool}${opts.slug ? `@${opts.slug}` : \"\"} = ${policy}`));\n });\n","import { Command } from \"commander\";\nimport { info, success } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const hygieneCommand = new Command(\"hygiene\").description(\"Data-quality scanning\");\n\nhygieneCommand\n .command(\"scan\")\n .description(\"Scan customers for data-quality issues (missing/malformed/duplicate)\")\n .action(async () => {\n const { scanHygiene } = await import(\"../core/hygiene.js\");\n const issues = await scanHygiene(dataDir());\n if (issues.length === 0) {\n console.log(success(\"✓ No data-quality issues found.\"));\n return;\n }\n console.log(info(`${issues.length} issue(s):`));\n for (const i of issues) {\n const fix = i.suggestedFix ? ` → fix: ${i.suggestedFix}` : \"\";\n console.log(` [${i.type}] ${i.slug}: ${i.detail}${fix}`);\n }\n });\n","import { Command } from \"commander\";\nimport { info, success } from \"../ui/colors.js\";\nimport type { MemoryType } from \"../core/memory.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\nconst TYPES = [\"fact\", \"preference\", \"learning\", \"instruction\"];\n\nexport const memoryCommand = new Command(\"memory\").description(\n \"Agent memories (per customer + global)\"\n);\n\nmemoryCommand\n .command(\"add <text>\")\n .description(\"Add a memory (global unless --slug given)\")\n .option(\"--type <type>\", \"fact | preference | learning | instruction\", \"fact\")\n .option(\"--slug <slug>\", \"Customer slug (omit for global)\")\n .action(async (text: string, opts: { type: string; slug?: string }) => {\n const type = (TYPES.includes(opts.type) ? opts.type : \"fact\") as MemoryType;\n const { addMemory } = await import(\"../core/memory.js\");\n const m = addMemory(dataDir(), {\n scope: opts.slug ? \"customer\" : \"global\",\n ...(opts.slug ? { slug: opts.slug } : {}),\n type,\n text,\n });\n console.log(success(`Memory ${m.id} stored (${m.scope}${opts.slug ? `:${opts.slug}` : \"\"}).`));\n });\n\nmemoryCommand\n .command(\"list\")\n .description(\"List memories (global + customer if --slug)\")\n .option(\"--slug <slug>\", \"Customer slug\")\n .action(async (opts: { slug?: string }) => {\n const { loadMemories } = await import(\"../core/memory.js\");\n const mems = loadMemories(dataDir(), opts.slug);\n if (mems.length === 0) {\n console.log(info(\"No memories.\"));\n return;\n }\n for (const m of mems) console.log(`[${m.scope}/${m.type}] ${m.text}`);\n });\n\nmemoryCommand\n .command(\"search <query>\")\n .description(\"Search memories by relevance\")\n .option(\"--slug <slug>\", \"Customer slug\")\n .action(async (query: string, opts: { slug?: string }) => {\n const { searchMemory } = await import(\"../core/memory.js\");\n const hits = await searchMemory(dataDir(), query, opts.slug);\n if (hits.length === 0) {\n console.log(info(\"No matching memories.\"));\n return;\n }\n for (const m of hits) console.log(`[${m.scope}/${m.type}] ${m.text}`);\n });\n","import { Command } from \"commander\";\nimport { info, success } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const sopCommand = new Command(\"sop\").description(\n \"Standard Operating Procedures (global / per customer)\"\n);\n\nsopCommand\n .command(\"add <title>\")\n .description(\"Add an SOP (global unless --slug given)\")\n .option(\"--triggers <csv>\", \"Comma-separated trigger keywords\", \"\")\n .option(\"--body <text>\", \"SOP body / steps\", \"\")\n .option(\"--slug <slug>\", \"Customer slug (omit for global)\")\n .action(async (title: string, opts: { triggers: string; body: string; slug?: string }) => {\n const { addSop } = await import(\"../core/sop.js\");\n const triggers = opts.triggers\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n const s = addSop(dataDir(), {\n scope: opts.slug ? \"customer\" : \"global\",\n ...(opts.slug ? { slug: opts.slug } : {}),\n title,\n triggers,\n body: opts.body,\n });\n console.log(success(`SOP ${s.id} added (${s.scope}${opts.slug ? `:${opts.slug}` : \"\"}).`));\n });\n\nsopCommand\n .command(\"list\")\n .description(\"List SOPs (global + customer if --slug)\")\n .option(\"--slug <slug>\", \"Customer slug\")\n .action(async (opts: { slug?: string }) => {\n const { loadSops } = await import(\"../core/sop.js\");\n const sops = loadSops(dataDir(), opts.slug);\n if (sops.length === 0) {\n console.log(info(\"No SOPs.\"));\n return;\n }\n for (const s of sops) console.log(`[${s.scope}] ${s.title} (${s.triggers.join(\", \")})`);\n });\n\nsopCommand\n .command(\"find <query>\")\n .description(\"Find SOPs relevant to a task\")\n .option(\"--slug <slug>\", \"Customer slug\")\n .action(async (query: string, opts: { slug?: string }) => {\n const { findSops } = await import(\"../core/sop.js\");\n const hits = await findSops(dataDir(), query, opts.slug);\n if (hits.length === 0) {\n console.log(info(\"No matching SOPs.\"));\n return;\n }\n for (const s of hits) console.log(`[${s.scope}] ${s.title}`);\n });\n","import { Command } from \"commander\";\nimport { info, success } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const toneCommand = new Command(\"tone\").description(\n \"Customer tonality profiles (per customer + global)\"\n);\n\ntoneCommand\n .command(\"set\")\n .description(\"Set tone profile (global unless --slug given)\")\n .option(\"--formality <v>\", \"formal | casual | friendly\")\n .option(\"--language <v>\", \"Language code, e.g. de | en\")\n .option(\"--do <csv>\", \"Comma-separated phrases to prefer\")\n .option(\"--dont <csv>\", \"Comma-separated phrases to avoid\")\n .option(\"--slug <slug>\", \"Customer slug (omit for global)\")\n .action(\n async (opts: {\n formality?: string;\n language?: string;\n do?: string;\n dont?: string;\n slug?: string;\n }) => {\n const { setTone } = await import(\"../core/tone.js\");\n setTone(\n dataDir(),\n {\n ...(opts.formality ? { formality: opts.formality } : {}),\n ...(opts.language ? { language: opts.language } : {}),\n ...(opts.do ? { dos: opts.do.split(\",\").map((s) => s.trim()) } : {}),\n ...(opts.dont ? { donts: opts.dont.split(\",\").map((s) => s.trim()) } : {}),\n },\n opts.slug\n );\n console.log(\n success(`Tone profile saved (${opts.slug ? `customer:${opts.slug}` : \"global\"}).`)\n );\n }\n );\n\ntoneCommand\n .command(\"show\")\n .description(\"Show the effective tone profile\")\n .option(\"--slug <slug>\", \"Customer slug\")\n .action(async (opts: { slug?: string }) => {\n const { resolveTone, toneInstruction } = await import(\"../core/tone.js\");\n const profile = resolveTone(dataDir(), opts.slug);\n console.log(info(JSON.stringify(profile)));\n console.log(`instruction: ${toneInstruction(profile) || \"(none)\"}`);\n });\n","import { Command } from \"commander\";\nimport fs from \"fs\";\nimport { info, error } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const autofillCommand = new Command(\"autofill\")\n .description(\"Extract structured CRM fields from a transcript file\")\n .argument(\"<file>\", \"Path to transcript file\")\n .option(\"--slug <slug>\", \"Customer slug (for usage attribution)\")\n .action(async (file: string, opts: { slug?: string }) => {\n if (!fs.existsSync(file)) {\n console.error(error(`File not found: ${file}`));\n process.exitCode = 1;\n return;\n }\n const transcript = fs.readFileSync(file, \"utf-8\") as string;\n const { extractAutofill } = await import(\"../core/autofill.js\");\n const result = await extractAutofill(transcript, opts.slug ? { slug: opts.slug } : {});\n console.log(info(\"Extracted fields (review before applying):\"));\n console.log(JSON.stringify(result, null, 2));\n void dataDir;\n });\n","import { Command } from \"commander\";\nimport { info, bold } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const askCommand = new Command(\"ask\")\n .description(\"Ask your CRM a natural-language question\")\n .argument(\"<question>\", \"The question\")\n .option(\"--slug <slug>\", \"Scope to a customer\")\n .action(async (question: string, opts: { slug?: string }) => {\n const { askCrm } = await import(\"../core/ask.js\");\n const res = await askCrm(dataDir(), question, opts.slug);\n if (res.answer) {\n console.log(bold(\"Answer:\"));\n console.log(res.answer);\n }\n if (res.sources.length === 0) {\n console.log(info(\"No relevant data found.\"));\n return;\n }\n console.log(info(\"Sources:\"));\n res.sources.forEach((s, i) => console.log(` [${i + 1}] ${s.text.slice(0, 120)}`));\n });\n","import { Command } from \"commander\";\nimport { info } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const nbaCommand = new Command(\"nba\")\n .description(\"Next-best-action recommendations for a customer\")\n .argument(\"<slug>\", \"Customer slug\")\n .action(async (slug: string) => {\n const { nextBestAction } = await import(\"../core/nba.js\");\n const actions = await nextBestAction(dataDir(), slug);\n if (actions.length === 0) {\n console.log(info(\"No recommendations.\"));\n return;\n }\n for (const a of actions) console.log(`[${a.priority}] ${a.action} — ${a.reason}`);\n });\n","import { Command } from \"commander\";\nimport { info, success, error } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\n/** Master key from the environment only — never a flag (avoids shell history). */\nfunction masterKey(): string {\n const key = process.env[\"DXCRM_VAULT_KEY\"];\n if (!key) {\n console.error(error(\"DXCRM_VAULT_KEY is not set. Export your vault master key first.\"));\n process.exit(1);\n }\n return key;\n}\n\n/** Run a vault action, turning decryption/IO failures into a clean exit. */\nasync function guard(fn: () => Promise<void> | void): Promise<void> {\n try {\n await fn();\n } catch (e) {\n console.error(error((e as Error).message));\n process.exit(1);\n }\n}\n\nexport const vaultCommand = new Command(\"vault\").description(\n \"Local encrypted credential vault (AES-256-GCM)\"\n);\n\nvaultCommand\n .command(\"set <name> <value>\")\n .description(\"Store (or overwrite) a secret\")\n .action((name: string, value: string) =>\n guard(async () => {\n const { setSecret } = await import(\"../core/vault.js\");\n setSecret(dataDir(), masterKey(), name, value);\n console.log(success(`Secret '${name}' stored.`));\n })\n );\n\nvaultCommand\n .command(\"get <name>\")\n .description(\"Retrieve a secret\")\n .action((name: string) =>\n guard(async () => {\n const { getSecret } = await import(\"../core/vault.js\");\n const value = getSecret(dataDir(), masterKey(), name);\n if (value === undefined) {\n console.log(info(`No secret named '${name}'.`));\n return;\n }\n console.log(value);\n })\n );\n\nvaultCommand\n .command(\"list\")\n .description(\"List secret names (values stay encrypted)\")\n .action(() =>\n guard(async () => {\n const { listSecretKeys } = await import(\"../core/vault.js\");\n const names = listSecretKeys(dataDir(), masterKey());\n if (names.length === 0) {\n console.log(info(\"Vault is empty.\"));\n return;\n }\n for (const n of names.sort()) console.log(n);\n })\n );\n\nvaultCommand\n .command(\"rm <name>\")\n .description(\"Remove a secret\")\n .action((name: string) =>\n guard(async () => {\n const { removeSecret } = await import(\"../core/vault.js\");\n const removed = removeSecret(dataDir(), masterKey(), name);\n console.log(\n removed ? success(`Secret '${name}' removed.`) : info(`No secret named '${name}'.`)\n );\n })\n );\n","import { Command } from \"commander\";\nimport { info, success, warning, error } from \"../ui/colors.js\";\nimport type { ChurnLevel } from \"../core/churn.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nfunction paint(level: ChurnLevel, text: string): string {\n if (level === \"high\") return error(text);\n if (level === \"medium\") return warning(text);\n return success(text);\n}\n\nexport const churnCommand = new Command(\"churn\").description(\n \"Churn early-warning (relationship-health based)\"\n);\n\nchurnCommand\n .command(\"assess <slug>\")\n .description(\"Assess churn risk for one customer\")\n .action(async (slug: string) => {\n const { assessChurn } = await import(\"../core/churn.js\");\n const r = assessChurn(dataDir(), slug);\n console.log(paint(r.level, `${slug}: ${r.level.toUpperCase()} risk (${r.riskScore}/100)`));\n for (const s of r.signals) console.log(` • ${s}`);\n });\n\nchurnCommand\n .command(\"scan\")\n .description(\"Rank all customers by churn risk (highest first)\")\n .action(async () => {\n const { scanChurn } = await import(\"../core/churn.js\");\n const ranked = scanChurn(dataDir());\n if (ranked.length === 0) {\n console.log(info(\"No customers to assess.\"));\n return;\n }\n for (const r of ranked) {\n console.log(\n paint(r.level, `${r.riskScore.toString().padStart(3)} ${r.level.padEnd(6)} ${r.slug}`)\n );\n }\n });\n","import { Command } from \"commander\";\nimport { info, success, warning } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const leadscoreCommand = new Command(\"leadscore\").description(\n \"Predictive lead scoring (logistic regression on won/lost history)\"\n);\n\nleadscoreCommand\n .command(\"train\")\n .description(\"Train the model from won/lost history and persist it\")\n .action(async () => {\n const { buildLeadModel, saveLeadModel } = await import(\"../core/lead-model.js\");\n const model = buildLeadModel(dataDir());\n if (!model.sufficient) {\n console.log(\n warning(\n `Not enough closed history to train (${model.trainedOn} deals, need ≥4 with both outcomes).`\n )\n );\n console.log(info(\"Predictions fall back to the deterministic heuristic until then.\"));\n return;\n }\n saveLeadModel(dataDir(), model);\n console.log(success(`Trained on ${model.trainedOn} closed deals. Model saved.`));\n });\n\nleadscoreCommand\n .command(\"predict <slug>\")\n .description(\"Score a customer's open deals with the trained model\")\n .action(async (slug: string) => {\n const { loadLeadModel, buildLeadModel, predictWin } = await import(\"../core/lead-model.js\");\n const { readPipelineSync } = await import(\"../fs/pipeline-writer.js\");\n const model = loadLeadModel(dataDir()) ?? buildLeadModel(dataDir());\n const open = readPipelineSync(dataDir(), slug).filter(\n (d) => d.stage !== \"won\" && d.stage !== \"lost\"\n );\n if (open.length === 0) {\n console.log(info(`No open deals for ${slug}.`));\n return;\n }\n const source = model.sufficient ? \"model\" : \"heuristic\";\n console.log(info(`Win-probability for ${slug} (${source}):`));\n for (const d of open) {\n const p = Math.round(predictWin(model, d) * 100);\n console.log(` ${String(p).padStart(3)}% ${d.name} (${d.stage})`);\n }\n });\n\nexport default leadscoreCommand;\n","import { Command } from \"commander\";\nimport { info, success } from \"../ui/colors.js\";\n\nfunction dataDir(): string {\n return process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n}\n\nexport const enrichCommand = new Command(\"enrich\")\n .description(\"Enrich a customer's facts (offline domain-from-email + plugins)\")\n .argument(\"<slug>\", \"Customer slug\")\n .option(\"--write\", \"Write newly-derived fields back to main_facts.md\")\n .action(async (slug: string, opts: { write?: boolean }) => {\n const { enrichCustomer } = await import(\"../core/enrichment.js\");\n const res = await enrichCustomer(dataDir(), slug, { write: opts.write ?? false });\n const applied = Object.entries(res.applied);\n if (applied.length === 0) {\n console.log(info(`Nothing new to enrich for ${slug}.`));\n return;\n }\n for (const [k, v] of applied) console.log(` ${k}: ${String(v)}`);\n console.log(\n res.written\n ? success(`Applied ${applied.length} field(s) to ${slug}.`)\n : info(`Found ${applied.length} field(s) — re-run with --write to apply.`)\n );\n });\n","import fs from \"fs\";\nimport { Command } from \"commander\";\nimport { info, success } from \"../ui/colors.js\";\n\nexport const coachCommand = new Command(\"coach\")\n .description(\"Conversation-intelligence: analyze a call transcript\")\n .argument(\"<file>\", 'Path to a speaker-labelled transcript (\"Rep: ...\" / \"Customer: ...\")')\n .option(\n \"--rep <labels>\",\n \"Comma-separated speaker labels treated as the rep\",\n \"rep,sales,ae,me,agent\"\n )\n .action(async (file: string, opts: { rep: string }) => {\n if (!fs.existsSync(file)) {\n console.error(`Transcript not found: ${file}`);\n process.exit(1);\n }\n const transcript = fs.readFileSync(file, \"utf-8\") as string;\n const { analyzeConversation } = await import(\"../core/conversation-intel.js\");\n const labels = opts.rep\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n const a = analyzeConversation(transcript, labels);\n\n console.log(success(`Conversation analysis (${a.turns} turns)`));\n console.log(` Talk ratio (rep): ${Math.round(a.talkRatio * 100)}%`);\n console.log(` Questions asked: ${a.questionsAsked}`);\n console.log(` Longest monologue: ${a.longestMonologue} words`);\n if (a.objections.length > 0) {\n console.log(info(\" Objections:\"));\n for (const o of a.objections) console.log(` • ${o}`);\n }\n console.log(info(\" Coaching:\"));\n for (const c of a.coaching) console.log(` → ${c}`);\n });\n","import { Command } from \"commander\";\nimport { info, success, warning } from \"../ui/colors.js\";\n\nexport const complianceCommand = new Command(\"compliance\").description(\n \"Privacy/compliance posture (AI-Act Art. 50, local-LLM, PII, guardrails)\"\n);\n\ncomplianceCommand\n .command(\"status\", { isDefault: true })\n .description(\"Show the active compliance configuration\")\n .action(async () => {\n const { complianceConfig, aiDisclosure } = await import(\"../core/compliance.js\");\n const cfg = complianceConfig();\n const onOff = (b: boolean): string => (b ? success(\"on\") : warning(\"off\"));\n\n console.log(info(\"Compliance posture\"));\n console.log(` LLM provider: ${cfg.provider}`);\n if (cfg.local) {\n console.log(` Local endpoint: ${cfg.local.baseUrl}`);\n console.log(` Local model: ${cfg.local.model}`);\n console.log(success(\" → Customer data stays on-machine (data-residency moat).\"));\n }\n console.log(` AI-Act Art.50 label: ${onOff(cfg.aiDisclosure)}`);\n console.log(` PII masking: ${onOff(cfg.piiMasking)}`);\n console.log(` Prompt guardrails: ${onOff(cfg.guardrails)}`);\n if (cfg.aiDisclosure) console.log(info(` Disclosure: \"${aiDisclosure()}\"`));\n });\n","import { Command } from \"commander\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport type { ImapMailboxConfig, SyncImapResult } from \"../sync/connectors/imap.js\";\n\n/** Read IMAP mailbox connection settings from the environment. */\nexport function imapConfigFromEnv(env: NodeJS.ProcessEnv = process.env): ImapMailboxConfig | null {\n const host = env[\"DXCRM_IMAP_HOST\"];\n const user = env[\"DXCRM_IMAP_USER\"];\n const pass = env[\"DXCRM_IMAP_PASS\"];\n const accessToken = env[\"DXCRM_IMAP_TOKEN\"];\n if (!host || !user || (!pass && !accessToken)) return null;\n\n return {\n host,\n port: env[\"DXCRM_IMAP_PORT\"] ? Number(env[\"DXCRM_IMAP_PORT\"]) : 993,\n secure: env[\"DXCRM_IMAP_SECURE\"] !== \"false\",\n mailbox: env[\"DXCRM_IMAP_MAILBOX\"] ?? \"INBOX\",\n auth: accessToken ? { user, accessToken } : { user, pass: pass! },\n };\n}\n\nexport interface RunMailboxSyncOptions {\n dataDir: string;\n slug?: string | undefined;\n since?: Date | undefined;\n includeAttachments?: boolean | undefined;\n env?: NodeJS.ProcessEnv;\n}\n\n/**\n * Sync an IMAP mailbox (any provider). With a slug, all mail goes to that one\n * customer; without, mail is auto-routed to customers by sender/recipient\n * domain and unmatched mail is reported as unrouted.\n */\nexport async function runMailboxSync(\n opts: RunMailboxSyncOptions\n): Promise<SyncImapResult | { error: string }> {\n const config = imapConfigFromEnv(opts.env ?? process.env);\n if (!config) {\n const msg =\n \"IMAP not configured. Set DXCRM_IMAP_HOST, DXCRM_IMAP_USER and DXCRM_IMAP_PASS (or DXCRM_IMAP_TOKEN).\";\n console.error(error(msg));\n return { error: msg };\n }\n\n const { syncImapMailbox } = await import(\"../sync/connectors/imap.js\");\n const result = await syncImapMailbox({\n dataDir: opts.dataDir,\n config,\n ...(opts.slug ? { slug: opts.slug } : {}),\n ...(opts.since ? { since: opts.since } : {}),\n ...(opts.includeAttachments !== undefined\n ? { includeAttachments: opts.includeAttachments }\n : {}),\n });\n\n const target = opts.slug ? `customer ${bold(opts.slug)}` : \"all customers (auto-routed)\";\n console.log(\n success(\n `✓ IMAP ${config.mailbox} → ${target}: +${result.synced} synced, ${result.skipped} skipped, ${result.unrouted} unrouted`\n )\n );\n if (!opts.slug && result.unrouted > 0) {\n console.log(\n info(\n ` ${result.unrouted} message(s) matched no customer. Add their domains via 'dxcrm create <slug> --domain <domain>'.`\n )\n );\n }\n return result;\n}\n\nexport const mailboxCommand = new Command(\"mailbox\").description(\n \"Sync any IMAP mailbox (Gmail, Outlook, custom) into the CRM\"\n);\n\nmailboxCommand\n .command(\"sync\")\n .description(\"Sync an IMAP mailbox; auto-routes to customers by domain unless a slug is given\")\n .argument(\"[slug]\", \"Route all mail to this customer (omit to auto-route by domain)\")\n .option(\"--since <date>\", \"Only sync messages after this date (YYYY-MM-DD)\")\n .option(\"--no-attachments\", \"Skip downloading/converting/indexing attachments\")\n .action(async (slug: string | undefined, options: { since?: string; attachments?: boolean }) => {\n const dataDir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n await runMailboxSync({\n dataDir,\n slug,\n ...(options.since ? { since: new Date(options.since) } : {}),\n includeAttachments: options.attachments !== false,\n });\n });\n","// Single source of truth for the dxcrm command set.\n// Both the CLI entrypoint (src/cli.ts) and the docs generator\n// (scripts/generate-docs.ts) consume this array, so the published\n// CLI reference can never drift from the commands that actually ship.\nimport type { Command } from \"commander\";\nimport { createCommand } from \"./create.js\";\nimport { listCommand } from \"./list.js\";\nimport { validateCommand } from \"./validate.js\";\nimport { sessionCommand } from \"./session.js\";\nimport { guideCommand, mcpCommand } from \"./guide.js\";\nimport { initCommand } from \"./init.js\";\nimport { syncCommand } from \"./sync.js\";\nimport { backupCommand, restoreCommand } from \"./backup.js\";\nimport { daemonCommand } from \"./daemon.js\";\nimport { statusCommand } from \"./status.js\";\nimport { agentCommand } from \"./agent.js\";\nimport { importCommand } from \"./import.js\";\nimport { serverCommand } from \"./server.js\";\nimport { auditCommand } from \"./audit.js\";\nimport { logsCommand } from \"./logs.js\";\nimport { doctorCommand } from \"./doctor.js\";\nimport { rbacCommand } from \"./rbac.js\";\nimport { gdprCommand } from \"./gdpr.js\";\nimport { securityReportCommand } from \"./security-report.js\";\nimport { stagesCommand } from \"./pipeline-stages.js\";\nimport { pluginCommand } from \"./plugin.js\";\nimport { goalCommand } from \"./goal.js\";\nimport { pushCommand } from \"./push.js\";\nimport { attachCommand } from \"./attach.js\";\nimport { templateCommand } from \"./template.js\";\nimport { sequenceCommand } from \"./sequence.js\";\nimport { quoteCommand } from \"./quote.js\";\nimport { ticketCommand } from \"./ticket.js\";\nimport { surveyCommand } from \"./survey.js\";\nimport { kbCommand } from \"./kb.js\";\nimport { fieldsCommand, objectCommand } from \"./fields.js\";\nimport { webhookCommand } from \"./webhook.js\";\nimport { segmentCommand } from \"./segment.js\";\nimport { identityCommand } from \"./identity.js\";\nimport { metricsCommand } from \"./metrics.js\";\nimport { usageCommand } from \"./usage.js\";\nimport { approvalsCommand, policyCommand } from \"./approvals.js\";\nimport { hygieneCommand } from \"./hygiene.js\";\nimport { memoryCommand } from \"./memory.js\";\nimport { sopCommand } from \"./sop.js\";\nimport { toneCommand } from \"./tone.js\";\nimport { autofillCommand } from \"./autofill.js\";\nimport { askCommand } from \"./ask.js\";\nimport { nbaCommand } from \"./nba.js\";\nimport { vaultCommand } from \"./vault.js\";\nimport { churnCommand } from \"./churn.js\";\nimport { leadscoreCommand } from \"./leadscore.js\";\nimport { enrichCommand } from \"./enrich.js\";\nimport { coachCommand } from \"./coach.js\";\nimport { complianceCommand } from \"./compliance.js\";\nimport { mailboxCommand } from \"./mailbox.js\";\n\n/** Every top-level `dxcrm` command, in display order. */\nexport const ALL_COMMANDS: readonly Command[] = [\n initCommand,\n createCommand,\n listCommand,\n validateCommand,\n sessionCommand,\n guideCommand,\n mcpCommand,\n syncCommand,\n mailboxCommand,\n backupCommand,\n restoreCommand,\n daemonCommand,\n statusCommand,\n agentCommand,\n importCommand,\n serverCommand,\n auditCommand,\n logsCommand,\n doctorCommand,\n rbacCommand,\n gdprCommand,\n securityReportCommand,\n stagesCommand,\n pluginCommand,\n goalCommand,\n pushCommand,\n attachCommand,\n templateCommand,\n sequenceCommand,\n quoteCommand,\n ticketCommand,\n surveyCommand,\n kbCommand,\n fieldsCommand,\n objectCommand,\n webhookCommand,\n segmentCommand,\n identityCommand,\n metricsCommand,\n usageCommand,\n approvalsCommand,\n policyCommand,\n hygieneCommand,\n memoryCommand,\n sopCommand,\n toneCommand,\n autofillCommand,\n askCommand,\n nbaCommand,\n vaultCommand,\n churnCommand,\n leadscoreCommand,\n enrichCommand,\n coachCommand,\n complianceCommand,\n];\n","#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { ALL_COMMANDS } from \"./commands/registry.js\";\n\nconst program = new Command();\nprogram\n .name(\"dxcrm\")\n .description(\"DatasynxOpenCRM — local-first, MCP-native CRM\")\n .version(\"0.1.0\")\n .exitOverride(); // for testability\n\nfor (const command of ALL_COMMANDS) {\n program.addCommand(command);\n}\n\nawait program.parseAsync(process.argv);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,eAAsB,eAAe,MAKI;CACvC,MAAM,KAAK,QAAQ,KAAK,MAAM,EAAE,OAAO,KAAK,CAAC;CAC7C,MAAM,UAAU,KAAK,WAAW,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAC7E,MAAM,kBAAkB,SAAS,EAAE;CACnC,MAAM,MAAM,KAAK,KAAK,SAAS,aAAa,EAAE;CAG9C,MAAM,yBAAQ,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;CAClD,MAAM,eAAe,SAAS,IAAI;EAChC,MAAM,KAAK;EACX,QAAQ,KAAK;EACb,OAAO,KAAK;EACZ,oBAAoB;EACpB,MAAM,CAAC;EACP,UAAU;EACV,SAAS;EACT,SAAS;CACX,CAAC;CAGD,MAAM,mBAAmB,KAAK,KAAK,KAAK,iBAAiB;CACzD,IAAI,CAAC,GAAG,WAAW,gBAAgB,GACjC,gBAAgB,kBAAkB,oBAAoB,KAAK,KAAK,KAAK;CAIvE,MAAM,eAAe,KAAK,KAAK,KAAK,aAAa;CACjD,IAAI,CAAC,GAAG,WAAW,YAAY,GAC7B,gBACE,cACA,gBAAgB,KAAK,KAAK,0HAC5B;CAIF,MAAM,cAAc,KAAK,KAAK,KAAK,cAAc;CACjD,IAAI,CAAC,GAAG,WAAW,WAAW,GAe5B,cAAc,aAAa;EARzB,OAAO;GACL,MAAM;GACN,OARe,KAAK,SACpB,QAAQ,KAAK,OAAO,SAAS,KAAK,WAClC,KAAK,QACH,QAAQ,KAAK,MAAM,SAAS,KAAK,UACjC;GAKF,SAAS;EACX;EACA,SAAS;EACT,0BAAS,IAAI,KAAK,GAAE,YAAY;CAED,CAAC;CAGpC,OAAO;EAAE;EAAI;CAAI;AACnB;AAEA,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAC9C,YAAY,uBAAuB,EACnC,SAAS,UAAU,eAAe,EAClC,OAAO,qBAAqB,iCAAiC,EAC7D,OAAO,mBAAmB,uBAAuB,EACjD,OAAO,OAAO,MAAc,SAA8C;CACzE,IAAI;EACF,MAAM,EAAE,IAAI,QAAQ,MAAM,eAAe;GAAE;GAAM,GAAG;EAAK,CAAC;EAC1D,QAAQ,IAAI,QAAQ,uBAAuB,KAAK,EAAE,GAAG,CAAC;EACtD,QAAQ,IAAI,UAAU,KAAK;EAC3B,QAAQ,IAAI,oEAAoE;CAClF,SAAS,KAAK;EACZ,QAAQ,MAAM,MAAM,KAAM,IAAc,SAAS,CAAC;EAClD,QAAQ,KAAK,CAAC;CAChB;AACF,CAAC;;;AC5EH,SAAgB,oBAAoB,WAAkC;CACpE,MAAM,QAAQ,IAAI,MAAM;EACtB,MAAM;GAAC;GAAQ;GAAQ;GAAS;GAAY;GAAQ;EAAS;EAC7D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;EACxB,WAAW;GAAC;GAAI;GAAI;GAAI;GAAI;GAAI;EAAE;EAClC,UAAU;CACZ,CAAC;CAED,KAAK,MAAM,EAAE,MAAM,WAAW,WAC5B,MAAM,KAAK;EACT;EACA,MAAM;EACN,MAAM;EACN,MAAM,YAAY;EAClB,MAAM,KAAK,KAAK,IAAI,KAAK;EACzB,MAAM;CACR,CAAC;CAGH,OAAO,MAAM,SAAS;AACxB;;;ACzBA,MAAa,cAAc,IAAI,QAAQ,MAAM,EAC1C,YAAY,oBAAoB,EAChC,OAAO,oBAAoB,wBAAwB,EACnD,OAAO,OAAO,SAA8B;CAC3C,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAC7D,MAAM,QAAQ,kBAAkB,OAAO;CAEvC,IAAI,MAAM,WAAW,GAAG;EACtB,QAAQ,IAAI,uDAAqD;EACjE;CACF;CAEA,MAAM,YAGD,CAAC;CAEN,KAAK,MAAM,QAAQ,OACjB,IAAI;EACF,MAAM,QAAQ,MAAM,cAAc,SAAS,IAAI;EAC/C,IAAI,KAAK,QAAQ;GACf,MAAM,IAAI,KAAK,OAAO,YAAY;GAClC,IACE,CAAC,MAAM,KAAK,YAAY,EAAE,SAAS,CAAC,KACpC,CAAC,KAAK,SAAS,CAAC,KAChB,EAAE,MAAM,sBAAsB,IAAI,YAAY,EAAE,SAAS,CAAC,GAE1D;EACJ;EACA,UAAU,KAAK;GAAE;GAAM;EAAM,CAAC;CAChC,QAAQ,CAER;CAGF,IAAI,UAAU,WAAW,GAAG;EAC1B,QAAQ,IAAI,KAAK,SAAS,0BAA0B,KAAK,OAAO,KAAK,mBAAmB;EACxF;CACF;CAEA,QAAQ,IAAI,oBAAoB,SAAS,CAAC;AAC5C,CAAC;;;ACtCH,MAAM,uBAAgD;CACpD,MAAM,CAAC;CACP,UAAU;AACZ;AAEA,SAAgB,SACd,WACA,SACA,MAC6C;CAC7C,MAAM,QAAkB,CAAC;CACzB,MAAM,UAAU,EAAE,GAAG,KAAK;CAE1B,KAAK,MAAM,CAAC,OAAO,iBAAiB,OAAO,QAAQ,oBAAoB,GACrE,IAAI,QAAQ,WAAW,KAAA,KAAa,QAAQ,WAAW,MAAM;EAC3D,QAAQ,SAAS;EACjB,MAAM,KAAK,GAAG,MAAM,KAAK,KAAK,UAAU,YAAY,GAAG;CACzD;CAGF,IAAI,QAAQ,eAAe,KAAA,KAAa,QAAQ,YAAY;EAC1D,QAAQ,aAAa,QAAQ;EAC7B,MAAM,KAAK,aAAa,OAAO,QAAQ,UAAU,GAAG;CACtD;CAEA,IAAI,MAAM,WAAW,GAAG,OAAO;CAE/B,MAAM,SAAS,OAAO,OAAO;CAC7B,MAAM,aAAa,OAAO,UAAU,OAAO,SAAS,OAAO;CAC3D,GAAG,cAAc,WAAW,UAAU;CACtC,OAAO;EAAE;EAAO,SAAS;CAAW;AACtC;AAEA,eAAsB,YAAY,MAAyB,SAAgC;CACzF,MAAM,eAAe,KAAK,KAAK,SAAS,WAAW;CAEnD,IAAI,CAAC,GAAG,WAAW,YAAY,GAAG;EAChC,QAAQ,IAAI,QAAQ,iCAAiC,CAAC;EACtD;CACF;CAEA,MAAM,QAAQ,kBAAkB,OAAO;CAEvC,IAAI,aAAa;CACjB,IAAI,aAAa;CAEjB,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,YAAY,KAAK,KAAK,cAAc,MAAM,eAAe;EAC/D,MAAM,mBAAmB,KAAK,KAAK,cAAc,MAAM,iBAAiB;EAExE,IAAI,CAAC,GAAG,WAAW,SAAS,GAAG;GAC7B,QAAQ,IAAI,MAAM,KAAK,KAAK,wBAAwB,CAAC;GACrD;GACA;EACF;EAEA,IAAI;GACF,IAAI,UAAU,GAAG,aAAa,WAAW,OAAO;GAChD,IAAI,SAAS,OAAO,OAAO;GAE3B,IAAI,KAAK,KAAK;IACZ,MAAM,SAAS,SAAS,WAAW,SAAS,OAAO,IAA+B;IAClF,IAAI,QAAQ;KACV,UAAU,OAAO;KACjB,SAAS,OAAO,OAAO;KACvB;KACA,QAAQ,IAAI,KAAK,KAAK,KAAK,UAAU,OAAO,MAAM,KAAK,IAAI,GAAG,CAAC;IACjE;GACF;GAEA,gBAAgB,MAAM,OAAO,IAAI;GAEjC,IAAI,CAAC,GAAG,WAAW,gBAAgB,GACjC,QAAQ,IAAI,QAAQ,KAAK,KAAK,0BAA0B,CAAC;QAEzD,QAAQ,IAAI,QAAQ,KAAK,MAAM,CAAC;EAEpC,SAAS,KAAK;GACZ,QAAQ,IAAI,MAAM,KAAK,KAAK,IAAK,IAAc,SAAS,CAAC;GACzD;EACF;CACF;CAEA,IAAI,KAAK,OAAO,aAAa,GAC3B,QAAQ,IAAI,KAAK,aAAa,WAAW,cAAc,CAAC;CAG1D,IAAI,aAAa,GAAG;EAClB,QAAQ,MAAM,MAAM,KAAK,WAAW,iBAAiB,CAAC;EACtD,QAAQ,KAAK,CAAC;CAChB,OACE,QAAQ,IAAI,QAAQ,0BAA0B,CAAC;AAEnD;AAEA,MAAa,kBAAkB,IAAI,QAAQ,UAAU,EAClD,YAAY,4CAA4C,EACxD,OAAO,SAAS,6BAA6B,EAC7C,OAAO,OAAO,SAA4B;CACzC,MAAM,YAAY,MAAM,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,CAAC;AACxE,CAAC;;;ACxGH,MAAa,eAAe,IAAI,QAAQ,OAAO,EAC5C,YAAY,oCAAoC,EAChD,aAAa;CACZ,QAAQ,IAAI,iBAAiB;AAC/B,CAAC;AAEH,MAAa,aAAa,IAAI,QAAQ,KAAK,EAAE,YAAY,yCAAyC;AAElG,WAAW,QAAQ,MAAM,EAAE,aAAa;CACtC,QAAQ,IAAI,iBAAiB;AAC/B,CAAC;AAED,WACG,QAAQ,OAAO,EACf,YAAY,4DAA4D,EACxE,eAAe,mBAAmB,uCAAuC,EACzE,OAAO,iBAAiB,oCAAoC,KAAK,EACjE,OAAO,mBAAmB,mCAAmC,EAC7D,OAAO,OAAO,SAA0D;CACvE,MAAM,OAAO;EAAC;EAAS;EAAW;CAAK,EAAE,SAAS,KAAK,IAAI,IACtD,KAAK,OACN;CACJ,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAC7D,MAAM,EAAE,mBAAmB,MAAM,OAAO;CACxC,MAAM,QAAQ,eAAe,SAAS,KAAK,OAAO,MAAM,KAAK,KAAK;CAClE,QAAQ,IAAI,KAAK,0DAA0D,CAAC;CAC5E,QAAQ,IAAI,KAAK;CACjB,QAAQ,IAAI,KAAK,SAAS,KAAK,MAAM,QAAQ,KAAK,sCAAsC,CAAC;AAC3F,CAAC;AAEH,WACG,QAAQ,OAAO,EACf,YAAY,qCAAqC,EACjD,OAAO,UAAU,qCAAqC,EACtD,OAAO,iBAAiB,4BAA4B,MAAM,EAC1D,OAAO,OAAO,SAA2C;CACxD,IAAI,KAAK,MAAM;EACb,MAAM,OAAO,SAAS,KAAK,MAAM,EAAE;EACnC,QAAQ,MAAM,KAAK,4CAA4C,KAAK,IAAI,CAAC;EACzE,MAAM,EAAE,cAAc,MAAM,OAAO;EACnC,MAAM,UAAU,IAAI;CACtB,OAAO;EACL,MAAM,EAAE,eAAe,MAAM,OAAO;EACpC,MAAM,WAAW;CACnB;AACF,CAAC;ACoCH,MAAa,aAAa;;AAG1B,SAAgB,cAAc,SAAyB;CACrD,OAAO,8CAA8C,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAoCzD,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuGlB,UAAU,KAAK;AACjB;;AAGA,SAAgB,YAAY,WAA0C;CACpE,OAAO;oEAC2D,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2B7E,cAAc,aAAa,8CAA8C,iCAAiC,KAAK;AACjH;;AAGA,MAAa,oBAAoB;;AAGjC,SAAgB,cAAc,SAAyB;CACrD,OAAO,8CAA8C,WAAW;;;;;;;;;;;;;;;;;;;sBAmB5C,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+C/B,UAAU,KAAK;AACjB;;AAGA,SAAgB,qBAA6B;CAC3C,OAAO;;;oEAG2D,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4EA8CH,KAAK;AACjF;;AAGA,SAAgB,kBAA0B;CACxC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oFAyC2E,KAAK;AACzF;;AAGA,SAAgB,iBAAiB,SAAyB;CACxD,OAAO,yCAAyC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA4ClD,UAAU,KAAK;AAC1B;;AAGA,SAAgB,sBAAsB,QAI3B;CACT,MAAM,QAAQ,EACZ,YAAY,CACV;EACE,MAAM,OAAO;EACb,WAAW;GACT,MAAM;GACN,SAAS;GACT,MAAM,CAAC,OAAO,aAAa;GAC3B,KAAK,EAAE,gBAAgB,OAAO,QAAQ;EACxC;CACF,CACF,EACF;CACA,OAAO,KAAK,UAAU,OAAO,MAAM,CAAC;AACtC;;AAGA,SAAgB,oBAAoB,SAAyB;CAC3D,OAAO;wDAC+C,WAAW;;;;;;;kEAOD,WAAW;;;;;;;;;;;;;;;;;;;;SAoBpE,WAAW;;;;;;;;;;;;;;;;;;;;;;WAsBT,UAAU,KAAK;AAC1B;;;AC1iBA,MAAMA,SAAO,GAAG,QAAQ;AACxB,MAAM,cAAc,KAAK,KAAKA,QAAM,cAAc;AAClD,MAAM,aAAa,KAAK,KAAKA,QAAM,SAAS;AAE5C,IAAa,oBAAb,MAA2D;CACzD,OAAgB;CAEhB,SAAkB;EAChB,IAAI;GACF,SAAS,gBAAgB,EAAE,OAAO,SAAS,CAAC;GAC5C,OAAO;EACT,QAAQ,CAAC;EACT,OAAO,GAAG,WAAW,WAAW,KAAK,GAAG,WAAW,UAAU;CAC/D;CAEA,cAAuB;EACrB,IAAI,CAAC,GAAG,WAAW,WAAW,GAAG,OAAO;EACxC,IAAI;GAGF,OAAO,CAAC,CAFK,KAAK,MAAM,GAAG,aAAa,aAAa,OAAO,CACzC,EAAE,gBACF;EACrB,QAAQ;GACN,OAAO;EACT;CACF;CAEA,MAAM,QAAQ,QAA+C;EAC3D,MAAM,eAAyB,CAAC;EAGhC,KAAK,eAAe,MAAM;EAG1B,KAAK,oBAAoB;EAGzB,MAAM,eAAe,KAAK,KAAK,OAAO,SAAS,WAAW;EAC1D,GAAG,cAAc,cAAc,cAAc,OAAO,OAAO,CAAC;EAC5D,aAAa,KAAK,YAAY;EAG9B,MAAM,qBAAqB,KAAK,KAAK,OAAO,SAAS,SAAS;EAC9D,GAAG,UAAU,oBAAoB,EAAE,WAAW,KAAK,CAAC;EACpD,MAAM,QAAQ;GACZ;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,MAAM,kBAAkB,EAAE,aAAa,EAAE,MAAM,EAAE;EACjD,MAAM,eAAe,KAAK,KAAK,oBAAoB,eAAe;EAClE,GAAG,cAAc,cAAc,KAAK,UAAU,iBAAiB,MAAM,CAAC,CAAC;EACvE,aAAa,KAAK,YAAY;EAE9B,OAAO;GACL,WAAW,KAAK;GAChB,SAAS;GACT,WAAW;GACX,YAAY;GACZ;GACA,OAAO,GAAG,MAAM,OAAO,MAAM,WAAW;EAC1C;CACF;CAEA,MAAM,YAA2B;EAC/B,IAAI,CAAC,GAAG,WAAW,WAAW,GAAG;EACjC,IAAI;GACF,MAAM,OAAO,KAAK,MAAM,GAAG,aAAa,aAAa,OAAO,CAAC;GAC7D,MAAM,UAAU,KAAK;GACrB,IAAI,SACF,OAAO,QAAQ;GAEjB,GAAG,cAAc,aAAa,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;EAC7D,QAAQ,CAAC;CACX;CAEA,eAAuB,QAA6B;EAClD,IAAI,OAAgC,CAAC;EACrC,IAAI,GAAG,WAAW,WAAW,GAC3B,IAAI;GACF,OAAO,KAAK,MAAM,GAAG,aAAa,aAAa,OAAO,CAAC;EACzD,QAAQ,CAAC;EAEX,IAAI,CAAC,KAAK,eAAe,KAAK,gBAAgB,CAAC;EAC/C,KAAM,cAA0C,OAAO,cAAc;GACnE,MAAM;GACN,SAAS,QAAQ;GACjB,MAAM,CAAC,OAAO,aAAa;GAC3B,KAAK,EAAE,gBAAgB,OAAO,QAAQ;EACxC;EAEA,GAAG,UAAU,KAAK,QAAQ,WAAW,GAAG,EAAE,WAAW,KAAK,CAAC;EAC3D,GAAG,cAAc,aAAa,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;CAC7D;CAEA,sBAAoC;EAClC,GAAG,UAAU,YAAY,EAAE,WAAW,KAAK,CAAC;EAC5C,MAAM,eAAe,KAAK,KAAK,YAAY,eAAe;EAC1D,IAAI,WAAoC,CAAC;EACzC,IAAI,GAAG,WAAW,YAAY,GAC5B,IAAI;GACF,WAAW,KAAK,MAAM,GAAG,aAAa,cAAc,OAAO,CAAC;EAC9D,QAAQ,CAAC;EAEX,IAAI,CAAC,SAAS,gBAAgB,SAAS,iBAAiB,CAAC;EACzD,MAAM,QAAQ,SAAS;EACvB,IAAI,CAAC,MAAM,UAAU,MAAM,WAAW,CAAC;EACvC,MAAM,QAAQ,MAAM;EACpB,MAAM,WAAW;EACjB,IAAI,CAAC,MAAM,SAAS,QAAQ,GAC1B,MAAM,KAAK,QAAQ;EAErB,GAAG,cAAc,cAAc,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;CAClE;AACF;;;ACpHA,SAAS,uBAA+B;CACtC,QAAQ,QAAQ,UAAhB;EACE,KAAK,UACH,OAAO,KAAK,KACV,GAAG,QAAQ,GACX,WACA,uBACA,UACA,4BACF;EACF,KAAK,SACH,OAAO,KAAK,KACV,QAAQ,IAAI,cAAc,GAAG,QAAQ,GACrC,UACA,4BACF;EACF,SACE,OAAO,KAAK,KAAK,GAAG,QAAQ,GAAG,WAAW,kBAAkB,4BAA4B;CAC5F;AACF;AAEA,MAAM,iBAAiB,qBAAqB;AAE5C,IAAa,uBAAb,MAA8D;CAC5D,OAAgB;CAEhB,SAAkB;EAChB,OAAO,GAAG,WAAW,cAAc,KAAK,GAAG,WAAW,KAAK,QAAQ,cAAc,CAAC;CACpF;CAEA,cAAuB;EACrB,IAAI,CAAC,GAAG,WAAW,cAAc,GAAG,OAAO;EAC3C,IAAI;GAGF,OAAO,CAAC,CAFK,KAAK,MAAM,GAAG,aAAa,gBAAgB,OAAO,CAC5C,EAAE,gBACF;EACrB,QAAQ;GACN,OAAO;EACT;CACF;CAEA,MAAM,QAAQ,QAA+C;EAE3D,GAAG,UAAU,KAAK,QAAQ,cAAc,GAAG,EAAE,WAAW,KAAK,CAAC;EAE9D,IAAI,OAAgC,CAAC;EACrC,IAAI,GAAG,WAAW,cAAc,GAC9B,IAAI;GACF,OAAO,KAAK,MAAM,GAAG,aAAa,gBAAgB,OAAO,CAAC;EAC5D,QAAQ,CAAC;EAEX,IAAI,CAAC,KAAK,eAAe,KAAK,gBAAgB,CAAC;EAC/C,KAAM,cAA0C,OAAO,cAAc;GACnE,SAAS,QAAQ;GACjB,MAAM,CAAC,OAAO,aAAa;GAC3B,KAAK,EAAE,gBAAgB,OAAO,QAAQ;EACxC;EACA,GAAG,cAAc,gBAAgB,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;EAE9D,OAAO;GACL,WAAW,KAAK;GAChB,SAAS;GACT,WAAW;GACX,YAAY;GACZ,cAAc,CAAC;GACf,OAAO;EACT;CACF;CAEA,MAAM,YAA2B;EAC/B,IAAI,CAAC,GAAG,WAAW,cAAc,GAAG;EACpC,IAAI;GACF,MAAM,OAAO,KAAK,MAAM,GAAG,aAAa,gBAAgB,OAAO,CAAC;GAChE,MAAM,UAAU,KAAK;GACrB,IAAI,SACF,OAAO,QAAQ;GAEjB,GAAG,cAAc,gBAAgB,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;EAChE,QAAQ,CAAC;CACX;AACF;;;AClFA,MAAM,YAAY,KAAK,KAAK,GAAG,QAAQ,GAAG,QAAQ;AAClD,MAAM,eAAe,KAAK,KAAK,WAAW,aAAa;AAEvD,IAAa,eAAb,MAAsD;CACpD,OAAgB;CAEhB,SAAkB;EAChB,IAAI;GACF,SAAS,eAAe,EAAE,OAAO,SAAS,CAAC;GAC3C,OAAO;EACT,QAAQ,CAAC;EACT,OAAO,GAAG,WAAW,SAAS;CAChC;CAEA,cAAuB;EACrB,IAAI,CAAC,GAAG,WAAW,YAAY,GAAG,OAAO;EACzC,OAAO,GAAG,aAAa,cAAc,OAAO,EAAE,SAAS,gCAAgC;CACzF;CAEA,MAAM,QAAQ,QAA+C;EAC3D,GAAG,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;EAC3C,MAAM,eAAyB,CAAC;EAGhC,IAAI,CAAC,KAAK,YAAY,GAAG;GACvB,MAAM,QAAQ;IACZ;IACA,gBAAgB,OAAO,WAAW;IAClC,aAAa,KAAK,UAAU,QAAQ,QAAQ;IAC5C,WAAW,KAAK,UAAU,OAAO,aAAa,EAAE;IAChD,4BAA4B,KAAK,UAAU,OAAO,OAAO,EAAE;IAC3D;IACA;IACA;IACA;GACF,EAAE,KAAK,IAAI;GAEX,GAAG,eAAe,cAAc,OAAO,OAAO;EAChD;EAGA,MAAM,aAAa,KAAK,KAAK,OAAO,SAAS,WAAW;EACxD,IAAI,CAAC,GAAG,WAAW,UAAU,GAAG;GAC9B,GAAG,cAAc,YAAY,cAAc,OAAO,OAAO,CAAC;GAC1D,aAAa,KAAK,UAAU;EAC9B,OAEE,IAAI,CADa,GAAG,aAAa,YAAY,OACjC,EAAE,SAAS,iBAAiB,GAAG;GACzC,GAAG,eAAe,YAAY,gBAAgB,cAAc,OAAO,OAAO,CAAC;GAC3E,aAAa,KAAK,aAAa,aAAa;EAC9C;EAGF,OAAO;GACL,WAAW,KAAK;GAChB,SAAS;GACT,WAAW;GACX,YAAY;GACZ;GACA,OAAO;EACT;CACF;CAEA,MAAM,YAA2B;EAC/B,IAAI,CAAC,GAAG,WAAW,YAAY,GAAG;EAGlC,MAAM,UAFU,GAAG,aAAa,cAAc,OAExB,EAAE,QAAQ,8CAA8C,EAAE;EAChF,GAAG,cAAc,cAAc,OAAO;CACxC;AACF;;;ACtEA,MAAMC,SAAO,GAAG,QAAQ;AACxB,MAAM,eAAe,KAAK,KAAKA,QAAM,WAAW;AAChD,MAAM,gBAAgB,KAAK,KAAK,cAAc,eAAe;AAC7D,MAAM,qBAAqB,KAAK,KAAK,cAAc,WAAW;AAE9D,IAAa,kBAAb,MAAyD;CACvD,OAAgB;CAEhB,SAAkB;EAChB,IAAI;GACF,SAAS,kBAAkB,EAAE,OAAO,SAAS,CAAC;GAC9C,OAAO;EACT,QAAQ,CAAC;EACT,OAAO,GAAG,WAAW,YAAY,KAAK,GAAG,WAAW,aAAa;CACnE;CAEA,cAAuB;EACrB,IAAI,CAAC,GAAG,WAAW,aAAa,GAAG,OAAO;EAC1C,IAAI;GAGF,OAAO,CAAC,CAFK,KAAK,MAAM,GAAG,aAAa,eAAe,OAAO,CAC3C,EAAE,gBACF;EACrB,QAAQ;GACN,OAAO;EACT;CACF;CAEA,MAAM,QAAQ,QAA+C;EAC3D,GAAG,UAAU,cAAc,EAAE,WAAW,KAAK,CAAC;EAC9C,GAAG,UAAU,oBAAoB,EAAE,WAAW,KAAK,CAAC;EAEpD,MAAM,eAAyB,CAAC;EAGhC,IAAI,OAAgC,CAAC;EACrC,IAAI,GAAG,WAAW,aAAa,GAC7B,IAAI;GACF,OAAO,KAAK,MAAM,GAAG,aAAa,eAAe,OAAO,CAAC;EAC3D,QAAQ,CAAC;EAEX,IAAI,CAAC,KAAK,eAAe,KAAK,gBAAgB,CAAC;EAC/C,MAAM,UAAU,KAAK;EAErB,QAAQ,OAAO,cAAc;GAC3B,SAAS,QAAQ;GACjB,MAAM,CAAC,OAAO,aAAa;GAC3B,WAAW;GACX,KAAK,EAAE,gBAAgB,OAAO,QAAQ;EACxC;EAGA,QAAQ,GAAG,OAAO,WAAW,UAAU;GACrC,KAAK,oBAAoB,OAAO,SAAS;GACzC,WAAW;GACX,SAAS;EACX;EAEA,GAAG,cAAc,eAAe,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;EAI7D,MAAM,WAAW,KAAK,KAAK,oBAAoB,SAAS;EACxD,IAAI,CAAC,GAAG,WAAW,QAAQ,GAAG;GAC5B,GAAG,cAAc,UAAU,YAAY,UAAU,CAAC;GAClD,aAAa,KAAK,QAAQ;EAC5B,OAEE,IAAI,CADa,GAAG,aAAa,UAAU,OAC/B,EAAE,SAAS,iBAAiB,GAAG;GACzC,GAAG,eAAe,UAAU,gBAAgB,mBAAmB,CAAC;GAChE,aAAa,KAAK,WAAW,aAAa;EAC5C;EAIF,MAAM,aAAa,KAAK,KAAK,oBAAoB,WAAW;EAC5D,IAAI,CAAC,GAAG,WAAW,UAAU,GAAG;GAC9B,GAAG,cAAc,YAAY,cAAc,OAAO,OAAO,CAAC;GAC1D,aAAa,KAAK,UAAU;EAC9B,OAEE,IAAI,CADa,GAAG,aAAa,YAAY,OACjC,EAAE,SAAS,iBAAiB,GAAG;GACzC,GAAG,eAAe,YAAY,gBAAgB,cAAc,OAAO,OAAO,CAAC;GAC3E,aAAa,KAAK,aAAa,aAAa;EAC9C;EAIF,MAAM,YAAY,KAAK,KAAK,oBAAoB,UAAU;EAC1D,MAAM,eAAe,qBAAqB;EAC1C,IAAI,CAAC,GAAG,WAAW,SAAS,GAC1B,GAAG,cAAc,WAAW,YAAY;OACnC,IAAI,CAAC,GAAG,aAAa,WAAW,OAAO,EAAE,SAAS,kBAAkB,GACzE,GAAG,eAAe,WAAW,SAAS,YAAY;EAEpD,aAAa,KAAK,SAAS;EAE3B,OAAO;GACL,WAAW,KAAK;GAChB,SAAS;GACT,WAAW;GACX,YAAY;GACZ;GACA,OAAO;EACT;CACF;CAEA,MAAM,YAA2B;EAC/B,IAAI,CAAC,GAAG,WAAW,aAAa,GAAG;EACnC,IAAI;GACF,MAAM,OAAO,KAAK,MAAM,GAAG,aAAa,eAAe,OAAO,CAAC;GAC/D,MAAM,UAAU,KAAK;GACrB,IAAI,SAAS;IACX,OAAO,QAAQ;IACf,OAAO,QAAQ;GACjB;GACA,GAAG,cAAc,eAAe,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;EAC/D,QAAQ,CAAC;CACX;AACF;AAEA,SAAS,qBAA6B;CACpC,OAAO;;;AAGT;AAEA,SAAS,uBAA+B;CACtC,OAAO;;;;;;;AAOT;;;ACtIA,MAAMC,SAAO,GAAG,QAAQ;AACxB,MAAM,cAAc,QAAQ,IAAI,kBAAkB,KAAK,KAAKA,QAAM,SAAS;AAC3E,MAAM,gBAAgB,KAAK,KAAK,aAAa,aAAa;AAC1D,MAAM,cAAc,KAAK,KAAK,aAAa,SAAS;AACpD,MAAM,gBAAgB,KAAK,KAAK,aAAa,QAAQ;AAErD,IAAa,gBAAb,MAAuD;CACrD,OAAgB;CAEhB,SAAkB;EAChB,IAAI;GACF,SAAS,gBAAgB,EAAE,OAAO,SAAS,CAAC;GAC5C,OAAO;EACT,QAAQ,CAAC;EACT,OAAO,GAAG,WAAW,WAAW,KAAK,GAAG,WAAW,aAAa;CAClE;CAEA,cAAuB;EACrB,IAAI,CAAC,GAAG,WAAW,aAAa,GAAG,OAAO;EAC1C,OAAO,GAAG,aAAa,eAAe,OAAO,EAAE,SAAS,UAAU;CACpE;CAEA,MAAM,QAAQ,QAA+C;EAC3D,GAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;EAC7C,GAAG,UAAU,eAAe,EAAE,WAAW,KAAK,CAAC;EAE/C,MAAM,eAAyB,CAAC;EAIhC,KAAK,eAAe,MAAM;EAG1B,IAAI,CAAC,GAAG,WAAW,WAAW,GAAG;GAC/B,GAAG,cAAc,aAAa,kBAAkB,QAAQ,CAAC;GACzD,aAAa,KAAK,WAAW;EAC/B,OAEE,IAAI,CADa,GAAG,aAAa,aAAa,OAClC,EAAE,SAAS,iBAAiB,GAAG;GACzC,GAAG,eACD,aACA,uMACF;GACA,aAAa,KAAK,cAAc,aAAa;EAC/C;EAKF,MAAM,YAAY,KAAK,KAAK,eAAe,iBAAiB;EAC5D,GAAG,cAAc,WAAW,mBAAmB,CAAC;EAChD,aAAa,KAAK,SAAS;EAE3B,OAAO;GACL,WAAW,KAAK;GAChB,SAAS;GACT,WAAW;GACX,YAAY;GACZ;GACA,OACE;EACJ;CACF;CAEA,MAAM,YAA2B;EAC/B,IAAI,CAAC,GAAG,WAAW,aAAa,GAAG;EAGnC,MAAM,UAFU,GAAG,aAAa,eAAe,OAEzB,EAAE,QAAQ,wDAAwD,EAAE;EAC1F,GAAG,cAAc,eAAe,OAAO;EAEvC,MAAM,YAAY,KAAK,KAAK,eAAe,iBAAiB;EAC5D,IAAI,GAAG,WAAW,SAAS,GAAG,GAAG,WAAW,SAAS;CACvD;CAEA,eAAuB,QAA6B;EAGlD,IAAI,UAAU,GAAG,WAAW,aAAa,IAAI,GAAG,aAAa,eAAe,OAAO,IAAI;EAEvF,IAAI,QAAQ,SAAS,UAAU,GAAG;EAElC,IAAI,QAAQ,SAAS,cAAc,GAAG;GAEpC,UAAU,QAAQ,QAChB,gBACA;IACE;IACA;IACA,gBAAgB,KAAK,UAAU,QAAQ,QAAQ;IAC/C,cAAc,KAAK,UAAU,OAAO,aAAa,EAAE;IACnD;IACA,yBAAyB,KAAK,UAAU,OAAO,OAAO;IACtD;IACA;IACA;IACA;IACA;IACA;IACA;GACF,EAAE,KAAK,IAAI,CACb;GACA,GAAG,cAAc,eAAe,OAAO;EACzC,OAAO;GAEL,MAAM,WAAW;IACf;IACA;IACA;IACA;IACA,gBAAgB,KAAK,UAAU,QAAQ,QAAQ;IAC/C,cAAc,KAAK,UAAU,OAAO,aAAa,EAAE;IACnD;IACA,yBAAyB,KAAK,UAAU,OAAO,OAAO;IACtD;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF,EAAE,KAAK,IAAI;GAEX,GAAG,eAAe,eAAe,QAAQ;EAC3C;CACF;AACF;;;ACvIA,MAAMC,SAAO,GAAG,QAAQ;AACxB,MAAM,eAAe,KAAK,KAAKA,QAAM,UAAU,OAAO,KAAK;AAG3D,MAAM,oBAAoB,KAAK,KAAKA,QAAM,WAAW,QAAQ;AAC7D,MAAM,oBAAoB,KAAK,KAAK,mBAAmB,iBAAiB;AAGxE,MAAM,UAAU,KAAK,KAAKA,QAAM,WAAW,aAAa;AACxD,MAAM,iBAAiB,KAAK,KAAK,SAAS,iBAAiB;AAG3D,MAAM,mBAAmB,KAAK,KAAKA,QAAM,WAAW,WAAW;AAG/D,MAAM,iBAAiB,KAAK,KAAKA,QAAM,WAAW,mBAAmB,QAAQ;AAE7E,IAAa,qBAAb,MAA4D;CAC1D,OAAgB;CAEhB,SAAkB;EAEhB,IAAI;GACF,SAAS,aAAa,EAAE,OAAO,SAAS,CAAC;GACzC,OAAO;EACT,QAAQ,CAAC;EAET,IAAI,GAAG,WAAW,YAAY,GAAG,OAAO;EAExC,OAAO,GAAG,WAAW,KAAK,KAAKA,QAAM,SAAS,CAAC;CACjD;CAEA,cAAuB;EACrB,KAAK,MAAM,cAAc,CAAC,mBAAmB,cAAc,GAAG;GAC5D,IAAI,CAAC,GAAG,WAAW,UAAU,GAAG;GAChC,IAAI;IAIF,IAHa,KAAK,MAAM,GAAG,aAAa,YAAY,OAAO,CAGpD,GAAG,aAAa,qBAAqB,OAAO;GACrD,QAAQ,CAAC;EACX;EACA,OAAO;CACT;CAEA,MAAM,QAAQ,QAA+C;EAC3D,MAAM,eAAyB,CAAC;EAGhC,GAAG,UAAU,mBAAmB,EAAE,WAAW,KAAK,CAAC;EACnD,KAAK,cAAc,mBAAmB,MAAM;EAI5C,IAAI,CAAC,GAAG,WAAW,gBAAgB,GAAG;GACpC,GAAG,UAAU,KAAK,QAAQ,gBAAgB,GAAG,EAAE,WAAW,KAAK,CAAC;GAChE,GAAG,cAAc,kBAAkB,iBAAiB,OAAO,OAAO,CAAC;GACnE,aAAa,KAAK,gBAAgB;EACpC,OAEE,IAAI,CADa,GAAG,aAAa,kBAAkB,OACvC,EAAE,SAAS,iBAAiB,GAAG;GACzC,GAAG,eAAe,kBAAkB,gBAAgB,uBAAuB,CAAC;GAC5E,aAAa,KAAK,mBAAmB,aAAa;EACpD;EAIF,MAAM,aAAa,KAAK,KAAK,OAAO,SAAS,WAAW;EACxD,GAAG,UAAU,OAAO,SAAS,EAAE,WAAW,KAAK,CAAC;EAChD,IAAI,CAAC,GAAG,WAAW,UAAU,GAAG;GAC9B,GAAG,cAAc,YAAY,cAAc,OAAO,OAAO,CAAC;GAC1D,aAAa,KAAK,UAAU;EAC9B,OAEE,IAAI,CADa,GAAG,aAAa,YAAY,OACjC,EAAE,SAAS,iBAAiB,GAAG;GACzC,GAAG,eAAe,YAAY,gBAAgB,cAAc,OAAO,OAAO,CAAC;GAC3E,aAAa,KAAK,aAAa,aAAa;EAC9C;EAKF,MAAM,WAAW,KAAK,KAAK,gBAAgB,cAAc;EACzD,GAAG,UAAU,UAAU,EAAE,WAAW,KAAK,CAAC;EAC1C,MAAM,YAAY,KAAK,KAAK,UAAU,UAAU;EAChD,GAAG,cAAc,WAAW,gBAAgB,CAAC;EAC7C,aAAa,KAAK,SAAS;EAE3B,OAAO;GACL,WAAW,KAAK;GAChB,SAAS;GACT,WAAW;GACX,YAAY;GACZ;GACA,OACE;EACJ;CACF;CAEA,MAAM,YAA2B;EAC/B,KAAK,MAAM,cAAc,CAAC,mBAAmB,cAAc,GAAG;GAC5D,IAAI,CAAC,GAAG,WAAW,UAAU,GAAG;GAChC,IAAI;IACF,MAAM,OAAO,KAAK,MAAM,GAAG,aAAa,YAAY,OAAO,CAAC;IAG5D,IAAI,KAAK,YAAY;KACnB,OAAO,KAAK,WAAW;KACvB,OAAO,KAAK,WAAW;IACzB;IACA,GAAG,cAAc,YAAY,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;GAC5D,QAAQ,CAAC;EACX;EAEA,MAAM,WAAW,KAAK,KAAK,gBAAgB,cAAc;EACzD,IAAI,GAAG,WAAW,QAAQ,GAAG,GAAG,OAAO,UAAU,EAAE,WAAW,KAAK,CAAC;CACtE;CAEA,cAAsB,YAAoB,QAA6B;EACrE,IAAI,OAAiD,EAAE,YAAY,CAAC,EAAE;EACtE,IAAI,GAAG,WAAW,UAAU,GAC1B,IAAI;GACF,OAAO,KAAK,MAAM,GAAG,aAAa,YAAY,OAAO,CAAC;GAGtD,IAAI,CAAC,KAAK,YAAY,KAAK,aAAa,CAAC;EAC3C,QAAQ,CAAC;EAIX,KAAK,WAAY,sBAAsB;GACrC,SAAS,QAAQ;GACjB,MAAM,CAAC,OAAO,aAAa;GAC3B,KAAK,EAAE,gBAAgB,OAAO,QAAQ;EACxC;EAGA,KAAK,WAAY,2BAA2B,EAC1C,WAAW,oBAAoB,OAAO,SAAS,MACjD;EAEA,GAAG,cAAc,YAAY,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;CAC5D;AACF;AAEA,SAAS,yBAAiC;CACxC,OAAO;;;AAGT;;;ACtJA,MAAMC,SAAO,GAAG,QAAQ;AACxB,MAAM,aAAa,KAAK,KAAKA,QAAM,SAAS;AAC5C,MAAM,oBAAoB,KAAK,KAAK,YAAY,UAAU;AAE1D,IAAa,gBAAb,MAAuD;CACrD,OAAgB;CAEhB,SAAkB;EAChB,OAAO,GAAG,WAAW,UAAU,KAAK,GAAG,WAAW,iBAAiB;CACrE;CAEA,cAAuB;EACrB,IAAI,CAAC,GAAG,WAAW,iBAAiB,GAAG,OAAO;EAC9C,IAAI;GAIF,OAAO,CAAC,CAHK,KAAK,MAAM,GAAG,aAAa,mBAAmB,OAAO,CAGtD,GAAG,aAAa;EAC9B,QAAQ;GACN,OAAO;EACT;CACF;CAEA,MAAM,QAAQ,QAA+C;EAC3D,GAAG,UAAU,YAAY,EAAE,WAAW,KAAK,CAAC;EAC5C,MAAM,eAAyB,CAAC;EAGhC,IAAI,OAAiD,EAAE,YAAY,CAAC,EAAE;EACtE,IAAI,GAAG,WAAW,iBAAiB,GACjC,IAAI;GACF,OAAO,KAAK,MAAM,GAAG,aAAa,mBAAmB,OAAO,CAAC;GAG7D,IAAI,CAAC,KAAK,YAAY,KAAK,aAAa,CAAC;EAC3C,QAAQ,CAAC;EAEX,KAAK,WAAY,sBAAsB;GACrC,SAAS,QAAQ;GACjB,MAAM,CAAC,OAAO,aAAa;GAC3B,KAAK,EAAE,gBAAgB,OAAO,QAAQ;EACxC;EACA,GAAG,cAAc,mBAAmB,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;EAKjE,MAAM,WAAW,KAAK,KAAK,OAAO,SAAS,WAAW,OAAO;EAC7D,GAAG,UAAU,UAAU,EAAE,WAAW,KAAK,CAAC;EAC1C,MAAM,YAAY,KAAK,KAAK,UAAU,kBAAkB;EACxD,IAAI,CAAC,GAAG,WAAW,SAAS,GAAG;GAC7B,GAAG,cAAc,WAAW,oBAAoB,OAAO,OAAO,CAAC;GAC/D,aAAa,KAAK,SAAS;EAC7B;EAEA,OAAO;GACL,WAAW,KAAK;GAChB,SAAS;GACT,WAAW;GACX,YAAY;GACZ;GACA,OACE;EACJ;CACF;CAEA,MAAM,YAA2B;EAC/B,IAAI,CAAC,GAAG,WAAW,iBAAiB,GAAG;EACvC,IAAI;GACF,MAAM,OAAO,KAAK,MAAM,GAAG,aAAa,mBAAmB,OAAO,CAAC;GAGnE,IAAI,KAAK,YACP,OAAO,KAAK,WAAW;GAEzB,GAAG,cAAc,mBAAmB,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;EACnE,QAAQ,CAAC;CACX;AACF;;;AC/EA,MAAMC,SAAO,GAAG,QAAQ;AACxB,MAAM,eAAe,KAAK,KAAKA,QAAM,YAAY,UAAU;AAC3D,MAAM,kBAAkB,KAAK,KAAK,cAAc,iBAAiB;AAEjE,IAAa,kBAAb,MAAyD;CACvD,OAAgB;CAEhB,SAAkB;EAChB,OAAO,GAAG,WAAW,YAAY,KAAK,GAAG,WAAW,eAAe;CACrE;CAEA,cAAuB;EACrB,IAAI,CAAC,GAAG,WAAW,eAAe,GAAG,OAAO;EAC5C,IAAI;GAIF,OAAO,CAAC,CAHK,KAAK,MAAM,GAAG,aAAa,iBAAiB,OAAO,CAGpD,GAAG,aAAa;EAC9B,QAAQ;GACN,OAAO;EACT;CACF;CAEA,MAAM,QAAQ,QAA+C;EAE3D,GAAG,UAAU,cAAc,EAAE,WAAW,KAAK,CAAC;EAE9C,IAAI,OAAiD,EAAE,YAAY,CAAC,EAAE;EACtE,IAAI,GAAG,WAAW,eAAe,GAC/B,IAAI;GACF,OAAO,KAAK,MAAM,GAAG,aAAa,iBAAiB,OAAO,CAAC;GAG3D,IAAI,CAAC,KAAK,YAAY,KAAK,aAAa,CAAC;EAC3C,QAAQ,CAAC;EAIX,KAAK,WAAY,sBAAsB;GACrC,SAAS,QAAQ;GACjB,MAAM,CAAC,OAAO,aAAa;GAC3B,KAAK,EAAE,gBAAgB,OAAO,QAAQ;EACxC;EAEA,GAAG,cAAc,iBAAiB,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;EAE/D,OAAO;GACL,WAAW,KAAK;GAChB,SAAS;GACT,WAAW;GACX,YAAY;GACZ,cAAc,CAAC;GACf,OAAO;EACT;CACF;CAEA,MAAM,YAA2B;EAC/B,IAAI,CAAC,GAAG,WAAW,eAAe,GAAG;EACrC,IAAI;GACF,MAAM,OAAO,KAAK,MAAM,GAAG,aAAa,iBAAiB,OAAO,CAAC;GAGjE,IAAI,KAAK,YACP,OAAO,KAAK,WAAW;GAEzB,GAAG,cAAc,iBAAiB,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;EACjE,QAAQ,CAAC;CACX;AACF;;;ACpEA,MAAMC,SAAO,GAAG,QAAQ;AACxB,MAAM,YAAY,KAAK,KAAKA,QAAM,QAAQ;AAC1C,MAAM,eAAe,KAAK,KAAK,WAAW,QAAQ,YAAY,yBAAyB;AAEvF,IAAa,eAAb,MAAsD;CACpD,OAAgB;CAEhB,SAAkB;EAChB,OAAO,GAAG,WAAW,SAAS,KAAK,GAAG,WAAW,YAAY;CAC/D;CAEA,cAAuB;EACrB,IAAI,CAAC,GAAG,WAAW,YAAY,GAAG,OAAO;EACzC,IAAI;GAIF,OAAO,CAAC,CAHK,KAAK,MAAM,GAAG,aAAa,cAAc,OAAO,CAGjD,GAAG,aAAa;EAC9B,QAAQ;GACN,OAAO;EACT;CACF;CAEA,MAAM,QAAQ,QAA+C;EAE3D,GAAG,UAAU,KAAK,QAAQ,YAAY,GAAG,EAAE,WAAW,KAAK,CAAC;EAE5D,IAAI,OAAiD,EAAE,YAAY,CAAC,EAAE;EACtE,IAAI,GAAG,WAAW,YAAY,GAC5B,IAAI;GACF,OAAO,KAAK,MAAM,GAAG,aAAa,cAAc,OAAO,CAAC;GAGxD,IAAI,CAAC,KAAK,YAAY,KAAK,aAAa,CAAC;EAC3C,QAAQ,CAAC;EAIX,KAAK,WAAY,sBAAsB;GACrC,SAAS,QAAQ;GACjB,MAAM,CAAC,OAAO,aAAa;GAC3B,KAAK,EAAE,gBAAgB,OAAO,QAAQ;EACxC;EAEA,GAAG,cAAc,cAAc,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;EAE5D,OAAO;GACL,WAAW,KAAK;GAChB,SAAS;GACT,WAAW;GACX,YAAY;GACZ,cAAc,CAAC;GACf,OAAO;EACT;CACF;CAEA,MAAM,YAA2B;EAC/B,IAAI,CAAC,GAAG,WAAW,YAAY,GAAG;EAClC,IAAI;GACF,MAAM,OAAO,KAAK,MAAM,GAAG,aAAa,cAAc,OAAO,CAAC;GAG9D,IAAI,KAAK,YACP,OAAO,KAAK,WAAW;GAEzB,GAAG,cAAc,cAAc,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;EAC9D,QAAQ,CAAC;CACX;AACF;;;AClEA,MAAM,OAAO,GAAG,QAAQ;AACxB,MAAM,WAAW,KAAK,KAAK,MAAM,OAAO;AACxC,MAAM,qBAAqB,KAAK,KAAK,UAAU,oBAAoB;AAmBnE,IAAa,cAAb,MAAqD;CACnD,OAAgB;CAEhB,SAAkB;EAChB,IAAI;GACF,SAAS,cAAc,EAAE,OAAO,SAAS,CAAC;GAC1C,OAAO;EACT,QAAQ,CAAC;EACT,OAAO,GAAG,WAAW,QAAQ;CAC/B;CAEA,cAAuB;EACrB,IAAI,CAAC,GAAG,WAAW,kBAAkB,GAAG,OAAO;EAC/C,IAAI;GAEF,QADiB,KAAK,MAAM,GAAG,aAAa,oBAAoB,OAAO,CACxD,EAAE,cAAc,CAAC,GAAG,MAAM,MAAM,EAAE,SAAS,kBAAkB;EAC9E,QAAQ;GACN,OAAO;EACT;CACF;CAEA,MAAM,QAAQ,QAA+C;EAC3D,GAAG,UAAU,UAAU,EAAE,WAAW,KAAK,CAAC;EAC1C,MAAM,eAAyB,CAAC;EAIhC,IAAI,CAAC,KAAK,YAAY,GAAG;GACvB,IAAI,WAAyB,CAAC;GAC9B,IAAI,GAAG,WAAW,kBAAkB,GAClC,IAAI;IACF,WAAW,KAAK,MAAM,GAAG,aAAa,oBAAoB,OAAO,CAAC;GACpE,QAAQ,CAAC;GAEX,IAAI,CAAC,SAAS,YAAY,SAAS,aAAa,CAAC;GACjD,SAAS,WAAW,KAAK;IACvB,MAAM,OAAO;IACb,WAAW;KACT,MAAM;KACN,SAAS,QAAQ;KACjB,MAAM,CAAC,OAAO,aAAa;KAC3B,KAAK,EAAE,gBAAgB,OAAO,QAAQ;IACxC;GACF,CAAC;GACD,GAAG,cAAc,oBAAoB,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;EACxE;EAIA,MAAM,iBAAiB,KAAK,KAAK,OAAO,SAAS,OAAO;EACxD,GAAG,UAAU,gBAAgB,EAAE,WAAW,KAAK,CAAC;EAChD,MAAM,kBAAkB,KAAK,KAAK,gBAAgB,eAAe;EACjE,GAAG,cAAc,iBAAiB,sBAAsB,MAAM,CAAC;EAC/D,aAAa,KAAK,eAAe;EAIjC,MAAM,aAAa,KAAK,KAAK,OAAO,SAAS,WAAW;EACxD,IAAI,CAAC,GAAG,WAAW,UAAU,GAAG;GAC9B,GAAG,cAAc,YAAY,cAAc,OAAO,OAAO,CAAC;GAC1D,aAAa,KAAK,UAAU;EAC9B,OAEE,IAAI,CADa,GAAG,aAAa,YAAY,OACjC,EAAE,SAAS,iBAAiB,GAAG;GACzC,GAAG,eAAe,YAAY,gBAAgB,cAAc,OAAO,OAAO,CAAC;GAC3E,aAAa,KAAK,aAAa,aAAa;EAC9C;EAGF,OAAO;GACL,WAAW,KAAK;GAChB,SAAS;GACT,WAAW;GACX,YAAY;GACZ;GACA,OACE;EAGJ;CACF;CAEA,MAAM,YAA2B;EAC/B,IAAI,CAAC,GAAG,WAAW,kBAAkB,GAAG;EACxC,IAAI;GACF,MAAM,WAAW,KAAK,MAAM,GAAG,aAAa,oBAAoB,OAAO,CAAC;GACxE,IAAI,SAAS,YACX,SAAS,aAAa,SAAS,WAAW,QAAQ,MAAM,EAAE,SAAS,kBAAkB;GAEvF,GAAG,cAAc,oBAAoB,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;EACxE,QAAQ,CAAC;CACX;AACF;;;AC5GA,MAAa,qBAAyC;CAEpD,IAAI,kBAAkB;CACtB,IAAI,aAAa;CACjB,IAAI,YAAY;CAChB,IAAI,gBAAgB;CACpB,IAAI,cAAc;CAClB,IAAI,mBAAmB;CAEvB,IAAI,cAAc;CAClB,IAAI,gBAAgB;CACpB,IAAI,aAAa;CACjB,IAAI,qBAAqB;AAC3B;AAEA,eAAsB,mBAAmB,QAAiD;CACxF,MAAM,UAA2B,CAAC;CAClC,KAAK,MAAM,WAAW,oBAAoB;EACxC,IAAI,CAAC,QAAQ,OAAO,GAAG;EACvB,IAAI;GACF,QAAQ,KAAK,MAAM,QAAQ,QAAQ,MAAM,CAAC;EAC5C,SAAS,KAAK;GACZ,QAAQ,KAAK;IACX,WAAW,QAAQ;IACnB,SAAS;IACT,WAAW;IACX,YAAY;IACZ,cAAc,CAAC;IACf,OAAQ,IAAc;GACxB,CAAC;EACH;CACF;CACA,OAAO;AACT;;;ACvCA,MAAa,cAAc,IAAI,QAAQ,MAAM,EAC1C,YAAY,4CAA4C,EACxD,OACC,gBACA,2GACF,EACC,OAAO,OAAO,SAA4B;CACzC,MAAM,UAAU,QAAQ,IAAI;CAG5B,MAAM,aAAa,KAAK,KAAK,SAAS,UAAU;CAChD,GAAG,UAAU,YAAY,EAAE,WAAW,KAAK,CAAC;CAG5C,MAAM,aAAa,KAAK,KAAK,YAAY,aAAa;CACtD,IAAI,CAAC,GAAG,WAAW,UAAU,GAC3B,GAAG,cACD,YACA,KAAK,UACH;EACE,SAAS;EACT;EACA,0BAAS,IAAI,KAAK,GAAE,YAAY;CAClC,GACA,MACA,CACF,CACF;CAIF,MAAM,OAAO,GAAG,QAAQ;CAOxB,MAAM,kBAAkB;EALtB,KAAK,KAAK,MAAM,aAAa,WAAW;EACxC,KAAK,KAAK,MAAM,aAAa,OAAO;EACpC,KAAK,KAAK,MAAM,aAAa,MAAM;EACnC,KAAK,KAAK,MAAM,aAAa,MAAM;CAEJ,EAAE,QAAQ,MAAM,GAAG,WAAW,CAAC,CAAC;CAGjE,MAAM,cAAc,KAAK,KAAK,YAAY,cAAc;CACxD,IAAI,CAAC,GAAG,WAAW,WAAW,GAAG;EAC/B,MAAM,UAAmC;GACvC,OAAO;IAAE,MAAM;IAAS,OAAO;IAAI,SAAS;GAAM;GAClD,SAAS;GACT,0BAAS,IAAI,KAAK,GAAE,YAAY;EAClC;EACA,IAAI,gBAAgB,SAAS,GAC3B,QAAQ,cAAc;GACpB,MAAM;GACN,OAAO;GACP,YAAY,CAAC,QAAQ,MAAM;GAC3B,SAAS;EACX;EAEF,GAAG,cAAc,aAAa,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;CAChE;CAGA,GAAG,UAAU,KAAK,KAAK,SAAS,WAAW,GAAG,EAAE,WAAW,KAAK,CAAC;CAGjE,MAAM,aAAa,KAAK,KAAK,YAAY,aAAa;CACtD,IAAI,CAAC,GAAG,WAAW,UAAU,GAC3B,GAAG,cACD,YACA,KAAK,UACH;EACE,SAAS;EACT,aAAa;EACb,YAAY;GACV,UAAU;IAAC;IAAQ;IAAsB;IAAW;IAAQ;GAAU;GACtE,YAAY;IACV,MAAM,EAAE,MAAM,SAAS;IACvB,oBAAoB;KAClB,MAAM;KACN,MAAM;MACJ;MACA;MACA;MACA;MACA;MACA;MACA;MACA;KACF;IACF;IACA,QAAQ,EAAE,MAAM,SAAS;IACzB,OAAO;KAAE,MAAM;KAAU,QAAQ;IAAQ;IACzC,SAAS;KAAE,MAAM;KAAU,QAAQ;IAAO;IAC1C,SAAS;KAAE,MAAM;KAAU,QAAQ;IAAO;IAC1C,MAAM;KAAE,MAAM;KAAS,OAAO,EAAE,MAAM,SAAS;IAAE;IACjD,UAAU;KAAE,MAAM;KAAU,MAAM;MAAC;MAAO;MAAO;MAAO;KAAK;IAAE;IAC/D,YAAY;KAAE,MAAM;KAAU,SAAS;IAAE;IACzC,iBAAiB;KAAE,MAAM;KAAU,QAAQ;IAAO;IAClD,iBAAiB,EAAE,MAAM,SAAS;GACpC;EACF;CACF,GACA,MACA,CACF,CACF;CAIF,QAAQ,IAAI,KAAK,4BAA4B,CAAC;CAG9C,MAAM,gBAAgB,KAAK,QACzB,KAAK,QAAQ,IAAI,IAAI,OAAO,KAAK,GAAG,EAAE,QAAQ,GAC9C,mBACF;CAEA,IAAI,KAAK,MACP,QAAQ,IAAI,KAAK,uCAAuC,KAAK,KAAK,IAAI,GAAG,CAAC;CAG5E,MAAM,UAAU,MAAM,mBAAmB;EACvC;EACA;EACA,UAAU;EACV,YAAY;EACZ,GAAI,KAAK,OAAO,EAAE,SAAS,KAAK,KAAK,IAAI,CAAC;CAC5C,CAAC;CAED,IAAI,QAAQ,WAAW,GACrB,QAAQ,IACN,KAAK,iFAAiF,CACxF;MAEA,KAAK,MAAM,KAAK,SACd,IAAI,EAAE,SAAS;EACb,QAAQ,IAAI,QAAQ,OAAO,EAAE,UAAU,KAAK,EAAE,UAAU,WAAW,CAAC;EACpE,IAAI,EAAE,OAAO,QAAQ,IAAI,OAAO,EAAE,OAAO;CAC3C,OACE,QAAQ,IAAI,MAAM,OAAO,EAAE,UAAU,KAAK,EAAE,SAAS,UAAU,CAAC;CAKtE,QAAQ,IAAI,QAAQ,sCAAsC,KAAK,OAAO,GAAG,CAAC;CAC1E,IAAI,KAAK,MAAM;EACb,QAAQ,IAAI,KAAK,kBAAkB,KAAK,MAAM,CAAC;EAC/C,QAAQ,IAAI,KAAK,gDAAgD,CAAC;CACpE,OACE,QAAQ,IAAI,KAAK,2CAA2C,CAAC;AAEjE,CAAC;;;ACvJH,MAAa,cAAc,IAAI,QAAQ,MAAM,EAC1C,SAAS,UAAU,uBAAuB,EAC1C,YAAY,2CAA2C,EACvD,OAAO,kBAAkB,qDAAqD,EAC9E,OAAO,WAAW,iBAAiB,EACnC,OAAO,iBAAiB,uBAAuB,EAC/C,OAAO,yBAAyB,gDAAgD,EAChF,OAAO,oBAAoB,wDAAwD,EACnF,OACC,OACE,MACA,SAOG;CACH,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAC7D,MAAM,cAAc,KAAK,KAAK,SAAS,aAAa,IAAI;CAExD,IAAI,CAAC,GAAG,WAAW,WAAW,GAAG;EAC/B,QAAQ,MACN,MAAM,eAAe,KAAK,0DAA0D,CACtF;EACA,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,cAAc,KAAK,KAAK,aAAa,cAAc;CACzD,IAAI,CAAC,GAAG,WAAW,WAAW,GAAG;EAC/B,QAAQ,MAAM,MAAM,gCAAgC,KAAK,GAAG,CAAC;EAC7D,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,UAAU,KAAK,MAAM,GAAG,aAAa,aAAa,OAAO,CAAC;CAIhE,MAAM,QAAQ,KAAK,QACf,IAAI,KAAK,KAAK,KAAK,oBACnB,IAAI,KAAK,KAAK,IAAI,IAAI,MAAU,KAAK,KAAK,GAAI;CAClD,MAAM,WAAW,KAAK;CACtB,MAAM,YACJ,CAAC,KAAK,eACN,aAAa,eACb,aAAa,iBACb,aAAa;CACf,MAAM,gBAAgB,aAAa;CACnC,MAAM,kBACJ,CAAC,KAAK,SACN,aAAa,WACb,aAAa,eACb,aAAa;CACf,MAAM,kBAAkB,aAAa;CAErC,IAAI,cAAc;CAGlB,IAAI,aAAa,QAAQ,OAAO,WAAW,QAAQ,MAAM,OAAO;EAC9D,MAAM,YAAY,KAAK,KAAK,SAAS,YAAY,kBAAkB;EACnE,MAAM,WAAW,KAAK,KAAK,SAAS,YAAY,wBAAwB;EAExE,IAAI,CAAC,GAAG,WAAW,SAAS,KAAK,CAAC,GAAG,WAAW,QAAQ,GACtD,QAAQ,IAAI,KAAK,oEAAoE,CAAC;OAEtF,IAAI;GACF,QAAQ,IAAI,KAAK,uBAAuB,KAAK,IAAI,EAAE,IAAI,CAAC;GACxD,MAAM,EAAE,iBAAiB,MAAM,OAAO;GACtC,MAAM,EAAE,WAAW,gBAAgB,MAAM,OAAO;GAEhD,MAAM,SAAS,MAAM,YAAY;IAC/B;IACA;IACA,MAAA,MAJiB,aAAa,UAAU,SAAS;IAKjD,OAAO,QAAQ,MAAM;IACrB;IACA,oBAAoB,KAAK,gBAAgB;GAC3C,CAAC;GACD,eAAe,OAAO;GACtB,QAAQ,IAAI,QAAQ,eAAe,OAAO,OAAO,WAAW,OAAO,QAAQ,SAAS,CAAC;EACvF,SAAS,KAAK;GACZ,QAAQ,MAAM,MAAM,0BAA2B,IAAc,SAAS,CAAC;EACzE;CAEJ,OAAO,IAAI,WACT,QAAQ,IAAI,KAAK,4DAA4D,CAAC;CAIhF,IAAI,eACF,IAAI;EACF,QAAQ,IAAI,KAAK,mCAAmC,KAAK,IAAI,EAAE,IAAI,CAAC;EACpE,MAAM,EAAE,sBAAsB,MAAM,OAAO;EAC3C,MAAM,QAAQ,MAAM,kBAAkB,OAAO;EAC7C,IAAI,CAAC,OACH,QAAQ,IAAI,KAAK,6DAA6D,CAAC;OAC1E;GACL,MAAM,EAAE,eAAe,aAAa,MAAM,OAAO;GACjD,MAAM,cAAc,MAAM,SAAS;IAAE;IAAM;IAAS,aAAa;IAAO;GAAM,CAAC;GAC/E,eAAe,YAAY;GAC3B,QAAQ,IACN,QACE,yBAAyB,YAAY,OAAO,WAAW,YAAY,QAAQ,SAC7E,CACF;GAEA,MAAM,EAAE,0BAA0B,MAAM,OAAO;GAC/C,MAAM,YAAY,MAAM,sBAAsB;IAC5C;IACA;IACA,aAAa;IACb;GACF,CAAC;GACD,eAAe,UAAU;GACzB,QAAQ,IACN,QACE,4BAA4B,UAAU,OAAO,WAAW,UAAU,QAAQ,SAC5E,CACF;EACF;CACF,SAAS,KAAK;EACZ,QAAQ,MAAM,MAAM,8BAA+B,IAAc,SAAS,CAAC;CAC7E;CAIF,IAAI,iBAAiB;EACnB,MAAM,qBAAqB,KAAK,KAAK,SAAS,YAAY,cAAc;EACxE,IAAI,GAAG,WAAW,kBAAkB,GAClC,IAAI;GACF,MAAM,iBAAiB,KAAK,MAAM,GAAG,aAAa,oBAAoB,OAAO,CAAC;GAI9E,IAAI,eAAe,aAAa,WAAW,eAAe,YAAY,OAAO,QAAQ;IACnF,MAAM,EAAE,0BAA0B,MAAM,OAAO;IAC/C,MAAM,OAAO,eAAe,YAAY,cAAc,CAAC,QAAQ,MAAM;IACrE,IAAI,mBAAmB;IAEvB,KAAK,MAAM,aAAa,eAAe,YAAY,OAAO;KACxD,IAAI,CAAC,GAAG,WAAW,SAAS,GAAG;KAC/B,MAAM,QAAQ,GACX,YAAY,SAAS,EACrB,QAAQ,MAAM,KAAK,MAAM,QAAQ,EAAE,SAAS,GAAG,CAAC,CAAC,EACjD,KAAK,MAAM,KAAK,KAAK,WAAW,CAAC,CAAC;KAErC,KAAK,MAAM,QAAQ,OACjB,IAAI;MACF,MAAM,sBAAsB,MAAM,MAAM,OAAO;MAC/C;KACF,QAAQ,CAER;IAEJ;IAEA,IAAI,mBAAmB,GAAG;KACxB,eAAe;KACf,QAAQ,IAAI,QAAQ,qBAAqB,iBAAiB,WAAW,CAAC;IACxE,OACE,QAAQ,IAAI,KAAK,6BAA6B,CAAC;GAEnD,OACE,QAAQ,IAAI,KAAK,+BAA+B,CAAC;EAErD,SAAS,KAAK;GACZ,QAAQ,MAAM,MAAM,+BAAgC,IAAc,SAAS,CAAC;EAC9E;CAEJ;CAGA,IAAI,iBAAiB;EACnB,MAAM,YAAY,KAAK,KAAK,SAAS,YAAY,mBAAmB;EACpE,IAAI,CAAC,GAAG,WAAW,SAAS,GAC1B,QAAQ,IAAI,KAAK,mEAAmE,CAAC;OAErF,IAAI;GACF,MAAM,YAAY,KAAK,MAAM,GAAG,aAAa,WAAW,OAAO,CAAC;GAIhE,MAAM,cAAc,UAAU,eAAe,UAAU;GACvD,IAAI,CAAC,aACH,QAAQ,IAAI,KAAK,qDAAqD,CAAC;QAClE;IACL,QAAQ,IAAI,KAAK,8BAA8B,KAAK,IAAI,EAAE,IAAI,CAAC;IAC/D,MAAM,EAAE,yBAAyB,MAAM,OAAO;IAC9C,MAAM,SAAS,MAAM,qBAAqB;KACxC;KACA;KACA;KACA,cAAc;IAChB,CAAC;IACD,eAAe,OAAO;IACtB,IAAI,OAAO,OAAO,SAAS,GACzB,KAAK,MAAM,OAAO,OAAO,QACvB,QAAQ,MAAM,MAAM,qBAAqB,KAAK,CAAC;IAGnD,QAAQ,IACN,QAAQ,sBAAsB,OAAO,OAAO,WAAW,OAAO,QAAQ,SAAS,CACjF;GACF;EACF,SAAS,KAAK;GACZ,QAAQ,MAAM,MAAM,iCAAkC,IAAc,SAAS,CAAC;EAChF;CAEJ;CAEA,IAAI,cAAc,GAChB,QAAQ,IACN,QACE,sBAAsB,KAAK,OAAO,WAAW,CAAC,EAAE,wBAAwB,KAAK,IAAI,GACnF,CACF;MAEA,QAAQ,IAAI,KAAK,8CAA8C,KAAK,IAAI,GAAG,CAAC;AAEhF,CACF;;;AC5NF,SAASC,eAAqB;CAC5B,OAAO,KAAK,KAAK,QAAQ,IAAI,GAAG,YAAY,YAAY;AAC1D;AAEA,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAAE,YAAY,mCAAmC;AAElG,cAAc,QAAQ,OAAO,EAAE,OAAO,YAAY;CAChD,MAAM,UAAUA,aAAW;CAE3B,IAAI,GAAG,WAAW,OAAO,GAAG;EAC1B,MAAM,MAAM,SAAS,GAAG,aAAa,SAAS,OAAO,GAAa,EAAE;EACpE,IAAI;GACF,QAAQ,KAAK,KAAK,CAAC;GACnB,QAAQ,IAAI,KAAK,+BAA+B,IAAI,EAAE,CAAC;GACvD;EACF,QAAQ,CAER;CACF;CAEA,MAAM,aAAa,KAAK,QACtB,KAAK,QAAQ,IAAI,IAAI,OAAO,KAAK,GAAG,EAAE,QAAQ,GAC9C,6BACF;CAEA,MAAM,QAAQ,MAAM,QAAQ,UAAU,CAAC,UAAU,GAAG;EAClD,UAAU;EACV,OAAO;CACT,CAAC;CACD,MAAM,MAAM;CAEZ,GAAG,UAAU,KAAK,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;CACvD,GAAG,cAAc,SAAS,OAAO,MAAM,GAAG,CAAC;CAC3C,QAAQ,IAAI,QAAQ,yBAAyB,MAAM,IAAI,EAAE,CAAC;AAC5D,CAAC;AAED,cAAc,QAAQ,MAAM,EAAE,aAAa;CACzC,MAAM,UAAUA,aAAW;CAE3B,IAAI,CAAC,GAAG,WAAW,OAAO,GAAG;EAC3B,QAAQ,IAAI,KAAK,qBAAqB,CAAC;EACvC;CACF;CAEA,MAAM,MAAM,SAAS,GAAG,aAAa,SAAS,OAAO,GAAa,EAAE;CACpE,IAAI;EACF,QAAQ,KAAK,KAAK,SAAS;EAC3B,GAAG,WAAW,OAAO;EACrB,QAAQ,IAAI,QAAQ,mBAAmB,CAAC;CAC1C,SAAS,KAAK;EACZ,QAAQ,MAAM,MAAM,KAAM,IAAc,SAAS,CAAC;CACpD;AACF,CAAC;AAED,cAAc,QAAQ,QAAQ,EAAE,aAAa;CAC3C,MAAM,UAAUA,aAAW;CAE3B,IAAI,CAAC,GAAG,WAAW,OAAO,GAAG;EAC3B,QAAQ,IAAI,KAAK,sBAAsB,CAAC;EACxC;CACF;CAEA,MAAM,MAAM,SAAS,GAAG,aAAa,SAAS,OAAO,GAAa,EAAE;CACpE,IAAI;EACF,QAAQ,KAAK,KAAK,CAAC;EACnB,QAAQ,IAAI,QAAQ,wBAAwB,IAAI,EAAE,CAAC;CACrD,QAAQ;EACN,QAAQ,IAAI,KAAK,mCAAmC,CAAC;EACrD,GAAG,WAAW,OAAO;CACvB;AACF,CAAC;;;AClED,SAAgB,UAAU,WAA2B;CACnD,MAAM,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,QAAQ;CACtD,MAAM,OAAO,KAAK,MAAM,OAAO,GAAK;CACpC,IAAI,OAAO,IAAI,OAAO,GAAG,KAAK;CAC9B,MAAM,QAAQ,KAAK,MAAM,OAAO,EAAE;CAClC,IAAI,QAAQ,IAAI,OAAO,GAAG,MAAM;CAChC,OAAO,GAAG,KAAK,MAAM,QAAQ,EAAE,EAAE;AACnC;AAEA,SAAS,YAAY,SAAqD;CACxE,MAAM,UAAU,KAAK,KAAK,SAAS,YAAY,YAAY;CAC3D,IAAI,CAAC,GAAG,WAAW,OAAO,GAAG,OAAO,EAAE,SAAS,MAAM;CACrD,IAAI;EACF,MAAM,MAAM,SAAS,GAAG,aAAa,SAAS,OAAO,EAAE,KAAK,GAAG,EAAE;EACjE,IAAI,MAAM,GAAG,GAAG,OAAO,EAAE,SAAS,MAAM;EACxC,QAAQ,KAAK,KAAK,CAAC;EACnB,OAAO;GAAE,SAAS;GAAM;EAAI;CAC9B,QAAQ;EACN,OAAO,EAAE,SAAS,MAAM;CAC1B;AACF;AAEA,eAAe,kBAAkB,WAKtB;CACT,IAAI;EACF,MAAM,MAAM,MAAM,MAAM,GAAG,UAAU,QAAQ,OAAO,EAAE,EAAE,YAAY,EAClE,QAAQ,YAAY,QAAQ,GAAI,EAClC,CAAC;EACD,IAAI,CAAC,IAAI,IAAI,OAAO;EASpB,QAAO,MARa,IAAI,KAAK,GAQjB,YAAY;CAC1B,QAAQ;EACN,OAAO;CACT;AACF;AAEA,eAAsB,UACpB,MACA,SACe;CACf,MAAM,MAAM,WAAW,QAAQ,IAAI;CAEnC,IAAI,KAAK,WAAW;EAClB,MAAM,YAAY,cAAc,GAAG;EACnC,MAAM,MAAM,IAAI,OAAO,EAAE;EACzB,QAAQ,IAAI,GAAG;EACf,QAAQ,IAAI,KAAK,wBAAwB,CAAC;EAC1C,QAAQ,IAAI,GAAG;EACf,IAAI,UAAU,WAAW,GACvB,QAAQ,IAAI,KAAK,4BAA4B,CAAC;OAE9C,KAAK,MAAM,SAAS,WAClB,QAAQ,IAAI,IAAI,MAAM,SAAS,IAAI,MAAM,OAAO,IAAI,MAAM,SAAS;EAGvE,QAAQ,IAAI,GAAG;EACf;CACF;CAEA,MAAM,SAAS,YAAY,GAAG;CAC9B,MAAM,QAAQ,kBAAkB,GAAG;CACnC,MAAM,YAAY,cAAc,GAAG;CACnC,MAAM,YAAY,cAAc,GAAG;CAEnC,MAAM,MAAM,IAAI,OAAO,EAAE;CACzB,QAAQ,IAAI,GAAG;CACf,QAAQ,IAAI,KAAK,yBAAyB,CAAC;CAC3C,QAAQ,IAAI,GAAG;CAGf,MAAM,aAAa,OAAO,UAAU,QAAQ,gBAAgB,OAAO,IAAI,EAAE,IAAI,MAAM,aAAa;CAChG,QAAQ,IAAI,gBAAgB,YAAY;CAGxC,QAAQ,IAAI,gBAAgB,MAAM,OAAO,QAAQ;CAGjD,MAAM,UAAU,WAAW,KAAK,gBAAgB,GAAG,EAAE,MAAM;CAC3D,IAAI,SAAS;EACX,MAAM,YAAY,QAAQ,QAAQ,KAAK,QAAQ,MAAM,KAAK;EAC1D,QAAQ,IAAI,gBAAgB,QAAQ,aAAa,IAAI,QAAQ,aAAa,GAAG,WAAW;CAC1F,OACE,QAAQ,IAAI,mBAAmB;CAIjC,IAAI,MAAM,SAAS,GAAG;EACpB,QAAQ,IAAI,SAAS;EACrB,KAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,QAAQ,UAAU;GACxB,MAAM,SAAS,OAAO,gBAClB,SAAS,UAAU,MAAM,aAAa,MACtC;GACJ,QAAQ,IAAI,MAAM,KAAK,MAAM,QAAQ;EACvC;CACF;CAGA,MAAM,iBAAiB,UAAU;CACjC,IAAI,iBAAiB,GACnB,QAAQ,IACN,iBAAiB,eAAe,aAAa,mBAAmB,IAAI,MAAM,GAAG,4BAC/E;MAEA,QAAQ,IAAI,6BAA6B;CAI3C,MAAM,YAAY,KAAK,QAAQ,QAAQ,IAAI;CAC3C,IAAI,WAAW;EACb,MAAM,eAAe,MAAM,kBAAkB,SAAS;EACtD,IAAI,gBAAgB,aAAa,SAAS,GAAG;GAC3C,QAAQ,IAAI,KAAK,mBAAmB,CAAC;GACrC,KAAK,MAAM,KAAK,cAAc;IAC5B,MAAM,YAAY,EAAE,QAAQ,GAAG,EAAE,UAAU;IAC3C,QAAQ,IAAI,KAAK,MAAM,UAAU,OAAO,EAAE,EAAE,KAAK,EAAE,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;GACxF;EACF,OAAO,IAAI,iBAAiB,MAC1B,QAAQ,IAAI,KAAK,2BAA2B,CAAC;OAE7C,QAAQ,IAAI,KAAK,8BAA8B,UAAU,EAAE,CAAC;CAEhE;CAEA,QAAQ,IAAI,GAAG;AACjB;AAEA,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAC9C,YAAY,sDAAsD,EAClE,OAAO,eAAe,iCAAiC,EACvD,OAAO,gBAAgB,+DAA+D,EACtF,QAAQ,SAAS,UAAU,MAAM,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,CAAC,CAAC;;;ACjJnF,SAAS,UAAU,SAAyB;CAC1C,OAAO,KAAK,KAAK,SAAS,YAAY,QAAQ;AAChD;AAEA,SAAS,gBAAgB,SAAiB,MAAsB;CAC9D,OAAO,KAAK,KAAK,UAAU,OAAO,GAAG,GAAG,KAAK,YAAY;AAC3D;AAEA,eAAsB,cACpB,MACA,MACA,SACe;CACf,MAAM,MAAM,WAAW,QAAQ,IAAI;CACnC,MAAM,cAAc,KAAK,KAAK,KAAK,aAAa,IAAI;CAEpD,IAAI,CAAC,GAAG,WAAW,WAAW,GAAG;EAC/B,QAAQ,MACN,MAAM,eAAe,KAAK,0DAA0D,CACtF;EACA,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,UAAW,KAAK,WAAW;CACjC,MAAM,SAAsC,KAAK,cAAc,CAAC,OAAO,IAAI,CAAC,OAAO;CAEnF,MAAM,SAAsB,kBAAkB,MAAM;EAClD;EACA;EACA;EACA,4BAAW,IAAI,KAAK,GAAE,YAAY;EAClC,UAAU;EACV,GAAI,KAAK,WAAW,KAAA,IAAY,EAAE,gBAAgB,KAAK,OAAO,IAAI,CAAC;CACrE,CAAC;CAED,cAAc,gBAAgB,KAAK,IAAI,GAAG,MAAM;CAEhD,QAAQ,IAAI,QAAQ,oBAAoB,KAAK,IAAI,GAAG,CAAC;CACrD,QAAQ,IAAI,KAAK,eAAe,SAAS,CAAC;CAC1C,QAAQ,IAAI,KAAK,eAAe,OAAO,KAAK,IAAI,GAAG,CAAC;CACpD,QAAQ,IAAI,KAAK,+BAA+B,KAAK,YAAY,CAAC;CAElE,IAAI,YAAY,cAAc,CAAC,QAAQ,IAAI,uBACzC,QAAQ,IACN,KACE,6FACF,CACF;AAEJ;AAEA,eAAsB,eAAe,SAAiC;CAEpE,MAAM,OAAO,UADD,WAAW,QAAQ,IAAI,CACT;CAE1B,IAAI,CAAC,GAAG,WAAW,IAAI,GAAG;EACxB,QAAQ,IAAI,KAAK,wEAAwE,CAAC;EAC1F;CACF;CAEA,MAAM,QAAQ,GAAG,YAAY,IAAI,EAAE,QAAQ,MAAM,EAAE,SAAS,aAAa,CAAC;CAE1E,IAAI,MAAM,WAAW,GAAG;EACtB,QAAQ,IAAI,KAAK,uBAAuB,CAAC;EACzC;CACF;CAEA,QAAQ,IAAI,KAAK,cAAc,MAAM,OAAO,IAAI,CAAC;CAEjD,KAAK,MAAM,QAAQ,OACjB,IAAI;EACF,MAAM,MAAM,KAAK,MACf,GAAG,aAAa,KAAK,KAAK,MAAM,IAAI,GAAG,OAAO,CAChD;EACA,MAAM,WAAW,IAAI,WACjB,cAAc,IAAI,KAAK,IAAI,QAAQ,EAAE,eAAe,MACpD;EACJ,QAAQ,IACN,KAAK,KAAK,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,QAAQ,KAAK,IAAI,OAAO,KAAK,GAAG,EAAE,KAAK,UAAU,CACrF;CACF,QAAQ;EACN,QAAQ,IAAI,KAAK,KAAK,KAAK,aAAa,CAAC;CAC3C;CAEF,QAAQ,IAAI,EAAE;AAChB;AAEA,eAAsB,eAAe,MAAc,SAAiC;CAElF,MAAM,aAAa,gBADP,WAAW,QAAQ,IAAI,GACK,IAAI;CAE5C,IAAI,CAAC,GAAG,WAAW,UAAU,GAAG;EAC9B,QAAQ,MAAM,MAAM,gCAAgC,KAAK,GAAG,CAAC;EAC7D,QAAQ,KAAK,CAAC;CAChB;CAEA,GAAG,WAAW,UAAU;CACxB,QAAQ,IAAI,QAAQ,oBAAoB,MAAM,CAAC;AACjD;AAEA,MAAa,eAAe,IAAI,QAAQ,OAAO,EAAE,YAAY,4BAA4B;AAEzF,aACG,QAAQ,cAAc,EACtB,YAAY,6CAA6C,EACzD,OAAO,uBAAuB,mCAAmC,UAAU,EAC3E,OAAO,mBAAmB,uCAAuC,EACjE,OAAO,sBAAsB,2BAA2B,EACxD,QAAQ,MAAc,SACrB,cAAc,MAAM,MAAM,QAAQ,IAAI,iBAAiB,CACzD;AAEF,aACG,QAAQ,QAAQ,EAChB,YAAY,4BAA4B,EACxC,aAAa,eAAe,QAAQ,IAAI,iBAAiB,CAAC;AAE7D,aACG,QAAQ,eAAe,EACvB,YAAY,oCAAoC,EAChD,QAAQ,SAAiB,eAAe,MAAM,QAAQ,IAAI,iBAAiB,CAAC;;;;ACvG/E,SAAS,mBACP,WACoE;CACpE,MAAM,KAAK,aAAa,IAAI,YAAY;CACxC,IAAI,EAAE,SAAS,KAAK,GAAG,OAAO;CAC9B,IAAI,EAAE,SAAS,MAAM,GAAG,OAAO;CAC/B,IAAI,EAAE,SAAS,QAAQ,GAAG,OAAO;CACjC,IAAI,EAAE,SAAS,QAAQ,KAAK,EAAE,SAAS,OAAO,GAAG,OAAO;CACxD,IAAI,EAAE,SAAS,QAAQ,GAAG,OAAO;CACjC,OAAO;AACT;;AAGA,SAAS,cACP,QAC4D;CAC5D,MAAM,KAAK,UAAU,IAAI,YAAY;CACrC,IAAI,EAAE,SAAS,QAAQ,GAAG,OAAO;CACjC,IAAI,EAAE,SAAS,UAAU,GAAG,OAAO;CACnC,IAAI,EAAE,SAAS,SAAS,KAAK,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,MAAM,GAAG,OAAO;CAC9E,IAAI,EAAE,SAAS,SAAS,KAAK,EAAE,SAAS,UAAU,GAAG,OAAO;CAC5D,OAAO;AACT;;AAGA,SAAS,gBAAgB,UAAyD;CAChF,MAAM,KAAK,YAAY,IAAI,YAAY;CACvC,IAAI,EAAE,SAAS,QAAQ,KAAK,EAAE,SAAS,UAAU,GAAG,OAAO;CAC3D,IAAI,EAAE,SAAS,MAAM,GAAG,OAAO;CAC/B,IAAI,EAAE,SAAS,KAAK,GAAG,OAAO;CAC9B,OAAO;AACT;AAEA,SAAS,QAAQ,KAAqC;CACpD,OAAO,WAAW,QAAQ,EAAE,OAAO,KAAK,UAAU,GAAG,CAAC,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AACnF;AAEA,SAASC,UAAQ,MAAsB;CACrC,OAAO,KACJ,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE,EACtB,MAAM,GAAG,EAAE;AAChB;AAEA,SAAS,SAAS,SAAgD;CAChE,MAAM,QAAQ,QAAQ,KAAK,EAAE,MAAM,IAAI;CACvC,IAAI,MAAM,SAAS,GAAG,OAAO,CAAC;CAC9B,MAAM,WAAW,MAAM,MAAM,IAAI,MAAM,GAAG,EAAE,KAAK,MAAM,EAAE,KAAK,EAAE,QAAQ,UAAU,EAAE,CAAC;CACrF,OAAO,MAAM,MAAM,CAAC,EAAE,KAAK,SAAS;EAClC,MAAM,SAAS,KAAK,MAAM,GAAG,EAAE,KAAK,MAAM,EAAE,KAAK,EAAE,QAAQ,UAAU,EAAE,CAAC;EACxE,MAAM,MAA8B,CAAC;EACrC,QAAQ,SAAS,GAAG,MAAM;GACxB,IAAI,KAAK,OAAO,MAAM;EACxB,CAAC;EACD,OAAO;CACT,CAAC;AACH;AAEA,MAAM,uBAAuB;CAC3B;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAS,eACP,SACA,MACA,QACA,OACA,QACoC;CACpC,MAAM,OAAOA,UAAQ,QAAQ,SAAS;CACtC,MAAM,cAAc,KAAK,KAAK,SAAS,aAAa,IAAI;CACxD,MAAM,gBAAgB,KAAK,KAAK,aAAa,eAAe;CAE5D,IAAI,GAAG,WAAW,aAAa,GAAG,OAAO;EAAE;EAAM,SAAS;CAAM;CAChE,IAAI,QAAQ,OAAO;EAAE;EAAM,SAAS;CAAK;CAEzC,GAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;CAE7C,MAAM,yBAAQ,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;CAgBlD,gBAAgB,eAAe,GAfX;EAClB;EACA,SAAS;EACT,SAAS,WAAW,WAAW;EAC/B,QAAQ,UAAU,UAAU;EAC5B;EACA,YAAY;EACZ,YAAY;EACZ,oBAAoB;EACpB;EACA;CACF,EACG,OAAO,OAAO,EACd,KAAK,IAEoC,EAAE,kBAAkB,KAAK,GAAG;CACxE,gBAAgB,KAAK,KAAK,aAAa,iBAAiB,GAAG,oBAAoB,KAAK,KAAK;CACzF,gBAAgB,KAAK,KAAK,aAAa,aAAa,GAAG,gBAAgB,KAAK,KAAK;CACjF,cAAc,KAAK,KAAK,aAAa,cAAc,GAAG;EACpD,OAAO;GACL,OAAO,SACH,QAAQ,OAAO,SAAS,WACxB,QACE,QAAQ,MAAM,SAAS,UACvB;GACN,SAAS;EACX;EACA,aAAa;GAAE,OAAO,CAAC;GAAG,YAAY,CAAC,QAAQ,MAAM;GAAG,SAAS;EAAM;CACzE,CAAC;CAED,OAAO;EAAE;EAAM,SAAS;CAAK;AAC/B;AAEA,SAAS,qBAAqB,SAAiB,UAAiC;CAC9E,MAAM,WAAW;EAAC;EAAU,SAAS,YAAY;EAAG,SAAS,YAAY;CAAC;CAC1E,KAAK,MAAM,QAAQ,UAAU;EAC3B,MAAM,IAAI,KAAK,KAAK,SAAS,IAAI;EACjC,IAAI,GAAG,WAAW,CAAC,GAAG,OAAO,GAAG,aAAa,GAAG,OAAO;CACzD;CAEA,MAAM,QADQ,GAAG,YAAY,OACX,EAAE,MAAM,MAAM,EAAE,YAAY,MAAM,SAAS,YAAY,CAAC;CAC1E,IAAI,OAAO,OAAO,GAAG,aAAa,KAAK,KAAK,SAAS,KAAK,GAAG,OAAO;CACpE,OAAO;AACT;AAEA,eAAe,WAAW,SAAkC;CAC1D,MAAM,UAAU,MAAM,OAAO,YAAY;CACzC,MAAM,MAAM,IAAI,OAAO,OAAO;CAC9B,MAAM,SAAS,GAAG,QAAQ;CAC1B,GAAG,UAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;CACxC,IAAI,aAAa,QAAQ,IAAI;CAC7B,OAAO;AACT;AAEA,eAAe,wBACb,YACA,MACA,KACuB;CACvB,MAAM,SAAuB;EAC3B,kBAAkB;EAClB,sBAAsB;EACtB,SAAS;EACT,QAAQ,CAAC;CACX;CAEA,IAAI,UAAU;CACd,IAAI,SAAwB;CAE5B,IAAI,WAAW,SAAS,MAAM,GAAG;EAC/B,SAAS,MAAM,WAAW,UAAU;EACpC,UAAU;CACZ;CAEA,IAAI,CAAC,GAAG,SAAS,OAAO,EAAE,YAAY,GAAG;EACvC,OAAO,OAAO,KAAK,0DAA0D;EAC7E,OAAO;CACT;CAEA,MAAM,cACJ,qBAAqB,SAAS,cAAc,KAAK,qBAAqB,SAAS,cAAc;CAC/F,MAAM,gBACJ,qBAAqB,SAAS,gBAAgB,KAC9C,qBAAqB,SAAS,gBAAgB,KAC9C,qBAAqB,SAAS,WAAW,KACzC,qBAAqB,SAAS,WAAW;CAE3C,IAAI,CAAC,aAAa;EAChB,OAAO,OAAO,KAAK,kDAAkD;EACrE,IAAI,QAAQ,GAAG,OAAO,QAAQ,EAAE,WAAW,KAAK,CAAC;EACjD,OAAO;CACT;CAEA,MAAM,WAAW,SAAS,WAAW;CACrC,MAAM,aAAa,gBAAgB,SAAS,aAAa,IAAI,CAAC;CAE9D,IAAI,KAAK,QAAQ;EACf,QAAQ,IACN,KACE,aAAa,SAAS,OAAO,aAAa,WAAW,OAAO,mCAC9D,CACF;EACA,IAAI,QAAQ,GAAG,OAAO,QAAQ,EAAE,WAAW,KAAK,CAAC;EACjD,OAAO;CACT;CAEA,MAAM,0BAAU,IAAI,IAAoB;CACxC,KAAK,MAAM,OAAO,UAAU;EAC1B,MAAM,QAAQ,IAAI,WAAW,IAAI,mBAAmB,IAAI,KAAK;EAC7D,IAAI,CAAC,MAAM;EACX,MAAM,UAAU,IAAI,cAAc,IAAI,QAAQ,gBAAgB,EAAE;EAChE,MAAM,QAAQ,IAAI,YAAY;EAC9B,IAAI;GACF,MAAM,EAAE,MAAM,YAAY,eAAe,KAAK,MAAM,QAAQ,OAAO,KAAK;GACxE,IAAI,IAAI,OAAO,QAAQ,IAAI,IAAI,OAAO,IAAI;GAC1C,QAAQ,IAAI,KAAK,YAAY,GAAG,IAAI;GACpC,IAAI,SAAS,OAAO;EACtB,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,YAAY,KAAK,KAAM,IAAc,SAAS;EACnE;CACF;CAEA,MAAM,QAAQ,IAAI,iBAAiB,GAAG;CACtC,KAAK,MAAM,OAAO,YAAY;EAC5B,MAAM,YAAY,IAAI,gBAAgB,IAAI,aAAa;EACvD,MAAM,OAAO,YAAY,QAAQ,IAAI,SAAS,IAAI,KAAA;EAClD,IAAI,CAAC,MAAM;EAEX,MAAM,KAAK,IAAI,SAAS,QAAQ,GAAG;EACnC,MAAM,YAAY,oBAAoB;EACtC,IAAI,MAAM,MAAM,KAAK,MAAM,SAAS,GAAG;GACrC,OAAO;GACP;EACF;EAEA,MAAM,OAAO,IAAI,mBAAmB,IAAI,mCAAkB,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;EAC9F,MAAM,SAAS,IAAI,kBAAkB,IAAI,cAAc,IAAI,MAAM,GAAG,GAAG;EACvE,MAAM,KAAK,IAAI,WAAW,IAAI,YAAY;EAC1C,MAAM,OAAO,EAAE,SAAS,MAAM,IACzB,SACD,EAAE,SAAS,OAAO,IACf,UACD,EAAE,SAAS,SAAS,IACjB,YACA;EAET,IAAI;GACF,MAAM,kBAAkB,KAAK,MAAM;IACjC;IACA;IACA,MAAM;IACN,SAAS;IACT,WAAW,CAAC;IACZ;IACA,yBAAQ,IAAI,KAAK,GAAE,YAAY;GACjC,CAAC;GACD,MAAM,aAAa,MAAM,SAAS;GAClC,OAAO;EACT,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,YAAY,GAAG,IAAK,IAAc,SAAS;EAChE;CACF;CAEA,IAAI,QAAQ,GAAG,OAAO,QAAQ,EAAE,WAAW,KAAK,CAAC;CACjD,OAAO;AACT;AAEA,eAAe,uBACb,YACA,MACA,KACuB;CACvB,MAAM,SAAuB;EAC3B,kBAAkB;EAClB,sBAAsB;EACtB,SAAS;EACT,QAAQ,CAAC;CACX;CAEA,IAAI,UAAU;CACd,IAAI,SAAwB;CAE5B,IAAI,WAAW,SAAS,MAAM,GAAG;EAC/B,SAAS,MAAM,WAAW,UAAU;EACpC,UAAU;CACZ;CAEA,IAAI,CAAC,GAAG,SAAS,OAAO,EAAE,YAAY,GAAG;EACvC,OAAO,OAAO,KAAK,yDAAyD;EAC5E,OAAO;CACT;CAEA,MAAM,UACJ,qBAAqB,SAAS,mBAAmB,KACjD,qBAAqB,SAAS,mBAAmB;CACnD,MAAM,gBACJ,qBAAqB,SAAS,gBAAgB,KAC9C,qBAAqB,SAAS,gBAAgB;CAEhD,IAAI,CAAC,SAAS;EACZ,OAAO,OAAO,KAAK,sDAAsD;EACzE,IAAI,QAAQ,GAAG,OAAO,QAAQ,EAAE,WAAW,KAAK,CAAC;EACjD,OAAO;CACT;CAEA,MAAM,OAAO,SAAS,OAAO;CAC7B,MAAM,aAAa,gBAAgB,SAAS,aAAa,IAAI,CAAC;CAE9D,IAAI,KAAK,QAAQ;EACf,QAAQ,IACN,KACE,aAAa,KAAK,OAAO,kBAAkB,WAAW,OAAO,kCAC/D,CACF;EACA,IAAI,QAAQ,GAAG,OAAO,QAAQ,EAAE,WAAW,KAAK,CAAC;EACjD,OAAO;CACT;CAEA,MAAM,0BAAU,IAAI,IAAoB;CACxC,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,QAAQ,IAAI,WAAW,IAAI,WAAW,IAAI,KAAK;EACrD,IAAI,CAAC,MAAM;EACX,MAAM,KAAK,IAAI,SAAS,IAAI,SAAS;EACrC,IAAI;GACF,MAAM,EAAE,MAAM,YAAY,eAAe,KAAK,MAAM,IAAI,IAAI,KAAK;GACjE,IAAI,IAAI,QAAQ,IAAI,IAAI,IAAI;GAC5B,QAAQ,IAAI,KAAK,YAAY,GAAG,IAAI;GACpC,IAAI,SAAS,OAAO;EACtB,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,iBAAiB,KAAK,KAAM,IAAc,SAAS;EACxE;CACF;CAEA,MAAM,QAAQ,IAAI,iBAAiB,GAAG;CACtC,KAAK,MAAM,OAAO,YAAY;EAC5B,MAAM,QAAQ,IAAI,aAAa,IAAI,sBAAsB;EACzD,MAAM,OAAO,QAAQ,QAAQ,IAAI,KAAK,IAAI,KAAA;EAC1C,IAAI,CAAC,MAAM;EAEX,MAAM,KAAK,IAAI,SAAS,QAAQ,GAAG;EACnC,MAAM,YAAY,mBAAmB;EACrC,IAAI,MAAM,MAAM,KAAK,MAAM,SAAS,GAAG;GACrC,OAAO;GACP;EACF;EAEA,MAAM,OACJ,IAAI,eAAe,IAAI,aAAa,MAAM,GAAG,EAAE,sBAAK,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;EAC1F,MAAM,SAAS,IAAI,WAAW,IAAI,cAAc,IAAI,MAAM,GAAG,GAAG;EAChE,MAAM,KAAK,IAAI,WAAW,IAAI,YAAY;EAC1C,MAAM,OACJ,MAAM,SACD,SACD,MAAM,UACH,UACD,MAAM,YACH,YACA;EAEX,IAAI;GACF,MAAM,kBAAkB,KAAK,MAAM;IACjC;IACA;IACA,MAAM;IACN,SAAS;IACT,WAAW,CAAC;IACZ;IACA,yBAAQ,IAAI,KAAK,GAAE,YAAY;GACjC,CAAC;GACD,MAAM,aAAa,MAAM,SAAS;GAClC,OAAO;EACT,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,YAAY,GAAG,IAAK,IAAc,SAAS;EAChE;CACF;CAEA,IAAI,QAAQ,GAAG,OAAO,QAAQ,EAAE,WAAW,KAAK,CAAC;CACjD,OAAO;AACT;AAEA,eAAsB,UACpB,YACA,MASA,SACuB;CACvB,MAAM,MAAM,WAAW,QAAQ,IAAI;CACnC,MAAM,SAAuB;EAC3B,kBAAkB;EAClB,sBAAsB;EACtB,SAAS;EACT,QAAQ,CAAC;CACX;CAGA,IAAI,KAAK,SAAS,gBAAgB,KAAK,SAAS,OAC9C,OAAO,uBAAuB,MAAM,GAAG;CAEzC,IAAI,KAAK,SAAS,eAAe,KAAK,SAAS,OAC7C,OAAO,sBAAsB,MAAM,GAAG;CAKxC,IACE,KAAK,SAAS,aACd,cACA,GAAG,WAAW,UAAU,KACxB,GAAG,SAAS,UAAU,EAAE,YAAY,GACpC;EACA,MAAM,EAAE,wBAAwB,MAAM,OAAO;EAC7C,MAAM,IAAI,MAAM,oBAAoB,YAAY,KAAK;GACnD,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;GACtC,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;GACtC,UAAU,KAAK,YAAY,CAAC;EAC9B,CAAC;EACD,IAAI,EAAE,wBAAwB,GAC5B,QAAQ,MAAM,qCAAqC,EAAE,uBAAuB;EAE9E,IAAI,EAAE,iBAAiB,GACrB,QAAQ,MAAM,6BAA6B,EAAE,gBAAgB;EAE/D,OAAO;GACL,kBAAkB,EAAE;GACpB,sBAAsB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE;GAClE,SAAS;GACT,QAAQ,EAAE;EACZ;CACF;CACA,IAAI,KAAK,SAAS,gBAAgB,YAChC,OAAO,wBAAwB,YAAY,MAAM,GAAG;CAEtD,IAAI,KAAK,SAAS,eAAe,YAC/B,OAAO,uBAAuB,YAAY,MAAM,GAAG;CAGrD,IAAI,CAAC,GAAG,WAAW,UAAU,GAAG;EAC9B,QAAQ,MAAM,MAAM,qBAAqB,YAAY,CAAC;EACtD,QAAQ,KAAK,CAAC;CAChB;CAGA,MAAM,OAAO,SADG,GAAG,aAAa,YAAY,OAChB,CAAC;CAE7B,IAAI,KAAK,WAAW,GAAG;EACrB,QAAQ,IAAI,KAAK,uBAAuB,CAAC;EACzC,OAAO;CACT;CAEA,MAAM,UAAU,OAAO,KAAK,KAAK,EAAG;CACpC,MAAM,EAAE,iBAAiB,MAAM,OAAO;CACtC,MAAM,UAAU,MAAM,aAAa,SAAS,CAAC,GAAG,oBAAoB,CAAC;CAErE,IAAI,KAAK,QAAQ;EACf,QAAQ,IAAI,KAAK,aAAa,KAAK,OAAO,sBAAsB,CAAC;EACjE,OAAO,QAAQ,OAAO,EAAE,SAAS,CAAC,GAAG,OAAO,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;EACrF,QAAQ,IAAI,KAAK,wBAAwB,KAAK,OAAO,oCAAoC,CAAC;EAC1F,OAAO;CACT;CAGA,MAAM,eAAe,KAAK,QAAQ,MAAM;EAEtC,QADa,EAAE,QAAQ,QAAQ,OAAO,IAC1B,KAAK,EAAE,SAAS;CAC9B,CAAC;CAED,MAAM,0BAAU,IAAI,IAAoB;CAExC,KAAK,MAAM,OAAO,cAAc;EAC9B,MAAM,QAAQ,IAAI,QAAQ,QAAQ,OAAO,IAAI,KAAK;EAClD,IAAI,CAAC,MAAM;EAEX,MAAM,UAAU,IAAI,QAAQ,UAAU,OAAO,IAAI,KAAK;EACtD,MAAM,SAAS,IAAI,QAAQ,SAAS,OAAO,IAAI,KAAK;EAEpD,IAAI;GACF,MAAM,EAAE,MAAM,YAAY,eAAe,KAAK,MAAM,QAAQ,OAAO,KAAK,UAAU,KAAK;GACvF,QAAQ,IAAI,KAAK,YAAY,GAAG,IAAI;GACpC,IAAI,SAAS,OAAO;EACtB,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,aAAa,KAAK,KAAM,IAAc,SAAS;EACpE;CACF;CAGA,MAAM,QAAQ,IAAI,iBAAiB,GAAG;CACtC,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,gBAAgB,IAAI,QAAQ,mBAAmB,OAAO,IAAI,KAAK;EACrE,MAAM,SAAS,IAAI,QAAQ,YAAY,OAAO,IAAI,KAAK;EACvD,MAAM,gBAAgB,IAAI,QAAQ,WAAW,OAAO,IAAI,KAAK;EAC7D,MAAM,eAAe,IAAI,QAAQ,eAAe,OAAO,IAAI,KAAK;EAChE,MAAM,QAAQ,IAAI,QAAQ,WAAW,OAAO,IAAI,KAAK;EAErD,IAAI,CAAC,SAAS,CAAC,cAAc;EAE7B,MAAM,OAAO,QAAQ,IAAI,KAAK,YAAY,CAAC;EAC3C,IAAI,CAAC,MAAM;EAEX,MAAM,UAAU,QAAQ,GAAG;EAC3B,MAAM,SAAS,KAAK,SAAS,YAAY,YAAY;EACrD,MAAM,YAAY,cACd,GAAG,OAAO,cAAc,gBACxB,GAAG,OAAO,SAAS;EAEvB,MAAM,OAAO,sBACF;GACL,IAAI;IACF,OAAO,IAAI,KAAK,YAAY,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE;GACzD,QAAQ;IACN,wBAAO,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;GAC7C;EACF,GAAG,qBACH,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;EAExC,MAAM,cAAc;GAClB,MAAM,IAAI,aAAa,YAAY;GACnC,IAAI,EAAE,SAAS,MAAM,GAAG,OAAO;GAC/B,IAAI,EAAE,SAAS,SAAS,KAAK,EAAE,SAAS,MAAM,GAAG,OAAO;GACxD,IAAI,EAAE,SAAS,OAAO,GAAG,OAAO;GAChC,IAAI,EAAE,SAAS,MAAM,GAAG,OAAO;GAC/B,OAAO;EACT,GAAG;EAEH,IAAI;GACF,IAAI,MAAM,MAAM,KAAK,MAAM,SAAS,GAAG;IACrC,OAAO;IACP;GACF;GAEA,MAAM,kBAAkB,KAAK,MAAM;IACjC;IACA;IACA,MAAM;IACN,SAAS,MAAM,MAAM,GAAG,GAAG;IAC3B,WAAW,CAAC;IACZ;IACA,yBAAQ,IAAI,KAAK,GAAE,YAAY;GACjC,CAAC;GACD,MAAM,aAAa,MAAM,SAAS;GAElC,OAAO;EACT,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,iBAAiB,KAAK,KAAM,IAAc,SAAS;EACxE;CACF;CAEA,OAAO;AACT;AAEA,eAAe,uBACb,MACA,KACuB;CACvB,MAAM,SAAuB;EAC3B,kBAAkB;EAClB,sBAAsB;EACtB,SAAS;EACT,QAAQ,CAAC;CACX;CACA,MAAM,QAAQ,KAAK,SAAS,QAAQ,IAAI,iBAAiB;CACzD,MAAM,cAAc,KAAK,OAAO,QAAQ,IAAI,eAAe;CAE3D,IAAI,CAAC,SAAS,CAAC,aAAa;EAC1B,QAAQ,MACN,MAAM,sFAAsF,CAC9F;EACA,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,EACJ,yBACA,sBACA,8BACA,sBACA,uBACA,sBACA,0BACA,sBACA,mCACE,MAAM,OAAO;CAEjB,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,IAAI;EACF,WAAW,MAAM,wBAAwB,aAAa,KAAK;EAC3D,QAAQ,MAAM,qBAAqB,aAAa,KAAK;EACrD,gBAAiB,MAAM,6BAA6B,aAAa,KAAK,KAAM,CAAC;EAC7E,QAAS,MAAM,qBAAqB,aAAa,KAAK,KAAM,CAAC;EAC7D,SAAU,MAAM,sBAAsB,aAAa,KAAK,KAAM,CAAC;EAC/D,QAAS,MAAM,qBAAqB,aAAa,KAAK,KAAM,CAAC;EAC7D,YAAa,MAAM,yBAAyB,aAAa,KAAK,KAAM,CAAC;EACrE,QAAS,MAAM,qBAAqB,aAAa,KAAK,KAAM,CAAC;EAC7D,kBAAmB,MAAM,+BAA+B,aAAa,KAAK,KAAM,CAAC;CACnF,SAAS,KAAK;EACZ,OAAO,OAAO,KAAK,mBAAoB,IAAc,SAAS;EAC9D,OAAO;CACT;CAEA,IAAI,KAAK,QAAQ;EACf,QAAQ,IACN,KACE,aAAa,SAAS,OAAO,aAAa,MAAM,OAAO,UAAU,cAAc,OAAO,kBAAkB,MAAM,OAAO,UAAU,OAAO,OAAO,WAAW,MAAM,OAAO,uBACvK,CACF;EACA,OAAO;CACT;CAGA,MAAM,0BAAU,IAAI,IAAoB;CACxC,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,OAAO,QAAQ,MAAM,KAAK;EAChC,IAAI,CAAC,MAAM;EACX,MAAM,SAAS,QAAQ,SAAS,SAAS,QAAQ,gBAAgB,EAAE,KAAK;EACxE,MAAM,QAAQ,QAAQ,SAAS;EAC/B,IAAI;GACF,MAAM,EAAE,MAAM,YAAY,eAAe,KAAK,MAAM,QAAQ,OAAO,KAAK;GACxE,QAAQ,IAAI,QAAQ,IAAI,IAAI;GAC5B,QAAQ,IAAI,KAAK,YAAY,GAAG,IAAI;GACpC,IAAI,SAAS,OAAO;EACtB,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,YAAY,KAAK,KAAM,IAAc,SAAS;EACnE;CACF;CAGA,MAAM,QAAQ,IAAI,iBAAiB,GAAG;CACtC,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,KAAK,QAAQ,QAAQ,IAAI,KAAK,KAAK,IAAI,KAAA;EACpD,IAAI,CAAC,MAAM;EAEX,MAAM,YAAY,qBAAqB,KAAK;EAC5C,IAAI,MAAM,MAAM,KAAK,MAAM,SAAS,GAAG;GACrC,OAAO;GACP;EACF;EAEA,MAAM,OAAO,KAAK,iCAAgB,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;EACtE,MAAM,SAAS,KAAK,eAAe,KAAK,WAAW,IAAI,MAAM,GAAG,GAAG;EACnE,MAAM,KAAK,KAAK,QAAQ,IAAI,YAAY;EACxC,MAAM,OAAO,EAAE,SAAS,MAAM,IACzB,SACD,EAAE,SAAS,OAAO,IACf,UACD,EAAE,SAAS,SAAS,IACjB,YACA;EAET,IAAI;GACF,MAAM,kBAAkB,KAAK,MAAM;IACjC;IACA;IACA,MAAM;IACN,SAAS;IACT,WAAW,CAAC;IACZ;IACA,yBAAQ,IAAI,KAAK,GAAE,YAAY;GACjC,CAAC;GACD,MAAM,aAAa,MAAM,SAAS;GAClC,OAAO;EACT,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,QAAQ,KAAK,GAAG,IAAK,IAAc,SAAS;EACjE;CACF;CAGA,MAAM,EAAE,eAAe,MAAM,OAAO;CACpC,MAAM,yBAAQ,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;CAClD,MAAM,8BAAc,IAAI,IAAgD;CACxE,KAAK,MAAM,OAAO,eAAe;EAC/B,MAAM,cAAc,IAAI,SAAS,MAAM,KAAK;EAC5C,IAAI,CAAC,IAAI,QAAQ,CAAC,aAAa;EAE/B,IAAI,OAAO,QAAQ,IAAI,YAAY,YAAY,CAAC;EAChD,IAAI,CAAC,MAAM;GACT,MAAM,SAAS,IAAI,SAAS,SAAS,QAAQ,gBAAgB,EAAE,KAAK;GACpE,IAAI;IACF,MAAM,IAAI,eAAe,KAAK,aAAa,QAAQ,IAAI,KAAK;IAC5D,OAAO,EAAE;IACT,QAAQ,IAAI,YAAY,YAAY,GAAG,IAAI;IAC3C,IAAI,EAAE,SAAS,OAAO;GACxB,SAAS,KAAK;IACZ,OAAO,OAAO,KAAK,gBAAgB,IAAI,KAAK,KAAM,IAAc,SAAS;IACzE;GACF;EACF;EACA,YAAY,IAAI,IAAI,IAAI;GAAE;GAAM,UAAU,IAAI;EAAK,CAAC;EAEpD,IAAI;GACF,MAAM,WAAW,KAAK,MAAM;IAC1B,MAAM,IAAI;IACV,OAAO,mBAAmB,IAAI,SAAS;IACvC,UAAU;IACV,SAAS;IACT,OAAO,6BAA6B,IAAI,aAAa,gBAAgB;IACrE,GAAI,OAAO,IAAI,WAAW,WAAW,EAAE,OAAO,IAAI,OAAO,IAAI,CAAC;IAC9D,GAAI,OAAO,IAAI,gBAAgB,WAAW,EAAE,aAAa,IAAI,YAAY,IAAI,CAAC;IAC9E,GAAI,IAAI,YAAY,EAAE,YAAY,IAAI,UAAU,IAAI,CAAC;GACvD,CAAC;GACD,OAAO,iBAAiB,OAAO,iBAAiB,KAAK;EACvD,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,gBAAgB,IAAI,KAAK,KAAM,IAAc,SAAS;EAC3E;CACF;CAGA,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,KAAK,SAAS,KAAK,KAAK,KAAK,MAAM,KAAK;EACrD,IAAI,CAAC,MAAM;EAEX,MAAM,SAAS,KAAK,SAAS,QAAQ,gBAAgB,EAAE,KAAK,KAAK,OAAO,MAAM,GAAG,EAAE,MAAM;EACzF,IAAI;EACJ,IAAI;GACF,MAAM,IAAI,eAAe,KAAK,MAAM,QAAQ,KAAK,SAAS,IAAI,KAAK;GACnE,OAAO,EAAE;GACT,QAAQ,IAAI,KAAK,YAAY,GAAG,IAAI;GACpC,IAAI,EAAE,SAAS,OAAO;EACxB,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,SAAS,KAAK,KAAM,IAAc,SAAS;GAC9D;EACF;EAEA,MAAM,YAAY,qBAAqB,KAAK;EAC5C,IAAI,MAAM,MAAM,KAAK,MAAM,SAAS,GAAG;GACrC,OAAO;GACP;EACF;EAEA,MAAM,cAAc,KAAK,QAAQ,GAAG,KAAK,KAAK,IAAI,KAAK,UAAU,KAAK;EACtE,IAAI;GACF,MAAM,kBAAkB,KAAK,MAAM;IACjC,uBAAM,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;IAC1C,MAAM;IACN,MAAM,KAAK;IACX,SAAS,qCAAqC,KAAK,UAAU,MAAM,aAAa,YAAY;IAC5F,WAAW,CAAC;IACZ;IACA,yBAAQ,IAAI,KAAK,GAAE,YAAY;GACjC,CAAC;GACD,MAAM,aAAa,MAAM,SAAS;GAClC,OAAO,iBAAiB,OAAO,iBAAiB,KAAK;EACvD,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,QAAQ,KAAK,GAAG,IAAK,IAAc,SAAS;EACjE;CACF;CAGA,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,OAAO,MAAM,QACf,QAAQ,IAAI,MAAM,KAAK,IACvB,MAAM,SACJ,QAAQ,IAAI,MAAM,MAAM,IACxB,KAAA;EACN,IAAI,CAAC,MAAM;GACT,OAAO;GACP;EACF;EAEA,MAAM,YAAY,sBAAsB,MAAM;EAC9C,IAAI,MAAM,MAAM,KAAK,MAAM,SAAS,GAAG;GACrC,OAAO;GACP;EACF;EAEA,MAAM,QAAQ,MAAM,iBAAiB,MAAM,iCAAgB,IAAI,KAAK,GAAE,YAAY,GAAG,MACnF,GACA,EACF;EACA,IAAI;GACF,MAAM,kBAAkB,KAAK,MAAM;IACjC;IACA,MAAM;IACN,MAAM;IACN,SAAS,MAAM,WAAW;IAC1B,UAAU,MAAM,eAAe,MAAM,WAAW,IAAI,MAAM,GAAG,GAAG;IAChE,WAAW,CAAC;IACZ;IACA,yBAAQ,IAAI,KAAK,GAAE,YAAY;GACjC,CAAC;GACD,MAAM,aAAa,MAAM,SAAS;GAClC,OAAO,kBAAkB,OAAO,kBAAkB,KAAK;EACzD,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,SAAS,MAAM,GAAG,IAAK,IAAc,SAAS;EACnE;CACF;CAGA,MAAM,EAAE,aAAa,cAAc,iBAAiB,MAAM,OAAO;CACjE,MAAM,EAAE,YAAY,iBAAiB,MAAM,OAAO;CAClD,MAAM,WAAW,aAAa,GAAG;CACjC,KAAK,MAAM,KAAK,OAAO;EACrB,MAAM,cAAc,EAAE,SAAS,MAAM,KAAK;EAC1C,IAAI,CAAC,aAAa;GAChB,OAAO;GACP;EACF;EACA,IAAI,OAAO,QAAQ,IAAI,YAAY,YAAY,CAAC;EAChD,IAAI,CAAC,MACH,IAAI;GACF,MAAM,IAAI,eAAe,KAAK,aAAa,IAAI,IAAI,KAAK;GACxD,OAAO,EAAE;GACT,QAAQ,IAAI,YAAY,YAAY,GAAG,IAAI;GAC3C,IAAI,EAAE,SAAS,OAAO;EACxB,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,SAAS,EAAE,GAAG,KAAM,IAAc,SAAS;GAC9D;EACF;EAGF,IAAI,EAAE,WAAW,QAAQ,IAAI,EAAE,WAAW,IAAI;EAC9C,IAAI,EAAE,WAAW,QAAQ,IAAI,EAAE,WAAW,IAAI;EAE9C,MAAM,UAAU,qBAAqB,EAAE;EACvC,MAAM,kBAAkB,MAAM,YAAY,KAAK,IAAI;EACnD,IAAI,gBAAgB,MAAM,OAAO,EAAE,eAAe,IAAI,SAAS,OAAO,CAAC,GAAG;GACxE,OAAO;GACP;EACF;EAEA,MAAM,WAAW,EAAE,gCAAe,IAAI,KAAK,GAAE,YAAY,GAAG,MAAM,GAAG,EAAE;EACvE,MAAM,SAAS,cAAc,EAAE,MAAM;EACrC,MAAM,WAAW,gBAAgB,EAAE,QAAQ;EAC3C,MAAM,SAAS,WAAW,YAAY,WAAW;EACjD,IAAI;GACF,MAAM,aAAa,KAAK,MAAM;IAC5B,IAAI,aAAa,eAAe;IAChC,OAAO,EAAE,WAAW,QAAQ,EAAE,cAAc,EAAE;IAC9C;IACA;IACA;IACA,QAAQ,WAAW,SAAS,UAAU,QAAQ;IAC9C,aAAa,GAAG,EAAE,eAAe,GAAG,OAAO,QAAQ,GAAG,KAAK;IAC3D,GAAI,SAAS,EAAE,WAAW,EAAE,cAAc,SAAS,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC;GACvE,CAAC;GACD,OAAO,iBAAiB,OAAO,iBAAiB,KAAK;EACvD,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,QAAQ,EAAE,GAAG,IAAK,IAAc,SAAS;EAC9D;CACF;CAGA,IAAI,UAAU,SAAS,KAAK,YAAY,OAAO,GAAG;EAChD,MAAM,EAAE,eAAe,eAAe,MAAM,OAAO;EACnD,MAAM,wBAAQ,IAAI,IAA8B;EAChD,KAAK,MAAM,MAAM,WAAW;GAC1B,IAAI,CAAC,GAAG,eAAe;GACvB,MAAM,MAAM,MAAM,IAAI,GAAG,aAAa,KAAK,CAAC;GAC5C,IAAI,KAAK,EAAE;GACX,MAAM,IAAI,GAAG,eAAe,GAAG;EACjC;EACA,KAAK,MAAM,CAAC,OAAO,UAAU,OAAO;GAClC,MAAM,MAAM,YAAY,IAAI,KAAK;GACjC,IAAI,CAAC,KAAK;GAEV,IAAI,WAAW,KAAK,IAAI,IAAI,EAAE,MAAM,MAAM,EAAE,aAAa,IAAI,QAAQ,GAAG;IACtE,OAAO;IACP;GACF;GACA,MAAM,iBAAiB,MAAM,KAAK,OAAO;IACvC,MAAM,WAAW,OAAO,GAAG,aAAa,YAAY,GAAG,WAAW,IAAI,GAAG,WAAW;IACpF,MAAM,YACJ,OAAO,GAAG,cAAc,WACpB,GAAG,YACH,OAAO,GAAG,eAAe,WACvB,GAAG,aAAa,WAChB;IACR,OAAO;KACL,aAAa,GAAG,UAAU,QAAQ,GAAG,eAAe;KACpD;KACA;IACF;GACF,CAAC;GACD,IAAI;IACF,MAAM,cAAc,KAAK;KACvB,MAAM,IAAI;KACV,UAAU,IAAI;KACd,WAAW;IACb,CAAC;IACD,OAAO,kBAAkB,OAAO,kBAAkB,KAAK;GACzD,SAAS,KAAK;IACZ,OAAO,OAAO,KAAK,kBAAkB,IAAI,SAAS,KAAM,IAAc,SAAS;GACjF;EACF;CACF;CAGA,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,KAAK,WAAW,QAAQ,IAAI,KAAK,QAAQ,IAAI,KAAA;EAC1D,IAAI,CAAC,MAAM;GACT,OAAO;GACP;EACF;EACA,MAAM,YAAY,qBAAqB,KAAK;EAC5C,IAAI,MAAM,MAAM,KAAK,MAAM,SAAS,GAAG;GACrC,OAAO;GACP;EACF;EACA,MAAM,QAAQ,KAAK,gCAAe,IAAI,KAAK,GAAE,YAAY,GAAG,MAAM,GAAG,EAAE;EACvE,MAAM,QAAQ,KAAK,SAAS;EAC5B,IAAI;GACF,MAAM,kBAAkB,KAAK,MAAM;IACjC;IACA,MAAM;IACN,MAAM;IACN,SAAS;IACT,SAAS,GAAG,QAAQ,KAAK,OAAO,KAAK,KAAK,SAAS,KAAK,MAAM,GAAG,GAAG;IACpE,WAAW,CAAC;IACZ;IACA,yBAAQ,IAAI,KAAK,GAAE,YAAY;GACjC,CAAC;GACD,MAAM,aAAa,MAAM,SAAS;GAClC,OAAO,iBAAiB,OAAO,iBAAiB,KAAK;EACvD,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,QAAQ,KAAK,GAAG,IAAK,IAAc,SAAS;EACjE;CACF;CAGA,KAAK,MAAM,MAAM,iBAAiB;EAChC,MAAM,OAAO,GAAG,YACZ,QAAQ,IAAI,GAAG,SAAS,IACxB,GAAG,SACD,QAAQ,IAAI,GAAG,MAAM,IACrB,KAAA;EACN,IAAI,CAAC,MAAM;GACT,OAAO;GACP;EACF;EACA,MAAM,YAAY,+BAA+B,GAAG;EACpD,IAAI,MAAM,MAAM,KAAK,MAAM,SAAS,GAAG;GACrC,OAAO;GACP;EACF;EACA,MAAM,eAAe,GAAG,UAAU,QAAQ,GAAG,cAAc;EAC3D,IAAI;GACF,MAAM,kBAAkB,KAAK,MAAM;IACjC,OAAO,GAAG,gCAAe,IAAI,KAAK,GAAE,YAAY,GAAG,MAAM,GAAG,EAAE;IAC9D,MAAM;IACN,MAAM;IACN,SAAS,aAAa;IACtB,SAAS,wBAAwB,aAAa,YAAY,GAAG,UAAU,MAAM;IAC7E,WAAW,CAAC;IACZ;IACA,yBAAQ,IAAI,KAAK,GAAE,YAAY;GACjC,CAAC;GACD,MAAM,aAAa,MAAM,SAAS;GAClC,OAAO,qBAAqB,OAAO,qBAAqB,KAAK;EAC/D,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,kBAAkB,GAAG,GAAG,IAAK,IAAc,SAAS;EACzE;CACF;CAEA,OAAO;AACT;AAEA,eAAsB,sBACpB,MACA,MAAc,QAAQ,IAAI,GACH;CACvB,MAAM,SAAuB;EAC3B,kBAAkB;EAClB,sBAAsB;EACtB,SAAS;EACT,QAAQ,CAAC;CACX;CACA,MAAM,QAAQ,KAAK,SAAS,QAAQ,IAAI,sBAAsB;CAC9D,MAAM,cAAc,KAAK,OAAO,QAAQ,IAAI,oBAAoB;CAEhE,IAAI,CAAC,SAAS,CAAC,aAAa;EAC1B,OAAO,OAAO,KACZ,6FACF;EACA,OAAO;CACT;CAEA,MAAM,EAAE,uBAAuB,6BAC7B,MAAM,OAAO;CAEf,IAAI;CACJ,IAAI;CAEJ,IAAI;EACF,CAAC,SAAS,cAAc,MAAM,QAAQ,IAAI,CACxC,sBAAsB,aAAa,KAAK,GACxC,yBAAyB,aAAa,KAAK,CAC7C,CAAC;CACH,SAAS,KAAK;EACZ,OAAO,OAAO,KAAK,kBAAmB,IAAc,SAAS;EAC7D,OAAO;CACT;CAEA,IAAI,KAAK,QAAQ;EACf,QAAQ,IACN,KAAK,aAAa,QAAQ,OAAO,YAAY,WAAW,OAAO,2BAA2B,CAC5F;EACA,OAAO;CACT;CAGA,MAAM,iCAAiB,IAAI,IAAoB;CAC/C,MAAM,8BAAc,IAAI,IAAoB;CAE5C,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,QAAQ,OAAO,YAAY,OAAO,QAAQ,IAAI,KAAK;EACzD,IAAI,CAAC,MAAM;EACX,MAAM,QAAQ,OAAO,iBAAiB;EACtC,IAAI;GACF,MAAM,EAAE,MAAM,YAAY,eAAe,KAAK,MAAM,IAAI,OAAO,KAAK;GACpE,IAAI,OAAO,IAAI,eAAe,IAAI,OAAO,IAAI,IAAI;GACjD,IAAI,OAAO,QAAQ,OAAO,YAAY,IAAI,OAAO,OAAO,OAAO,IAAI;GACnE,IAAI,SAAS,OAAO;EACtB,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,WAAW,KAAK,KAAM,IAAc,SAAS;EAClE;CACF;CAGA,MAAM,QAAQ,IAAI,iBAAiB,GAAG;CACtC,KAAK,MAAM,YAAY,YAAY;EACjC,MAAM,QACH,SAAS,aAAa,eAAe,IAAI,SAAS,SAAS,OAC3D,SAAS,UAAU,YAAY,IAAI,SAAS,MAAM,MACnD,KAAA;EACF,IAAI,CAAC,MAAM;EAEX,MAAM,YAAY,wBAAwB,SAAS;EACnD,IAAI,MAAM,MAAM,KAAK,MAAM,SAAS,GAAG;GACrC,OAAO;GACP;EACF;EAEA,MAAM,OAAO,SAAS,6BAAY,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;EACtE,MAAM,SAAS,SAAS,QAAQ,SAAS,WAAW,IAAI,MAAM,GAAG,GAAG;EACpE,MAAM,KAAK,SAAS,QAAQ,IAAI,YAAY;EAC5C,MAAM,OACJ,MAAM,SACD,SACD,MAAM,UACH,UACD,MAAM,YACH,YACA;EAEX,IAAI;GACF,MAAM,kBAAkB,KAAK,MAAM;IACjC;IACA;IACA,MAAM;IACN,SAAS,GAAG,SAAS,WAAW,KAAK,IAAI;IACzC,WAAW,CAAC;IACZ;IACA,yBAAQ,IAAI,KAAK,GAAE,YAAY;GACjC,CAAC;GACD,MAAM,aAAa,MAAM,SAAS;GAClC,OAAO;EACT,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,YAAY,SAAS,GAAG,IAAK,IAAc,SAAS;EACzE;CACF;CAEA,OAAO;AACT;AAEA,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAC9C,YAAY,+EAA+E,EAC3F,SAAS,UAAU,kCAAkC,EACrD,OAAO,mBAAmB,sDAAsD,KAAK,EACrF,OAAO,aAAa,gDAAgD,EACpE,OAAO,iBAAiB,yBAAyB,EACjD,OAAO,mBAAmB,4CAA4C,EACtE,OAAO,eAAe,iDAAiD,EACvE,OAAO,aAAa,2DAA2D,EAC/E,OAAO,YAAY,wCAAwC,EAC3D,OACC,yBACA,yEACF,EACC,OACC,OACE,YACA,SAUG;CACH,MAAM,SAAS,KAAK,UAAU;CAG9B,MAAM,WAAmC,CAAC;CAC1C,IAAI,KAAK,UACP,KAAK,MAAM,QAAQ,KAAK,SAAS,MAAM,GAAG,GAAG;EAC3C,MAAM,CAAC,IAAI,OAAO,KAAK,MAAM,GAAG;EAChC,IAAI,MAAM,KAAK,SAAS,GAAG,KAAK,KAAK,IAAI,KAAK;CAChD;CAIF,IAAI,KAAK,WAAW,KAAK,SAAS,aAAa,YAAY;EACzD,MAAM,EAAE,yBAAyB,MAAM,OAAO;EAC9C,MAAM,WAAW,MAAM,qBAAqB,UAAU;EACtD,QAAQ,IAAI,KAAK,6CAA6C,CAAC;EAC/D,QAAQ,IAAI,4CAA4C;EACxD,QAAQ,IAAI,KAAK,mBAAmB,SAAS,gBAAgB,CAAC;EAC9D,QAAQ,IACN,KACE,mBAAmB,SAAS,cAAc,IAAI,SAAS,iBAAiB,qBAC1E,CACF;EACA,QAAQ,IAAI,KAAK,mBAAmB,SAAS,YAAY,CAAC;EAC1D,QAAQ,IAAI,KAAK,mBAAmB,SAAS,kBAAkB,CAAC;EAChE,IAAI,SAAS,yBAAyB,SAAS,GAAG;GAChD,QAAQ,IACN,KAAK,wBAAwB,SAAS,yBAAyB,OAAO,UAAU,CAClF;GACA,QAAQ,IACN,KAAK,SAAS,yBAAyB,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,IAAI,SAAS,yBAAyB,SAAS,KAAK,SAAS,IAC5H;EACF;EACA,IAAI,SAAS,eAAe,SAAS,GAAG;GACtC,QAAQ,IAAI,KAAK,sBAAsB,SAAS,eAAe,KAAK,IAAI,GAAG,CAAC;GAC5E,QAAQ,IACN,sBAAsB,SAAS,eAAe,KAAK,MAAM,GAAG,EAAE,OAAO,EAAE,KAAK,GAAG,EAAE,EACnF;EACF;EACA,IAAI,SAAS,cAAc,SAAS,GAClC,QAAQ,IACN,KAAK,qCAAqC,SAAS,cAAc,KAAK,IAAI,GAAG,CAC/E;EAEF,QAAQ,IAAI,KAAK,6BAA6B,SAAS,iBAAiB,KAAK,CAAC;EAC9E,QAAQ,IAAI,KAAK,0CAA0C,CAAC;EAC5D;CACF;CAEA,IAAI,CAAC,QACH,QAAQ,IAAI,KAAK,kBAAkB,KAAK,KAAK,IAAI,EAAE,IAAI,YAAY,CAAC;CAGtE,MAAM,SAAS,MAAM,UACnB,YACA;EACE,MAAM,KAAK;EACX,GAAI,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;EACjC,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;EACvC,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;EAC1C,GAAI,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;EACpC,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;EACtC;CACF,GACA,QAAQ,IAAI,iBACd;CAEA,IAAI,CAAC,QAAQ;EACX,QAAQ,IAAI,QAAQ,oBAAoB,CAAC;EACzC,QAAQ,IAAI,KAAK,6BAA6B,OAAO,kBAAkB,CAAC;EACxE,QAAQ,IAAI,KAAK,6BAA6B,OAAO,sBAAsB,CAAC;EAC5E,QAAQ,IAAI,KAAK,6BAA6B,OAAO,SAAS,CAAC;EAC/D,IAAI,OAAO,OAAO,SAAS,GAAG;GAC5B,QAAQ,IAAI,MAAM,aAAa,OAAO,OAAO,OAAO,GAAG,CAAC;GACxD,OAAO,OAAO,MAAM,GAAG,CAAC,EAAE,SAAS,MAAM,QAAQ,IAAI,MAAM,OAAO,GAAG,CAAC,CAAC;EACzE;CACF;AACF,CACF;;;AClqCF,SAAS,WAAW,SAAyB;CAC3C,OAAO,KAAK,KAAK,SAAS,YAAY,YAAY;AACpD;AAEA,eAAsB,eACpB,MACA,SACe;CACf,MAAM,OAAO,SAAS,KAAK,QAAQ,QAAQ,EAAE;CAC7C,MAAM,MAAM,KAAK,QAAQ,WAAW,QAAQ,IAAI;CAGhD,IAAI,KAAK,MACP,QAAQ,IAAI,oBAAoB,KAAK;CAGvC,MAAM,UAAU,WAAW,GAAG;CAG9B,IAAI,GAAG,WAAW,OAAO,GAAG;EAC1B,MAAM,WAAW,SAAS,GAAG,aAAa,SAAS,OAAO,EAAE,KAAK,GAAG,EAAE;EACtE,IAAI,CAAC,MAAM,QAAQ,GACjB,IAAI;GACF,QAAQ,KAAK,UAAU,CAAC;GACxB,QAAQ,IAAI,KAAK,+BAA+B,SAAS,EAAE,CAAC;GAC5D;EACF,QAAQ,CAER;CAEJ;CAGA,MAAM,cAAc,KAAK,QACvB,KAAK,QAAQ,IAAI,IAAI,OAAO,KAAK,GAAG,EAAE,QAAQ,GAC9C,0BACF;CAEA,MAAM,MAAyB;EAC7B,GAAG,QAAQ;EACX,gBAAgB;EAChB,gBAAgB,OAAO,IAAI;CAC7B;CAEA,IAAI,KAAK,MACP,IAAI,oBAAoB,KAAK;CAG/B,MAAM,QAAQ,MAAM,QAAQ,UAAU,CAAC,WAAW,GAAG;EACnD,UAAU;EACV,OAAO;EACP;CACF,CAAC;CACD,MAAM,MAAM;CAGZ,GAAG,UAAU,KAAK,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;CACvD,GAAG,cAAc,SAAS,OAAO,MAAM,GAAG,GAAG,OAAO;CAEpD,MAAM,WAAW,GAAG,SAAS;CAE7B,QAAQ,IAAI,QAAQ,oDAAoD,KAAK,KAAK,CAAC;CACnF,QAAQ,IAAI,KAAK,aAAa,KAAK,CAAC;CACpC,QAAQ,IAAI,KAAK,gDAAgD,SAAS,GAAG,KAAK,KAAK,CAAC;AAC1F;AAEA,SAAgB,gBAAgB,SAAwB;CAEtD,MAAM,UAAU,WADJ,QAAQ,IAAI,qBAAqB,WAAW,QAAQ,IAAI,CACtC;CAE9B,IAAI,CAAC,GAAG,WAAW,OAAO,GAAG;EAC3B,QAAQ,IAAI,KAAK,sBAAsB,CAAC;EACxC;CACF;CAEA,MAAM,MAAM,SAAS,GAAG,aAAa,SAAS,OAAO,EAAE,KAAK,GAAG,EAAE;CACjE,IAAI,MAAM,GAAG,GAAG;EACd,QAAQ,IAAI,KAAK,yCAAyC,CAAC;EAC3D;CACF;CAEA,IAAI;EACF,QAAQ,KAAK,KAAK,CAAC;EACnB,QAAQ,IAAI,QAAQ,wBAAwB,IAAI,EAAE,CAAC;CACrD,QAAQ;EACN,QAAQ,IAAI,KAAK,uCAAuC,CAAC;EACzD,IAAI;GACF,GAAG,WAAW,OAAO;EACvB,QAAQ,CAER;CACF;AACF;AAEA,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAAE,YACjD,+CACF;AAEA,cACG,QAAQ,OAAO,EACf,YAAY,2CAA2C,EACvD,OAAO,iBAAiB,4BAA4B,MAAM,EAC1D,OAAO,gBAAgB,sCAAsC,EAC7D,QAAQ,SAA0C,eAAe,IAAI,CAAC;AAEzE,cACG,QAAQ,QAAQ,EAChB,YAAY,gCAAgC,EAC5C,aAAa,gBAAgB,CAAC;;;AChHjC,MAAM,MAAM,IAAI,OAAO,EAAE;AAEzB,eAAsB,SACpB,MAMA,SACe;CACf,MAAM,MAAM,WAAW,QAAQ,IAAI;CACnC,MAAM,QAAQ,KAAK,SAAS;CAG5B,MAAM,UAAU,eADG,aAAa,GACQ,GAAG;EACzC,GAAI,KAAK,SAAS,KAAA,IAAY,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;EACrD,GAAI,KAAK,UAAU,KAAA,IAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;EACxD;CACF,CAAC;CAED,QAAQ,IAAI,GAAG;CACf,QAAQ,IAAI,gCAAgC;CAE5C,IAAI,KAAK,MAAM,QAAQ,IAAI,cAAc,KAAK,MAAM;CACpD,IAAI,KAAK,OAAO,QAAQ,IAAI,cAAc,KAAK,OAAO;CAEtD,QAAQ,IAAI,GAAG;CAEf,IAAI,QAAQ,WAAW,GAAG;EACxB,QAAQ,IAAI,0BAA0B;EACtC,QAAQ,IAAI,GAAG;EACf;CACF;CAEA,KAAK,MAAM,SAAS,SAClB,QAAQ,IACN,IAAI,MAAM,UAAU,IAAI,MAAM,MAAM,OAAO,EAAE,EAAE,IAAI,MAAM,KAAK,OAAO,EAAE,EAAE,IAAI,MAAM,KAAK,OAAO,EAAE,EAAE,IAAI,MAAM,SAC/G;CAGF,QAAQ,IAAI,GAAG;CACf,QAAQ,IAAI,IAAI,QAAQ,OAAO,OAAO,QAAQ,WAAW,IAAI,MAAM,MAAM,OAAO;CAChF,QAAQ,IAAI,GAAG;AACjB;AAEA,MAAa,eAAe,IAAI,QAAQ,OAAO,EAC5C,YAAY,kDAAkD,EAC9D,OAAO,iBAAiB,yBAAyB,EACjD,OAAO,mBAAmB,iBAAiB,EAC3C,OAAO,eAAe,2CAA2C,QAAQ,EACzE,OAAO,UAAU,0DAA0D,EAC3E,QAAQ,SACP,SAAS,MAAM,QAAQ,IAAI,iBAAiB,CAC9C;;;ACrDF,MAAM,SAAS;CAAC;CAAS;CAAQ;CAAQ;AAAO;AAEhD,SAAS,WAAW,OAAiB,MAAsB;CACzD,IAAI,UAAU,SAAS,OAAO,MAAM,IAAI;CACxC,IAAI,UAAU,QAAQ,OAAO,QAAQ,IAAI;CACzC,IAAI,UAAU,QAAQ,OAAO,KAAK,IAAI;CACtC,OAAO;AACT;AAEA,SAAS,WAAW,MAMP;CACX,OAAO;EACL,GAAI,KAAK,SAAS,OAAO,SAAS,KAAK,KAAK,IAAI,EAAE,OAAO,KAAK,MAAkB,IAAI,CAAC;EACrF,GAAI,KAAK,cAAc,KAAA,IAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;EACpE,GAAI,KAAK,UAAU,KAAA,IAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;EACxD,GAAI,KAAK,aAAa,KAAA,IAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;EACjE,OAAO,KAAK,SAAS;CACvB;AACF;AAEA,SAASC,aAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,cAAc,IAAI,QAAQ,MAAM,EAC1C,YAAY,iDAAiD,EAC7D,OAAO,mBAAmB,4CAA4C,EACtE,OAAO,sBAAsB,gDAAgD,EAC7E,OAAO,iBAAiB,6CAA6C,EACrE,OAAO,qBAAqB,6BAA6B,EACzD,OAAO,eAAe,qCAAqC,QAAQ,EACnE,OAAO,aAAa,kEAAkE,EACtF,OACC,OAAO,SAOD;CACJ,MAAM,QAAQ,WAAW,IAAI;CAE7B,IAAI,KAAK,SAAS;EAChB,MAAM,EAAE,kBAAkB,MAAM,OAAO;EACvC,MAAM,IAAI,cAAcA,WAAQ,GAAG,KAAK;EACxC,QAAQ,IAAI,KAAK,UAAU,EAAE,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM,OAAO,CAAC;EACxE,IAAI,EAAE,SAAS,QAAQ,IAAI,KAAK,KAAK,EAAE,QAAQ,KAAK,EAAE,QAAQ,CAAC;EAC/D,QAAQ,IAAI,aAAa;EACzB,KAAK,MAAM,OAAO,QAAQ;GACxB,MAAM,IAAI,EAAE,QAAQ;GACpB,IAAI,IAAI,GAAG,QAAQ,IAAI,OAAO,WAAW,KAAiB,IAAI,OAAO,CAAC,CAAC,EAAE,GAAG,GAAG;EACjF;EACA,QAAQ,IAAI,iBAAiB;EAC7B,KAAK,MAAM,CAAC,MAAM,MAAM,OAAO,QAAQ,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE,GAC9E,QAAQ,IAAI,OAAO,KAAK,OAAO,EAAE,EAAE,GAAG,GAAG;EAE3C,IAAI,EAAE,aAAa,SAAS,GAAG;GAC7B,QAAQ,IAAI,MAAM,kBAAkB,CAAC;GACrC,KAAK,MAAM,KAAK,EAAE,cAAc,QAAQ,IAAI,OAAO,EAAE,GAAG,KAAK,EAAE,UAAU,IAAI,EAAE,SAAS;EAC1F;EACA;CACF;CAEA,MAAM,EAAE,cAAc,MAAM,OAAO;CACnC,MAAM,UAAU,UAAUA,WAAQ,GAAG,KAAK;CAC1C,IAAI,QAAQ,WAAW,GAAG;EACxB,QAAQ,IAAI,QAAQ,0BAA0B,CAAC;EAC/C;CACF;CACA,KAAK,MAAM,KAAK,SAAS;EACvB,MAAM,MAAM,EAAE,UAAU,IAAI,KAAK,UAAU,EAAE,OAAO,MAAM;EAC1D,QAAQ,IACN,GAAG,EAAE,GAAG,IAAI,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,IAAI,EAAE,UAAU,KAChG;CACF;AACF,CACF;;;AClFF,SAASC,aAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,SAAS,KAAK,QAA6B;CACzC,IAAI,WAAW,MAAM,OAAO,QAAQ,GAAG;CACvC,IAAI,WAAW,QAAQ,OAAO,QAAQ,GAAG;CACzC,OAAO,MAAM,GAAG;AAClB;AAEA,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAC9C,YAAY,gFAAgF,EAC5F,OAAO,SAAS,sDAAsD,EACtE,OAAO,OAAO,SAA4B;CACzC,MAAM,EAAE,gBAAgB,qBAAqB,MAAM,OAAO;CAE1D,IAAI,KAAK,KAAK;EACZ,MAAM,UAAU,iBAAiBA,WAAQ,CAAC;EAC1C,QAAQ,IACN,QAAQ,SAAS,IACb,QAAQ,WAAW,QAAQ,OAAO,wBAAwB,IAC1D,QAAQ,iBAAiB,CAC/B;CACF;CAEA,MAAM,SAAS,MAAM,eAAeA,WAAQ,CAAC;CAE7C,QAAQ,IAAI,KAAK,cAAc,CAAC;CAChC,KAAK,MAAM,KAAK,OAAO,QACrB,QAAQ,IAAI,KAAK,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,OAAO,EAAE,EAAE,GAAG,EAAE,QAAQ;CAGpE,IAAI,OAAO,IAAI;EACb,MAAM,QAAQ,OAAO,OAAO,QAAQ,MAAM,EAAE,WAAW,MAAM,EAAE;EAC/D,QAAQ,IACN,QAAQ,IAAI,QAAQ,mBAAmB,MAAM,aAAa,IAAI,QAAQ,gBAAgB,CACxF;CACF,OAAO;EACL,QAAQ,IAAI,MAAM,4CAA4C,CAAC;EAC/D,QAAQ,WAAW;CACrB;AACF,CAAC;;;ACzCH,MAAM,QAAgB;CAAC;CAAS;CAAW;AAAK;AAEhD,eAAsB,WAAW,OAAe,MAAc,SAAiC;CAC7F,MAAM,MAAM,WAAW,QAAQ,IAAI;CACnC,IAAI,CAAC,MAAM,SAAS,IAAY,GAAG;EACjC,QAAQ,MAAM,MAAM,mBAAmB,KAAK,cAAc,MAAM,KAAK,IAAI,GAAG,CAAC;EAC7E,QAAQ,KAAK,CAAC;CAChB;CACA,aAAa,KAAK,OAAO,IAAY;CACrC,QAAQ,IAAI,QAAQ,KAAK,KAAK,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,CAAC;AACzD;AAEA,eAAsB,YAAY,SAAiC;CAEjE,MAAM,SAAS,cADH,WAAW,QAAQ,IAAI,CACH;CAChC,MAAM,UAAU,OAAO,QAAQ,OAAO,MAAM;CAE5C,IAAI,QAAQ,WAAW,GAAG;EACxB,QAAQ,IAAI,KAAK,wDAAwD,CAAC;EAC1E;CACF;CAEA,QAAQ,IAAI,KAAK,iBAAiB,CAAC;CACnC,KAAK,MAAM,CAAC,OAAO,SAAS,SAC1B,QAAQ,IAAI,KAAK,KAAK,KAAK,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,MAAM,CAAC;CAE1D,IAAI,OAAO,SACT,QAAQ,IAAI,KAAK,gBAAgB,OAAO,SAAS,CAAC;CAEpD,QAAQ,IAAI,EAAE;AAChB;AAEA,eAAsB,aAAa,OAAe,MAAc,SAAiC;CAC/F,MAAM,MAAM,WAAW,QAAQ,IAAI;CACnC,MAAM,EAAE,YAAY,MAAM,OAAO;CACjC,MAAM,OAAO,QAAQ,KAAK,KAAK;CAE/B,IADgB,SAAS,MAAM,IACrB,GACR,QAAQ,IAAI,QAAQ,KAAK,MAAM,IAAI,KAAK,aAAa,KAAK,EAAE,CAAC;MAE7D,QAAQ,IAAI,MAAM,KAAK,MAAM,IAAI,KAAK,gBAAgB,KAAK,EAAE,CAAC;AAElE;AAEA,MAAa,cAAc,IAAI,QAAQ,MAAM,EAAE,YAAY,kCAAkC;AAE7F,YACG,QAAQ,oBAAoB,EAC5B,YAAY,gCAAgC,MAAM,KAAK,IAAI,EAAE,EAAE,EAC/D,QAAQ,OAAe,SAAiB,WAAW,OAAO,MAAM,QAAQ,IAAI,iBAAiB,CAAC;AAEjG,YACG,QAAQ,MAAM,EACd,MAAM,MAAM,EACZ,YAAY,gCAAgC,EAC5C,aAAa,YAAY,QAAQ,IAAI,iBAAiB,CAAC;AAE1D,YACG,QAAQ,sBAAsB,EAC9B,YAAY,2CAA2C,EACvD,QAAQ,OAAe,SACtB,aAAa,OAAO,MAAM,QAAQ,IAAI,iBAAiB,CACzD;;;ACnDF,SAAS,aAAa,SAAyB;CAC7C,OAAO,KAAK,KAAK,SAAS,YAAY,oBAAoB;AAC5D;AAEA,SAAS,aAAa,SAAkC;CACtD,MAAM,IAAI,aAAa,OAAO;CAC9B,IAAI,CAAC,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC;CAC/B,IAAI;EACF,OAAO,KAAK,MAAM,GAAG,aAAa,GAAG,OAAO,CAAW;CACzD,QAAQ;EACN,OAAO,CAAC;CACV;AACF;AAEA,SAAS,cAAc,SAAiB,QAA6B;CACnE,MAAM,IAAI,aAAa,OAAO;CAC9B,GAAG,UAAU,KAAK,QAAQ,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC;CACjD,MAAM,WAAW,aAAa,OAAO;CACrC,SAAS,KAAK,MAAM;CACpB,cAAc,GAAG,QAAQ;AAC3B;AAEA,eAAsB,aACpB,MACA,MACA,SACe;CACf,MAAM,MAAM,WAAW,QAAQ,IAAI;CACnC,MAAM,cAAc,KAAK,KAAK,KAAK,aAAa,IAAI;CAEpD,IAAI,CAAC,KAAK,SAAS;EACjB,QAAQ,IAAI,KAAK,sCAAsC,KAAK,IAAI,GAAG,CAAC;EACpE,QAAQ,IAAI,KAAK,gBAAgB,aAAa,CAAC;EAC/C,QAAQ,IAAI,KAAK,yDAAyD,CAAC;EAC3E,QAAQ,IAAI,KAAK,+DAA+D,CAAC;EACjF,QAAQ,IAAI,KAAK,oCAAoC,KAAK,WAAW,CAAC;EACtE;CACF;CAEA,IAAI,CAAC,GAAG,WAAW,WAAW,GAC5B,QAAQ,KAAK,KAAK,eAAe,KAAK,+CAA+C,CAAC;MACjF;EACL,GAAG,OAAO,aAAa;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;EACvD,IAAI;GACF,MAAM,EAAE,sBAAsB,MAAM,OAAO;GAC3C,MAAM,kBAAkB,KAAK,IAAI;EACnC,QAAQ,CAER;CACF;CAKA,MAAM,kBAAkB,KAAK,KAAK,KAAK,YAAY,kBAAkB;CACrE,IAAI,GAAG,WAAW,eAAe,GAC/B,MAAM,aAAwB,kBAAkB,WAC7C,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,GAAG,QAAQ,MAAO,EAAwB,SAAS,IAAI,CAC1F;CAIF,MAAM,YAAY,KAAK,KAAK,KAAK,YAAY,YAAY;CACzD,IAAI,GAAG,WAAW,SAAS,GAAG;EAC5B,MAAM,EAAE,WAAW,eAAe,MAAM,OAAO;EAS/C,WAAW,KARG,UAAU,GACJ,EAAE,KAAK,OAAO;GAChC,GAAG;GACH,eAAe;IACb,GAAG,EAAE;IACL,UAAU,EAAE,cAAc,SAAS,QAAQ,OAAO,GAAG,SAAS,IAAI;GACpE;EACF,EACsB,CAAC;CACzB;CAGA,MAAM,EAAE,mBAAmB,uBAAuB,MAAM,OAAO;CAC/D,MAAM,OAAO,MAAM,kBAAkB,GAAG;CACxC,MAAM,YAAY,KAAK,QAAQ,MAAM,EAAE,SAAS,IAAI;CACpD,IAAI,UAAU,WAAW,KAAK,QAC5B,MAAM,mBAAmB,KAAK,SAAS;CAGzC,MAAM,QAAQ,SAAS;CACvB,MAAM,uBAAM,IAAI,KAAK,GAAE,YAAY;CAEnC,gBAAgB,KAAK;EACnB,WAAW;EACX;EACA,MAAM;EACN;EACA,SAAS;CACX,CAAC;CAED,cAAc,KAAK;EACjB;EACA,UAAU;EACV,UAAU;EACV,QAAQ;CACV,CAAC;CAED,QAAQ,IAAI,QAAQ,eAAe,KAAK,IAAI,EAAE,UAAU,CAAC;CACzD,QAAQ,IAAI,KAAK,yCAAyC,CAAC;CAC3D,QAAQ,IAAI,KAAK,+CAA+C,CAAC;AACnE;AAEA,eAAsB,oBAAoB,SAAiC;CAEzE,MAAM,UAAU,aADJ,WAAW,QAAQ,IAAI,CACH;CAEhC,IAAI,QAAQ,WAAW,GAAG;EACxB,QAAQ,IAAI,KAAK,wBAAwB,CAAC;EAC1C;CACF;CAEA,QAAQ,IAAI,KAAK,qBAAqB,QAAQ,OAAO,IAAI,CAAC;CAC1D,KAAK,MAAM,KAAK,SACd,QAAQ,IAAI,KAAK,KAAK,EAAE,SAAS,IAAI,EAAE,SAAS,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,QAAQ,CAAC;CAEzF,QAAQ,IAAI,EAAE;AAChB;AAEA,MAAa,cAAc,IAAI,QAAQ,MAAM,EAAE,YAAY,uBAAuB;AAElF,YACG,QAAQ,cAAc,EACtB,YAAY,sEAAsE,EAClF,OAAO,aAAa,uCAAuC,EAC3D,QAAQ,MAAc,SACrB,aAAa,MAAM,MAAM,QAAQ,IAAI,iBAAiB,CACxD;AAEF,YACG,QAAQ,eAAe,EACvB,YAAY,+BAA+B,EAC3C,aAAa,oBAAoB,QAAQ,IAAI,iBAAiB,CAAC;;;AClJlE,MAAM,SAAS;;8BAEF,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFnD,eAAsB,kBACpB,MACA,UACe;CACf,MAAM,SAAS;CAEf,IAAI,KAAK,QAAQ;EACf,MAAM,aAAa,KAAK,QAAQ,KAAK,MAAM;EAC3C,GAAG,cAAc,YAAY,QAAQ,OAAO;EAC5C,QAAQ,IAAI,QAAQ,iCAAiC,YAAY,CAAC;CACpE,OACE,QAAQ,IAAI,MAAM;AAEtB;AAEA,MAAa,wBAAwB,IAAI,QAAQ,iBAAiB,EAC/D,YAAY,wEAAwE,EACpF,OAAO,mBAAmB,wCAAwC,EAClE,QAAQ,SAA8B,kBAAkB,MAAM,QAAQ,IAAI,iBAAiB,CAAC;;;AC/F/F,SAAS,iBAAiB,QAA+B;CACvD,QAAQ,IAAI,KAAK,sBAAsB,CAAC;CACxC,QAAQ,IACN,KACE,KAAK,KAAK,OAAO,EAAE,EAAE,GAAG,QAAQ,OAAO,EAAE,EAAE,GAAG,QAAQ,OAAO,CAAC,EAAE,GAAG,QAAQ,OAAO,CAAC,EAAE,GAAG,QAAQ,OAAO,CAAC,EAAE,OAC5G,CACF;CACA,QAAQ,IAAI,KAAK,KAAK,IAAI,OAAO,EAAE,GAAG,CAAC;CACvC,KAAK,MAAM,KAAK,QAAQ;EACtB,MAAM,OAAO,EAAE,gBAAgB,KAAA,IAAY,OAAO,EAAE,WAAW,IAAI;EACnE,MAAM,UAAU,EAAE,UAAU,QAAQ;EACpC,MAAM,QAAQ,EAAE,SAAS;EACzB,QAAQ,IACN,KACE,KAAK,EAAE,GAAG,OAAO,EAAE,EAAE,GAAG,EAAE,MAAM,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,EAAE,GAAG,QAAQ,OAAO,CAAC,EAAE,GAAG,OACpH,CACF;CACF;CACA,QAAQ,IAAI,EAAE;AAChB;AAEA,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAAE,YAAY,+BAA+B;AAE9F,cACG,QAAQ,MAAM,EACd,YAAY,qCAAqC,EACjD,aAAa;CAGZ,iBADe,kBADC,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,CAEvC,CAAC;AACzB,CAAC;AAEH,cACG,QAAQ,kBAAkB,EAC1B,YAAY,mCAAmC,EAC/C,OAAO,eAAe,uBAAuB,GAAG,EAChD,OAAO,qBAAqB,+BAA+B,EAC3D,OAAO,iBAAiB,+BAA+B,EACvD,OAAO,WAAW,gCAAgC,EAClD,QAEG,IACA,OACA,SACG;CAUH,iBATgB,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GASnC;EAPxB;EACA;EACA,OAAO,SAAS,KAAK,OAAO,EAAE;EAC9B,GAAI,KAAK,gBAAgB,KAAA,IAAY,EAAE,aAAa,SAAS,KAAK,aAAa,EAAE,EAAE,IAAI,CAAC;EACxF,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;EAC1C,GAAI,KAAK,QAAQ,EAAE,SAAS,KAAK,IAAI,CAAC;CAEV,CAAC;CAC/B,QAAQ,IAAI,QAAQ,YAAY,GAAG,QAAQ,CAAC;AAC9C,CACF;AAEF,cACG,QAAQ,aAAa,EACrB,YAAY,+BAA+B,EAC3C,QAAQ,OAAe;CACtB,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAE7D,IAAI,CADa,kBAAkB,OACvB,EAAE,MAAM,MAAM,EAAE,OAAO,EAAE,GAAG;EACtC,QAAQ,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC;EAChD,QAAQ,KAAK,CAAC;CAChB;CACA,oBAAoB,SAAS,EAAE;CAC/B,QAAQ,IAAI,QAAQ,YAAY,GAAG,UAAU,CAAC;AAChD,CAAC;AAEH,cACG,QAAQ,OAAO,EACf,YAAY,mCAAmC,EAC/C,aAAa;CAEZ,gBADgB,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,CACtC;CACvB,QAAQ,IAAI,QAAQ,qCAAqC,CAAC;AAC5D,CAAC;;;ACjFH,MAAM,2BAAW,IAAI,IAAyB;AAS9C,SAAgB,UAAU,MAAuC;CAC/D,OAAO,SAAS,IAAI,IAAI;AAC1B;AAEA,SAAgB,cAA6B;CAC3C,OAAO,MAAM,KAAK,SAAS,OAAO,CAAC;AACrC;;;ACpBA,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAAE,YAAY,sBAAsB;AAErF,cACG,QAAQ,MAAM,EACd,YAAY,6BAA6B,EACzC,aAAa;CACZ,MAAM,UAAU,YAAY;CAC5B,IAAI,QAAQ,WAAW,GAAG;EACxB,QAAQ,IAAI,KAAK,wBAAwB,CAAC;EAC1C;CACF;CACA,QAAQ,IAAI,KAAK,qBAAqB,QAAQ,OAAO,IAAI,CAAC;CAC1D,KAAK,MAAM,KAAK,SACd,QAAQ,IAAI,KAAK,KAAK,EAAE,KAAK,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,IAAI,EAAE,eAAe,IAAI,CAAC;CAElF,QAAQ,IAAI,EAAE;AAChB,CAAC;AAEH,cACG,QAAQ,aAAa,EACrB,YAAY,qCAAqC,EACjD,QAAQ,SAAiB;CACxB,MAAM,SAAS,UAAU,IAAI;CAC7B,IAAI,CAAC,QAAQ;EACX,QAAQ,IAAI,MAAM,WAAW,KAAK,aAAa,CAAC;EAChD,QAAQ,KAAK,CAAC;CAChB;CACA,QAAQ,IAAI,KAAK,cAAc,OAAO,KAAK,GAAG,CAAC;CAC/C,QAAQ,IAAI,KAAK,cAAc,OAAO,SAAS,CAAC;CAChD,IAAI,OAAO,aAAa,QAAQ,IAAI,KAAK,kBAAkB,OAAO,aAAa,CAAC;CAChF,IAAI,OAAO,UAAU,QACnB,QAAQ,IAAI,KAAK,gBAAgB,OAAO,SAAS,KAAK,IAAI,GAAG,CAAC;CAEhE,QAAQ,IAAI,EAAE;AAChB,CAAC;;;AClCH,eAAsB,WACpB,aACA,SACe;CAEf,MAAM,OAAO,MAAM,WADP,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GACtB;EAAE;EAAa,UAAU,QAAQ;CAAS,CAAC;CAC9E,QAAQ,IAAI,QAAQ,mBAAmB,KAAK,KAAK,EAAE,GAAG,CAAC;CACvD,QAAQ,IAAI,KAAK,mBAAmB,KAAK,aAAa,CAAC;CACvD,QAAQ,IAAI,KAAK,oBAAoB,KAAK,OAAO,eAAe,GAAG,CAAC;CACpE,QAAQ,IAAI,KAAK,mBAAmB,KAAK,UAAU,CAAC;CACpD,QAAQ,IAAI,KAAK,oBAAoB,KAAK,cAAc,gBAAgB,eAAe,GAAG,CAAC;CAC3F,QAAQ,IAAI,KAAK,oBAAoB,KAAK,cAAc,IAAI,eAAe,GAAG,CAAC;CAC/E,IAAI,KAAK,cAAc,SAAS,SAAS,GAAG;EAC1C,QAAQ,IAAI,KAAK,kBAAkB,CAAC;EACpC,KAAK,MAAM,MAAM,KAAK,cAAc,UAAU;GAC5C,QAAQ,IAAI,KAAK,KAAK,GAAG,SAAS,IAAI,GAAG,QAAQ,CAAC;GAClD,QAAQ,IAAI,KAAK,UAAU,GAAG,UAAU,CAAC;EAC3C;CACF;AACF;AAEA,eAAsB,gBAA+B;CAEnD,MAAM,QAAQ,eADF,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,CACzB;CAChC,IAAI,MAAM,WAAW,GAAG;EACtB,QAAQ,IAAI,KAAK,sDAAsD,CAAC;EACxE;CACF;CACA,QAAQ,IAAI,KAAK,oBAAoB,MAAM,OAAO,IAAI,CAAC;CACvD,KAAK,MAAM,KAAK,OAAO;EACrB,MAAM,MACJ,IAAI,OAAO,KAAK,MAAM,EAAE,WAAW,EAAE,CAAC,IAAI,IAAI,OAAO,KAAK,KAAK,MAAM,EAAE,WAAW,EAAE,CAAC;EACvF,MAAM,aAAa,IAAI,KAAK,EAAE,QAAQ,EAAE,QAAQ,IAAI,KAAK,IAAI;EAC7D,MAAM,WAAW,KAAK,IAAI,GAAG,KAAK,KAAK,aAAa,KAAU,CAAC;EAC/D,QAAQ,IAAI,KAAK,KAAK,EAAE,IAAI,CAAC;EAC7B,QAAQ,IAAI,KAAK,KAAK,EAAE,aAAa,CAAC;EACtC,QAAQ,IACN,KACE,MAAM,IAAI,IAAI,EAAE,SAAS,SAAS,EAAE,OAAO,eAAe,EAAE,MAAM,EAAE,SAAS,IAAI,SAAS,QAC5F,CACF;EACA,QAAQ,IAAI,EAAE;CAChB;AACF;AAEA,eAAsB,cAAc,QAAgB,SAA8C;CAChG,MAAM,MAAM,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CACzD,MAAM,WAAW,SAAS,QAAQ,UAAU,EAAE;CAC9C,IAAI,MAAM,QAAQ,KAAK,WAAW,KAAK,WAAW,KAAK;EACrD,QAAQ,MAAM,MAAM,qCAAqC,CAAC;EAC1D,QAAQ,KAAK,CAAC;CAChB;CAEA,IAAI,CAAC,MADiB,mBAAmB,KAAK,QAAQ,QAAQ,GAChD;EACZ,QAAQ,MAAM,MAAM,WAAW,OAAO,YAAY,CAAC;EACnD,QAAQ,KAAK,CAAC;CAChB;CACA,QAAQ,IAAI,QAAQ,UAAU,KAAK,MAAM,EAAE,uBAAuB,KAAK,OAAO,QAAQ,CAAC,EAAE,EAAE,CAAC;AAC9F;AAEA,eAAsB,cAAc,QAA+B;CAGjE,IAAI,CAAC,MADmB,WADZ,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GACjB,MAAM,GAC9B;EACd,QAAQ,MAAM,MAAM,WAAW,OAAO,YAAY,CAAC;EACnD,QAAQ,KAAK,CAAC;CAChB;CACA,QAAQ,IAAI,QAAQ,UAAU,KAAK,MAAM,EAAE,WAAW,CAAC;AACzD;AAEA,MAAa,cAAc,IAAI,QAAQ,MAAM,EAAE,YAAY,+BAA+B;AAE1F,YACG,QAAQ,mBAAmB,EAC3B,YAAY,iDAAiD,EAC7D,eAAe,qBAAqB,8BAA8B,EAClE,QAAQ,aAAqB,SAA+B,WAAW,aAAa,IAAI,CAAC;AAE5F,YACG,QAAQ,QAAQ,EAChB,YAAY,qCAAqC,EACjD,aAAa,cAAc,CAAC;AAE/B,YACG,QAAQ,iBAAiB,EACzB,YAAY,iCAAiC,EAC7C,eAAe,kBAAkB,gBAAgB,EACjD,QAAQ,QAAgB,SAA+B,cAAc,QAAQ,IAAI,CAAC;AAErF,YACG,QAAQ,iBAAiB,EACzB,YAAY,uBAAuB,EACnC,QAAQ,WAAmB,cAAc,MAAM,CAAC;;;ACtFnD,eAAsB,gBACpB,MACA,SASe;CACf,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAC7D,MAAM,eAAuC,CAAC;CAC9C,IAAI,QAAQ,WAAW,aAAa,oBAAoB,QAAQ;CAChE,IAAI,QAAQ,aAAa,aAAa,0BAA0B,QAAQ;CACxE,IAAI,QAAQ,UAAU,aAAa,uBAAuB,QAAQ;CAClE,IAAI,QAAQ,QAAQ,aAAa,iBAAiB,QAAQ;CAC1D,IAAI,QAAQ,WAAW,aAAa,oBAAoB,QAAQ;CAEhE,MAAM,MAAM,MAAM,SAAS,SAAS,QAAQ,UAAU,MAAM;EAC1D,YAAY,QAAQ;EACpB;CACF,CAAC;CAED,QAAQ,IAAI,QAAQ,mCAAmC,KAAK,IAAI,EAAE,GAAG,CAAC;CACtE,QAAQ,IAAI,KAAK,iBAAiB,IAAI,UAAU,CAAC;CACjD,QAAQ,IAAI,KAAK,iBAAiB,IAAI,MAAM,CAAC;CAC7C,QAAQ,IAAI,KAAK,iBAAiB,IAAI,YAAY,CAAC;CACnD,QAAQ,IAAI,KAAK,iBAAiB,IAAI,aAAa,SAAS,CAAC;CAE7D,IAAI,QAAQ,WAAW,SAAS,WAAW,GAAG;EAC5C,QAAQ,IAAI,KAAK,sEAAsE,CAAC;EACxF,QAAQ,IAAI,KAAK,2CAA2C,CAAC;CAC/D;AACF;AAEA,eAAsB,cAAc,SAA8D;CAEhG,IAAI,OAAO,MAAM,kBADD,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,CACnB;CAE1C,IAAI,QAAQ,MAAM,OAAO,KAAK,QAAQ,MAAM,EAAE,SAAS,QAAQ,IAAI;CACnE,IAAI,QAAQ,UAAU,OAAO,KAAK,QAAQ,MAAM,EAAE,aAAa,QAAQ,QAAQ;CAE/E,IAAI,KAAK,WAAW,GAAG;EACrB,QAAQ,IAAI,KAAK,yEAAyE,CAAC;EAC3F;CACF;CAEA,MAAM,MAAM,KAAK,IAAI;CACrB,QAAQ,IAAI,KAAK,0BAA0B,KAAK,OAAO,IAAI,CAAC;CAC5D,KAAK,MAAM,KAAK,MAAM;EACpB,MAAM,YAAY,EAAE,YAChB,KAAK,OAAO,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ,IAAI,QAAQ,OAAU,IAAK,IACrE;EACJ,MAAM,YAAY,cAAc,OAAO,GAAG,UAAU,eAAe;EACnE,MAAM,eACJ,EAAE,cAAc,QAAQ,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ,IAAI,MAAM,OAAU,KAAK;EAEjF,QAAQ,IAAI,KAAK,KAAK,EAAE,IAAI,CAAC;EAC7B,QAAQ,IAAI,KAAK,KAAK,EAAE,SAAS,KAAK,EAAE,KAAK,IAAI,EAAE,OAAO,EAAE,CAAC;EAC7D,QAAQ,IACN,KACE,aAAa,EAAE,gBAAgB,gBAAgB,YAAY,eAAe,kBAAkB,IAC9F,CACF;EACA,QAAQ,IAAI,KAAK,iBAAiB,EAAE,eAAe,KAAK,CAAC;EACzD,QAAQ,IAAI,EAAE;CAChB;AACF;AAEA,eAAsB,cAAc,IAA2B;CAC7D,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAC7D,IAAI;EACF,MAAM,OAAO,SAAS,EAAE;EACxB,QAAQ,IAAI,QAAQ,kBAAkB,KAAK,EAAE,EAAE,SAAS,CAAC;CAC3D,QAAQ;EACN,QAAQ,MAAM,MAAM,6BAA6B,IAAI,CAAC;EACtD,QAAQ,KAAK,CAAC;CAChB;AACF;AAEA,eAAsB,aAAa,SAAwD;CACzF,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAC7D,IAAI,QAAQ,IAAI;EAEd,MAAM,OAAM,MADO,kBAAkB,OAAO,GAC3B,MAAM,MAAM,EAAE,OAAO,QAAQ,EAAE;EAChD,IAAI,CAAC,KAAK;GACR,QAAQ,MAAM,MAAM,6BAA6B,QAAQ,IAAI,CAAC;GAC9D,QAAQ,KAAK,CAAC;EAChB;EACA,QAAQ,IAAI,KAAK,iBAAiB,IAAI,GAAG,mCAAmC,CAAC;EAC7E,QAAQ,IAAI,KAAK,oEAAoE,CAAC;EACtF;CACF;CACA,MAAM,SAAS,MAAM,2BACnB,SACA,YAAY;EACV,MAAM,IAAI,MAAM,2DAA2D;CAC7E,GACA,EACF;CACA,QAAQ,IAAI,KAAK,cAAc,OAAO,QAAQ,OAAO,eAAe,OAAO,OAAO,QAAQ,CAAC;CAC3F,IAAI,OAAO,QAAQ,SAAS,GAAG,QAAQ,IAAI,QAAQ,cAAc,OAAO,QAAQ,KAAK,IAAI,GAAG,CAAC;CAC7F,IAAI,OAAO,OAAO,SAAS,GAAG,QAAQ,IAAI,MAAM,aAAa,OAAO,OAAO,KAAK,IAAI,GAAG,CAAC;AAC1F;AAEA,MAAa,cAAc,IAAI,QAAQ,MAAM,EAAE,YAC7C,6EACF;AAEA,YACG,QAAQ,iBAAiB,EACzB,YAAY,6CAA6C,EACzD,eAAe,yBAAyB,2CAA2C,EACnF,eAAe,uBAAuB,yCAAyC,EAC/E,OAAO,wBAAwB,iCAAiC,EAChE,OAAO,2BAA2B,+BAA+B,EACjE,OAAO,qBAAqB,yBAAyB,EACrD,OAAO,kBAAkB,0BAA0B,EACnD,OAAO,qBAAqB,4BAA4B,EACxD,OACC,OACE,MACA,SASG;CACH,MAAM,gBAAgB,MAAM,IAAI;AAClC,CACF;AAEF,YACG,QAAQ,QAAQ,EAChB,YAAY,6BAA6B,EACzC,OAAO,iBAAiB,yBAAyB,EACjD,OAAO,yBAAyB,oBAAoB,EACpD,OAAO,OAAO,SAA+C;CAC5D,MAAM,cAAc,IAAI;AAC1B,CAAC;AAEH,YACG,QAAQ,aAAa,EACrB,YAAY,kCAAkC,EAC9C,OAAO,OAAO,OAAe;CAC5B,MAAM,cAAc,EAAE;AACxB,CAAC;AAEH,YACG,QAAQ,OAAO,EACf,YAAY,mCAAmC,EAC/C,OAAO,SAAS,kCAAkC,EAClD,OAAO,aAAa,qCAAqC,EACzD,OAAO,OAAO,SAAyC;CACtD,MAAM,aAAa,IAAI;AACzB,CAAC;;;ACtKH,eAAsB,UACpB,MACA,UACA,SACmD;CACnD,MAAM,MAAM,WAAW,QAAQ,IAAI;CACnC,MAAM,cAAc,KAAK,KAAK,KAAK,aAAa,IAAI;CAEpD,IAAI,CAAC,GAAG,WAAW,WAAW,GAAG;EAC/B,MAAM,MAAM,aAAa,KAAK;EAC9B,QAAQ,MAAM,MAAM,GAAG,CAAC;EACxB,OAAO,EAAE,OAAO,IAAI;CACtB;CAEA,IAAI,CAAC,GAAG,WAAW,QAAQ,GAAG;EAC5B,MAAM,MAAM,mBAAmB;EAC/B,QAAQ,MAAM,MAAM,GAAG,CAAC;EACxB,OAAO,EAAE,OAAO,IAAI;CACtB;CAEA,MAAM,iBAAiB,KAAK,KAAK,aAAa,aAAa;CAC3D,GAAG,UAAU,gBAAgB,EAAE,WAAW,KAAK,CAAC;CAEhD,MAAM,WAAW,KAAK,SAAS,QAAQ;CACvC,MAAM,OAAO,KAAK,KAAK,gBAAgB,QAAQ;CAE/C,IAAI,GAAG,WAAW,IAAI,GAAG;EACvB,MAAM,MAAM,8BAA8B;EAC1C,QAAQ,IAAI,KAAK,GAAG,CAAC;EACrB,OAAO,EAAE,UAAU,KAAK;CAC1B;CAEA,GAAG,aAAa,UAAU,IAAI;CAC9B,QAAQ,IAAI,QAAQ,YAAY,KAAK,QAAQ,EAAE,MAAM,KAAK,IAAI,GAAG,CAAC;CAClE,OAAO,EAAE,UAAU,KAAK;AAC1B;AAqBA,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAC9C,YAAY,uEAAuE,EACnF,SAAS,UAAU,eAAe,EAClC,SAAS,UAAU,4BAA4B,EAC/C,OAAO,OAAO,MAAc,SAAiB;CAC5C,MAAM,UAAU,MAAM,MAAM,QAAQ,IAAI,iBAAiB;AAC3D,CAAC;;;AC7DH,MAAa,kBAAkB,IAAI,QAAQ,UAAU,EAAE,YAAY,wBAAwB;AAE3F,gBACG,QAAQ,MAAM,EACd,OAAO,yBAAyB,oBAAoB,EACpD,QAAQ,SAAgC;CAEvC,MAAM,YAAY,cADF,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GACpB,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC,CAAC;CACzF,IAAI,UAAU,WAAW,GAAG;EAC1B,QAAQ,IAAI,KAAK,qBAAqB,CAAC;EACvC;CACF;CACA,KAAK,MAAM,KAAK,WACd,QAAQ,IAAI,KAAK,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,KAAK,EAAE,SAAS;AAEhE,CAAC;AAEH,gBAAgB,QAAQ,UAAU,EAAE,QAAQ,OAAe;CAEzD,MAAM,OAAO,YADG,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GAC3B,EAAE;CACpC,IAAI,CAAC,MAAM;EACT,QAAQ,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;EACjD,QAAQ,KAAK,CAAC;CAChB;CACA,QAAQ,IAAI,KAAK,YAAY,KAAK,SAAS,CAAC;CAC5C,QAAQ,IAAI,aAAa,KAAK,SAAS,cAAc,KAAK,UAAU;CACpE,QAAQ,IAAI,cAAc,KAAK,UAAU,KAAK,IAAI,KAAK,kBAAkB;CACzE,QAAQ,IAAI,OAAO,KAAK,IAAI;AAC9B,CAAC;AAED,gBACG,QAAQ,cAAc,EACtB,OAAO,iBAAiB,+BAA+B,EACvD,OAAO,OAAO,IAAY,SAA4B;CACrD,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAC7D,MAAM,OAAO,YAAY,SAAS,EAAE;CACpC,IAAI,CAAC,MAAM;EACT,QAAQ,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;EACjD,QAAQ,KAAK,CAAC;CAChB;CACA,MAAM,OAAO,KAAK,OAAO,MAAM,2BAA2B,SAAS,KAAK,IAAI,IAAI,CAAC;CACjF,QAAQ,IAAI,KAAK,YAAY,YAAY,KAAK,SAAS,IAAI,GAAG,CAAC;CAC/D,QAAQ,IAAI,YAAY,KAAK,MAAM,IAAI,CAAC;AAC1C,CAAC;AAEH,gBACG,QAAQ,aAAa,EACrB,OAAO,yBAAyB,YAAY,SAAS,EACrD,OAAO,uBAAuB,cAAc,EAC5C,QAAQ,IAAY,SAAiD;CACpE,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAE7D,IADiB,YAAY,SAAS,EAC3B,GAAG;EACZ,QAAQ,MAAM,MAAM,aAAa,GAAG,iBAAiB,CAAC;EACtD,QAAQ,KAAK,CAAC;CAChB;CAUA,cAAc,SAAS;EARrB;EACA,SAAS,KAAK,WAAW,eAAe;EACxC,UAAU,KAAK;EACf,WAAW,CAAC;EACZ,UAAU;EACV,4BAAW,IAAI,KAAK,GAAE,YAAY;EAClC,MAAM;CAEkB,CAAC;CAC3B,QAAQ,IAAI,QAAQ,eAAe,GAAG,yBAAyB,KAAK,SAAS,EAAE,CAAC;AAClF,CAAC;AAEH,gBAAgB,QAAQ,aAAa,EAAE,QAAQ,OAAe;CAG5D,IADgB,eADA,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GACrB,EAC9B,GACR,QAAQ,IAAI,QAAQ,eAAe,GAAG,UAAU,CAAC;MAC5C;EACL,QAAQ,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;EACjD,QAAQ,KAAK,CAAC;CAChB;AACF,CAAC;;;ACxED,MAAa,kBAAkB,IAAI,QAAQ,UAAU,EAAE,YAAY,wBAAwB;AAE3F,gBACG,QAAQ,MAAM,EACd,YAAY,oBAAoB,EAChC,aAAa;CACZ,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAC7D,MAAM,YAAY,cAAc,OAAO;CACvC,MAAM,cAAc,gBAAgB,OAAO;CAE3C,IAAI,UAAU,WAAW,GAAG;EAC1B,QAAQ,IAAI,KAAK,qBAAqB,CAAC;EACvC;CACF;CAEA,KAAK,MAAM,OAAO,WAAW;EAC3B,MAAM,QAAQ,YAAY,QAAQ,MAAM,EAAE,eAAe,IAAI,EAAE,EAAE;EACjE,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,EAAE,KAAK,IAAI,KAAK,KAAK,IAAI,MAAM,OAAO,UAAU,MAAM,UAAU;CAC9F;AACF,CAAC;AAEH,gBACG,QAAQ,aAAa,EACrB,YAAY,gCAAgC,EAC5C,OAAO,iBAAiB,uBAAuB,EAC/C,QAAQ,IAAY,SAA4B;CAC/C,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAG7D,IADiB,YAAY,SAAS,EAC3B,GAAG;EACZ,QAAQ,MAAM,MAAM,aAAa,GAAG,iBAAiB,CAAC;EACtD,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,MAAgB;EACpB;EACA,MAAM,KAAK,QAAQ;EACnB,OAAO;GACL;IAAE,KAAK;IAAG,YAAY;IAAS,eAAe;GAAK;GACnD;IAAE,KAAK;IAAG,YAAY;IAAc,eAAe;GAAK;GACxD;IAAE,KAAK;IAAG,YAAY;IAAc,eAAe;GAAK;EAC1D;EACA,4BAAW,IAAI,KAAK,GAAE,YAAY;CACpC;CAEA,cAAc,SAAS,GAAG;CAC1B,QAAQ,IAAI,QAAQ,eAAe,GAAG,iBAAiB,IAAI,MAAM,OAAO,OAAO,CAAC;CAChF,QAAQ,IAAI,KAAK,2BAA2B,GAAG,uCAAuC,CAAC;AACzF,CAAC;AAEH,gBACG,QAAQ,eAAe,EACvB,YAAY,yCAAyC,EACrD,eAAe,mBAAmB,uBAAuB,EACzD,eAAe,mBAAmB,aAAa,EAC/C,OAAO,OAAO,MAAc,SAA8C;CACzE,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAE7D,MAAM,MAAM,YAAY,SAAS,KAAK,QAAQ;CAC9C,IAAI,CAAC,KAAK;EACR,QAAQ,MAAM,MAAM,aAAa,KAAK,SAAS,YAAY,CAAC;EAC5D,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,eAAe,UAAU,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC;CAClF,MAAM,uBAAM,IAAI,KAAK,GAAE,YAAY;CAEnC,MAAM,gBAAgB,SAAS;EAC7B,IAAI;EACJ,YAAY,KAAK;EACjB;EACA,cAAc,KAAK;EACnB,YAAY;EACZ,QAAQ;EACR,aAAa;EACb,gBAAgB,CAAC;CACnB,CAAC;CAED,QAAQ,IAAI,QAAQ,cAAc,KAAK,MAAM,gBAAgB,IAAI,KAAK,EAAE,CAAC;CACzE,QAAQ,IAAI,KAAK,kBAAkB,cAAc,CAAC;AACpD,CAAC;AAEH,gBACG,QAAQ,QAAQ,EAChB,YAAY,wBAAwB,EACpC,OAAO,iBAAiB,yBAAyB,EACjD,QAAQ,SAA4B;CAEnC,IAAI,cAAc,gBADF,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,CACpB;CAEzC,IAAI,KAAK,MACP,cAAc,YAAY,QAAQ,MAAM,EAAE,SAAS,KAAK,IAAI;CAG9D,IAAI,YAAY,WAAW,GAAG;EAC5B,QAAQ,IAAI,KAAK,uBAAuB,CAAC;EACzC;CACF;CAEA,KAAK,MAAM,KAAK,aAAa;EAC3B,MAAM,WAAW,QAAQ,EAAE;EAC3B,MAAM,WAAW,EAAE,aAAa,cAAc,EAAE,WAAW,MAAM,GAAG,EAAE,MAAM;EAC5E,QAAQ,IACN,KAAK,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,aAAa,SAAS,EAAE,WAAW,KAAK,EAAE,OAAO,KAAK,WAAW,UACpG;CACF;AACF,CAAC;AAEH,gBACG,QAAQ,KAAK,EACb,YAAY,0CAA0C,EACtD,OAAO,aAAa,yCAAyC,EAC7D,OAAO,OAAO,SAA+B;CAC5C,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAC7D,MAAM,yBAAQ,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;CAElD,IAAI,KAAK,QAAQ;EACf,MAAM,cAAc,gBAAgB,OAAO,EAAE,QAAQ,MAAM,EAAE,WAAW,QAAQ;EAChF,QAAQ,IAAI,KAAK,aAAa,YAAY,OAAO,0BAA0B,OAAO,CAAC;EACnF,KAAK,MAAM,KAAK,aACd,QAAQ,IAAI,oBAAoB,EAAE,GAAG,IAAI,EAAE,aAAa,SAAS,EAAE,YAAY,EAAE;EAEnF;CACF;CAEA,MAAM,SAAS,MAAM,iBAAiB,SAAS,KAAK;CACpD,QAAQ,IACN,QACE,qBAAqB,OAAO,KAAK,SAAS,OAAO,UAAU,cAAc,OAAO,OAAO,OAAO,QAChG,CACF;CACA,IAAI,OAAO,OAAO,SAAS,GACzB,KAAK,MAAM,KAAK,OAAO,QACrB,QAAQ,MAAM,MAAM,YAAY,GAAG,CAAC;AAG1C,CAAC;;;AChJH,MAAa,eAAe,IAAI,QAAQ,OAAO,EAAE,YAAY,wBAAwB;AAErF,aACG,QAAQ,iBAAiB,EACzB,YAAY,iCAAiC,EAC7C,eAAe,iBAAiB,WAAW,EAC3C,OACC,mBACA,uFACF,EACC,OAAO,mBAAmB,eAAe,IAAI,EAC7C,OAAO,kBAAkB,oBAAoB,IAAI,EACjD,OACC,OAAO,MAAc,SAAuE;CAC1F,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAE7D,MAAM,aAAa,KAAK,SAAS,kBAC9B,MAAM,GAAG,EACT,KAAK,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,OAAO,EACd,KAAK,SAAS;EACb,MAAM,QAAQ,KAAK,MAAM,KAAK;EAC9B,MAAM,YAAY,WAAW,MAAM,MAAM,SAAS,MAAM,GAAG;EAC3D,MAAM,WAAW,WAAW,MAAM,MAAM,SAAS,MAAM,GAAG;EAE1D,OAAO;GAAE,aADW,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,KAAK;GAC9B;GAAU;EAAU;CAC5C,CAAC;CAEH,IAAI;EACF,MAAM,QAAQ,MAAM,cAAc,SAAS;GACzC;GACA,UAAU,KAAK;GACf;GACA,YAAY,WAAW,KAAK,GAAG;GAC/B,gBAAgB,SAAS,KAAK,OAAO,EAAE;EACzC,CAAC;EACD,QAAQ,IAAI,QAAQ,WAAW,KAAK,MAAM,WAAW,EAAE,WAAW,CAAC;EACnE,QAAQ,IAAI,KAAK,gBAAgB,MAAM,MAAM,QAAQ,CAAC,EAAE,GAAG,MAAM,UAAU,CAAC;EAC5E,QAAQ,IAAI,KAAK,kBAAkB,MAAM,YAAY,CAAC;EACtD,QAAQ,IAAI,KAAK,WAAW,MAAM,UAAU,CAAC;CAC/C,SAAS,KAAK;EACZ,QAAQ,MAAM,MAAM,6BAA8B,IAAc,SAAS,CAAC;EAC1E,QAAQ,KAAK,CAAC;CAChB;AACF,CACF;AAEF,aACG,QAAQ,MAAM,EACd,YAAY,aAAa,EACzB,OAAO,iBAAiB,yBAAyB,EACjD,QAAQ,SAA4B;CAEnC,MAAM,SAAS,WADC,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GAC1B,KAAK,IAAI;CAE5C,IAAI,OAAO,WAAW,GAAG;EACvB,QAAQ,IAAI,KAAK,kBAAkB,CAAC;EACpC;CACF;CAEA,KAAK,MAAM,KAAK,QACd,QAAQ,IACN,KAAK,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,SAAS,IAAI,EAAE,MAAM,QAAQ,CAAC,EAAE,GAAG,EAAE,SAAS,KAAK,EAAE,OAAO,KAAK,EAAE,YAC/G;AAEJ,CAAC;AAEH,aACG,QAAQ,mBAAmB,EAC3B,YAAY,oBAAoB,EAChC,QAAQ,gBAAwB;CAE/B,MAAM,QAAQ,UADE,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GAC5B,WAAW;CAE5C,IAAI,CAAC,OAAO;EACV,QAAQ,MAAM,MAAM,UAAU,YAAY,YAAY,CAAC;EACvD,QAAQ,KAAK,CAAC;CAChB;CAEA,QAAQ,IAAI,KAAK,UAAU,MAAM,aAAa,CAAC;CAC/C,QAAQ,IAAI,aAAa,MAAM,KAAK,UAAU,MAAM,UAAU;CAC9D,QAAQ,IAAI,WAAW,MAAM,OAAO,iBAAiB,MAAM,YAAY;CACvE,QAAQ,IACN,aAAa,MAAM,SAAS,QAAQ,CAAC,EAAE,SAAS,MAAM,IAAI,QAAQ,CAAC,EAAE,WAAW,MAAM,MAAM,QAAQ,CAAC,EAAE,GAAG,MAAM,UAClH;CACA,KAAK,MAAM,QAAQ,MAAM,WACvB,QAAQ,IAAI,OAAO,KAAK,YAAY,IAAI,KAAK,SAAS,KAAK,KAAK,UAAU,KAAK,KAAK,OAAO;AAE/F,CAAC;;;ACtFH,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAAE,YAAY,wBAAwB;AAEvF,cACG,QAAQ,MAAM,EACd,YAAY,cAAc,EAC1B,OAAO,iBAAiB,yBAAyB,EACjD,OAAO,qBAAqB,kBAAkB,EAC9C,OAAO,yBAAyB,oBAAoB,EACpD,OAAO,OAAO,SAAgE;CAE7E,MAAM,UAAU,MAAM,eADN,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GACf;EAC5C,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;EACvC,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;EAC7C,GAAI,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;CACrD,CAAC;CAED,IAAI,QAAQ,WAAW,GAAG;EACxB,QAAQ,IAAI,KAAK,mBAAmB,CAAC;EACrC;CACF;CAEA,KAAK,MAAM,EAAE,MAAM,QAAQ,OAAO,SAAS;EAMzC,MAAM,OAJJ,EAAE,UACF,EAAE,0BAAS,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,KAC/C,EAAE,WAAW,cACb,EAAE,WAAW,WACO,WAAW;EACjC,QAAQ,IACN,KAAK,KAAK,EAAE,EAAE,EAAE,KAAK,KAAK,KAAK,EAAE,MAAM,KAAK,EAAE,OAAO,GAAG,EAAE,SAAS,GAAG,EAAE,WAAW,MAAM,EAAE,aAAa,KAAK,MAC/G;CACF;AACF,CAAC;AAEH,cACG,QAAQ,eAAe,EACvB,YAAY,gCAAgC,EAC5C,eAAe,mBAAmB,cAAc,EAChD,OAAO,wBAAwB,aAAa,EAC5C,OAAO,yBAAyB,oCAAoC,QAAQ,EAC5E,OAAO,qBAAqB,UAAU,EACtC,OACC,OACE,MACA,SACG;CACH,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAC7D,MAAM,yBAAQ,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;CAClD,MAAM,QAAQ,aAAa,OAAO;CAClC,MAAM,WAAY,KAAK,YAAmC;CAE1D,MAAM,KAAK,aAAa,MADD,YAAY,SAAS,IAAI,CAChB;CAEhC,MAAM,SAAiB;EACrB;EACA,OAAO,KAAK;EACZ,QAAQ;EACR;EACA,GAAI,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;EACnD,SAAS;EACT,QAAQ,WAAW,OAAO,UAAU,KAAK;EACzC,GAAI,KAAK,cAAc,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;CAC9D;CAEA,MAAM,aAAa,SAAS,MAAM,MAAM;CACxC,QAAQ,IAAI,QAAQ,YAAY,KAAK,EAAE,EAAE,eAAe,MAAM,CAAC;CAC/D,QAAQ,IAAI,KAAK,cAAc,OAAO,QAAQ,CAAC;AACjD,CACF;AAEF,cACG,QAAQ,mBAAmB,EAC3B,YAAY,iBAAiB,EAC7B,eAAe,iBAAiB,eAAe,EAC/C,OAAO,qBAAqB,YAAY,EACxC,OAAO,qBAAqB,cAAc,EAC1C,OAAO,OAAO,UAAkB,SAA+D;CAC9F,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAE7D,MAAM,UAAS,MADO,YAAY,SAAS,KAAK,IAAI,GAC7B,MAAM,MAAM,EAAE,OAAO,QAAQ;CAEpD,IAAI,CAAC,QAAQ;EACX,QAAQ,MAAM,MAAM,WAAW,SAAS,YAAY,CAAC;EACrD,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,yBAAQ,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;CAClD,MAAM,UAAkB;EACtB,GAAG;EACH,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAA2B,IAAI,CAAC;EACjE,GAAI,KAAK,aAAa,KAAA,IAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;EACjE,GAAI,KAAK,WAAW,cAAc,CAAC,OAAO,WAAW,EAAE,UAAU,MAAM,IAAI,CAAC;CAC9E;CAEA,MAAM,aAAa,SAAS,KAAK,MAAM,OAAO;CAC9C,QAAQ,IAAI,QAAQ,YAAY,KAAK,QAAQ,EAAE,SAAS,CAAC;AAC3D,CAAC;AAEH,cACG,QAAQ,kBAAkB,EAC1B,YAAY,gBAAgB,EAC5B,eAAe,iBAAiB,eAAe,EAC/C,OAAO,uBAAuB,kBAAkB,EAChD,OAAO,OAAO,UAAkB,SAAgD;CAC/E,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAE7D,MAAM,UAAS,MADO,YAAY,SAAS,KAAK,IAAI,GAC7B,MAAM,MAAM,EAAE,OAAO,QAAQ;CAEpD,IAAI,CAAC,QAAQ;EACX,QAAQ,MAAM,MAAM,WAAW,SAAS,YAAY,CAAC;EACrD,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,yBAAQ,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;CAClD,MAAM,UAAkB;EAAE,GAAG;EAAQ,QAAQ;EAAU,UAAU,OAAO,YAAY;CAAM;CAC1F,MAAM,aAAa,SAAS,KAAK,MAAM,OAAO;CAC9C,QAAQ,IAAI,QAAQ,YAAY,KAAK,QAAQ,EAAE,QAAQ,CAAC;AAC1D,CAAC;;;AC9GH,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAAE,YAAY,yBAAyB;AAExF,cACG,QAAQ,MAAM,EACd,YAAY,6BAA6B,EACzC,aAAa;CAEZ,MAAM,UAAU,YADA,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,CAC1B;CACnC,IAAI,QAAQ,WAAW,GAAG;EACxB,QAAQ,IAAI,KAAK,mBAAmB,CAAC;EACrC;CACF;CACA,KAAK,MAAM,KAAK,SACd,QAAQ,IAAI,KAAK,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,SAAS,MAAM,GAAG,EAAE,GAAG;AAE1E,CAAC;AAEH,cACG,QAAQ,aAAa,EACrB,YAAY,gCAAgC,EAC5C,OAAO,iBAAiB,6BAA6B,KAAK,EAC1D,OAAO,kBAAkB,iBAAiB,EAC1C,QAAQ,IAAY,SAA8C;CAWjE,YAVgB,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GAUxC;EARnB;EACA,MAAO,KAAK,QAAqC;EACjD,UAAU,KAAK,YAAY;EAC3B,OAAO;GAAE,KAAK;GAAG,KAAK;EAAG;EACzB,gBAAgB;EAChB,eAAe;EACf,4BAAW,IAAI,KAAK,GAAE,YAAY;CAEV,CAAC;CAC3B,QAAQ,IAAI,QAAQ,aAAa,GAAG,UAAU,CAAC;AACjD,CAAC;AAEH,cACG,QAAQ,iBAAiB,EACzB,YAAY,qCAAqC,EACjD,eAAe,iBAAiB,eAAe,EAC/C,eAAe,mBAAmB,eAAe,EACjD,OACC,kBACA,cACA,QAAQ,IAAI,uBAAuB,uBACrC,EACC,OAAO,OAAO,UAAkB,SAA0D;CACzF,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAE7D,IAAI,CADW,UAAU,SAAS,QACxB,GAAG;EACX,QAAQ,MAAM,MAAM,WAAW,SAAS,YAAY,CAAC;EACrD,QAAQ,KAAK,CAAC;CAChB;CACA,MAAM,QAAQ,oBAAoB,KAAK,MAAM,KAAK,OAAO,QAAQ;CACjE,MAAM,kBAAkB,SAAS,UAAU,KAAK,MAAM,KAAK,OAAO,KAAK;CACvE,QAAQ,IAAI,QAAQ,0BAA0B,CAAC;CAC/C,QAAQ,IAAI,KAAK,UAAU,KAAK,OAAO,wBAAwB,OAAO,CAAC;AACzE,CAAC;AAEH,cACG,QAAQ,oBAAoB,EAC5B,YAAY,mCAAmC,EAC/C,OAAO,iBAAiB,yBAAyB,EACjD,QAAQ,UAAkB,SAA4B;CAErD,MAAM,YAAY,oBADF,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GACd,UAAU,KAAK,IAAI;CAClE,MAAM,MAAM,aAAa,SAAS;CAClC,MAAM,YAAY,UAAU,QAAQ,MAAM,EAAE,SAAS,CAAC,EAAE;CACxD,MAAM,aAAa,UAAU,QAAQ,MAAM,EAAE,SAAS,CAAC,EAAE;CAEzD,QAAQ,IAAI,KAAK,WAAW,UAAU,CAAC;CACvC,QAAQ,IACN,KACE,cAAc,UAAU,OAAO,SAAS,IAAI,eAAe,UAAU,gBAAgB,YACvF,CACF;CACA,KAAK,MAAM,KAAK,WACd,QAAQ,IACN,KAAK,EAAE,KAAK,IAAI,EAAE,aAAa,WAAW,EAAE,QAAQ,EAAE,UAAU,MAAM,EAAE,QAAQ,MAAM,GAAG,EAAE,EAAE,KAAK,IACpG;AAEJ,CAAC;;;ACpFH,MAAa,YAAY,IAAI,QAAQ,IAAI,EAAE,YAAY,2BAA2B;AAElF,UACG,QAAQ,MAAM,EACd,YAAY,sBAAsB,EAClC,OAAO,oBAAoB,oBAAoB,EAC/C,OAAO,YAAY,2BAA2B,EAC9C,QAAQ,SAAkD;CAEzD,MAAM,WAAW,eADD,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GACpB;EACvC,GAAI,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;EACnD,GAAI,KAAK,SAAS,EAAE,YAAY,KAAK,IAAI,CAAC;CAC5C,CAAC;CACD,IAAI,SAAS,WAAW,GAAG;EACzB,QAAQ,IAAI,KAAK,oBAAoB,CAAC;EACtC;CACF;CACA,KAAK,MAAM,KAAK,UAAU;EACxB,MAAM,MAAM,EAAE,SAAS,cAAc;EACrC,QAAQ,IAAI,KAAK,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,KAAK,EAAE,QAAQ,KAAK;CAClE;AACF,CAAC;AAEH,UACG,QAAQ,UAAU,EAClB,YAAY,kBAAkB,EAC9B,QAAQ,OAAe;CAEtB,MAAM,UAAU,aADA,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GACvB,EAAE;CACxC,IAAI,CAAC,SAAS;EACZ,QAAQ,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC;EAChD,QAAQ,KAAK,CAAC;CAChB;CACA,QAAQ,IAAI,KAAK,QAAQ,KAAK,CAAC;CAC/B,QAAQ,IAAI,aAAa,QAAQ,SAAS,UAAU,QAAQ,KAAK,KAAK,IAAI,KAAK,UAAU;CACzF,QAAQ,IAAI,OAAO,QAAQ,IAAI;AACjC,CAAC;AAEH,UACG,QAAQ,gBAAgB,EACxB,YAAY,oBAAoB,EAChC,OAAO,YAAY,6BAA6B,EAChD,QAAQ,OAAe,SAA+B;CAErD,MAAM,UAAU,eADA,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GACrB,OAAO,KAAK,SAAS,EAAE,YAAY,KAAK,IAAI,CAAC,CAAC;CACtF,IAAI,QAAQ,WAAW,GAAG;EACxB,QAAQ,IAAI,KAAK,aAAa,CAAC;EAC/B;CACF;CACA,KAAK,MAAM,KAAK,SAAS;EACvB,QAAQ,IAAI,KAAK,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO;EACzC,QAAQ,IAAI,OAAO,EAAE,KAAK,MAAM,GAAG,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,IAAI;CAClE;AACF,CAAC;AAEH,UACG,QAAQ,aAAa,EACrB,YAAY,mDAAmD,EAC/D,eAAe,mBAAmB,eAAe,EACjD,OAAO,oBAAoB,YAAY,SAAS,EAChD,OAAO,iBAAiB,kBAAkB,EAC1C,QAAQ,IAAY,SAA+D;CAClF,MAAM,UAAU,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;CAC7D,MAAM,uBAAM,IAAI,KAAK,GAAE,YAAY;CAYnC,eAAe,SAAS;EAVtB;EACA,OAAO,KAAK;EACZ,UAAU,KAAK;EACf,MAAM,CAAC;EACP,QAAQ;EACR,WAAW;EACX,WAAW;EACX,GAAI,KAAK,SAAS,EAAE,gBAAgB,KAAK,OAAO,IAAI,CAAC;EACrD,MAAM;CAEsB,CAAC;CAC/B,QAAQ,IAAI,QAAQ,cAAc,GAAG,yBAAyB,KAAK,SAAS,EAAE,CAAC;CAC/E,QAAQ,IAAI,KAAK,iCAAiC,KAAK,SAAS,GAAG,GAAG,IAAI,CAAC;AAC7E,CAAC;AAEH,UACG,QAAQ,aAAa,EACrB,YAAY,qBAAqB,EACjC,QAAQ,OAAe;CAEtB,IAAI,gBADY,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,GAChC,EAAE,GAC7B,QAAQ,IAAI,QAAQ,cAAc,GAAG,UAAU,CAAC;MAC3C;EACL,QAAQ,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC;EAChD,QAAQ,KAAK,CAAC;CAChB;AACF,CAAC;;;AClGH,MAAM,cAAc;CAAC;CAAQ;CAAU;CAAW;CAAQ;AAAQ;AAElE,SAASC,aAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,SAAS,QAAQ,OAAe,MAA0B;CACxD,OAAO,CAAC,GAAG,MAAM,KAAK;AACxB;;AAGA,SAAS,eAAe,MAAsC;CAC5D,MAAM,CAAC,MAAM,MAAM,QAAQ,KAAK,MAAM,GAAG;CACzC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,SAAS,IAAI,GAAG,OAAO;CAC1D,OAAO;EACL;EACM;EACN,GAAI,OAAO,EAAE,SAAS,KAAK,MAAM,GAAG,EAAE,KAAK,MAAM,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC;CAClE;AACF;AAEA,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAAE,YACjD,sDACF;AAEA,cACG,QAAQ,MAAM,EACd,YAAY,4BAA4B,EACxC,OAAO,YAAY;CAClB,MAAM,EAAE,yBAAyB,MAAM,OAAO;CAC9C,MAAM,OAAO,qBAAqBA,WAAQ,CAAC;CAC3C,IAAI,KAAK,WAAW,GAAG;EACrB,QAAQ,IAAI,KAAK,wEAAwE,CAAC;EAC1F;CACF;CACA,KAAK,MAAM,KAAK,MAAM;EACpB,MAAM,OAAO,EAAE,UAAU,KAAK,EAAE,QAAQ,KAAK,IAAI,EAAE,KAAK;EACxD,QAAQ,IAAI,GAAG,EAAE,KAAK,IAAI,EAAE,KAAK,GAAG,OAAO,EAAE,QAAQ,MAAM,EAAE,UAAU,IAAI;CAC7E;AACF,CAAC;AAEH,cACG,QAAQ,mBAAmB,EAC3B,YAAY,+DAA+D,EAC3E,OAAO,mBAAmB,sBAAsB,EAChD,OAAO,mBAAmB,sCAAsC,EAChE,OAAO,OAAO,MAAc,MAAc,SAA+C;CACxF,IAAI,CAAC,YAAY,SAAS,IAAI,GAAG;EAC/B,QAAQ,MAAM,MAAM,iBAAiB,KAAK,iBAAiB,YAAY,KAAK,IAAI,GAAG,CAAC;EACpF,QAAQ,WAAW;EACnB;CACF;CACA,MAAM,EAAE,sBAAsB,MAAM,OAAO;CAC3C,kBAAkBA,WAAQ,GAAG;EAC3B;EACM;EACN,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;EAC1C,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAQ,MAAM,GAAG,EAAE,KAAK,MAAM,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC;CAClF,CAAC;CACD,QAAQ,IAAI,QAAQ,iBAAiB,KAAK,KAAK,KAAK,WAAW,CAAC;AAClE,CAAC;AAEH,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAAE,YACjD,gEACF;AAEA,cACG,QAAQ,eAAe,EACvB,YAAY,oEAAoE,EAChF,OAAO,mBAAmB,sBAAsB,EAChD,OAAO,kBAAkB,0BAA0B,SAAS,CAAC,CAAa,EAC1E,OAAO,OAAO,MAAc,SAA8C;CACzE,MAAM,SAA4B,CAAC;CACnC,KAAK,MAAM,QAAQ,KAAK,OAAO;EAC7B,MAAM,IAAI,eAAe,IAAI;EAC7B,IAAI,CAAC,GAAG;GACN,QAAQ,MAAM,MAAM,yBAAyB,KAAK,wBAAwB,CAAC;GAC3E,QAAQ,WAAW;GACnB;EACF;EACA,OAAO,KAAK,CAAC;CACf;CACA,MAAM,EAAE,uBAAuB,MAAM,OAAO;CAC5C,mBAAmBA,WAAQ,GAAG;EAAE;EAAM,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;EAAI;CAAO,CAAC;CAC5F,QAAQ,IAAI,QAAQ,kBAAkB,KAAK,iBAAiB,OAAO,OAAO,WAAW,CAAC;AACxF,CAAC;AAEH,cACG,QAAQ,YAAY,EACpB,YAAY,+CAA+C,EAC3D,OAAO,cAAc,yBAAyB,SAAS,CAAC,CAAa,EACrE,OAAO,OAAO,MAAc,SAA4B;CACvD,MAAM,SAAiC,CAAC;CACxC,KAAK,MAAM,MAAM,KAAK,KAAK;EACzB,MAAM,KAAK,GAAG,QAAQ,GAAG;EACzB,IAAI,KAAK,GAAG;EACZ,OAAO,GAAG,MAAM,GAAG,EAAE,EAAE,KAAK,KAAK,GAAG,MAAM,KAAK,CAAC,EAAE,KAAK;CACzD;CACA,MAAM,EAAE,iBAAiB,MAAM,OAAO;CACtC,MAAM,MAAM,aAAaA,WAAQ,GAAG,MAAM,MAAM;CAChD,IAAI,CAAC,IAAI,IAAI;EACX,QAAQ,MAAM,MAAM,6BAA6B,IAAI,UAAU,CAAC,GAAG,KAAK,IAAI,GAAG,CAAC;EAChF,QAAQ,WAAW;EACnB;CACF;CACA,QAAQ,IAAI,QAAQ,WAAW,KAAK,UAAU,IAAI,OAAQ,IAAI,CAAC;AACjE,CAAC;AAEH,cACG,QAAQ,aAAa,EACrB,YAAY,iCAAiC,EAC7C,OAAO,OAAO,SAAiB;CAC9B,MAAM,EAAE,gBAAgB,MAAM,OAAO;CACrC,MAAM,UAAU,YAAYA,WAAQ,GAAG,IAAI;CAC3C,IAAI,QAAQ,WAAW,GAAG;EACxB,QAAQ,IAAI,KAAK,mBAAmB,KAAK,GAAG,CAAC;EAC7C;CACF;CACA,KAAK,MAAM,KAAK,SAAS,QAAQ,IAAI,GAAG,EAAE,GAAG,IAAI,KAAK,UAAU,EAAE,MAAM,GAAG;AAC7E,CAAC;;;ACxHH,SAASC,aAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,iBAAiB,IAAI,QAAQ,SAAS,EAAE,YACnD,sDACF;AAEA,eACG,QAAQ,WAAW,EACnB,YAAY,yEAAyE,EACrF,OAAO,kBAAkB,kCAAkC,GAAG,EAC9D,OAAO,qBAAqB,mCAAmC,EAC/D,OAAO,OAAO,KAAa,SAA8C;CACxE,MAAM,EAAE,eAAe,MAAM,OAAO;CACpC,MAAM,SAAS,KAAK,OACjB,MAAM,GAAG,EACT,KAAK,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;CACjB,MAAM,MAAM,WAAWA,WAAQ,GAAG,KAAK,QAAQ,KAAK,MAAM;CAC1D,QAAQ,IAAI,QAAQ,WAAW,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI,EAAE,EAAE,CAAC;AAC1E,CAAC;AAEH,eACG,QAAQ,MAAM,EACd,YAAY,4BAA4B,EACxC,OAAO,YAAY;CAClB,MAAM,EAAE,iBAAiB,MAAM,OAAO;CACtC,MAAM,OAAO,aAAaA,WAAQ,CAAC;CACnC,IAAI,KAAK,WAAW,GAAG;EACrB,QAAQ,IAAI,KAAK,yBAAyB,CAAC;EAC3C;CACF;CACA,KAAK,MAAM,KAAK,MAAM,QAAQ,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,EAAE,OAAO,KAAK,IAAI,EAAE,EAAE;AACjF,CAAC;AAEH,eACG,QAAQ,aAAa,EACrB,YAAY,+BAA+B,EAC3C,OAAO,OAAO,OAAe;CAC5B,MAAM,EAAE,kBAAkB,MAAM,OAAO;CACvC,IAAI,cAAcA,WAAQ,GAAG,EAAE,GAAG,QAAQ,IAAI,QAAQ,WAAW,IAAI,CAAC;MACjE;EACH,QAAQ,MAAM,MAAM,cAAc,IAAI,CAAC;EACvC,QAAQ,WAAW;CACrB;AACF,CAAC;AAEH,eACG,QAAQ,OAAO,EACf,YAAY,qDAAqD,EACjE,OAAO,YAAY;CAClB,MAAM,EAAE,kBAAkB,MAAM,OAAO;CACvC,MAAM,IAAI,MAAM,cAAcA,WAAQ,CAAC;CACvC,QAAQ,IAAI,KAAK,WAAW,EAAE,QAAQ,kBAAkB,EAAE,aAAa,EAAE,CAAC;AAC5E,CAAC;;;ACtDH,SAASC,aAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,iBAAiB,IAAI,QAAQ,SAAS,EAAE,YACnD,4CACF;AAEA,eACG,QAAQ,eAAe,EACvB,YAAY,8BAA8B,EAC1C,OAAO,mBAAmB,qDAAqD,EAC/E,OAAO,gBAAgB,uCAAuC,EAC9D,OAAO,wBAAwB,oBAAoB,EACnD,OAAO,oBAAoB,oCAAoC,EAC/D,OACC,OACE,MACA,SACG;CACH,MAAM,WAA4B;EAChC,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;EAC1C,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,MAAM,GAAG,EAAE,KAAK,MAAM,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC;EACvE,GAAI,KAAK,eAAe,EAAE,cAAc,OAAO,KAAK,YAAY,EAAE,IAAI,CAAC;EACvE,GAAI,KAAK,YAAY,EAAE,WAAW,OAAO,KAAK,SAAS,EAAE,IAAI,CAAC;CAChE;CACA,MAAM,EAAE,kBAAkB,MAAM,OAAO;CACvC,cAAcA,WAAQ,GAAG,MAAM,QAAQ;CACvC,QAAQ,IAAI,QAAQ,YAAY,KAAK,aAAa,KAAK,UAAU,QAAQ,GAAG,CAAC;AAC/E,CACF;AAEF,eACG,QAAQ,MAAM,EACd,YAAY,uBAAuB,EACnC,OAAO,YAAY;CAClB,MAAM,EAAE,iBAAiB,MAAM,OAAO;CACtC,MAAM,OAAO,aAAaA,WAAQ,CAAC;CACnC,IAAI,KAAK,WAAW,GAAG;EACrB,QAAQ,IAAI,KAAK,sBAAsB,CAAC;EACxC;CACF;CACA,KAAK,MAAM,KAAK,MAAM,QAAQ,IAAI,GAAG,EAAE,KAAK,IAAI,KAAK,UAAU,EAAE,QAAQ,GAAG;AAC9E,CAAC;AAEH,eACG,QAAQ,gBAAgB,EACxB,YAAY,mCAAmC,EAC/C,OAAO,OAAO,SAAiB;CAC9B,MAAM,EAAE,cAAc,oBAAoB,MAAM,OAAO;CACvD,MAAM,MAAM,aAAaA,WAAQ,CAAC,EAAE,MAAM,MAAM,EAAE,SAAS,IAAI;CAC/D,IAAI,CAAC,KAAK;EACR,QAAQ,MAAM,MAAM,sBAAsB,MAAM,CAAC;EACjD,QAAQ,WAAW;EACnB;CACF;CACA,MAAM,UAAU,MAAM,gBAAgBA,WAAQ,GAAG,IAAI,QAAQ;CAC7D,QAAQ,IAAI,KAAK,GAAG,QAAQ,OAAO,YAAY,CAAC;CAChD,KAAK,MAAM,QAAQ,SAAS,QAAQ,IAAI,IAAI;AAC9C,CAAC;;;AC5DH,SAASC,aAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,kBAAkB,IAAI,QAAQ,UAAU,EAAE,YACrD,2CACF;AAEA,gBACG,QAAQ,YAAY,EACpB,YAAY,mEAAmE,EAC/E,OAAO,YAAY;CAClB,MAAM,EAAE,0BAA0B,MAAM,OAAO;CAC/C,MAAM,WAAW,MAAM,sBAAsBA,WAAQ,CAAC;CACtD,IAAI,SAAS,WAAW,GAAG;EACzB,QAAQ,IAAI,KAAK,8BAA8B,CAAC;EAChD;CACF;CACA,QAAQ,IAAI,KAAK,GAAG,SAAS,OAAO,uBAAuB,CAAC;CAC5D,KAAK,MAAM,KAAK,UAAU,QAAQ,IAAI,GAAG,EAAE,IAAI,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG;AACzE,CAAC;;;ACpBH,SAASC,aAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,iBAAiB,IAAI,QAAQ,SAAS,EAChD,YAAY,6CAA6C,EACzD,OAAO,YAAY;CAClB,MAAM,EAAE,wBAAwB,MAAM,OAAO;CAC7C,MAAM,IAAI,oBAAoBA,WAAQ,CAAC;CACvC,QAAQ,IAAI,KAAK,gBAAgB,CAAC;CAClC,QAAQ,IAAI,uBAAuB,EAAE,iBAAiB;CACtD,QAAQ,IAAI,uBAAuB,EAAE,kBAAkB;CACvD,QAAQ,IAAI,wBAAwB,EAAE,iBAAiB,KAAK,QAAQ,CAAC,EAAE,EAAE;CACzE,QAAQ,IAAI,KAAK,UAAU,CAAC;CAC5B,KAAK,MAAM,CAAC,MAAM,MAAM,OAAO,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE,GACzE,QAAQ,IAAI,KAAK,KAAK,IAAI,GAAG;CAE/B,QAAQ,IAAI,KAAK,WAAW,CAAC;CAC7B,KAAK,MAAM,CAAC,OAAO,MAAM,OAAO,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE,GAC3E,QAAQ,IAAI,KAAK,MAAM,IAAI,GAAG;AAElC,CAAC;;;ACrBH,SAASC,aAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,eAAe,IAAI,QAAQ,OAAO,EAC5C,YAAY,uCAAuC,EACnD,OAAO,iBAAiB,oBAAoB,EAC5C,OAAO,OAAO,SAA4B;CACzC,MAAM,EAAE,mBAAmB,MAAM,OAAO;CACxC,MAAM,MAAM,eAAeA,WAAQ,GAAG,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC,CAAC;CAC1E,QAAQ,IAAI,KAAK,WAAW,CAAC;CAC7B,QAAQ,IAAI,mBAAmB,IAAI,OAAO;CAC1C,QAAQ,IAAI,mBAAmB,IAAI,kBAAkB;CACrD,QAAQ,IAAI,mBAAmB,IAAI,mBAAmB;CACtD,QAAQ,IAAI,oBAAoB,IAAI,aAAa,QAAQ,CAAC,GAAG;CAC7D,IAAI,CAAC,KAAK,MAAM;EACd,QAAQ,IAAI,KAAK,cAAc,CAAC;EAChC,KAAK,MAAM,CAAC,MAAM,MAAM,OAAO,QAAQ,IAAI,MAAM,EAAE,MAChD,GAAG,MAAM,EAAE,GAAG,UAAU,EAAE,GAAG,OAChC,GACE,QAAQ,IAAI,KAAK,KAAK,KAAK,EAAE,QAAQ,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,QAAQ;CAExE;AACF,CAAC;;;ACtBH,SAASC,aAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,mBAAmB,IAAI,QAAQ,WAAW,EAAE,YACvD,kCACF;AAEA,iBACG,QAAQ,MAAM,EACd,YAAY,mCAAmC,EAC/C,OAAO,qBAAqB,iCAAiC,SAAS,EACtE,OAAO,OAAO,SAA6B;CAC1C,MAAM,EAAE,kBAAkB,MAAM,OAAO;CACvC,MAAM,OAAO,cAAcA,WAAQ,GAAG,KAAK,MAA6C;CACxF,IAAI,KAAK,WAAW,GAAG;EACrB,QAAQ,IAAI,KAAK,MAAM,KAAK,OAAO,YAAY,CAAC;EAChD;CACF;CACA,KAAK,MAAM,KAAK,MAAM,QAAQ,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,KAAK,IAAI,EAAE,QAAQ,IAAI,IAAI,EAAE,aAAa;AAC5F,CAAC;AAEH,iBACG,QAAQ,cAAc,EACtB,YAAY,0BAA0B,EACtC,OAAO,OAAO,OAAe;CAC5B,MAAM,EAAE,mBAAmB,MAAM,OAAO;CACxC,IAAI,eAAeA,WAAQ,GAAG,IAAI,UAAU,GAAG,QAAQ,IAAI,QAAQ,YAAY,IAAI,CAAC;MAC/E;EACH,QAAQ,MAAM,MAAM,cAAc,IAAI,CAAC;EACvC,QAAQ,WAAW;CACrB;AACF,CAAC;AAEH,iBACG,QAAQ,aAAa,EACrB,YAAY,yBAAyB,EACrC,OAAO,OAAO,OAAe;CAC5B,MAAM,EAAE,mBAAmB,MAAM,OAAO;CACxC,IAAI,eAAeA,WAAQ,GAAG,IAAI,UAAU,GAAG,QAAQ,IAAI,QAAQ,YAAY,IAAI,CAAC;MAC/E;EACH,QAAQ,MAAM,MAAM,cAAc,IAAI,CAAC;EACvC,QAAQ,WAAW;CACrB;AACF,CAAC;AAEH,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAAE,YACjD,wDACF;AAEA,cACG,QAAQ,qBAAqB,EAC7B,YAAY,wDAAwD,EACpE,OAAO,iBAAiB,uCAAuC,EAC/D,OAAO,OAAO,MAAc,QAAgB,SAA4B;CACvE,IAAI,CAAC;EAAC;EAAQ;EAAW;CAAO,EAAE,SAAS,MAAM,GAAG;EAClD,QAAQ,MAAM,MAAM,uCAAuC,CAAC;EAC5D,QAAQ,WAAW;EACnB;CACF;CACA,MAAM,EAAE,cAAc,MAAM,OAAO;CACnC,UAAUA,WAAQ,GAAG,MAAM,QAAkB,KAAK,IAAI;CACtD,QAAQ,IAAI,QAAQ,UAAU,OAAO,KAAK,OAAO,IAAI,KAAK,SAAS,GAAG,KAAK,QAAQ,CAAC;AACtF,CAAC;;;AChEH,SAASC,YAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,iBAAiB,IAAI,QAAQ,SAAS,EAAE,YAAY,uBAAuB;AAExF,eACG,QAAQ,MAAM,EACd,YAAY,sEAAsE,EAClF,OAAO,YAAY;CAClB,MAAM,EAAE,gBAAgB,MAAM,OAAO;CACrC,MAAM,SAAS,MAAM,YAAYA,UAAQ,CAAC;CAC1C,IAAI,OAAO,WAAW,GAAG;EACvB,QAAQ,IAAI,QAAQ,iCAAiC,CAAC;EACtD;CACF;CACA,QAAQ,IAAI,KAAK,GAAG,OAAO,OAAO,WAAW,CAAC;CAC9C,KAAK,MAAM,KAAK,QAAQ;EACtB,MAAM,MAAM,EAAE,eAAe,YAAY,EAAE,iBAAiB;EAC5D,QAAQ,IAAI,MAAM,EAAE,KAAK,IAAI,EAAE,KAAK,IAAI,EAAE,SAAS,KAAK;CAC1D;AACF,CAAC;;;ACpBH,SAASC,YAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AACA,MAAM,QAAQ;CAAC;CAAQ;CAAc;CAAY;AAAa;AAE9D,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAAE,YACjD,wCACF;AAEA,cACG,QAAQ,YAAY,EACpB,YAAY,2CAA2C,EACvD,OAAO,iBAAiB,8CAA8C,MAAM,EAC5E,OAAO,iBAAiB,iCAAiC,EACzD,OAAO,OAAO,MAAc,SAA0C;CACrE,MAAM,OAAQ,MAAM,SAAS,KAAK,IAAI,IAAI,KAAK,OAAO;CACtD,MAAM,EAAE,cAAc,MAAM,OAAO;CACnC,MAAM,IAAI,UAAUA,UAAQ,GAAG;EAC7B,OAAO,KAAK,OAAO,aAAa;EAChC,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;EACvC;EACA;CACF,CAAC;CACD,QAAQ,IAAI,QAAQ,UAAU,EAAE,GAAG,WAAW,EAAE,QAAQ,KAAK,OAAO,IAAI,KAAK,SAAS,GAAG,GAAG,CAAC;AAC/F,CAAC;AAEH,cACG,QAAQ,MAAM,EACd,YAAY,6CAA6C,EACzD,OAAO,iBAAiB,eAAe,EACvC,OAAO,OAAO,SAA4B;CACzC,MAAM,EAAE,iBAAiB,MAAM,OAAO;CACtC,MAAM,OAAO,aAAaA,UAAQ,GAAG,KAAK,IAAI;CAC9C,IAAI,KAAK,WAAW,GAAG;EACrB,QAAQ,IAAI,KAAK,cAAc,CAAC;EAChC;CACF;CACA,KAAK,MAAM,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAE,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,MAAM;AACtE,CAAC;AAEH,cACG,QAAQ,gBAAgB,EACxB,YAAY,8BAA8B,EAC1C,OAAO,iBAAiB,eAAe,EACvC,OAAO,OAAO,OAAe,SAA4B;CACxD,MAAM,EAAE,iBAAiB,MAAM,OAAO;CACtC,MAAM,OAAO,MAAM,aAAaA,UAAQ,GAAG,OAAO,KAAK,IAAI;CAC3D,IAAI,KAAK,WAAW,GAAG;EACrB,QAAQ,IAAI,KAAK,uBAAuB,CAAC;EACzC;CACF;CACA,KAAK,MAAM,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAE,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,MAAM;AACtE,CAAC;;;ACrDH,SAASC,YAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,aAAa,IAAI,QAAQ,KAAK,EAAE,YAC3C,uDACF;AAEA,WACG,QAAQ,aAAa,EACrB,YAAY,yCAAyC,EACrD,OAAO,oBAAoB,oCAAoC,EAAE,EACjE,OAAO,iBAAiB,oBAAoB,EAAE,EAC9C,OAAO,iBAAiB,iCAAiC,EACzD,OAAO,OAAO,OAAe,SAA4D;CACxF,MAAM,EAAE,WAAW,MAAM,OAAO;CAChC,MAAM,WAAW,KAAK,SACnB,MAAM,GAAG,EACT,KAAK,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;CACjB,MAAM,IAAI,OAAOA,UAAQ,GAAG;EAC1B,OAAO,KAAK,OAAO,aAAa;EAChC,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;EACvC;EACA;EACA,MAAM,KAAK;CACb,CAAC;CACD,QAAQ,IAAI,QAAQ,OAAO,EAAE,GAAG,UAAU,EAAE,QAAQ,KAAK,OAAO,IAAI,KAAK,SAAS,GAAG,GAAG,CAAC;AAC3F,CAAC;AAEH,WACG,QAAQ,MAAM,EACd,YAAY,yCAAyC,EACrD,OAAO,iBAAiB,eAAe,EACvC,OAAO,OAAO,SAA4B;CACzC,MAAM,EAAE,aAAa,MAAM,OAAO;CAClC,MAAM,OAAO,SAASA,UAAQ,GAAG,KAAK,IAAI;CAC1C,IAAI,KAAK,WAAW,GAAG;EACrB,QAAQ,IAAI,KAAK,UAAU,CAAC;EAC5B;CACF;CACA,KAAK,MAAM,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAE,MAAM,IAAI,EAAE,MAAM,KAAK,EAAE,SAAS,KAAK,IAAI,EAAE,EAAE;AACzF,CAAC;AAEH,WACG,QAAQ,cAAc,EACtB,YAAY,8BAA8B,EAC1C,OAAO,iBAAiB,eAAe,EACvC,OAAO,OAAO,OAAe,SAA4B;CACxD,MAAM,EAAE,aAAa,MAAM,OAAO;CAClC,MAAM,OAAO,MAAM,SAASA,UAAQ,GAAG,OAAO,KAAK,IAAI;CACvD,IAAI,KAAK,WAAW,GAAG;EACrB,QAAQ,IAAI,KAAK,mBAAmB,CAAC;EACrC;CACF;CACA,KAAK,MAAM,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAE,MAAM,IAAI,EAAE,OAAO;AAC7D,CAAC;;;ACxDH,SAASC,YAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,cAAc,IAAI,QAAQ,MAAM,EAAE,YAC7C,oDACF;AAEA,YACG,QAAQ,KAAK,EACb,YAAY,+CAA+C,EAC3D,OAAO,mBAAmB,4BAA4B,EACtD,OAAO,kBAAkB,6BAA6B,EACtD,OAAO,cAAc,mCAAmC,EACxD,OAAO,gBAAgB,kCAAkC,EACzD,OAAO,iBAAiB,iCAAiC,EACzD,OACC,OAAO,SAMD;CACJ,MAAM,EAAE,YAAY,MAAM,OAAO;CACjC,QACEA,UAAQ,GACR;EACE,GAAI,KAAK,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;EACtD,GAAI,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;EACnD,GAAI,KAAK,KAAK,EAAE,KAAK,KAAK,GAAG,MAAM,GAAG,EAAE,KAAK,MAAM,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC;EAClE,GAAI,KAAK,OAAO,EAAE,OAAO,KAAK,KAAK,MAAM,GAAG,EAAE,KAAK,MAAM,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC;CAC1E,GACA,KAAK,IACP;CACA,QAAQ,IACN,QAAQ,uBAAuB,KAAK,OAAO,YAAY,KAAK,SAAS,SAAS,GAAG,CACnF;AACF,CACF;AAEF,YACG,QAAQ,MAAM,EACd,YAAY,iCAAiC,EAC7C,OAAO,iBAAiB,eAAe,EACvC,OAAO,OAAO,SAA4B;CACzC,MAAM,EAAE,aAAa,oBAAoB,MAAM,OAAO;CACtD,MAAM,UAAU,YAAYA,UAAQ,GAAG,KAAK,IAAI;CAChD,QAAQ,IAAI,KAAK,KAAK,UAAU,OAAO,CAAC,CAAC;CACzC,QAAQ,IAAI,gBAAgB,gBAAgB,OAAO,KAAK,UAAU;AACpE,CAAC;;;AC7CH,MAAa,kBAAkB,IAAI,QAAQ,UAAU,EAClD,YAAY,sDAAsD,EAClE,SAAS,UAAU,yBAAyB,EAC5C,OAAO,iBAAiB,uCAAuC,EAC/D,OAAO,OAAO,MAAc,SAA4B;CACvD,IAAI,CAAC,GAAG,WAAW,IAAI,GAAG;EACxB,QAAQ,MAAM,MAAM,mBAAmB,MAAM,CAAC;EAC9C,QAAQ,WAAW;EACnB;CACF;CACA,MAAM,aAAa,GAAG,aAAa,MAAM,OAAO;CAChD,MAAM,EAAE,oBAAoB,MAAM,OAAO;CACzC,MAAM,SAAS,MAAM,gBAAgB,YAAY,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC,CAAC;CACrF,QAAQ,IAAI,KAAK,4CAA4C,CAAC;CAC9D,QAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAE7C,CAAC;;;ACrBH,SAASC,YAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,aAAa,IAAI,QAAQ,KAAK,EACxC,YAAY,0CAA0C,EACtD,SAAS,cAAc,cAAc,EACrC,OAAO,iBAAiB,qBAAqB,EAC7C,OAAO,OAAO,UAAkB,SAA4B;CAC3D,MAAM,EAAE,WAAW,MAAM,OAAO;CAChC,MAAM,MAAM,MAAM,OAAOA,UAAQ,GAAG,UAAU,KAAK,IAAI;CACvD,IAAI,IAAI,QAAQ;EACd,QAAQ,IAAI,KAAK,SAAS,CAAC;EAC3B,QAAQ,IAAI,IAAI,MAAM;CACxB;CACA,IAAI,IAAI,QAAQ,WAAW,GAAG;EAC5B,QAAQ,IAAI,KAAK,yBAAyB,CAAC;EAC3C;CACF;CACA,QAAQ,IAAI,KAAK,UAAU,CAAC;CAC5B,IAAI,QAAQ,SAAS,GAAG,MAAM,QAAQ,IAAI,MAAM,IAAI,EAAE,IAAI,EAAE,KAAK,MAAM,GAAG,GAAG,GAAG,CAAC;AACnF,CAAC;;;ACrBH,SAASC,YAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,aAAa,IAAI,QAAQ,KAAK,EACxC,YAAY,iDAAiD,EAC7D,SAAS,UAAU,eAAe,EAClC,OAAO,OAAO,SAAiB;CAC9B,MAAM,EAAE,mBAAmB,MAAM,OAAO;CACxC,MAAM,UAAU,MAAM,eAAeA,UAAQ,GAAG,IAAI;CACpD,IAAI,QAAQ,WAAW,GAAG;EACxB,QAAQ,IAAI,KAAK,qBAAqB,CAAC;EACvC;CACF;CACA,KAAK,MAAM,KAAK,SAAS,QAAQ,IAAI,IAAI,EAAE,SAAS,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ;AAClF,CAAC;;;ACfH,SAASC,YAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;;AAGA,SAAS,YAAoB;CAC3B,MAAM,MAAM,QAAQ,IAAI;CACxB,IAAI,CAAC,KAAK;EACR,QAAQ,MAAM,MAAM,iEAAiE,CAAC;EACtF,QAAQ,KAAK,CAAC;CAChB;CACA,OAAO;AACT;;AAGA,eAAe,MAAM,IAA+C;CAClE,IAAI;EACF,MAAM,GAAG;CACX,SAAS,GAAG;EACV,QAAQ,MAAM,MAAO,EAAY,OAAO,CAAC;EACzC,QAAQ,KAAK,CAAC;CAChB;AACF;AAEA,MAAa,eAAe,IAAI,QAAQ,OAAO,EAAE,YAC/C,gDACF;AAEA,aACG,QAAQ,oBAAoB,EAC5B,YAAY,+BAA+B,EAC3C,QAAQ,MAAc,UACrB,MAAM,YAAY;CAChB,MAAM,EAAE,cAAc,MAAM,OAAO;CACnC,UAAUA,UAAQ,GAAG,UAAU,GAAG,MAAM,KAAK;CAC7C,QAAQ,IAAI,QAAQ,WAAW,KAAK,UAAU,CAAC;AACjD,CAAC,CACH;AAEF,aACG,QAAQ,YAAY,EACpB,YAAY,mBAAmB,EAC/B,QAAQ,SACP,MAAM,YAAY;CAChB,MAAM,EAAE,cAAc,MAAM,OAAO;CACnC,MAAM,QAAQ,UAAUA,UAAQ,GAAG,UAAU,GAAG,IAAI;CACpD,IAAI,UAAU,KAAA,GAAW;EACvB,QAAQ,IAAI,KAAK,oBAAoB,KAAK,GAAG,CAAC;EAC9C;CACF;CACA,QAAQ,IAAI,KAAK;AACnB,CAAC,CACH;AAEF,aACG,QAAQ,MAAM,EACd,YAAY,2CAA2C,EACvD,aACC,MAAM,YAAY;CAChB,MAAM,EAAE,mBAAmB,MAAM,OAAO;CACxC,MAAM,QAAQ,eAAeA,UAAQ,GAAG,UAAU,CAAC;CACnD,IAAI,MAAM,WAAW,GAAG;EACtB,QAAQ,IAAI,KAAK,iBAAiB,CAAC;EACnC;CACF;CACA,KAAK,MAAM,KAAK,MAAM,KAAK,GAAG,QAAQ,IAAI,CAAC;AAC7C,CAAC,CACH;AAEF,aACG,QAAQ,WAAW,EACnB,YAAY,iBAAiB,EAC7B,QAAQ,SACP,MAAM,YAAY;CAChB,MAAM,EAAE,iBAAiB,MAAM,OAAO;CACtC,MAAM,UAAU,aAAaA,UAAQ,GAAG,UAAU,GAAG,IAAI;CACzD,QAAQ,IACN,UAAU,QAAQ,WAAW,KAAK,WAAW,IAAI,KAAK,oBAAoB,KAAK,GAAG,CACpF;AACF,CAAC,CACH;;;AC/EF,SAASC,YAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,SAAS,MAAM,OAAmB,MAAsB;CACtD,IAAI,UAAU,QAAQ,OAAO,MAAM,IAAI;CACvC,IAAI,UAAU,UAAU,OAAO,QAAQ,IAAI;CAC3C,OAAO,QAAQ,IAAI;AACrB;AAEA,MAAa,eAAe,IAAI,QAAQ,OAAO,EAAE,YAC/C,iDACF;AAEA,aACG,QAAQ,eAAe,EACvB,YAAY,oCAAoC,EAChD,OAAO,OAAO,SAAiB;CAC9B,MAAM,EAAE,gBAAgB,MAAM,OAAO;CACrC,MAAM,IAAI,YAAYA,UAAQ,GAAG,IAAI;CACrC,QAAQ,IAAI,MAAM,EAAE,OAAO,GAAG,KAAK,IAAI,EAAE,MAAM,YAAY,EAAE,SAAS,EAAE,UAAU,MAAM,CAAC;CACzF,KAAK,MAAM,KAAK,EAAE,SAAS,QAAQ,IAAI,OAAO,GAAG;AACnD,CAAC;AAEH,aACG,QAAQ,MAAM,EACd,YAAY,kDAAkD,EAC9D,OAAO,YAAY;CAClB,MAAM,EAAE,cAAc,MAAM,OAAO;CACnC,MAAM,SAAS,UAAUA,UAAQ,CAAC;CAClC,IAAI,OAAO,WAAW,GAAG;EACvB,QAAQ,IAAI,KAAK,yBAAyB,CAAC;EAC3C;CACF;CACA,KAAK,MAAM,KAAK,QACd,QAAQ,IACN,MAAM,EAAE,OAAO,GAAG,EAAE,UAAU,SAAS,EAAE,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,CACzF;AAEJ,CAAC;;;ACxCH,SAASC,YAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,mBAAmB,IAAI,QAAQ,WAAW,EAAE,YACvD,mEACF;AAEA,iBACG,QAAQ,OAAO,EACf,YAAY,sDAAsD,EAClE,OAAO,YAAY;CAClB,MAAM,EAAE,gBAAgB,kBAAkB,MAAM,OAAO;CACvD,MAAM,QAAQ,eAAeA,UAAQ,CAAC;CACtC,IAAI,CAAC,MAAM,YAAY;EACrB,QAAQ,IACN,QACE,uCAAuC,MAAM,UAAU,qCACzD,CACF;EACA,QAAQ,IAAI,KAAK,kEAAkE,CAAC;EACpF;CACF;CACA,cAAcA,UAAQ,GAAG,KAAK;CAC9B,QAAQ,IAAI,QAAQ,cAAc,MAAM,UAAU,4BAA4B,CAAC;AACjF,CAAC;AAEH,iBACG,QAAQ,gBAAgB,EACxB,YAAY,sDAAsD,EAClE,OAAO,OAAO,SAAiB;CAC9B,MAAM,EAAE,eAAe,gBAAgB,eAAe,MAAM,OAAO;CACnE,MAAM,EAAE,qBAAqB,MAAM,OAAO;CAC1C,MAAM,QAAQ,cAAcA,UAAQ,CAAC,KAAK,eAAeA,UAAQ,CAAC;CAClE,MAAM,OAAO,iBAAiBA,UAAQ,GAAG,IAAI,EAAE,QAC5C,MAAM,EAAE,UAAU,SAAS,EAAE,UAAU,MAC1C;CACA,IAAI,KAAK,WAAW,GAAG;EACrB,QAAQ,IAAI,KAAK,qBAAqB,KAAK,EAAE,CAAC;EAC9C;CACF;CACA,MAAM,SAAS,MAAM,aAAa,UAAU;CAC5C,QAAQ,IAAI,KAAK,uBAAuB,KAAK,IAAI,OAAO,GAAG,CAAC;CAC5D,KAAK,MAAM,KAAK,MAAM;EACpB,MAAM,IAAI,KAAK,MAAM,WAAW,OAAO,CAAC,IAAI,GAAG;EAC/C,QAAQ,IAAI,KAAK,OAAO,CAAC,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,MAAM,EAAE;CACnE;AACF,CAAC;;;AC/CH,SAAS,UAAkB;CACzB,OAAO,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;AACtD;AAEA,MAAa,gBAAgB,IAAI,QAAQ,QAAQ,EAC9C,YAAY,iEAAiE,EAC7E,SAAS,UAAU,eAAe,EAClC,OAAO,WAAW,kDAAkD,EACpE,OAAO,OAAO,MAAc,SAA8B;CACzD,MAAM,EAAE,mBAAmB,MAAM,OAAO;CACxC,MAAM,MAAM,MAAM,eAAe,QAAQ,GAAG,MAAM,EAAE,OAAO,KAAK,SAAS,MAAM,CAAC;CAChF,MAAM,UAAU,OAAO,QAAQ,IAAI,OAAO;CAC1C,IAAI,QAAQ,WAAW,GAAG;EACxB,QAAQ,IAAI,KAAK,6BAA6B,KAAK,EAAE,CAAC;EACtD;CACF;CACA,KAAK,MAAM,CAAC,GAAG,MAAM,SAAS,QAAQ,IAAI,KAAK,EAAE,IAAI,OAAO,CAAC,GAAG;CAChE,QAAQ,IACN,IAAI,UACA,QAAQ,WAAW,QAAQ,OAAO,eAAe,KAAK,EAAE,IACxD,KAAK,SAAS,QAAQ,OAAO,0CAA0C,CAC7E;AACF,CAAC;;;ACrBH,MAAa,eAAe,IAAI,QAAQ,OAAO,EAC5C,YAAY,sDAAsD,EAClE,SAAS,UAAU,0EAAsE,EACzF,OACC,kBACA,qDACA,uBACF,EACC,OAAO,OAAO,MAAc,SAA0B;CACrD,IAAI,CAAC,GAAG,WAAW,IAAI,GAAG;EACxB,QAAQ,MAAM,yBAAyB,MAAM;EAC7C,QAAQ,KAAK,CAAC;CAChB;CACA,MAAM,aAAa,GAAG,aAAa,MAAM,OAAO;CAChD,MAAM,EAAE,wBAAwB,MAAM,OAAO;CAK7C,MAAM,IAAI,oBAAoB,YAJf,KAAK,IACjB,MAAM,GAAG,EACT,KAAK,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OACqC,CAAC;CAEhD,QAAQ,IAAI,QAAQ,0BAA0B,EAAE,MAAM,QAAQ,CAAC;CAC/D,QAAQ,IAAI,yBAAyB,KAAK,MAAM,EAAE,YAAY,GAAG,EAAE,EAAE;CACrE,QAAQ,IAAI,yBAAyB,EAAE,gBAAgB;CACvD,QAAQ,IAAI,yBAAyB,EAAE,iBAAiB,OAAO;CAC/D,IAAI,EAAE,WAAW,SAAS,GAAG;EAC3B,QAAQ,IAAI,KAAK,eAAe,CAAC;EACjC,KAAK,MAAM,KAAK,EAAE,YAAY,QAAQ,IAAI,SAAS,GAAG;CACxD;CACA,QAAQ,IAAI,KAAK,aAAa,CAAC;CAC/B,KAAK,MAAM,KAAK,EAAE,UAAU,QAAQ,IAAI,SAAS,GAAG;AACtD,CAAC;;;AChCH,MAAa,oBAAoB,IAAI,QAAQ,YAAY,EAAE,YACzD,yEACF;AAEA,kBACG,QAAQ,UAAU,EAAE,WAAW,KAAK,CAAC,EACrC,YAAY,0CAA0C,EACtD,OAAO,YAAY;CAClB,MAAM,EAAE,kBAAkB,iBAAiB,MAAM,OAAO;CACxD,MAAM,MAAM,iBAAiB;CAC7B,MAAM,SAAS,MAAwB,IAAI,QAAQ,IAAI,IAAI,QAAQ,KAAK;CAExE,QAAQ,IAAI,KAAK,oBAAoB,CAAC;CACtC,QAAQ,IAAI,0BAA0B,IAAI,UAAU;CACpD,IAAI,IAAI,OAAO;EACb,QAAQ,IAAI,0BAA0B,IAAI,MAAM,SAAS;EACzD,QAAQ,IAAI,0BAA0B,IAAI,MAAM,OAAO;EACvD,QAAQ,IAAI,QAAQ,2DAA2D,CAAC;CAClF;CACA,QAAQ,IAAI,0BAA0B,MAAM,IAAI,YAAY,GAAG;CAC/D,QAAQ,IAAI,0BAA0B,MAAM,IAAI,UAAU,GAAG;CAC7D,QAAQ,IAAI,0BAA0B,MAAM,IAAI,UAAU,GAAG;CAC7D,IAAI,IAAI,cAAc,QAAQ,IAAI,KAAK,kBAAkB,aAAa,EAAE,EAAE,CAAC;AAC7E,CAAC;;;;ACrBH,SAAgB,kBAAkB,MAAyB,QAAQ,KAA+B;CAChG,MAAM,OAAO,IAAI;CACjB,MAAM,OAAO,IAAI;CACjB,MAAM,OAAO,IAAI;CACjB,MAAM,cAAc,IAAI;CACxB,IAAI,CAAC,QAAQ,CAAC,QAAS,CAAC,QAAQ,CAAC,aAAc,OAAO;CAEtD,OAAO;EACL;EACA,MAAM,IAAI,qBAAqB,OAAO,IAAI,kBAAkB,IAAI;EAChE,QAAQ,IAAI,yBAAyB;EACrC,SAAS,IAAI,yBAAyB;EACtC,MAAM,cAAc;GAAE;GAAM;EAAY,IAAI;GAAE;GAAY;EAAM;CAClE;AACF;;;;;;AAeA,eAAsB,eACpB,MAC6C;CAC7C,MAAM,SAAS,kBAAkB,KAAK,OAAO,QAAQ,GAAG;CACxD,IAAI,CAAC,QAAQ;EACX,MAAM,MACJ;EACF,QAAQ,MAAM,MAAM,GAAG,CAAC;EACxB,OAAO,EAAE,OAAO,IAAI;CACtB;CAEA,MAAM,EAAE,oBAAoB,MAAM,OAAO;CACzC,MAAM,SAAS,MAAM,gBAAgB;EACnC,SAAS,KAAK;EACd;EACA,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;EACvC,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;EAC1C,GAAI,KAAK,uBAAuB,KAAA,IAC5B,EAAE,oBAAoB,KAAK,mBAAmB,IAC9C,CAAC;CACP,CAAC;CAED,MAAM,SAAS,KAAK,OAAO,YAAY,KAAK,KAAK,IAAI,MAAM;CAC3D,QAAQ,IACN,QACE,UAAU,OAAO,QAAQ,KAAK,OAAO,KAAK,OAAO,OAAO,WAAW,OAAO,QAAQ,YAAY,OAAO,SAAS,UAChH,CACF;CACA,IAAI,CAAC,KAAK,QAAQ,OAAO,WAAW,GAClC,QAAQ,IACN,KACE,KAAK,OAAO,SAAS,gGACvB,CACF;CAEF,OAAO;AACT;AAEA,MAAa,iBAAiB,IAAI,QAAQ,SAAS,EAAE,YACnD,6DACF;AAEA,eACG,QAAQ,MAAM,EACd,YAAY,iFAAiF,EAC7F,SAAS,UAAU,gEAAgE,EACnF,OAAO,kBAAkB,iDAAiD,EAC1E,OAAO,oBAAoB,kDAAkD,EAC7E,OAAO,OAAO,MAA0B,YAAuD;CAE9F,MAAM,eAAe;EACnB,SAFc,QAAQ,IAAI,qBAAqB,QAAQ,IAAI;EAG3D;EACA,GAAI,QAAQ,QAAQ,EAAE,OAAO,IAAI,KAAK,QAAQ,KAAK,EAAE,IAAI,CAAC;EAC1D,oBAAoB,QAAQ,gBAAgB;CAC9C,CAAC;AACH,CAAC;;;;AChCH,MAAa,eAAmC;CAC9C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;AC9GA,MAAM,UAAU,IAAI,QAAQ;AAC5B,QACG,KAAK,OAAO,EACZ,YAAY,+CAA+C,EAC3D,QAAQ,OAAO,EACf,aAAa;AAEhB,KAAK,MAAM,WAAW,cACpB,QAAQ,WAAW,OAAO;AAG5B,MAAM,QAAQ,WAAW,QAAQ,IAAI"}