@hasna/microservices 0.0.9 → 0.0.11

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 (100) hide show
  1. package/bin/index.js +236 -36
  2. package/bin/mcp.js +153 -4
  3. package/dist/index.js +120 -3
  4. package/microservices/microservice-analytics/package.json +27 -0
  5. package/microservices/microservice-analytics/src/cli/index.ts +373 -0
  6. package/microservices/microservice-analytics/src/db/analytics.ts +564 -0
  7. package/microservices/microservice-analytics/src/db/database.ts +93 -0
  8. package/microservices/microservice-analytics/src/db/migrations.ts +50 -0
  9. package/microservices/microservice-analytics/src/index.ts +37 -0
  10. package/microservices/microservice-analytics/src/mcp/index.ts +334 -0
  11. package/microservices/microservice-assets/package.json +27 -0
  12. package/microservices/microservice-assets/src/cli/index.ts +375 -0
  13. package/microservices/microservice-assets/src/db/assets.ts +370 -0
  14. package/microservices/microservice-assets/src/db/database.ts +93 -0
  15. package/microservices/microservice-assets/src/db/migrations.ts +51 -0
  16. package/microservices/microservice-assets/src/index.ts +32 -0
  17. package/microservices/microservice-assets/src/mcp/index.ts +346 -0
  18. package/microservices/microservice-compliance/package.json +27 -0
  19. package/microservices/microservice-compliance/src/cli/index.ts +467 -0
  20. package/microservices/microservice-compliance/src/db/compliance.ts +633 -0
  21. package/microservices/microservice-compliance/src/db/database.ts +93 -0
  22. package/microservices/microservice-compliance/src/db/migrations.ts +63 -0
  23. package/microservices/microservice-compliance/src/index.ts +46 -0
  24. package/microservices/microservice-compliance/src/mcp/index.ts +438 -0
  25. package/microservices/microservice-habits/package.json +27 -0
  26. package/microservices/microservice-habits/src/cli/index.ts +315 -0
  27. package/microservices/microservice-habits/src/db/database.ts +93 -0
  28. package/microservices/microservice-habits/src/db/habits.ts +451 -0
  29. package/microservices/microservice-habits/src/db/migrations.ts +46 -0
  30. package/microservices/microservice-habits/src/index.ts +31 -0
  31. package/microservices/microservice-habits/src/mcp/index.ts +313 -0
  32. package/microservices/microservice-health/package.json +27 -0
  33. package/microservices/microservice-health/src/cli/index.ts +484 -0
  34. package/microservices/microservice-health/src/db/database.ts +93 -0
  35. package/microservices/microservice-health/src/db/health.ts +708 -0
  36. package/microservices/microservice-health/src/db/migrations.ts +70 -0
  37. package/microservices/microservice-health/src/index.ts +63 -0
  38. package/microservices/microservice-health/src/mcp/index.ts +437 -0
  39. package/microservices/microservice-leads/package.json +27 -0
  40. package/microservices/microservice-leads/src/cli/index.ts +596 -0
  41. package/microservices/microservice-leads/src/db/database.ts +93 -0
  42. package/microservices/microservice-leads/src/db/leads.ts +520 -0
  43. package/microservices/microservice-leads/src/db/lists.ts +151 -0
  44. package/microservices/microservice-leads/src/db/migrations.ts +93 -0
  45. package/microservices/microservice-leads/src/index.ts +65 -0
  46. package/microservices/microservice-leads/src/lib/enrichment.ts +202 -0
  47. package/microservices/microservice-leads/src/lib/scoring.ts +134 -0
  48. package/microservices/microservice-leads/src/mcp/index.ts +533 -0
  49. package/microservices/microservice-notifications/package.json +27 -0
  50. package/microservices/microservice-notifications/src/cli/index.ts +349 -0
  51. package/microservices/microservice-notifications/src/db/database.ts +93 -0
  52. package/microservices/microservice-notifications/src/db/migrations.ts +62 -0
  53. package/microservices/microservice-notifications/src/db/notifications.ts +509 -0
  54. package/microservices/microservice-notifications/src/index.ts +41 -0
  55. package/microservices/microservice-notifications/src/mcp/index.ts +422 -0
  56. package/microservices/microservice-products/package.json +27 -0
  57. package/microservices/microservice-products/src/cli/index.ts +416 -0
  58. package/microservices/microservice-products/src/db/categories.ts +154 -0
  59. package/microservices/microservice-products/src/db/database.ts +93 -0
  60. package/microservices/microservice-products/src/db/migrations.ts +58 -0
  61. package/microservices/microservice-products/src/db/pricing-tiers.ts +66 -0
  62. package/microservices/microservice-products/src/db/products.ts +452 -0
  63. package/microservices/microservice-products/src/index.ts +53 -0
  64. package/microservices/microservice-products/src/mcp/index.ts +453 -0
  65. package/microservices/microservice-projects/package.json +27 -0
  66. package/microservices/microservice-projects/src/cli/index.ts +480 -0
  67. package/microservices/microservice-projects/src/db/database.ts +93 -0
  68. package/microservices/microservice-projects/src/db/migrations.ts +65 -0
  69. package/microservices/microservice-projects/src/db/projects.ts +715 -0
  70. package/microservices/microservice-projects/src/index.ts +57 -0
  71. package/microservices/microservice-projects/src/mcp/index.ts +501 -0
  72. package/microservices/microservice-proposals/package.json +27 -0
  73. package/microservices/microservice-proposals/src/cli/index.ts +400 -0
  74. package/microservices/microservice-proposals/src/db/database.ts +93 -0
  75. package/microservices/microservice-proposals/src/db/migrations.ts +52 -0
  76. package/microservices/microservice-proposals/src/db/proposals.ts +532 -0
  77. package/microservices/microservice-proposals/src/index.ts +37 -0
  78. package/microservices/microservice-proposals/src/mcp/index.ts +375 -0
  79. package/microservices/microservice-reading/package.json +27 -0
  80. package/microservices/microservice-reading/src/cli/index.ts +464 -0
  81. package/microservices/microservice-reading/src/db/database.ts +93 -0
  82. package/microservices/microservice-reading/src/db/migrations.ts +59 -0
  83. package/microservices/microservice-reading/src/db/reading.ts +524 -0
  84. package/microservices/microservice-reading/src/index.ts +51 -0
  85. package/microservices/microservice-reading/src/mcp/index.ts +368 -0
  86. package/microservices/microservice-travel/package.json +27 -0
  87. package/microservices/microservice-travel/src/cli/index.ts +505 -0
  88. package/microservices/microservice-travel/src/db/database.ts +93 -0
  89. package/microservices/microservice-travel/src/db/migrations.ts +77 -0
  90. package/microservices/microservice-travel/src/db/travel.ts +802 -0
  91. package/microservices/microservice-travel/src/index.ts +60 -0
  92. package/microservices/microservice-travel/src/mcp/index.ts +495 -0
  93. package/microservices/microservice-wiki/package.json +27 -0
  94. package/microservices/microservice-wiki/src/cli/index.ts +345 -0
  95. package/microservices/microservice-wiki/src/db/database.ts +93 -0
  96. package/microservices/microservice-wiki/src/db/migrations.ts +55 -0
  97. package/microservices/microservice-wiki/src/db/wiki.ts +395 -0
  98. package/microservices/microservice-wiki/src/index.ts +32 -0
  99. package/microservices/microservice-wiki/src/mcp/index.ts +344 -0
  100. package/package.json +1 -1
