@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.
- package/bin/index.js +236 -36
- package/bin/mcp.js +153 -4
- package/dist/index.js +120 -3
- package/microservices/microservice-analytics/package.json +27 -0
- package/microservices/microservice-analytics/src/cli/index.ts +373 -0
- package/microservices/microservice-analytics/src/db/analytics.ts +564 -0
- package/microservices/microservice-analytics/src/db/database.ts +93 -0
- package/microservices/microservice-analytics/src/db/migrations.ts +50 -0
- package/microservices/microservice-analytics/src/index.ts +37 -0
- package/microservices/microservice-analytics/src/mcp/index.ts +334 -0
- package/microservices/microservice-assets/package.json +27 -0
- package/microservices/microservice-assets/src/cli/index.ts +375 -0
- package/microservices/microservice-assets/src/db/assets.ts +370 -0
- package/microservices/microservice-assets/src/db/database.ts +93 -0
- package/microservices/microservice-assets/src/db/migrations.ts +51 -0
- package/microservices/microservice-assets/src/index.ts +32 -0
- package/microservices/microservice-assets/src/mcp/index.ts +346 -0
- package/microservices/microservice-compliance/package.json +27 -0
- package/microservices/microservice-compliance/src/cli/index.ts +467 -0
- package/microservices/microservice-compliance/src/db/compliance.ts +633 -0
- package/microservices/microservice-compliance/src/db/database.ts +93 -0
- package/microservices/microservice-compliance/src/db/migrations.ts +63 -0
- package/microservices/microservice-compliance/src/index.ts +46 -0
- package/microservices/microservice-compliance/src/mcp/index.ts +438 -0
- package/microservices/microservice-habits/package.json +27 -0
- package/microservices/microservice-habits/src/cli/index.ts +315 -0
- package/microservices/microservice-habits/src/db/database.ts +93 -0
- package/microservices/microservice-habits/src/db/habits.ts +451 -0
- package/microservices/microservice-habits/src/db/migrations.ts +46 -0
- package/microservices/microservice-habits/src/index.ts +31 -0
- package/microservices/microservice-habits/src/mcp/index.ts +313 -0
- package/microservices/microservice-health/package.json +27 -0
- package/microservices/microservice-health/src/cli/index.ts +484 -0
- package/microservices/microservice-health/src/db/database.ts +93 -0
- package/microservices/microservice-health/src/db/health.ts +708 -0
- package/microservices/microservice-health/src/db/migrations.ts +70 -0
- package/microservices/microservice-health/src/index.ts +63 -0
- package/microservices/microservice-health/src/mcp/index.ts +437 -0
- package/microservices/microservice-leads/package.json +27 -0
- package/microservices/microservice-leads/src/cli/index.ts +596 -0
- package/microservices/microservice-leads/src/db/database.ts +93 -0
- package/microservices/microservice-leads/src/db/leads.ts +520 -0
- package/microservices/microservice-leads/src/db/lists.ts +151 -0
- package/microservices/microservice-leads/src/db/migrations.ts +93 -0
- package/microservices/microservice-leads/src/index.ts +65 -0
- package/microservices/microservice-leads/src/lib/enrichment.ts +202 -0
- package/microservices/microservice-leads/src/lib/scoring.ts +134 -0
- package/microservices/microservice-leads/src/mcp/index.ts +533 -0
- package/microservices/microservice-notifications/package.json +27 -0
- package/microservices/microservice-notifications/src/cli/index.ts +349 -0
- package/microservices/microservice-notifications/src/db/database.ts +93 -0
- package/microservices/microservice-notifications/src/db/migrations.ts +62 -0
- package/microservices/microservice-notifications/src/db/notifications.ts +509 -0
- package/microservices/microservice-notifications/src/index.ts +41 -0
- package/microservices/microservice-notifications/src/mcp/index.ts +422 -0
- package/microservices/microservice-products/package.json +27 -0
- package/microservices/microservice-products/src/cli/index.ts +416 -0
- package/microservices/microservice-products/src/db/categories.ts +154 -0
- package/microservices/microservice-products/src/db/database.ts +93 -0
- package/microservices/microservice-products/src/db/migrations.ts +58 -0
- package/microservices/microservice-products/src/db/pricing-tiers.ts +66 -0
- package/microservices/microservice-products/src/db/products.ts +452 -0
- package/microservices/microservice-products/src/index.ts +53 -0
- package/microservices/microservice-products/src/mcp/index.ts +453 -0
- package/microservices/microservice-projects/package.json +27 -0
- package/microservices/microservice-projects/src/cli/index.ts +480 -0
- package/microservices/microservice-projects/src/db/database.ts +93 -0
- package/microservices/microservice-projects/src/db/migrations.ts +65 -0
- package/microservices/microservice-projects/src/db/projects.ts +715 -0
- package/microservices/microservice-projects/src/index.ts +57 -0
- package/microservices/microservice-projects/src/mcp/index.ts +501 -0
- package/microservices/microservice-proposals/package.json +27 -0
- package/microservices/microservice-proposals/src/cli/index.ts +400 -0
- package/microservices/microservice-proposals/src/db/database.ts +93 -0
- package/microservices/microservice-proposals/src/db/migrations.ts +52 -0
- package/microservices/microservice-proposals/src/db/proposals.ts +532 -0
- package/microservices/microservice-proposals/src/index.ts +37 -0
- package/microservices/microservice-proposals/src/mcp/index.ts +375 -0
- package/microservices/microservice-reading/package.json +27 -0
- package/microservices/microservice-reading/src/cli/index.ts +464 -0
- package/microservices/microservice-reading/src/db/database.ts +93 -0
- package/microservices/microservice-reading/src/db/migrations.ts +59 -0
- package/microservices/microservice-reading/src/db/reading.ts +524 -0
- package/microservices/microservice-reading/src/index.ts +51 -0
- package/microservices/microservice-reading/src/mcp/index.ts +368 -0
- package/microservices/microservice-travel/package.json +27 -0
- package/microservices/microservice-travel/src/cli/index.ts +505 -0
- package/microservices/microservice-travel/src/db/database.ts +93 -0
- package/microservices/microservice-travel/src/db/migrations.ts +77 -0
- package/microservices/microservice-travel/src/db/travel.ts +802 -0
- package/microservices/microservice-travel/src/index.ts +60 -0
- package/microservices/microservice-travel/src/mcp/index.ts +495 -0
- package/microservices/microservice-wiki/package.json +27 -0
- package/microservices/microservice-wiki/src/cli/index.ts +345 -0
- package/microservices/microservice-wiki/src/db/database.ts +93 -0
- package/microservices/microservice-wiki/src/db/migrations.ts +55 -0
- package/microservices/microservice-wiki/src/db/wiki.ts +395 -0
- package/microservices/microservice-wiki/src/index.ts +32 -0
- package/microservices/microservice-wiki/src/mcp/index.ts +344 -0
- 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
|
|
3523
|
-
import { join as
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
5781
|
+
const mcpBinFull = join5(homedir(), ".bun", "bin", "microservices-mcp");
|
|
5567
5782
|
let registered = 0;
|
|
5568
5783
|
if (target === "all" || target === "claude") {
|
|
5569
|
-
const claudePath =
|
|
5784
|
+
const claudePath = join5(homedir(), ".claude.json");
|
|
5570
5785
|
try {
|
|
5571
|
-
const
|
|
5572
|
-
|
|
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 =
|
|
5795
|
+
const codexPath = join5(homedir(), ".codex", "config.toml");
|
|
5589
5796
|
try {
|
|
5590
|
-
|
|
5591
|
-
|
|
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
|
-
|
|
5595
|
-
|
|
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 =
|
|
5812
|
+
const geminiPath = join5(homedir(), ".gemini", "settings.json");
|
|
5608
5813
|
try {
|
|
5609
|
-
const
|
|
5610
|
-
|
|
5611
|
-
|
|
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 =
|
|
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:
|
|
20010
|
+
version: getPackageVersion()
|
|
19862
20011
|
});
|
|
19863
20012
|
server.registerTool("search_microservices", {
|
|
19864
20013
|
title: "Search Microservices",
|