package/bin/index.js CHANGED
@@ -3519,8 +3519,8 @@ var {
3519
3519
 
3520
3520
  // src/cli/index.tsx
3521
3521
  import chalk2 from "chalk";
3522
- import { existsSync as existsSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
3523
- import { join as join4 } from "path";
3522
+ import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
3523
+ import { join as join5 } from "path";
3524
3524
  import { homedir } from "os";
3525
3525
 
3526
3526
  // src/cli/components/App.tsx
@@ -3962,7 +3962,8 @@ var CATEGORIES = [
3962
3962
  "Productivity",
3963
3963
  "HR",
3964
3964
  "Analytics",
3965
- "Management"
3965
+ "Management",
3966
+ "Personal"
3966
3967
  ];
3967
3968
  var MICROSERVICES = [
3968
3969
  {
@@ -4028,6 +4029,20 @@ var MICROSERVICES = [
4028
4029
  category: "CRM",
4029
4030
  tags: ["social-media", "posts", "scheduling", "engagement", "analytics", "x", "linkedin", "instagram"]
4030
4031
  },
4032
+ {
4033
+ name: "leads",
4034
+ displayName: "Leads",
4035
+ description: "Lead generation, storage, scoring, and data enrichment with pipeline tracking, bulk import/export, and deduplication",
4036
+ category: "CRM",
4037
+ tags: ["leads", "lead-generation", "scoring", "enrichment", "pipeline", "dedup", "import", "export"]
4038
+ },
4039
+ {
4040
+ name: "proposals",
4041
+ displayName: "Proposals",
4042
+ description: "Create, send, track, and convert proposals with templates, expiry tracking, and conversion analytics",
4043
+ category: "CRM",
4044
+ tags: ["proposals", "quotes", "estimates", "sales", "clients", "conversion"]
4045
+ },
4031
4046
  {
4032
4047
  name: "inventory",
4033
4048
  displayName: "Inventory",
@@ -4056,6 +4071,34 @@ var MICROSERVICES = [
4056
4071
  category: "Operations",
4057
4072
  tags: ["domains", "dns", "ssl", "registrar", "nameservers", "whois", "certificates"]
4058
4073
  },
4074
+ {
4075
+ name: "products",
4076
+ displayName: "Products",
4077
+ description: "Product catalog with categories, pricing tiers, variants, bulk import/export, and inventory status tracking",
4078
+ category: "Operations",
4079
+ tags: ["products", "catalog", "pricing", "categories", "sku", "inventory", "import", "export"]
4080
+ },
4081
+ {
4082
+ name: "notifications",
4083
+ displayName: "Notifications",
4084
+ description: "Send notifications across channels (email, Slack, SMS, webhook, in-app) with rules, templates, variable substitution, and event processing",
4085
+ category: "Operations",
4086
+ tags: ["notifications", "alerts", "email", "slack", "sms", "webhook", "in-app", "templates", "rules", "events"]
4087
+ },
4088
+ {
4089
+ name: "projects",
4090
+ displayName: "Projects",
4091
+ description: "Project management with milestones, deliverables, budget tracking, timelines, and progress reporting",
4092
+ category: "Operations",
4093
+ tags: ["projects", "milestones", "deliverables", "budget", "timeline", "planning", "tracking"]
4094
+ },
4095
+ {
4096
+ name: "compliance",
4097
+ displayName: "Compliance",
4098
+ description: "Compliance management with requirements tracking, license management, and audit scheduling across regulatory frameworks (GDPR, SOC2, HIPAA, PCI, ISO 27001)",
4099
+ category: "Operations",
4100
+ tags: ["compliance", "gdpr", "soc2", "hipaa", "pci", "iso27001", "audit", "licenses", "requirements", "regulatory"]
4101
+ },
4059
4102
  {
4060
4103
  name: "notes",
4061
4104
  displayName: "Notes",
@@ -4111,6 +4154,55 @@ var MICROSERVICES = [
4111
4154
  description: "Transcribe audio and video from files and URLs (YouTube, Vimeo, Wistia, etc.) using ElevenLabs or OpenAI Whisper",
4112
4155
  category: "Productivity",
4113
4156
  tags: ["transcription", "audio", "video", "youtube", "vimeo", "wistia", "elevenlabs", "openai", "whisper", "speech-to-text"]
4157
+ },
4158
+ {
4159
+ name: "wiki",
4160
+ displayName: "Wiki",
4161
+ description: "Wiki with pages, version history, internal links, and hierarchical page trees",
4162
+ category: "Productivity",
4163
+ tags: ["wiki", "pages", "knowledge-base", "versioning", "links", "markdown"]
4164
+ },
4165
+ {
4166
+ name: "assets",
4167
+ displayName: "Assets",
4168
+ description: "Digital asset management with collections, tagging, metadata, and type-based organization",
4169
+ category: "Productivity",
4170
+ tags: ["assets", "files", "collections", "media", "images", "documents", "digital-assets"]
4171
+ },
4172
+ {
4173
+ name: "habits",
4174
+ displayName: "Habits",
4175
+ description: "Habit tracking with streaks, completions, and analytics \u2014 daily, weekly, and monthly habits with completion rates and reports",
4176
+ category: "Personal",
4177
+ tags: ["habits", "streaks", "tracking", "completions", "daily", "weekly", "goals", "wellness"]
4178
+ },
4179
+ {
4180
+ name: "health",
4181
+ displayName: "Health",
4182
+ description: "Health tracking with metrics, medications, appointments, and fitness logs",
4183
+ category: "Personal",
4184
+ tags: ["health", "metrics", "medications", "appointments", "fitness", "wellness", "medical"]
4185
+ },
4186
+ {
4187
+ name: "reading",
4188
+ displayName: "Reading",
4189
+ description: "Reading tracker with books, highlights, reading sessions, pace analytics, and progress tracking",
4190
+ category: "Personal",
4191
+ tags: ["reading", "books", "highlights", "sessions", "tracking", "pace", "library"]
4192
+ },
4193
+ {
4194
+ name: "travel",
4195
+ displayName: "Travel",
4196
+ description: "Travel management with trips, bookings, documents, loyalty programs, and budget tracking",
4197
+ category: "Personal",
4198
+ tags: ["travel", "trips", "bookings", "flights", "hotels", "loyalty", "documents", "budget"]
4199
+ },
4200
+ {
4201
+ name: "analytics",
4202
+ displayName: "Analytics",
4203
+ description: "Business analytics with KPIs, dashboards, reports, and AI-powered executive summaries",
4204
+ category: "Analytics",
4205
+ tags: ["analytics", "kpis", "dashboards", "reports", "metrics", "business-intelligence", "executive-summary"]
4114
4206
  }
4115
4207
  ];
4116
4208
  function getMicroservice(name) {
@@ -4862,6 +4954,28 @@ function resolveSourceDir() {
4862
4954
  return fromBin;
4863
4955
  }
4864
4956
  var SOURCE_DIR = resolveSourceDir();
4957
+ var PRESERVED_DB_FILES = new Set(["data.db", "data.db-wal", "data.db-shm"]);
4958
+ function getCliCandidates(baseDir) {
4959
+ return [
4960
+ join2(baseDir, "src", "cli", "index.ts"),
4961
+ join2(baseDir, "cli.ts"),
4962
+ join2(baseDir, "src", "index.ts")
4963
+ ];
4964
+ }
4965
+ function hasInstalledSource(baseDir) {
4966
+ return getCliCandidates(baseDir).some((candidate) => existsSync2(candidate));
4967
+ }
4968
+ function clearInstalledSource(baseDir) {
4969
+ if (!existsSync2(baseDir)) {
4970
+ return;
4971
+ }
4972
+ for (const entry of readdirSync(baseDir)) {
4973
+ if (PRESERVED_DB_FILES.has(entry)) {
4974
+ continue;
4975
+ }
4976
+ rmSync(join2(baseDir, entry), { recursive: true, force: true });
4977
+ }
4978
+ }
4865
4979
  function getMicroservicePath(name) {
4866
4980
  const msName = name.startsWith("microservice-") ? name : `microservice-${name}`;
4867
4981
  return join2(SOURCE_DIR, msName);
@@ -4899,6 +5013,9 @@ function installMicroservice(name, options = {}) {
4899
5013
  if (!existsSync2(targetDir)) {
4900
5014
  mkdirSync2(targetDir, { recursive: true });
4901
5015
  }
5016
+ if (existsSync2(destPath) && overwrite) {
5017
+ clearInstalledSource(destPath);
5018
+ }
4902
5019
  cpSync(sourcePath, destPath, { recursive: true });
4903
5020
  return {
4904
5021
  microservice: cleanName,
@@ -4923,7 +5040,7 @@ function getInstalledMicroservices(targetDir) {
4923
5040
  }
4924
5041
  return readdirSync(dir).filter((f) => {
4925
5042
  const fullPath = join2(dir, f);
4926
- return f.startsWith("microservice-") && statSync(fullPath).isDirectory();
5043
+ return f.startsWith("microservice-") && statSync(fullPath).isDirectory() && hasInstalledSource(fullPath);
4927
5044
  }).map((f) => f.replace("microservice-", ""));
4928
5045
  }
4929
5046
  function removeMicroservice(name, options = {}) {
@@ -4952,7 +5069,7 @@ function getMicroserviceStatus(name) {
4952
5069
  const msName = name.startsWith("microservice-") ? name : `microservice-${name}`;
4953
5070
  const msPath = join2(dir, msName);
4954
5071
  const dbPath = join2(msPath, "data.db");
4955
- const installed = existsSync2(msPath);
5072
+ const installed = hasInstalledSource(msPath);
4956
5073
  const hasDatabase = existsSync2(dbPath);
4957
5074
  let dbSizeBytes = 0;
4958
5075
  if (hasDatabase) {
@@ -5274,6 +5391,65 @@ function App({ initialServices, overwrite = false }) {
5274
5391
  }, undefined, true, undefined, this);
5275
5392
  }
5276
5393
 
5394
+ // src/cli/config-utils.ts
5395
+ import { mkdirSync as mkdirSync3 } from "fs";
5396
+ import { dirname as dirname3 } from "path";
5397
+ function parseTimeoutMs(raw, fallback = 30000) {
5398
+ if (raw === undefined || raw.trim() === "") {
5399
+ return fallback;
5400
+ }
5401
+ const value = Number(raw);
5402
+ if (!Number.isInteger(value) || value <= 0) {
5403
+ throw new Error("Timeout must be a positive integer in milliseconds.");
5404
+ }
5405
+ return value;
5406
+ }
5407
+ function ensureParentDirectory(filePath) {
5408
+ mkdirSync3(dirname3(filePath), { recursive: true });
5409
+ }
5410
+ function upsertClaudeMcpConfig(content, command) {
5411
+ const parsed = content ? JSON.parse(content) : {};
5412
+ const config = parsed;
5413
+ if (!config.mcpServers) {
5414
+ config.mcpServers = {};
5415
+ }
5416
+ config.mcpServers.microservices = {
5417
+ type: "stdio",
5418
+ command,
5419
+ args: [],
5420
+ env: {}
5421
+ };
5422
+ return JSON.stringify(config, null, 2);
5423
+ }
5424
+ function upsertCodexMcpConfig(content, command) {
5425
+ const existing = content ?? "";
5426
+ if (existing.includes("[mcp_servers.microservices]")) {
5427
+ return { content: existing, alreadyRegistered: true };
5428
+ }
5429
+ const trimmed = existing.trimEnd();
5430
+ const prefix = trimmed.length > 0 ? `${trimmed}
5431
+
5432
+ ` : "";
5433
+ return {
5434
+ content: `${prefix}[mcp_servers.microservices]
5435
+ command = "${command}"
5436
+ `,
5437
+ alreadyRegistered: false
5438
+ };
5439
+ }
5440
+ function upsertGeminiMcpConfig(content, command) {
5441
+ const parsed = content ? JSON.parse(content) : {};
5442
+ const config = parsed;
5443
+ if (!config.mcpServers) {
5444
+ config.mcpServers = {};
5445
+ }
5446
+ config.mcpServers.microservices = {
5447
+ command,
5448
+ args: []
5449
+ };
5450
+ return JSON.stringify(config, null, 2);
5451
+ }
5452
+
5277
5453
  // src/lib/runner.ts
5278
5454
  import { existsSync as existsSync3 } from "fs";
5279
5455
  import { join as join3 } from "path";
@@ -5348,11 +5524,43 @@ async function getMicroserviceOperations(name) {
5348
5524
  return { commands, helpText };
5349
5525
  }
5350
5526
 
5527
+ // src/lib/package-info.ts
5528
+ import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
5529
+ import { dirname as dirname4, join as join4, resolve as resolve2 } from "path";
5530
+ import { fileURLToPath as fileURLToPath2 } from "url";
5531
+ var DEFAULT_VERSION = "0.0.1";
5532
+ function findNearestPackageJson(startDir) {
5533
+ let dir = resolve2(startDir);
5534
+ while (true) {
5535
+ const candidate = join4(dir, "package.json");
5536
+ if (existsSync4(candidate)) {
5537
+ return candidate;
5538
+ }
5539
+ const parent = dirname4(dir);
5540
+ if (parent === dir) {
5541
+ return null;
5542
+ }
5543
+ dir = parent;
5544
+ }
5545
+ }
5546
+ function readPackageVersion(packageJsonPath) {
5547
+ const raw = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
5548
+ return typeof raw.version === "string" && raw.version.length > 0 ? raw.version : DEFAULT_VERSION;
5549
+ }
5550
+ function getPackageVersion(startDir) {
5551
+ const resolvedStartDir = startDir ?? dirname4(fileURLToPath2(import.meta.url));
5552
+ const packageJsonPath = findNearestPackageJson(resolvedStartDir);
5553
+ if (!packageJsonPath) {
5554
+ return DEFAULT_VERSION;
5555
+ }
5556
+ return readPackageVersion(packageJsonPath);
5557
+ }
5558
+
5351
5559
  // src/cli/index.tsx
5352
5560
  import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
5353
5561
  var isTTY = process.stdout.isTTY ?? false;
5354
5562
  var program2 = new Command;
5355
- program2.name("microservices").description("Mini business apps for AI agents \u2014 invoices, contacts, bookkeeping and more").version("0.0.1").enablePositionalOptions();
5563
+ program2.name("microservices").description("Mini business apps for AI agents \u2014 invoices, contacts, bookkeeping and more").version(getPackageVersion()).enablePositionalOptions();
5356
5564
  program2.command("interactive", { isDefault: true }).alias("i").description("Interactive microservice browser").action(() => {
5357
5565
  if (!isTTY) {
5358
5566
  console.log(`Non-interactive environment detected. Use a subcommand:
@@ -5540,7 +5748,14 @@ program2.command("run").argument("<name>", "Microservice name").argument("[args.
5540
5748
  console.error(chalk2.red(`Microservice '${name}' is not installed or has no CLI.`));
5541
5749
  process.exit(1);
5542
5750
  }
5543
- const result = await runMicroserviceCommand(name, args, parseInt(options.timeout));
5751
+ let timeout;
5752
+ try {
5753
+ timeout = parseTimeoutMs(options.timeout);
5754
+ } catch (error) {
5755
+ console.error(chalk2.red(error instanceof Error ? error.message : String(error)));
5756
+ process.exit(1);
5757
+ }
5758
+ const result = await runMicroserviceCommand(name, args, timeout);
5544
5759
  if (result.stdout)
5545
5760
  console.log(result.stdout);
5546
5761
  if (result.stderr)
@@ -5563,21 +5778,13 @@ program2.command("ops").argument("<name>", "Microservice name").description("Lis
5563
5778
  program2.command("mcp").description("Register MCP server with AI coding agents").option("--register <target>", "Register with: claude, codex, gemini, or all", "all").action((options) => {
5564
5779
  const target = options.register;
5565
5780
  const mcpBin = "microservices-mcp";
5566
- const mcpBinFull = join4(homedir(), ".bun", "bin", "microservices-mcp");
5781
+ const mcpBinFull = join5(homedir(), ".bun", "bin", "microservices-mcp");
5567
5782
  let registered = 0;
5568
5783
  if (target === "all" || target === "claude") {
5569
- const claudePath = join4(homedir(), ".claude.json");
5784
+ const claudePath = join5(homedir(), ".claude.json");
5570
5785
  try {
5571
- const config = existsSync4(claudePath) ? JSON.parse(readFileSync2(claudePath, "utf-8")) : {};
5572
- if (!config.mcpServers)
5573
- config.mcpServers = {};
5574
- config.mcpServers.microservices = {
5575
- type: "stdio",
5576
- command: mcpBin,
5577
- args: [],
5578
- env: {}
5579
- };
5580
- writeFileSync2(claudePath, JSON.stringify(config, null, 2));
5786
+ const content = existsSync5(claudePath) ? readFileSync3(claudePath, "utf-8") : undefined;
5787
+ writeFileSync2(claudePath, upsertClaudeMcpConfig(content, mcpBin));
5581
5788
  console.log(chalk2.green(" + Claude Code") + chalk2.gray(` (${claudePath})`));
5582
5789
  registered++;
5583
5790
  } catch (e) {
@@ -5585,17 +5792,15 @@ program2.command("mcp").description("Register MCP server with AI coding agents")
5585
5792
  }
5586
5793
  }
5587
5794
  if (target === "all" || target === "codex") {
5588
- const codexPath = join4(homedir(), ".codex", "config.toml");
5795
+ const codexPath = join5(homedir(), ".codex", "config.toml");
5589
5796
  try {
5590
- let content = existsSync4(codexPath) ? readFileSync2(codexPath, "utf-8") : "";
5591
- if (content.includes("[mcp_servers.microservices]")) {
5797
+ const existing = existsSync5(codexPath) ? readFileSync3(codexPath, "utf-8") : undefined;
5798
+ const updated = upsertCodexMcpConfig(existing, mcpBin);
5799
+ if (updated.alreadyRegistered) {
5592
5800
  console.log(chalk2.yellow(" ~ Codex CLI (already registered)"));
5593
5801
  } else {
5594
- content += `
5595
- [mcp_servers.microservices]
5596
- command = "${mcpBin}"
5597
- `;
5598
- writeFileSync2(codexPath, content);
5802
+ ensureParentDirectory(codexPath);
5803
+ writeFileSync2(codexPath, updated.content);
5599
5804
  console.log(chalk2.green(" + Codex CLI") + chalk2.gray(` (${codexPath})`));
5600
5805
  }
5601
5806
  registered++;
@@ -5604,16 +5809,11 @@ command = "${mcpBin}"
5604
5809
  }
5605
5810
  }
5606
5811
  if (target === "all" || target === "gemini") {
5607
- const geminiPath = join4(homedir(), ".gemini", "settings.json");
5812
+ const geminiPath = join5(homedir(), ".gemini", "settings.json");
5608
5813
  try {
5609
- const config = existsSync4(geminiPath) ? JSON.parse(readFileSync2(geminiPath, "utf-8")) : {};
5610
- if (!config.mcpServers)
5611
- config.mcpServers = {};
5612
- config.mcpServers.microservices = {
5613
- command: mcpBinFull,
5614
- args: []
5615
- };
5616
- writeFileSync2(geminiPath, JSON.stringify(config, null, 2));
5814
+ const content = existsSync5(geminiPath) ? readFileSync3(geminiPath, "utf-8") : undefined;
5815
+ ensureParentDirectory(geminiPath);
5816
+ writeFileSync2(geminiPath, upsertGeminiMcpConfig(content, mcpBinFull));
5617
5817
  console.log(chalk2.green(" + Gemini CLI") + chalk2.gray(` (${geminiPath})`));
5618
5818
  registered++;
5619
5819
  } catch (e) {
package/bin/mcp.js CHANGED
@@ -19463,7 +19463,8 @@ var CATEGORIES = [
19463
19463
  "Productivity",
19464
19464
  "HR",
19465
19465
  "Analytics",
19466
- "Management"
19466
+ "Management",
19467
+ "Personal"
19467
19468
  ];
19468
19469
  var MICROSERVICES = [
19469
19470
  {
@@ -19529,6 +19530,20 @@ var MICROSERVICES = [
19529
19530
  category: "CRM",
19530
19531
  tags: ["social-media", "posts", "scheduling", "engagement", "analytics", "x", "linkedin", "instagram"]
19531
19532
  },
19533
+ {
19534
+ name: "leads",
19535
+ displayName: "Leads",
19536
+ description: "Lead generation, storage, scoring, and data enrichment with pipeline tracking, bulk import/export, and deduplication",
19537
+ category: "CRM",
19538
+ tags: ["leads", "lead-generation", "scoring", "enrichment", "pipeline", "dedup", "import", "export"]
19539
+ },
19540
+ {
19541
+ name: "proposals",
19542
+ displayName: "Proposals",
19543
+ description: "Create, send, track, and convert proposals with templates, expiry tracking, and conversion analytics",
19544
+ category: "CRM",
19545
+ tags: ["proposals", "quotes", "estimates", "sales", "clients", "conversion"]
19546
+ },
19532
19547
  {
19533
19548
  name: "inventory",
19534
19549
  displayName: "Inventory",
@@ -19557,6 +19572,34 @@ var MICROSERVICES = [
19557
19572
  category: "Operations",
19558
19573
  tags: ["domains", "dns", "ssl", "registrar", "nameservers", "whois", "certificates"]
19559
19574
  },
19575
+ {
19576
+ name: "products",
19577
+ displayName: "Products",
19578
+ description: "Product catalog with categories, pricing tiers, variants, bulk import/export, and inventory status tracking",
19579
+ category: "Operations",
19580
+ tags: ["products", "catalog", "pricing", "categories", "sku", "inventory", "import", "export"]
19581
+ },
19582
+ {
19583
+ name: "notifications",
19584
+ displayName: "Notifications",
19585
+ description: "Send notifications across channels (email, Slack, SMS, webhook, in-app) with rules, templates, variable substitution, and event processing",
19586
+ category: "Operations",
19587
+ tags: ["notifications", "alerts", "email", "slack", "sms", "webhook", "in-app", "templates", "rules", "events"]
19588
+ },
19589
+ {
19590
+ name: "projects",
19591
+ displayName: "Projects",
19592
+ description: "Project management with milestones, deliverables, budget tracking, timelines, and progress reporting",
19593
+ category: "Operations",
19594
+ tags: ["projects", "milestones", "deliverables", "budget", "timeline", "planning", "tracking"]
19595
+ },
19596
+ {
19597
+ name: "compliance",
19598
+ displayName: "Compliance",
19599
+ description: "Compliance management with requirements tracking, license management, and audit scheduling across regulatory frameworks (GDPR, SOC2, HIPAA, PCI, ISO 27001)",
19600
+ category: "Operations",
19601
+ tags: ["compliance", "gdpr", "soc2", "hipaa", "pci", "iso27001", "audit", "licenses", "requirements", "regulatory"]
19602
+ },
19560
19603
  {
19561
19604
  name: "notes",
19562
19605
  displayName: "Notes",
@@ -19612,6 +19655,55 @@ var MICROSERVICES = [
19612
19655
  description: "Transcribe audio and video from files and URLs (YouTube, Vimeo, Wistia, etc.) using ElevenLabs or OpenAI Whisper",
19613
19656
  category: "Productivity",
19614
19657
  tags: ["transcription", "audio", "video", "youtube", "vimeo", "wistia", "elevenlabs", "openai", "whisper", "speech-to-text"]
19658
+ },
19659
+ {
19660
+ name: "wiki",
19661
+ displayName: "Wiki",
19662
+ description: "Wiki with pages, version history, internal links, and hierarchical page trees",
19663
+ category: "Productivity",
19664
+ tags: ["wiki", "pages", "knowledge-base", "versioning", "links", "markdown"]
19665
+ },
19666
+ {
19667
+ name: "assets",
19668
+ displayName: "Assets",
19669
+ description: "Digital asset management with collections, tagging, metadata, and type-based organization",
19670
+ category: "Productivity",
19671
+ tags: ["assets", "files", "collections", "media", "images", "documents", "digital-assets"]
19672
+ },
19673
+ {
19674
+ name: "habits",
19675
+ displayName: "Habits",
19676
+ description: "Habit tracking with streaks, completions, and analytics \u2014 daily, weekly, and monthly habits with completion rates and reports",
19677
+ category: "Personal",
19678
+ tags: ["habits", "streaks", "tracking", "completions", "daily", "weekly", "goals", "wellness"]
19679
+ },
19680
+ {
19681
+ name: "health",
19682
+ displayName: "Health",
19683
+ description: "Health tracking with metrics, medications, appointments, and fitness logs",
19684
+ category: "Personal",
19685
+ tags: ["health", "metrics", "medications", "appointments", "fitness", "wellness", "medical"]
19686
+ },
19687
+ {
19688
+ name: "reading",
19689
+ displayName: "Reading",
19690
+ description: "Reading tracker with books, highlights, reading sessions, pace analytics, and progress tracking",
19691
+ category: "Personal",
19692
+ tags: ["reading", "books", "highlights", "sessions", "tracking", "pace", "library"]
19693
+ },
19694
+ {
19695
+ name: "travel",
19696
+ displayName: "Travel",
19697
+ description: "Travel management with trips, bookings, documents, loyalty programs, and budget tracking",
19698
+ category: "Personal",
19699
+ tags: ["travel", "trips", "bookings", "flights", "hotels", "loyalty", "documents", "budget"]
19700
+ },
19701
+ {
19702
+ name: "analytics",
19703
+ displayName: "Analytics",
19704
+ description: "Business analytics with KPIs, dashboards, reports, and AI-powered executive summaries",
19705
+ category: "Analytics",
19706
+ tags: ["analytics", "kpis", "dashboards", "reports", "metrics", "business-intelligence", "executive-summary"]
19615
19707
  }
19616
19708
  ];
19617
19709
  function getMicroservice(name) {
@@ -19677,6 +19769,28 @@ function resolveSourceDir() {
19677
19769
  return fromBin;
19678
19770
  }
19679
19771
  var SOURCE_DIR = resolveSourceDir();
19772
+ var PRESERVED_DB_FILES = new Set(["data.db", "data.db-wal", "data.db-shm"]);
19773
+ function getCliCandidates(baseDir) {
19774
+ return [
19775
+ join2(baseDir, "src", "cli", "index.ts"),
19776
+ join2(baseDir, "cli.ts"),
19777
+ join2(baseDir, "src", "index.ts")
19778
+ ];
19779
+ }
19780
+ function hasInstalledSource(baseDir) {
19781
+ return getCliCandidates(baseDir).some((candidate) => existsSync2(candidate));
19782
+ }
19783
+ function clearInstalledSource(baseDir) {
19784
+ if (!existsSync2(baseDir)) {
19785
+ return;
19786
+ }
19787
+ for (const entry of readdirSync(baseDir)) {
19788
+ if (PRESERVED_DB_FILES.has(entry)) {
19789
+ continue;
19790
+ }
19791
+ rmSync(join2(baseDir, entry), { recursive: true, force: true });
19792
+ }
19793
+ }
19680
19794
  function getMicroservicePath(name) {
19681
19795
  const msName = name.startsWith("microservice-") ? name : `microservice-${name}`;
19682
19796
  return join2(SOURCE_DIR, msName);
@@ -19714,6 +19828,9 @@ function installMicroservice(name, options = {}) {
19714
19828
  if (!existsSync2(targetDir)) {
19715
19829
  mkdirSync2(targetDir, { recursive: true });
19716
19830
  }
19831
+ if (existsSync2(destPath) && overwrite) {
19832
+ clearInstalledSource(destPath);
19833
+ }
19717
19834
  cpSync(sourcePath, destPath, { recursive: true });
19718
19835
  return {
19719
19836
  microservice: cleanName,
@@ -19735,7 +19852,7 @@ function getInstalledMicroservices(targetDir) {
19735
19852
  }
19736
19853
  return readdirSync(dir).filter((f) => {
19737
19854
  const fullPath = join2(dir, f);
19738
- return f.startsWith("microservice-") && statSync(fullPath).isDirectory();
19855
+ return f.startsWith("microservice-") && statSync(fullPath).isDirectory() && hasInstalledSource(fullPath);
19739
19856
  }).map((f) => f.replace("microservice-", ""));
19740
19857
  }
19741
19858
  function removeMicroservice(name, options = {}) {
@@ -19764,7 +19881,7 @@ function getMicroserviceStatus(name) {
19764
19881
  const msName = name.startsWith("microservice-") ? name : `microservice-${name}`;
19765
19882
  const msPath = join2(dir, msName);
19766
19883
  const dbPath = join2(msPath, "data.db");
19767
- const installed = existsSync2(msPath);
19884
+ const installed = hasInstalledSource(msPath);
19768
19885
  const hasDatabase = existsSync2(dbPath);
19769
19886
  let dbSizeBytes = 0;
19770
19887
  if (hasDatabase) {
@@ -19855,10 +19972,42 @@ async function getMicroserviceOperations(name) {
19855
19972
  return { commands, helpText };
19856
19973
  }
19857
19974
 
19975
+ // src/lib/package-info.ts
19976
+ import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
19977
+ import { dirname as dirname3, join as join4, resolve as resolve2 } from "path";
19978
+ import { fileURLToPath as fileURLToPath2 } from "url";
19979
+ var DEFAULT_VERSION = "0.0.1";
19980
+ function findNearestPackageJson(startDir) {
19981
+ let dir = resolve2(startDir);
19982
+ while (true) {
19983
+ const candidate = join4(dir, "package.json");
19984
+ if (existsSync4(candidate)) {
19985
+ return candidate;
19986
+ }
19987
+ const parent = dirname3(dir);
19988
+ if (parent === dir) {
19989
+ return null;
19990
+ }
19991
+ dir = parent;
19992
+ }
19993
+ }
19994
+ function readPackageVersion(packageJsonPath) {
19995
+ const raw = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
19996
+ return typeof raw.version === "string" && raw.version.length > 0 ? raw.version : DEFAULT_VERSION;
19997
+ }
19998
+ function getPackageVersion(startDir) {
19999
+ const resolvedStartDir = startDir ?? dirname3(fileURLToPath2(import.meta.url));
20000
+ const packageJsonPath = findNearestPackageJson(resolvedStartDir);
20001
+ if (!packageJsonPath) {
20002
+ return DEFAULT_VERSION;
20003
+ }
20004
+ return readPackageVersion(packageJsonPath);
20005
+ }
20006
+
19858
20007
  // src/mcp/index.ts
19859
20008
  var server = new McpServer({
19860
20009
  name: "microservices",
19861
- version: "0.0.1"
20010
+ version: getPackageVersion()
19862
20011
  });
19863
20012
  server.registerTool("search_microservices", {
19864
20013
  title: "Search Microservices",