@hasna/connectors 1.3.44 → 1.3.46
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/README.md +25 -0
- package/bin/index.js +792 -130
- package/bin/mcp.js +438 -52
- package/bin/serve.js +438 -52
- package/connectors/cloudflare-workers/.env.example +5 -0
- package/connectors/cloudflare-workers/AGENTS.md +11 -0
- package/connectors/cloudflare-workers/CLAUDE.md +11 -0
- package/connectors/cloudflare-workers/README.md +45 -0
- package/connectors/cloudflare-workers/package.json +47 -0
- package/connectors/cloudflare-workers/src/api/client.test.ts +144 -0
- package/connectors/cloudflare-workers/src/api/client.ts +386 -0
- package/connectors/cloudflare-workers/src/api/index.ts +1 -0
- package/connectors/cloudflare-workers/src/cli/index.ts +206 -0
- package/connectors/cloudflare-workers/src/index.ts +16 -0
- package/connectors/cloudflare-workers/src/types/index.ts +53 -0
- package/connectors/cloudflare-workers/src/utils/config.ts +61 -0
- package/connectors/cloudflare-workers/src/utils/output.ts +26 -0
- package/connectors/cloudflare-workers/tsconfig.build.json +4 -0
- package/connectors/cloudflare-workers/tsconfig.json +14 -0
- package/connectors/tidio/.env.example +3 -2
- package/connectors/tidio/CLAUDE.md +21 -96
- package/connectors/tidio/README.md +22 -18
- package/connectors/tidio/package.json +4 -2
- package/connectors/tidio/src/api/client.ts +26 -15
- package/connectors/tidio/src/api/index.ts +185 -128
- package/connectors/tidio/src/api/tidio.test.ts +175 -44
- package/connectors/tidio/src/cli/index.ts +154 -388
- package/connectors/tidio/src/index.ts +5 -3
- package/connectors/tidio/src/types/index.ts +135 -82
- package/connectors/tidio/src/utils/config.ts +90 -44
- package/connectors/wandb/.env.example +7 -0
- package/connectors/wandb/AGENTS.md +43 -0
- package/connectors/wandb/CLAUDE.md +67 -0
- package/connectors/wandb/README.md +65 -0
- package/connectors/wandb/package.json +52 -0
- package/connectors/wandb/src/api/client.test.ts +116 -0
- package/connectors/wandb/src/api/client.ts +83 -0
- package/connectors/wandb/src/api/graphql.ts +9 -0
- package/connectors/wandb/src/api/index.ts +36 -0
- package/connectors/wandb/src/api/projects.ts +36 -0
- package/connectors/wandb/src/api/viewer.ts +20 -0
- package/connectors/wandb/src/cli/index.ts +265 -0
- package/connectors/wandb/src/index.ts +22 -0
- package/connectors/wandb/src/types/index.ts +75 -0
- package/connectors/wandb/src/utils/config.ts +164 -0
- package/connectors/wandb/src/utils/output.ts +119 -0
- package/connectors/wandb/tsconfig.json +16 -0
- package/connectors/weights-biases/.env.example +7 -0
- package/connectors/weights-biases/CLAUDE.md +65 -0
- package/connectors/weights-biases/README.md +62 -0
- package/connectors/weights-biases/package.json +53 -0
- package/connectors/weights-biases/src/api/client.test.ts +46 -0
- package/connectors/weights-biases/src/api/client.ts +119 -0
- package/connectors/weights-biases/src/api/events.ts +18 -0
- package/connectors/weights-biases/src/api/index.ts +56 -0
- package/connectors/weights-biases/src/api/runs.ts +28 -0
- package/connectors/weights-biases/src/api/search.ts +10 -0
- package/connectors/weights-biases/src/cli/index.ts +289 -0
- package/connectors/weights-biases/src/index.ts +19 -0
- package/connectors/weights-biases/src/types/index.ts +92 -0
- package/connectors/weights-biases/src/utils/config.ts +168 -0
- package/connectors/weights-biases/src/utils/output.ts +116 -0
- package/connectors/weights-biases/tsconfig.json +16 -0
- package/connectors/zoominfo/.env.example +4 -0
- package/connectors/zoominfo/AGENTS.md +26 -0
- package/connectors/zoominfo/CLAUDE.md +20 -0
- package/connectors/zoominfo/README.md +69 -0
- package/connectors/zoominfo/package.json +52 -0
- package/connectors/zoominfo/src/api/client.test.ts +140 -0
- package/connectors/zoominfo/src/api/client.ts +228 -0
- package/connectors/zoominfo/src/api/index.ts +1 -0
- package/connectors/zoominfo/src/cli/index.ts +179 -0
- package/connectors/zoominfo/src/index.ts +3 -0
- package/connectors/zoominfo/src/types/index.ts +39 -0
- package/connectors/zoominfo/src/utils/config.ts +61 -0
- package/connectors/zoominfo/src/utils/output.ts +27 -0
- package/connectors/zoominfo/tsconfig.json +20 -0
- package/connectors/zotero/.env.example +7 -0
- package/connectors/zotero/.npmrc.example +2 -0
- package/connectors/zotero/AGENTS.md +40 -0
- package/connectors/zotero/CLAUDE.md +69 -0
- package/connectors/zotero/README.md +91 -0
- package/connectors/zotero/package.json +43 -0
- package/connectors/zotero/src/api/attachments.ts +130 -0
- package/connectors/zotero/src/api/client.test.ts +166 -0
- package/connectors/zotero/src/api/client.ts +169 -0
- package/connectors/zotero/src/api/collections.ts +26 -0
- package/connectors/zotero/src/api/index.ts +45 -0
- package/connectors/zotero/src/api/items.ts +64 -0
- package/connectors/zotero/src/cli/index.ts +386 -0
- package/connectors/zotero/src/index.ts +28 -0
- package/connectors/zotero/src/types/index.ts +129 -0
- package/connectors/zotero/src/utils/config.ts +245 -0
- package/connectors/zotero/src/utils/output.ts +119 -0
- package/connectors/zotero/tsconfig.json +16 -0
- package/connectors/zymbly/.env.example +2 -0
- package/connectors/zymbly/AGENTS.md +11 -0
- package/connectors/zymbly/CLAUDE.md +5 -0
- package/connectors/zymbly/README.md +35 -0
- package/connectors/zymbly/package.json +52 -0
- package/connectors/zymbly/src/api/client.test.ts +110 -0
- package/connectors/zymbly/src/api/client.ts +166 -0
- package/connectors/zymbly/src/api/index.ts +1 -0
- package/connectors/zymbly/src/cli/index.ts +156 -0
- package/connectors/zymbly/src/index.ts +12 -0
- package/connectors/zymbly/src/types/index.ts +34 -0
- package/connectors/zymbly/src/utils/config.ts +52 -0
- package/connectors/zymbly/src/utils/output.ts +17 -0
- package/connectors/zymbly/tsconfig.json +13 -0
- package/dist/index.js +45 -2
- package/dist/lib/compact-output.d.ts +40 -0
- package/dist/mcp/tools/jobs.d.ts +32 -0
- package/dist/mcp/tools/jobs.test.d.ts +1 -0
- package/package.json +3 -2
package/bin/index.js
CHANGED
|
@@ -1909,7 +1909,7 @@ var package_default;
|
|
|
1909
1909
|
var init_package = __esm(() => {
|
|
1910
1910
|
package_default = {
|
|
1911
1911
|
name: "@hasna/connectors",
|
|
1912
|
-
version: "1.3.
|
|
1912
|
+
version: "1.3.46",
|
|
1913
1913
|
description: "Open source connector library - Install API connectors with a single command",
|
|
1914
1914
|
type: "module",
|
|
1915
1915
|
bin: {
|
|
@@ -1941,11 +1941,12 @@ var init_package = __esm(() => {
|
|
|
1941
1941
|
"build:dashboard": "cd dashboard && bun run build",
|
|
1942
1942
|
postinstall: 'mkdir -p $HOME/.hasna/connectors 2>/dev/null || true; [ "$SKIP_DASHBOARD" = "1" ] || [ ! -f dashboard/package.json ] || [ -d dashboard/node_modules ] || (cd dashboard && bun install)',
|
|
1943
1943
|
dev: "bun run ./src/cli/index.tsx",
|
|
1944
|
+
"check:package-secrets": "bun run scripts/check-package-secrets.ts",
|
|
1944
1945
|
typecheck: "tsc --noEmit && tsc -p tsconfig.social.json --noEmit",
|
|
1945
1946
|
test: "bun test",
|
|
1946
1947
|
"secrets:scan:npmrc": "bun run scripts/scan-npmrc-auth.mjs",
|
|
1947
1948
|
"sdk:build": "cd sdk && bun run build",
|
|
1948
|
-
prepublishOnly: "bun run secrets:scan:npmrc && bun run build && bun test"
|
|
1949
|
+
prepublishOnly: "bun run secrets:scan:npmrc && bun run check:package-secrets && bun run build && bun test"
|
|
1949
1950
|
},
|
|
1950
1951
|
keywords: [
|
|
1951
1952
|
"connectors",
|
|
@@ -22235,6 +22236,13 @@ var init_ai_ml = __esm(() => {
|
|
|
22235
22236
|
category: "AI & ML",
|
|
22236
22237
|
tags: ["transcription", "meetings", "ai"]
|
|
22237
22238
|
},
|
|
22239
|
+
{
|
|
22240
|
+
name: "wandb",
|
|
22241
|
+
displayName: "Weights & Biases",
|
|
22242
|
+
description: "ML experiment tracking and run management via GraphQL",
|
|
22243
|
+
category: "AI & ML",
|
|
22244
|
+
tags: ["ml", "experiments", "tracking"]
|
|
22245
|
+
},
|
|
22238
22246
|
{
|
|
22239
22247
|
name: "wato",
|
|
22240
22248
|
displayName: "Wato",
|
|
@@ -22242,6 +22250,13 @@ var init_ai_ml = __esm(() => {
|
|
|
22242
22250
|
category: "AI & ML",
|
|
22243
22251
|
tags: ["ai", "agents", "memory", "workflows"]
|
|
22244
22252
|
},
|
|
22253
|
+
{
|
|
22254
|
+
name: "weights-biases",
|
|
22255
|
+
displayName: "Weights & Biases",
|
|
22256
|
+
description: "ML experiment tracking (runs, events, search)",
|
|
22257
|
+
category: "AI & ML",
|
|
22258
|
+
tags: ["ai", "ml", "wandb", "experiment-tracking"]
|
|
22259
|
+
},
|
|
22245
22260
|
{
|
|
22246
22261
|
name: "wavelineextract",
|
|
22247
22262
|
displayName: "Waveline Extract",
|
|
@@ -23886,6 +23901,20 @@ var init_business_tools = __esm(() => {
|
|
|
23886
23901
|
description: "HR platform for employees, leave, attendance, and timesheets",
|
|
23887
23902
|
category: "Business Tools",
|
|
23888
23903
|
tags: ["hr", "employees", "zoho"]
|
|
23904
|
+
},
|
|
23905
|
+
{
|
|
23906
|
+
name: "zymbly",
|
|
23907
|
+
displayName: "Zymbly",
|
|
23908
|
+
description: "Aircraft maintenance and CMMS platform for work orders, parts, and maintenance notes",
|
|
23909
|
+
category: "Business Tools",
|
|
23910
|
+
tags: ["maintenance", "aircraft", "work-orders", "cmms"]
|
|
23911
|
+
},
|
|
23912
|
+
{
|
|
23913
|
+
name: "zotero",
|
|
23914
|
+
displayName: "Zotero",
|
|
23915
|
+
description: "Bibliography and reference library API for items, collections, and attachments",
|
|
23916
|
+
category: "Business Tools",
|
|
23917
|
+
tags: ["bibliography", "citations", "research", "library", "references"]
|
|
23889
23918
|
}
|
|
23890
23919
|
];
|
|
23891
23920
|
});
|
|
@@ -26414,6 +26443,13 @@ var init_developer_tools = __esm(() => {
|
|
|
26414
26443
|
category: "Developer Tools",
|
|
26415
26444
|
tags: ["cdn", "dns", "edge"]
|
|
26416
26445
|
},
|
|
26446
|
+
{
|
|
26447
|
+
name: "cloudflare-workers",
|
|
26448
|
+
displayName: "Cloudflare Workers",
|
|
26449
|
+
description: "Cloudflare Workers REST API connector for scripts, multipart uploads, routes, deployments, versions, secrets, cron schedules, tails, subdomains, beta Workers, and scoped raw account or zone requests",
|
|
26450
|
+
category: "Developer Tools",
|
|
26451
|
+
tags: ["cloudflare", "workers", "serverless", "edge", "deployments", "developer-tools"]
|
|
26452
|
+
},
|
|
26417
26453
|
{
|
|
26418
26454
|
name: "googlecloud",
|
|
26419
26455
|
displayName: "Google Cloud",
|
|
@@ -28821,6 +28857,13 @@ var init_marketing_sales = __esm(() => {
|
|
|
28821
28857
|
description: "Reviews and user-generated content platform for e-commerce",
|
|
28822
28858
|
category: "Marketing & Sales",
|
|
28823
28859
|
tags: ["reviews", "ugc", "ecommerce", "marketing"]
|
|
28860
|
+
},
|
|
28861
|
+
{
|
|
28862
|
+
name: "zoominfo",
|
|
28863
|
+
displayName: "ZoomInfo",
|
|
28864
|
+
description: "ZoomInfo B2B sales intelligence API for contact and company search, enrichment, lookup, and output field discovery",
|
|
28865
|
+
category: "Marketing & Sales",
|
|
28866
|
+
tags: ["sales-intelligence", "enrichment", "contacts", "companies", "b2b"]
|
|
28824
28867
|
}
|
|
28825
28868
|
];
|
|
28826
28869
|
});
|
|
@@ -31471,6 +31514,79 @@ var init_installer = __esm(() => {
|
|
|
31471
31514
|
CONNECTORS_DIR = resolveConnectorsDir();
|
|
31472
31515
|
});
|
|
31473
31516
|
|
|
31517
|
+
// src/lib/compact-output.ts
|
|
31518
|
+
function parseNonNegativeInt(raw, flag) {
|
|
31519
|
+
if (raw === undefined)
|
|
31520
|
+
return { value: undefined };
|
|
31521
|
+
if (!/^\d+$/.test(raw)) {
|
|
31522
|
+
return {
|
|
31523
|
+
value: undefined,
|
|
31524
|
+
error: `Invalid value for ${flag}: '${raw}'. Expected a non-negative integer.`
|
|
31525
|
+
};
|
|
31526
|
+
}
|
|
31527
|
+
return { value: parseInt(raw, 10) };
|
|
31528
|
+
}
|
|
31529
|
+
function normalizeLimit(value, fallback, max = MAX_COMPACT_LIMIT) {
|
|
31530
|
+
if (value === undefined || !Number.isFinite(value))
|
|
31531
|
+
return fallback;
|
|
31532
|
+
return Math.min(Math.max(1, Math.floor(value)), max);
|
|
31533
|
+
}
|
|
31534
|
+
function parseCursor(raw) {
|
|
31535
|
+
if (raw === undefined || raw === "")
|
|
31536
|
+
return { value: 0 };
|
|
31537
|
+
return parseNonNegativeInt(raw, "--cursor");
|
|
31538
|
+
}
|
|
31539
|
+
function pageItems(items, options) {
|
|
31540
|
+
const offset = Math.max(0, options.offset ?? 0);
|
|
31541
|
+
const limit = options.limit === undefined ? undefined : Math.max(1, Math.floor(options.limit));
|
|
31542
|
+
const paged = limit === undefined ? items.slice(offset) : items.slice(offset, offset + limit);
|
|
31543
|
+
const nextOffset = limit === undefined || offset + paged.length >= items.length ? null : offset + paged.length;
|
|
31544
|
+
return {
|
|
31545
|
+
items: paged,
|
|
31546
|
+
total: items.length,
|
|
31547
|
+
offset,
|
|
31548
|
+
limit: limit ?? null,
|
|
31549
|
+
nextOffset
|
|
31550
|
+
};
|
|
31551
|
+
}
|
|
31552
|
+
function truncateText(value, max = DEFAULT_TEXT_WIDTH) {
|
|
31553
|
+
const text = (value ?? "").replace(/\s+/g, " ").trim();
|
|
31554
|
+
if (text.length <= max)
|
|
31555
|
+
return text;
|
|
31556
|
+
if (max <= 3)
|
|
31557
|
+
return text.slice(0, max);
|
|
31558
|
+
return `${text.slice(0, max - 3).trimEnd()}...`;
|
|
31559
|
+
}
|
|
31560
|
+
function firstNonEmptyLines(value, maxLines, maxWidth = DEFAULT_TEXT_WIDTH) {
|
|
31561
|
+
return (value ?? "").split(`
|
|
31562
|
+
`).map((line) => line.trim()).filter(Boolean).slice(0, maxLines).map((line) => truncateText(line, maxWidth));
|
|
31563
|
+
}
|
|
31564
|
+
function compactConnector(connector, descriptionWidth = DEFAULT_TEXT_WIDTH) {
|
|
31565
|
+
return {
|
|
31566
|
+
name: connector.name,
|
|
31567
|
+
displayName: connector.displayName,
|
|
31568
|
+
version: connector.version,
|
|
31569
|
+
category: connector.category,
|
|
31570
|
+
description: truncateText(connector.description, descriptionWidth)
|
|
31571
|
+
};
|
|
31572
|
+
}
|
|
31573
|
+
function maybeTruncateOutput(text, options = {}) {
|
|
31574
|
+
const enabled = options.enabled ?? true;
|
|
31575
|
+
const maxChars = options.maxChars ?? DEFAULT_OUTPUT_CHARS;
|
|
31576
|
+
if (!enabled || text.length <= maxChars) {
|
|
31577
|
+
return { text, truncated: false };
|
|
31578
|
+
}
|
|
31579
|
+
const hint = options.hint ?? "Use --verbose for full output.";
|
|
31580
|
+
const omitted = text.length - maxChars;
|
|
31581
|
+
return {
|
|
31582
|
+
text: `${text.slice(0, maxChars).trimEnd()}
|
|
31583
|
+
|
|
31584
|
+
[truncated ${omitted} chars] ${hint}`,
|
|
31585
|
+
truncated: true
|
|
31586
|
+
};
|
|
31587
|
+
}
|
|
31588
|
+
var DEFAULT_COMPACT_LIMIT = 20, DEFAULT_MCP_LIMIT = 20, MAX_COMPACT_LIMIT = 100, DEFAULT_TEXT_WIDTH = 96, DEFAULT_OUTPUT_CHARS = 6000;
|
|
31589
|
+
|
|
31474
31590
|
// src/lib/lock.ts
|
|
31475
31591
|
import { openSync, closeSync, unlinkSync as unlinkSync2, existsSync as existsSync14, statSync as statSync6 } from "fs";
|
|
31476
31592
|
import { mkdirSync as mkdirSync7 } from "fs";
|
|
@@ -49612,26 +49728,44 @@ function registerDiscoveryTools(server, stripped) {
|
|
|
49612
49728
|
server.registerTool("search_connectors", {
|
|
49613
49729
|
title: "Search Connectors",
|
|
49614
49730
|
description: "Search connectors by name or keyword.",
|
|
49615
|
-
inputSchema: {
|
|
49616
|
-
|
|
49731
|
+
inputSchema: {
|
|
49732
|
+
query: exports_external.string(),
|
|
49733
|
+
limit: exports_external.number().optional(),
|
|
49734
|
+
verbose: exports_external.boolean().optional()
|
|
49735
|
+
}
|
|
49736
|
+
}, async ({ query, limit, verbose }) => {
|
|
49617
49737
|
const { getInstalledConnectors: getInstalledConnectors2 } = await Promise.resolve().then(() => (init_installer(), exports_installer));
|
|
49618
49738
|
const { getPromotedConnectors: getPromotedConnectors2 } = await Promise.resolve().then(() => (init_promotions(), exports_promotions));
|
|
49619
49739
|
const { getUsageMap: getUsageMap2 } = await Promise.resolve().then(() => (init_usage(), exports_usage));
|
|
49740
|
+
const resultLimit = normalizeLimit(limit, DEFAULT_MCP_LIMIT);
|
|
49620
49741
|
const results = searchConnectors(query, {
|
|
49621
49742
|
installed: getInstalledConnectors2(),
|
|
49622
49743
|
promoted: getPromotedConnectors2(),
|
|
49623
|
-
usage: getUsageMap2()
|
|
49744
|
+
usage: getUsageMap2(),
|
|
49745
|
+
limit: resultLimit
|
|
49624
49746
|
});
|
|
49625
|
-
return stripped(JSON.stringify(results.map((c) => ({
|
|
49747
|
+
return stripped(JSON.stringify(results.map((c) => ({
|
|
49748
|
+
name: c.name,
|
|
49749
|
+
displayName: c.displayName,
|
|
49750
|
+
version: c.version,
|
|
49751
|
+
category: c.category,
|
|
49752
|
+
description: verbose ? c.description : truncateText(c.description, 120),
|
|
49753
|
+
score: c.score,
|
|
49754
|
+
badges: c.badges,
|
|
49755
|
+
...verbose ? { matchReasons: c.matchReasons } : {}
|
|
49756
|
+
})), null, 2));
|
|
49626
49757
|
});
|
|
49627
49758
|
server.registerTool("list_connectors", {
|
|
49628
49759
|
title: "List Connectors",
|
|
49629
|
-
description: "List connectors.
|
|
49760
|
+
description: "List connectors with compact, paged defaults. Use verbose=true or compact=false for full metadata.",
|
|
49630
49761
|
inputSchema: {
|
|
49631
49762
|
category: exports_external.string().optional(),
|
|
49632
|
-
compact: exports_external.boolean().optional()
|
|
49763
|
+
compact: exports_external.boolean().optional(),
|
|
49764
|
+
limit: exports_external.number().optional(),
|
|
49765
|
+
cursor: exports_external.string().optional(),
|
|
49766
|
+
verbose: exports_external.boolean().optional()
|
|
49633
49767
|
}
|
|
49634
|
-
}, async ({ category, compact }) => {
|
|
49768
|
+
}, async ({ category, compact, limit, cursor, verbose }) => {
|
|
49635
49769
|
let connectors18 = CONNECTORS;
|
|
49636
49770
|
if (category) {
|
|
49637
49771
|
const matched = CATEGORIES.find((c) => c.toLowerCase() === category.toLowerCase());
|
|
@@ -49648,23 +49782,42 @@ function registerDiscoveryTools(server, stripped) {
|
|
|
49648
49782
|
}
|
|
49649
49783
|
connectors18 = getConnectorsByCategory(matched);
|
|
49650
49784
|
}
|
|
49651
|
-
const
|
|
49785
|
+
const parsedCursor = parseCursor(cursor);
|
|
49786
|
+
if (parsedCursor.error) {
|
|
49787
|
+
return {
|
|
49788
|
+
content: [{ type: "text", text: JSON.stringify({ error: parsedCursor.error }) }],
|
|
49789
|
+
isError: true
|
|
49790
|
+
};
|
|
49791
|
+
}
|
|
49792
|
+
const page = pageItems(connectors18, {
|
|
49793
|
+
offset: parsedCursor.value ?? 0,
|
|
49794
|
+
limit: normalizeLimit(limit, DEFAULT_MCP_LIMIT)
|
|
49795
|
+
});
|
|
49796
|
+
const data = compact === true ? page.items.map((c) => c.name) : verbose || compact === false ? page.items.map((c) => ({
|
|
49652
49797
|
name: c.name,
|
|
49653
49798
|
displayName: c.displayName,
|
|
49654
49799
|
version: c.version,
|
|
49655
49800
|
category: c.category,
|
|
49656
|
-
description: c.description
|
|
49657
|
-
|
|
49658
|
-
|
|
49801
|
+
description: c.description,
|
|
49802
|
+
tags: c.tags
|
|
49803
|
+
})) : page.items.map((c) => compactConnector(c, 120));
|
|
49804
|
+
return stripped(JSON.stringify({
|
|
49805
|
+
connectors: data,
|
|
49806
|
+
total: connectors18.length,
|
|
49807
|
+
count: data.length,
|
|
49808
|
+
nextCursor: page.nextOffset === null ? null : String(page.nextOffset),
|
|
49809
|
+
hint: page.nextOffset === null ? "Use verbose=true or compact=false for full connector metadata." : `Call again with cursor="${page.nextOffset}", or use verbose=true / compact=false for full connector metadata.`
|
|
49810
|
+
}, null, 2));
|
|
49659
49811
|
});
|
|
49660
49812
|
server.registerTool("connector_docs", {
|
|
49661
49813
|
title: "Connector Documentation",
|
|
49662
|
-
description: "Get connector docs. essential=true
|
|
49814
|
+
description: "Get compact connector docs by default. Use verbose=true for full parsed docs or essential=true for auth+env only.",
|
|
49663
49815
|
inputSchema: {
|
|
49664
49816
|
name: exports_external.string(),
|
|
49665
|
-
essential: exports_external.boolean().optional()
|
|
49817
|
+
essential: exports_external.boolean().optional(),
|
|
49818
|
+
verbose: exports_external.boolean().optional()
|
|
49666
49819
|
}
|
|
49667
|
-
}, async ({ name, essential }) => {
|
|
49820
|
+
}, async ({ name, essential, verbose }) => {
|
|
49668
49821
|
const meta = getConnector(name);
|
|
49669
49822
|
if (!meta) {
|
|
49670
49823
|
return {
|
|
@@ -49680,7 +49833,7 @@ function registerDiscoveryTools(server, stripped) {
|
|
|
49680
49833
|
isError: true
|
|
49681
49834
|
};
|
|
49682
49835
|
}
|
|
49683
|
-
const data = essential ? { name: meta.name, auth: docs.auth, envVars: docs.envVars } : {
|
|
49836
|
+
const data = essential ? { name: meta.name, auth: docs.auth, envVars: docs.envVars } : verbose ? {
|
|
49684
49837
|
name: meta.name,
|
|
49685
49838
|
displayName: meta.displayName,
|
|
49686
49839
|
version: meta.version,
|
|
@@ -49691,6 +49844,19 @@ function registerDiscoveryTools(server, stripped) {
|
|
|
49691
49844
|
envVars: docs.envVars,
|
|
49692
49845
|
cliCommands: docs.cliCommands,
|
|
49693
49846
|
dataStorage: docs.dataStorage
|
|
49847
|
+
} : {
|
|
49848
|
+
name: meta.name,
|
|
49849
|
+
displayName: meta.displayName,
|
|
49850
|
+
version: meta.version,
|
|
49851
|
+
category: meta.category,
|
|
49852
|
+
description: truncateText(meta.description, 120),
|
|
49853
|
+
overview: firstNonEmptyLines(docs.overview, 1, 140)[0] ?? "",
|
|
49854
|
+
auth: firstNonEmptyLines(docs.auth, 4, 140),
|
|
49855
|
+
envVars: docs.envVars.slice(0, 8),
|
|
49856
|
+
envVarCount: docs.envVars.length,
|
|
49857
|
+
cliCommands: firstNonEmptyLines(docs.cliCommands, 8, 140),
|
|
49858
|
+
dataStorage: firstNonEmptyLines(docs.dataStorage, 2, 140),
|
|
49859
|
+
hint: `Use connector_docs({ name: "${name}", verbose: true }) for full parsed docs, or raw CLI docs with connectors docs ${name} --raw.`
|
|
49694
49860
|
};
|
|
49695
49861
|
return {
|
|
49696
49862
|
content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
|
|
@@ -50125,9 +50291,11 @@ function registerOperationsTools(server, stripped) {
|
|
|
50125
50291
|
description: "Discover available API operations for a connector. Returns CLI commands the connector supports (e.g. messages, products, customers). Use this before run_connector_operation to know what's available.",
|
|
50126
50292
|
inputSchema: {
|
|
50127
50293
|
name: exports_external.string().describe("Connector name (e.g. stripe, gmail, anthropic)"),
|
|
50128
|
-
command: exports_external.string().optional().describe("Get detailed help for a specific subcommand (e.g. products, messages)")
|
|
50294
|
+
command: exports_external.string().optional().describe("Get detailed help for a specific subcommand (e.g. products, messages)"),
|
|
50295
|
+
verbose: exports_external.boolean().optional().describe("Include full auth status and raw help text."),
|
|
50296
|
+
limit: exports_external.number().optional().describe("Limit operation rows in compact mode.")
|
|
50129
50297
|
}
|
|
50130
|
-
}, async ({ name, command }) => {
|
|
50298
|
+
}, async ({ name, command, verbose, limit }) => {
|
|
50131
50299
|
const meta = getConnector(name);
|
|
50132
50300
|
if (!meta) {
|
|
50133
50301
|
return {
|
|
@@ -50159,6 +50327,32 @@ function registerOperationsTools(server, stripped) {
|
|
|
50159
50327
|
}
|
|
50160
50328
|
const ops = await getConnectorOperations(name);
|
|
50161
50329
|
const auth = getAuthStatus(name);
|
|
50330
|
+
if (!verbose) {
|
|
50331
|
+
const operationLimit = normalizeLimit(limit, 50);
|
|
50332
|
+
const operations = ops.operations.slice(0, operationLimit).map((operation) => ({
|
|
50333
|
+
name: operation.name,
|
|
50334
|
+
aliases: operation.aliases,
|
|
50335
|
+
usage: operation.usage,
|
|
50336
|
+
summary: truncateText(operation.summary || "", 140),
|
|
50337
|
+
source: operation.source
|
|
50338
|
+
}));
|
|
50339
|
+
return {
|
|
50340
|
+
content: [
|
|
50341
|
+
{
|
|
50342
|
+
type: "text",
|
|
50343
|
+
text: JSON.stringify({
|
|
50344
|
+
connector: name,
|
|
50345
|
+
displayName: meta.displayName,
|
|
50346
|
+
auth: { type: auth.type, configured: auth.configured },
|
|
50347
|
+
commands: ops.commands,
|
|
50348
|
+
operations,
|
|
50349
|
+
totalOperations: ops.operations.length,
|
|
50350
|
+
hint: `Use list_connector_operations({ name: "${name}", verbose: true }) for full help text, or command="<subcommand>" for one command.`
|
|
50351
|
+
}, null, 2)
|
|
50352
|
+
}
|
|
50353
|
+
]
|
|
50354
|
+
};
|
|
50355
|
+
}
|
|
50162
50356
|
return {
|
|
50163
50357
|
content: [
|
|
50164
50358
|
{
|
|
@@ -50182,9 +50376,11 @@ function registerOperationsTools(server, stripped) {
|
|
|
50182
50376
|
name: exports_external.string().describe("Connector name (e.g. stripe, gmail, anthropic)"),
|
|
50183
50377
|
args: exports_external.array(exports_external.string()).describe("CLI arguments for the connector command (e.g. ['products', 'list', '--limit', '5'])"),
|
|
50184
50378
|
format: exports_external.enum(["json", "pretty"]).optional().describe("Output format (default: json for structured parsing)"),
|
|
50185
|
-
timeout: exports_external.number().optional().describe("Timeout in milliseconds (default: 30000)")
|
|
50379
|
+
timeout: exports_external.number().optional().describe("Timeout in milliseconds (default: 30000)"),
|
|
50380
|
+
verbose: exports_external.boolean().optional().describe("Return full stdout/stderr without output truncation."),
|
|
50381
|
+
maxOutputChars: exports_external.number().optional().describe("Maximum output characters when verbose is false (default: 6000).")
|
|
50186
50382
|
}
|
|
50187
|
-
}, async ({ name, args, format, timeout }) => {
|
|
50383
|
+
}, async ({ name, args, format, timeout, verbose, maxOutputChars }) => {
|
|
50188
50384
|
const meta = getConnector(name);
|
|
50189
50385
|
if (!meta) {
|
|
50190
50386
|
return {
|
|
@@ -50207,6 +50403,11 @@ function registerOperationsTools(server, stripped) {
|
|
|
50207
50403
|
${result.stderr}`;
|
|
50208
50404
|
const looksLikeHelp = /Usage:|Commands:|Options:/i.test(combinedOutput);
|
|
50209
50405
|
if (!result.success && !looksLikeHelp) {
|
|
50406
|
+
const output = maybeTruncateOutput(result.stderr || result.stdout, {
|
|
50407
|
+
enabled: !verbose,
|
|
50408
|
+
maxChars: maxOutputChars ?? DEFAULT_OUTPUT_CHARS,
|
|
50409
|
+
hint: "Set verbose=true or maxOutputChars higher for full error output."
|
|
50410
|
+
});
|
|
50210
50411
|
return {
|
|
50211
50412
|
content: [
|
|
50212
50413
|
{
|
|
@@ -50214,7 +50415,9 @@ ${result.stderr}`;
|
|
|
50214
50415
|
text: JSON.stringify({
|
|
50215
50416
|
connector: name,
|
|
50216
50417
|
success: false,
|
|
50217
|
-
error:
|
|
50418
|
+
error: output.text,
|
|
50419
|
+
outputTruncated: output.truncated,
|
|
50420
|
+
hint: verbose ? undefined : "MCP error output is compact by default. Set verbose=true or maxOutputChars for more output."
|
|
50218
50421
|
}, null, 2)
|
|
50219
50422
|
}
|
|
50220
50423
|
],
|
|
@@ -50228,7 +50431,11 @@ ${result.stderr}`;
|
|
|
50228
50431
|
text: JSON.stringify({
|
|
50229
50432
|
connector: name,
|
|
50230
50433
|
success: true,
|
|
50231
|
-
output: looksLikeHelp ? (result.stdout || result.stderr).trim() : result.stdout
|
|
50434
|
+
output: maybeTruncateOutput(looksLikeHelp ? (result.stdout || result.stderr).trim() : result.stdout, {
|
|
50435
|
+
enabled: !verbose,
|
|
50436
|
+
maxChars: maxOutputChars ?? DEFAULT_OUTPUT_CHARS,
|
|
50437
|
+
hint: "Set verbose=true or maxOutputChars higher for full output."
|
|
50438
|
+
}).text
|
|
50232
50439
|
}, null, 2)
|
|
50233
50440
|
}
|
|
50234
50441
|
]
|
|
@@ -50249,11 +50456,14 @@ function registerSearchTools(server, stripped) {
|
|
|
50249
50456
|
description: "Search for available operations across installed connectors.",
|
|
50250
50457
|
inputSchema: {
|
|
50251
50458
|
query: exports_external.string(),
|
|
50252
|
-
installedOnly: exports_external.boolean().optional()
|
|
50459
|
+
installedOnly: exports_external.boolean().optional(),
|
|
50460
|
+
limit: exports_external.number().optional(),
|
|
50461
|
+
verbose: exports_external.boolean().optional()
|
|
50253
50462
|
}
|
|
50254
|
-
}, async ({ query, installedOnly }) => {
|
|
50463
|
+
}, async ({ query, installedOnly, limit, verbose }) => {
|
|
50255
50464
|
const installed = installedOnly ? getInstalledConnectors() : null;
|
|
50256
50465
|
const results = [];
|
|
50466
|
+
const resultLimit = normalizeLimit(limit, DEFAULT_MCP_LIMIT);
|
|
50257
50467
|
const connectors18 = installed || getInstalledConnectors();
|
|
50258
50468
|
for (const name of connectors18) {
|
|
50259
50469
|
try {
|
|
@@ -50272,22 +50482,31 @@ function registerSearchTools(server, stripped) {
|
|
|
50272
50482
|
results.push({
|
|
50273
50483
|
connector: name,
|
|
50274
50484
|
operation: operation.name,
|
|
50275
|
-
description: operation.summary || ops.helpText || ""
|
|
50485
|
+
description: verbose ? operation.summary || ops.helpText || "" : truncateText(operation.summary || ops.helpText || "", 160)
|
|
50276
50486
|
});
|
|
50487
|
+
if (results.length >= resultLimit)
|
|
50488
|
+
break;
|
|
50277
50489
|
}
|
|
50278
50490
|
}
|
|
50491
|
+
if (results.length >= resultLimit)
|
|
50492
|
+
break;
|
|
50279
50493
|
} catch {}
|
|
50280
50494
|
}
|
|
50281
|
-
return stripped(JSON.stringify(
|
|
50495
|
+
return stripped(JSON.stringify({
|
|
50496
|
+
results,
|
|
50497
|
+
count: results.length,
|
|
50498
|
+
hint: "Use limit=<n> for more rows and verbose=true for longer descriptions."
|
|
50499
|
+
}, null, 2));
|
|
50282
50500
|
});
|
|
50283
50501
|
server.registerTool("describe_tools", {
|
|
50284
50502
|
title: "Describe Tools",
|
|
50285
50503
|
description: "Get detailed documentation for a connector's operations.",
|
|
50286
50504
|
inputSchema: {
|
|
50287
50505
|
name: exports_external.string(),
|
|
50288
|
-
operation: exports_external.string().optional()
|
|
50506
|
+
operation: exports_external.string().optional(),
|
|
50507
|
+
verbose: exports_external.boolean().optional()
|
|
50289
50508
|
}
|
|
50290
|
-
}, async ({ name, operation }) => {
|
|
50509
|
+
}, async ({ name, operation, verbose }) => {
|
|
50291
50510
|
const meta = getConnector(name);
|
|
50292
50511
|
if (!meta) {
|
|
50293
50512
|
return {
|
|
@@ -50303,7 +50522,23 @@ function registerSearchTools(server, stripped) {
|
|
|
50303
50522
|
};
|
|
50304
50523
|
}
|
|
50305
50524
|
const ops = await getConnectorOperations(name);
|
|
50306
|
-
|
|
50525
|
+
if (verbose) {
|
|
50526
|
+
return stripped(JSON.stringify({ connector: name, displayName: meta.displayName, ...ops }, null, 2));
|
|
50527
|
+
}
|
|
50528
|
+
return stripped(JSON.stringify({
|
|
50529
|
+
connector: name,
|
|
50530
|
+
displayName: meta.displayName,
|
|
50531
|
+
commands: ops.commands,
|
|
50532
|
+
operations: ops.operations.map((item) => ({
|
|
50533
|
+
name: item.name,
|
|
50534
|
+
aliases: item.aliases,
|
|
50535
|
+
usage: item.usage,
|
|
50536
|
+
summary: truncateText(item.summary || "", 140),
|
|
50537
|
+
source: item.source
|
|
50538
|
+
})),
|
|
50539
|
+
totalOperations: ops.operations.length,
|
|
50540
|
+
hint: `Use describe_tools({ name: "${name}", verbose: true }) for full help text.`
|
|
50541
|
+
}, null, 2));
|
|
50307
50542
|
});
|
|
50308
50543
|
}
|
|
50309
50544
|
var init_search = __esm(() => {
|
|
@@ -50357,62 +50592,180 @@ var init_ranking = __esm(() => {
|
|
|
50357
50592
|
});
|
|
50358
50593
|
|
|
50359
50594
|
// src/mcp/tools/jobs.ts
|
|
50595
|
+
function normalizeOutputChars(value) {
|
|
50596
|
+
return normalizeLimit(value, DEFAULT_EXECUTION_OUTPUT_CHARS, MAX_EXECUTION_OUTPUT_CHARS);
|
|
50597
|
+
}
|
|
50598
|
+
function compactExecutionText(text, options, label) {
|
|
50599
|
+
return maybeTruncateOutput(text, {
|
|
50600
|
+
enabled: !options.verbose,
|
|
50601
|
+
maxChars: normalizeOutputChars(options.maxOutputChars),
|
|
50602
|
+
hint: `Set verbose=true or maxOutputChars higher for full ${label} output.`
|
|
50603
|
+
});
|
|
50604
|
+
}
|
|
50605
|
+
function compactJobExecutionResult(result, options = {}) {
|
|
50606
|
+
const output = compactExecutionText(result.output, options, "job");
|
|
50607
|
+
return {
|
|
50608
|
+
...result,
|
|
50609
|
+
output: output.text,
|
|
50610
|
+
outputTruncated: output.truncated,
|
|
50611
|
+
hint: options.verbose ? undefined : "MCP job output is compact by default. Set verbose=true or maxOutputChars for more output."
|
|
50612
|
+
};
|
|
50613
|
+
}
|
|
50614
|
+
function compactWorkflowExecutionResult(result, options = {}) {
|
|
50615
|
+
let truncatedOutputs = 0;
|
|
50616
|
+
const steps = result.steps.map((step) => {
|
|
50617
|
+
const output = compactExecutionText(step.output, options, "workflow step");
|
|
50618
|
+
if (output.truncated)
|
|
50619
|
+
truncatedOutputs++;
|
|
50620
|
+
return {
|
|
50621
|
+
...step,
|
|
50622
|
+
output: output.text,
|
|
50623
|
+
outputTruncated: output.truncated
|
|
50624
|
+
};
|
|
50625
|
+
});
|
|
50626
|
+
const finalOutput = compactExecutionText(result.final_output, options, "workflow final");
|
|
50627
|
+
if (finalOutput.truncated)
|
|
50628
|
+
truncatedOutputs++;
|
|
50629
|
+
return {
|
|
50630
|
+
...result,
|
|
50631
|
+
steps,
|
|
50632
|
+
final_output: finalOutput.text,
|
|
50633
|
+
finalOutputTruncated: finalOutput.truncated,
|
|
50634
|
+
truncatedOutputs,
|
|
50635
|
+
hint: options.verbose ? undefined : "MCP workflow output is compact by default. Set verbose=true or maxOutputChars for more output."
|
|
50636
|
+
};
|
|
50637
|
+
}
|
|
50360
50638
|
function registerJobsTools(server, stripped) {
|
|
50361
50639
|
server.registerTool("list_jobs", {
|
|
50362
50640
|
title: "List Jobs",
|
|
50363
|
-
description: "List scheduled connector jobs.",
|
|
50364
|
-
inputSchema: {
|
|
50365
|
-
|
|
50641
|
+
description: "List scheduled connector jobs with compact, paged defaults.",
|
|
50642
|
+
inputSchema: {
|
|
50643
|
+
limit: exports_external.number().optional(),
|
|
50644
|
+
cursor: exports_external.string().optional(),
|
|
50645
|
+
verbose: exports_external.boolean().optional()
|
|
50646
|
+
}
|
|
50647
|
+
}, async ({ limit, cursor, verbose }) => {
|
|
50648
|
+
const parsedCursor = parseCursor(cursor);
|
|
50649
|
+
if (parsedCursor.error) {
|
|
50650
|
+
return { content: [{ type: "text", text: JSON.stringify({ error: parsedCursor.error }) }], isError: true };
|
|
50651
|
+
}
|
|
50366
50652
|
const db = getDatabase();
|
|
50367
50653
|
const jobs = listJobs(db);
|
|
50368
|
-
|
|
50654
|
+
const page = pageItems(jobs, {
|
|
50655
|
+
offset: parsedCursor.value ?? 0,
|
|
50656
|
+
limit: normalizeLimit(limit, DEFAULT_MCP_LIMIT)
|
|
50657
|
+
});
|
|
50658
|
+
const data = verbose ? page.items : page.items.map((job) => ({
|
|
50659
|
+
name: job.name,
|
|
50660
|
+
connector: job.connector,
|
|
50661
|
+
command: `${job.command}${job.args.length ? ` ${job.args.join(" ")}` : ""}`,
|
|
50662
|
+
cron: job.cron,
|
|
50663
|
+
enabled: job.enabled,
|
|
50664
|
+
strip: job.strip,
|
|
50665
|
+
lastRunAt: job.last_run_at
|
|
50666
|
+
}));
|
|
50667
|
+
return stripped(JSON.stringify({
|
|
50668
|
+
jobs: data,
|
|
50669
|
+
total: jobs.length,
|
|
50670
|
+
count: data.length,
|
|
50671
|
+
nextCursor: page.nextOffset === null ? null : String(page.nextOffset),
|
|
50672
|
+
hint: "Use verbose=true for full job records, get_latest_job_run for run output, or connectors jobs show <name>."
|
|
50673
|
+
}, null, 2));
|
|
50369
50674
|
});
|
|
50370
50675
|
server.registerTool("get_latest_job_run", {
|
|
50371
50676
|
title: "Get Latest Job Run",
|
|
50372
|
-
description: "Get the most recent run output for a job.",
|
|
50373
|
-
inputSchema: {
|
|
50374
|
-
|
|
50677
|
+
description: "Get the most recent run output for a job. Output is truncated unless verbose=true.",
|
|
50678
|
+
inputSchema: {
|
|
50679
|
+
name: exports_external.string(),
|
|
50680
|
+
verbose: exports_external.boolean().optional(),
|
|
50681
|
+
maxOutputChars: exports_external.number().optional()
|
|
50682
|
+
}
|
|
50683
|
+
}, async ({ name, verbose, maxOutputChars }) => {
|
|
50375
50684
|
const db = getDatabase();
|
|
50376
50685
|
const job = getJobByName(name, db);
|
|
50377
50686
|
if (!job)
|
|
50378
50687
|
return { content: [{ type: "text", text: JSON.stringify({ error: `Job "${name}" not found` }) }], isError: true };
|
|
50379
50688
|
const run = getLatestRun(job.id, db);
|
|
50380
|
-
|
|
50689
|
+
if (!run)
|
|
50690
|
+
return stripped(JSON.stringify({ message: "No runs yet" }, null, 2));
|
|
50691
|
+
const outputLimit = normalizeLimit(maxOutputChars, 2000, 50000);
|
|
50692
|
+
return stripped(JSON.stringify({
|
|
50693
|
+
...run,
|
|
50694
|
+
raw_output: run.raw_output && !verbose ? truncateText(run.raw_output, outputLimit) : run.raw_output,
|
|
50695
|
+
stripped_output: run.stripped_output && !verbose ? truncateText(run.stripped_output, outputLimit) : run.stripped_output,
|
|
50696
|
+
hint: verbose ? undefined : "Long run output is truncated in MCP. Use verbose=true or maxOutputChars for more output."
|
|
50697
|
+
}, null, 2));
|
|
50381
50698
|
});
|
|
50382
50699
|
server.registerTool("run_job", {
|
|
50383
50700
|
title: "Run Job",
|
|
50384
50701
|
description: "Manually trigger a scheduled job.",
|
|
50385
|
-
inputSchema: {
|
|
50386
|
-
|
|
50702
|
+
inputSchema: {
|
|
50703
|
+
name: exports_external.string(),
|
|
50704
|
+
verbose: exports_external.boolean().optional().describe("Return full job output without truncation."),
|
|
50705
|
+
maxOutputChars: exports_external.number().optional().describe("Maximum output characters when verbose is false (default: 2000).")
|
|
50706
|
+
}
|
|
50707
|
+
}, async ({ name, verbose, maxOutputChars }) => {
|
|
50387
50708
|
const db = getDatabase();
|
|
50388
50709
|
const job = getJobByName(name, db);
|
|
50389
50710
|
if (!job)
|
|
50390
50711
|
return { content: [{ type: "text", text: JSON.stringify({ error: `Job "${name}" not found` }) }], isError: true };
|
|
50391
50712
|
const result = await triggerJob(job, db);
|
|
50392
|
-
return
|
|
50713
|
+
return stripped(JSON.stringify(compactJobExecutionResult(result, { verbose, maxOutputChars }), null, 2));
|
|
50393
50714
|
});
|
|
50394
50715
|
server.registerTool("list_workflows", {
|
|
50395
50716
|
title: "List Workflows",
|
|
50396
|
-
description: "List connector workflows.",
|
|
50397
|
-
inputSchema: {
|
|
50398
|
-
|
|
50717
|
+
description: "List connector workflows with compact, paged defaults.",
|
|
50718
|
+
inputSchema: {
|
|
50719
|
+
limit: exports_external.number().optional(),
|
|
50720
|
+
cursor: exports_external.string().optional(),
|
|
50721
|
+
verbose: exports_external.boolean().optional()
|
|
50722
|
+
}
|
|
50723
|
+
}, async ({ limit, cursor, verbose }) => {
|
|
50724
|
+
const parsedCursor = parseCursor(cursor);
|
|
50725
|
+
if (parsedCursor.error) {
|
|
50726
|
+
return { content: [{ type: "text", text: JSON.stringify({ error: parsedCursor.error }) }], isError: true };
|
|
50727
|
+
}
|
|
50399
50728
|
const db = getDatabase();
|
|
50400
50729
|
const workflows = listWorkflows(db);
|
|
50401
|
-
|
|
50730
|
+
const page = pageItems(workflows, {
|
|
50731
|
+
offset: parsedCursor.value ?? 0,
|
|
50732
|
+
limit: normalizeLimit(limit, DEFAULT_MCP_LIMIT)
|
|
50733
|
+
});
|
|
50734
|
+
const data = verbose ? page.items : page.items.map((workflow) => ({
|
|
50735
|
+
name: workflow.name,
|
|
50736
|
+
enabled: workflow.enabled,
|
|
50737
|
+
stepCount: workflow.steps.length,
|
|
50738
|
+
steps: workflow.steps.slice(0, 5).map((step) => ({
|
|
50739
|
+
connector: step.connector,
|
|
50740
|
+
command: step.command
|
|
50741
|
+
}))
|
|
50742
|
+
}));
|
|
50743
|
+
return stripped(JSON.stringify({
|
|
50744
|
+
workflows: data,
|
|
50745
|
+
total: workflows.length,
|
|
50746
|
+
count: data.length,
|
|
50747
|
+
nextCursor: page.nextOffset === null ? null : String(page.nextOffset),
|
|
50748
|
+
hint: "Use verbose=true for full workflow records, or connectors workflows show <name>."
|
|
50749
|
+
}, null, 2));
|
|
50402
50750
|
});
|
|
50403
50751
|
server.registerTool("run_workflow", {
|
|
50404
50752
|
title: "Run Workflow",
|
|
50405
50753
|
description: "Execute a connector workflow pipeline.",
|
|
50406
|
-
inputSchema: {
|
|
50407
|
-
|
|
50754
|
+
inputSchema: {
|
|
50755
|
+
name: exports_external.string(),
|
|
50756
|
+
verbose: exports_external.boolean().optional().describe("Return full workflow step output without truncation."),
|
|
50757
|
+
maxOutputChars: exports_external.number().optional().describe("Maximum output characters per output field when verbose is false (default: 2000).")
|
|
50758
|
+
}
|
|
50759
|
+
}, async ({ name, verbose, maxOutputChars }) => {
|
|
50408
50760
|
const db = getDatabase();
|
|
50409
50761
|
const wf = getWorkflowByName(name, db);
|
|
50410
50762
|
if (!wf)
|
|
50411
50763
|
return { content: [{ type: "text", text: JSON.stringify({ error: `Workflow "${name}" not found` }) }], isError: true };
|
|
50412
50764
|
const result = await runWorkflow(wf);
|
|
50413
|
-
return stripped(JSON.stringify(result, null, 2));
|
|
50765
|
+
return stripped(JSON.stringify(compactWorkflowExecutionResult(result, { verbose, maxOutputChars }), null, 2));
|
|
50414
50766
|
});
|
|
50415
50767
|
}
|
|
50768
|
+
var DEFAULT_EXECUTION_OUTPUT_CHARS = 2000, MAX_EXECUTION_OUTPUT_CHARS = 50000;
|
|
50416
50769
|
var init_jobs2 = __esm(() => {
|
|
50417
50770
|
init_zod();
|
|
50418
50771
|
init_database();
|
|
@@ -50472,11 +50825,38 @@ function registerAgentTools(server, stripped) {
|
|
|
50472
50825
|
});
|
|
50473
50826
|
server.registerTool("list_agents", {
|
|
50474
50827
|
title: "List Agents",
|
|
50475
|
-
description: "List
|
|
50476
|
-
inputSchema: {
|
|
50477
|
-
|
|
50828
|
+
description: "List registered agents with compact, paged defaults.",
|
|
50829
|
+
inputSchema: {
|
|
50830
|
+
limit: exports_external.number().optional(),
|
|
50831
|
+
cursor: exports_external.string().optional(),
|
|
50832
|
+
verbose: exports_external.boolean().optional()
|
|
50833
|
+
}
|
|
50834
|
+
}, async ({ limit, cursor, verbose }) => {
|
|
50835
|
+
const parsedCursor = parseCursor(cursor);
|
|
50836
|
+
if (parsedCursor.error) {
|
|
50837
|
+
return { content: [{ type: "text", text: JSON.stringify({ error: parsedCursor.error }) }], isError: true };
|
|
50838
|
+
}
|
|
50478
50839
|
const agents = listAgents();
|
|
50479
|
-
|
|
50840
|
+
const page = pageItems(agents, {
|
|
50841
|
+
offset: parsedCursor.value ?? 0,
|
|
50842
|
+
limit: normalizeLimit(limit, DEFAULT_MCP_LIMIT)
|
|
50843
|
+
});
|
|
50844
|
+
const data = verbose ? page.items : page.items.map((agent) => ({
|
|
50845
|
+
id: agent.id,
|
|
50846
|
+
name: agent.name,
|
|
50847
|
+
role: agent.role,
|
|
50848
|
+
lastSeenAt: agent.last_seen_at,
|
|
50849
|
+
projectId: agent.project_id
|
|
50850
|
+
}));
|
|
50851
|
+
return {
|
|
50852
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
50853
|
+
agents: data,
|
|
50854
|
+
total: agents.length,
|
|
50855
|
+
count: data.length,
|
|
50856
|
+
nextCursor: page.nextOffset === null ? null : String(page.nextOffset),
|
|
50857
|
+
hint: "Use verbose=true for full agent records."
|
|
50858
|
+
}, null, 2) }]
|
|
50859
|
+
};
|
|
50480
50860
|
});
|
|
50481
50861
|
server.registerTool("heartbeat", {
|
|
50482
50862
|
title: "Heartbeat",
|
|
@@ -53679,7 +54059,7 @@ function listFilesRecursive(dir, base = dir) {
|
|
|
53679
54059
|
return files;
|
|
53680
54060
|
}
|
|
53681
54061
|
function registerCommands(program2) {
|
|
53682
|
-
program2.command("install").alias("add").argument("[connectors...]", "Connectors to install").option("-o, --overwrite", "Overwrite existing connectors", false).option("-d, --dry-run", "Preview what would be installed without making changes", false).option("-c, --category <category>", "Install all connectors in a category").option("--preset <preset>", "Install a preset bundle (e.g. ai, fullstack, google)").option("--json", "Output results as JSON", false).description("Install one or more connectors").action((connectors18, options) => {
|
|
54062
|
+
program2.command("install").alias("add").argument("[connectors...]", "Connectors to install").option("-o, --overwrite", "Overwrite existing connectors", false).option("-d, --dry-run", "Preview what would be installed without making changes", false).option("-c, --category <category>", "Install all connectors in a category").option("--preset <preset>", "Install a preset bundle (e.g. ai, fullstack, google)").option("--json", "Output results as JSON", false).option("-v, --verbose", "Show full dry-run file lists", false).description("Install one or more connectors").action((connectors18, options) => {
|
|
53683
54063
|
if (options.category) {
|
|
53684
54064
|
const category = CATEGORIES.find((c) => c.toLowerCase() === options.category.toLowerCase());
|
|
53685
54065
|
if (!category) {
|
|
@@ -53783,9 +54163,13 @@ Dry run \u2014 no changes will be made
|
|
|
53783
54163
|
console.log(chalk2.dim(` manifest: ${a.manifestPath}`));
|
|
53784
54164
|
console.log(chalk2.dim(` index: ${a.indexPath}`));
|
|
53785
54165
|
if (a.files && a.files.length > 0) {
|
|
54166
|
+
const visibleFiles = options.verbose ? a.files : a.files.slice(0, 12);
|
|
53786
54167
|
console.log(chalk2.dim(` packaged runtime files (${a.files.length}):`));
|
|
53787
|
-
for (const f of
|
|
53788
|
-
console.log(chalk2.dim(` ${f}`));
|
|
54168
|
+
for (const f of visibleFiles) {
|
|
54169
|
+
console.log(chalk2.dim(` ${truncateText(f, 120)}`));
|
|
54170
|
+
}
|
|
54171
|
+
if (!options.verbose && a.files.length > visibleFiles.length) {
|
|
54172
|
+
console.log(chalk2.dim(` ... ${a.files.length - visibleFiles.length} more files (use --verbose)`));
|
|
53789
54173
|
}
|
|
53790
54174
|
}
|
|
53791
54175
|
console.log();
|
|
@@ -53915,20 +54299,42 @@ init_registry2();
|
|
|
53915
54299
|
init_installer();
|
|
53916
54300
|
init_auth();
|
|
53917
54301
|
import chalk3 from "chalk";
|
|
53918
|
-
function
|
|
53919
|
-
|
|
53920
|
-
|
|
53921
|
-
|
|
53922
|
-
|
|
54302
|
+
function printConnectorRows(connectors18, options = {}) {
|
|
54303
|
+
const nameWidth = 22;
|
|
54304
|
+
const versionWidth = 10;
|
|
54305
|
+
const categoryWidth = options.includeCategory ? 22 : 0;
|
|
54306
|
+
const descWidth = options.verbose ? 160 : 80;
|
|
54307
|
+
const categoryHeader = options.includeCategory ? chalk3.dim("Category".padEnd(categoryWidth)) : "";
|
|
54308
|
+
console.log(` ${chalk3.dim("Name".padEnd(nameWidth))}` + `${chalk3.dim("Version".padEnd(versionWidth))}` + categoryHeader + `${chalk3.dim("Description")}`);
|
|
54309
|
+
console.log(chalk3.dim(` ${"-".repeat(nameWidth + versionWidth + categoryWidth + 40)}`));
|
|
54310
|
+
for (const c of connectors18) {
|
|
54311
|
+
const description = options.verbose ? c.description : truncateText(c.description, descWidth);
|
|
54312
|
+
const category = options.includeCategory ? chalk3.dim(c.category.padEnd(categoryWidth)) : "";
|
|
54313
|
+
console.log(` ${chalk3.cyan(c.name.padEnd(nameWidth))}` + `${chalk3.dim((c.version || "-").padEnd(versionWidth))}` + category + description);
|
|
54314
|
+
}
|
|
54315
|
+
}
|
|
54316
|
+
function printPaginationHint(command, total, nextOffset, detailHint = true) {
|
|
54317
|
+
const parts = [
|
|
54318
|
+
nextOffset !== null ? `${command} --cursor ${nextOffset}` : null,
|
|
54319
|
+
detailHint ? "connectors info <name>" : null,
|
|
54320
|
+
`${command} --verbose`,
|
|
54321
|
+
`${command} --json`
|
|
54322
|
+
].filter(Boolean);
|
|
54323
|
+
if (parts.length > 0) {
|
|
54324
|
+
console.log(chalk3.dim(`
|
|
54325
|
+
More detail: ${parts.join(" | ")}`));
|
|
54326
|
+
}
|
|
54327
|
+
if (nextOffset !== null) {
|
|
54328
|
+
console.log(chalk3.dim(` Showing a compact page of ${total} total results.`));
|
|
53923
54329
|
}
|
|
53924
|
-
return { value: parseInt(raw, 10) };
|
|
53925
54330
|
}
|
|
53926
54331
|
function registerCommands2(program2) {
|
|
53927
|
-
program2.command("list").alias("ls").option("-c, --category <category>", "Filter by category").option("-a, --all", "Show all available connectors", false).option("-i, --installed", "Show only installed connectors", false).option("-b, --brief", "Output only connector names", false).option("--limit <n>", "Limit results").option("--offset <n>", "Skip first N results").option("--json", "Output as JSON", false).description("List available or installed connectors").action((options) => {
|
|
54332
|
+
program2.command("list").alias("ls").option("-c, --category <category>", "Filter by category").option("-a, --all", "Show all available connectors", false).option("-i, --installed", "Show only installed connectors", false).option("-b, --brief", "Output only connector names", false).option("--limit <n>", "Limit results").option("--offset <n>", "Skip first N results").option("--cursor <n>", "Cursor returned by compact output (same as --offset)").option("--json", "Output as JSON", false).option("-v, --verbose", "Show full human output instead of compact pages", false).description("List available or installed connectors").action((options) => {
|
|
53928
54333
|
const parsedLimit = parseNonNegativeInt(options.limit, "--limit");
|
|
53929
54334
|
const parsedOffset = parseNonNegativeInt(options.offset, "--offset");
|
|
53930
|
-
|
|
53931
|
-
|
|
54335
|
+
const parsedCursor = parseNonNegativeInt(options.cursor, "--cursor");
|
|
54336
|
+
if (parsedLimit.error || parsedOffset.error || parsedCursor.error) {
|
|
54337
|
+
const error2 = parsedLimit.error || parsedOffset.error || parsedCursor.error || "Invalid pagination options";
|
|
53932
54338
|
if (options.json) {
|
|
53933
54339
|
console.log(JSON.stringify({ error: error2 }));
|
|
53934
54340
|
} else {
|
|
@@ -53938,11 +54344,12 @@ function registerCommands2(program2) {
|
|
|
53938
54344
|
return;
|
|
53939
54345
|
}
|
|
53940
54346
|
const limit = parsedLimit.value;
|
|
53941
|
-
const offset = parsedOffset.value ?? 0;
|
|
54347
|
+
const offset = parsedCursor.value ?? parsedOffset.value ?? 0;
|
|
54348
|
+
const jsonLimit = limit === undefined ? undefined : Math.max(1, Math.floor(limit));
|
|
53942
54349
|
const page = (items) => {
|
|
53943
|
-
if (
|
|
54350
|
+
if (jsonLimit === undefined)
|
|
53944
54351
|
return items.slice(offset);
|
|
53945
|
-
return items.slice(offset, offset +
|
|
54352
|
+
return items.slice(offset, offset + jsonLimit);
|
|
53946
54353
|
};
|
|
53947
54354
|
if (options.brief) {
|
|
53948
54355
|
if (options.installed) {
|
|
@@ -53954,9 +54361,10 @@ function registerCommands2(program2) {
|
|
|
53954
54361
|
console.log(name);
|
|
53955
54362
|
}
|
|
53956
54363
|
} else if (options.category) {
|
|
53957
|
-
const
|
|
54364
|
+
const requestedCategory = options.category;
|
|
54365
|
+
const category = CATEGORIES.find((c) => c.toLowerCase() === requestedCategory.toLowerCase());
|
|
53958
54366
|
if (!category) {
|
|
53959
|
-
console.error(`Unknown category: ${
|
|
54367
|
+
console.error(`Unknown category: ${requestedCategory}`);
|
|
53960
54368
|
process.exit(1);
|
|
53961
54369
|
return;
|
|
53962
54370
|
}
|
|
@@ -53979,7 +54387,12 @@ function registerCommands2(program2) {
|
|
|
53979
54387
|
return;
|
|
53980
54388
|
}
|
|
53981
54389
|
if (options.installed) {
|
|
53982
|
-
const
|
|
54390
|
+
const installedSource = getInstalledConnectors();
|
|
54391
|
+
const installedPage = pageItems(installedSource, {
|
|
54392
|
+
offset,
|
|
54393
|
+
limit: limit ?? (options.verbose || options.all ? undefined : DEFAULT_COMPACT_LIMIT)
|
|
54394
|
+
});
|
|
54395
|
+
const installed = options.json ? page(installedSource) : installedPage.items;
|
|
53983
54396
|
if (installed.length === 0) {
|
|
53984
54397
|
if (options.json) {
|
|
53985
54398
|
console.log(JSON.stringify([]));
|
|
@@ -54026,8 +54439,9 @@ function registerCommands2(program2) {
|
|
|
54026
54439
|
const nameWidth = Math.max(6, ...statuses.map((s) => s.name.length)) + 2;
|
|
54027
54440
|
const catWidth = Math.max(10, ...statuses.map((s) => s.category.length)) + 2;
|
|
54028
54441
|
const authWidth = 10;
|
|
54442
|
+
const installedTitle = installedPage.limit === null ? `Installed connectors (${installedSource.length})` : `Installed connectors (showing ${installed.length} of ${installedSource.length})`;
|
|
54029
54443
|
console.log(chalk3.bold(`
|
|
54030
|
-
|
|
54444
|
+
${installedTitle}:
|
|
54031
54445
|
`));
|
|
54032
54446
|
console.log(` ${chalk3.dim("Name".padEnd(nameWidth))}` + `${chalk3.dim("Category".padEnd(catWidth))}` + `${chalk3.dim("Auth Type".padEnd(authWidth))}` + `${chalk3.dim("Status")}`);
|
|
54033
54447
|
console.log(chalk3.dim(` ${"\u2500".repeat(nameWidth + catWidth + authWidth + 24)}`));
|
|
@@ -54048,49 +54462,55 @@ Installed connectors (${installed.length}):
|
|
|
54048
54462
|
console.log(` ${chalk3.cyan(s.name.padEnd(nameWidth))}` + `${s.category.padEnd(catWidth)}` + `${authTypeLabel.padEnd(authWidth)}` + `${statusLabel}${expiryStr}`);
|
|
54049
54463
|
}
|
|
54050
54464
|
console.log();
|
|
54465
|
+
printPaginationHint("connectors list --installed", installedSource.length, installedPage.nextOffset);
|
|
54051
54466
|
return;
|
|
54052
54467
|
}
|
|
54053
54468
|
if (options.category) {
|
|
54054
|
-
const
|
|
54469
|
+
const requestedCategory = options.category;
|
|
54470
|
+
const category = CATEGORIES.find((c) => c.toLowerCase() === requestedCategory.toLowerCase());
|
|
54055
54471
|
if (!category) {
|
|
54056
54472
|
if (options.json) {
|
|
54057
|
-
console.log(JSON.stringify({ error: `Unknown category: ${
|
|
54473
|
+
console.log(JSON.stringify({ error: `Unknown category: ${requestedCategory}` }));
|
|
54058
54474
|
process.exit(1);
|
|
54059
54475
|
}
|
|
54060
|
-
console.log(chalk3.red(`Unknown category: ${
|
|
54476
|
+
console.log(chalk3.red(`Unknown category: ${requestedCategory}`));
|
|
54061
54477
|
console.log(chalk3.dim(`Available: ${CATEGORIES.join(", ")}`));
|
|
54062
54478
|
return;
|
|
54063
54479
|
}
|
|
54064
54480
|
const connectors18 = getConnectorsByCategory(category);
|
|
54065
|
-
const
|
|
54481
|
+
const humanPage = pageItems(connectors18, {
|
|
54482
|
+
offset,
|
|
54483
|
+
limit: limit ?? (options.verbose || options.all ? undefined : DEFAULT_COMPACT_LIMIT)
|
|
54484
|
+
});
|
|
54485
|
+
const pagedConnectors = options.json ? page(connectors18) : humanPage.items;
|
|
54066
54486
|
if (options.json) {
|
|
54067
54487
|
console.log(JSON.stringify(pagedConnectors));
|
|
54068
54488
|
return;
|
|
54069
54489
|
}
|
|
54490
|
+
const title = humanPage.limit === null ? `${category} (${connectors18.length})` : `${category} (showing ${pagedConnectors.length} of ${connectors18.length})`;
|
|
54070
54491
|
console.log(chalk3.bold(`
|
|
54071
|
-
${
|
|
54492
|
+
${title}:
|
|
54072
54493
|
`));
|
|
54073
|
-
|
|
54074
|
-
|
|
54075
|
-
for (const c of pagedConnectors) {
|
|
54076
|
-
console.log(` ${chalk3.cyan(c.name.padEnd(20))}${chalk3.dim((c.version || "-").padEnd(10))}${c.description}`);
|
|
54077
|
-
}
|
|
54494
|
+
printConnectorRows(pagedConnectors, { verbose: options.verbose });
|
|
54495
|
+
printPaginationHint(`connectors list --category "${category}"`, connectors18.length, humanPage.nextOffset);
|
|
54078
54496
|
return;
|
|
54079
54497
|
}
|
|
54080
54498
|
if (options.json) {
|
|
54081
54499
|
console.log(JSON.stringify(page(CONNECTORS)));
|
|
54082
54500
|
return;
|
|
54083
54501
|
}
|
|
54084
|
-
if (options.limit || options.offset) {
|
|
54085
|
-
const
|
|
54502
|
+
if (options.limit || options.offset || options.cursor || !options.all) {
|
|
54503
|
+
const humanPage = pageItems(CONNECTORS, {
|
|
54504
|
+
offset,
|
|
54505
|
+
limit: limit ?? (options.verbose || options.all ? undefined : DEFAULT_COMPACT_LIMIT)
|
|
54506
|
+
});
|
|
54507
|
+
const connectors18 = humanPage.items;
|
|
54508
|
+
const title = humanPage.limit === null ? `Available connectors (${CONNECTORS.length})` : `Available connectors (showing ${connectors18.length} of ${CONNECTORS.length})`;
|
|
54086
54509
|
console.log(chalk3.bold(`
|
|
54087
|
-
|
|
54510
|
+
${title}:
|
|
54088
54511
|
`));
|
|
54089
|
-
|
|
54090
|
-
|
|
54091
|
-
for (const c of connectors18) {
|
|
54092
|
-
console.log(` ${chalk3.cyan(c.name.padEnd(20))}` + `${chalk3.dim((c.version || "-").padEnd(10))}` + `${chalk3.dim(c.category.padEnd(24))}` + `${c.description}`);
|
|
54093
|
-
}
|
|
54512
|
+
printConnectorRows(connectors18, { includeCategory: true, verbose: options.verbose });
|
|
54513
|
+
printPaginationHint("connectors list", CONNECTORS.length, humanPage.nextOffset);
|
|
54094
54514
|
return;
|
|
54095
54515
|
}
|
|
54096
54516
|
console.log(chalk3.bold(`
|
|
@@ -54099,15 +54519,11 @@ Available connectors (${CONNECTORS.length}):
|
|
|
54099
54519
|
for (const category of CATEGORIES) {
|
|
54100
54520
|
const connectors18 = getConnectorsByCategory(category);
|
|
54101
54521
|
console.log(chalk3.bold(`${category} (${connectors18.length}):`));
|
|
54102
|
-
|
|
54103
|
-
console.log(chalk3.dim(` ${"\u2500".repeat(60)}`));
|
|
54104
|
-
for (const c of connectors18) {
|
|
54105
|
-
console.log(` ${chalk3.cyan(c.name.padEnd(20))}${chalk3.dim((c.version || "-").padEnd(10))}${c.description}`);
|
|
54106
|
-
}
|
|
54522
|
+
printConnectorRows(connectors18, { verbose: true });
|
|
54107
54523
|
console.log();
|
|
54108
54524
|
}
|
|
54109
54525
|
});
|
|
54110
|
-
program2.command("search").argument("<query>", "Search term").option("--json", "Output as JSON", false).option("--limit <n>", "Max results", "20").description("Search for connectors (ranked with fuzzy matching)").action((query, options) => {
|
|
54526
|
+
program2.command("search").argument("<query>", "Search term").option("--json", "Output as JSON", false).option("--limit <n>", "Max results", "20").option("-v, --verbose", "Show match details and full descriptions", false).description("Search for connectors (ranked with fuzzy matching)").action((query, options) => {
|
|
54111
54527
|
const parsedLimit = parseNonNegativeInt(options.limit, "--limit");
|
|
54112
54528
|
if (parsedLimit.error || parsedLimit.value === undefined) {
|
|
54113
54529
|
const error2 = parsedLimit.error || "Invalid --limit value";
|
|
@@ -54140,12 +54556,16 @@ Available connectors (${CONNECTORS.length}):
|
|
|
54140
54556
|
Found ${results.length} connector(s):
|
|
54141
54557
|
`));
|
|
54142
54558
|
console.log(` ${chalk3.dim("Name".padEnd(22))}${chalk3.dim("Score".padEnd(7))}${chalk3.dim("Category".padEnd(20))}${chalk3.dim("Description")}`);
|
|
54143
|
-
console.log(chalk3.dim(` ${"
|
|
54559
|
+
console.log(chalk3.dim(` ${"-".repeat(75)}`));
|
|
54144
54560
|
for (const c of results) {
|
|
54145
54561
|
const badges = c.badges.map((b) => b === "installed" ? chalk3.green("[INS]") : b === "hot" ? chalk3.red("[HOT]") : b === "promoted" ? chalk3.yellow("[PRO]") : "").join(" ");
|
|
54146
54562
|
const badgeStr = badges ? " " + badges : "";
|
|
54147
|
-
|
|
54563
|
+
const description = options.verbose ? c.description : truncateText(c.description, 72);
|
|
54564
|
+
const reasons = options.verbose && c.matchReasons.length > 0 ? chalk3.dim(` matches: ${c.matchReasons.join(", ")}`) : "";
|
|
54565
|
+
console.log(` ${chalk3.cyan(c.name.padEnd(22))}${String(c.score).padEnd(7)}${chalk3.dim(c.category.padEnd(20))}${description}${badgeStr}${reasons}`);
|
|
54148
54566
|
}
|
|
54567
|
+
console.log(chalk3.dim(`
|
|
54568
|
+
More detail: connectors info <name> | connectors search "${query}" --verbose | connectors search "${query}" --json`));
|
|
54149
54569
|
});
|
|
54150
54570
|
program2.command("info").argument("<connector>", "Connector name").option("--json", "Output as JSON", false).description("Show detailed info about a connector").action((connector, options) => {
|
|
54151
54571
|
const meta = getConnector(connector);
|
|
@@ -54176,7 +54596,7 @@ ${meta.displayName}`));
|
|
|
54176
54596
|
console.log(` Installed: ${isInstalled ? chalk3.green("yes") : "no"}`);
|
|
54177
54597
|
console.log(` Package: @hasna/connect-${meta.name}`);
|
|
54178
54598
|
});
|
|
54179
|
-
program2.command("docs").argument("<connector>", "Connector name").option("--json", "Output as structured JSON", false).option("--raw", "Output raw markdown", false).option("--essential", "Show auth and env vars only (no full docs)", false).description("Show connector documentation (auth, env vars, API, CLI commands)").action((connector, options) => {
|
|
54599
|
+
program2.command("docs").argument("<connector>", "Connector name").option("--json", "Output as structured JSON", false).option("--raw", "Output raw markdown", false).option("--essential", "Show auth and env vars only (no full docs)", false).option("-v, --verbose", "Show full parsed documentation sections", false).description("Show connector documentation (auth, env vars, API, CLI commands)").action((connector, options) => {
|
|
54180
54600
|
const meta = getConnector(connector);
|
|
54181
54601
|
if (!meta) {
|
|
54182
54602
|
if (options.json) {
|
|
@@ -54244,9 +54664,60 @@ Environment Variables`));
|
|
|
54244
54664
|
}, null, 2));
|
|
54245
54665
|
return;
|
|
54246
54666
|
}
|
|
54667
|
+
if (!options.verbose) {
|
|
54668
|
+
console.log(chalk3.bold(`
|
|
54669
|
+
${meta.displayName} - Documentation Summary`));
|
|
54670
|
+
console.log(chalk3.dim("-".repeat(50)));
|
|
54671
|
+
console.log(` Name: ${chalk3.cyan(meta.name)}`);
|
|
54672
|
+
console.log(` Version: ${meta.version || "-"}`);
|
|
54673
|
+
console.log(` Category: ${meta.category}`);
|
|
54674
|
+
console.log(` Description: ${truncateText(meta.description, 100)}`);
|
|
54675
|
+
const overview = firstNonEmptyLines(docs.overview, 1, 100);
|
|
54676
|
+
if (overview.length > 0) {
|
|
54677
|
+
console.log(chalk3.bold(`
|
|
54678
|
+
Overview`));
|
|
54679
|
+
console.log(` ${overview[0]}`);
|
|
54680
|
+
}
|
|
54681
|
+
const authLines = firstNonEmptyLines(docs.auth, 4, 100);
|
|
54682
|
+
if (authLines.length > 0) {
|
|
54683
|
+
console.log(chalk3.bold(`
|
|
54684
|
+
Authentication`));
|
|
54685
|
+
for (const line of authLines)
|
|
54686
|
+
console.log(` ${line}`);
|
|
54687
|
+
}
|
|
54688
|
+
if (docs.envVars.length > 0) {
|
|
54689
|
+
const visible = docs.envVars.slice(0, 8);
|
|
54690
|
+
console.log(chalk3.bold(`
|
|
54691
|
+
Environment Variables`));
|
|
54692
|
+
for (const v of visible) {
|
|
54693
|
+
console.log(` ${chalk3.cyan(v.variable.padEnd(30))}${truncateText(v.description, 80)}`);
|
|
54694
|
+
}
|
|
54695
|
+
if (docs.envVars.length > visible.length) {
|
|
54696
|
+
console.log(chalk3.dim(` ... ${docs.envVars.length - visible.length} more env vars`));
|
|
54697
|
+
}
|
|
54698
|
+
}
|
|
54699
|
+
const commandLines = firstNonEmptyLines(docs.cliCommands, 8, 100);
|
|
54700
|
+
if (commandLines.length > 0) {
|
|
54701
|
+
console.log(chalk3.bold(`
|
|
54702
|
+
CLI Commands`));
|
|
54703
|
+
for (const line of commandLines)
|
|
54704
|
+
console.log(` ${line}`);
|
|
54705
|
+
}
|
|
54706
|
+
const storageLines = firstNonEmptyLines(docs.dataStorage, 2, 100);
|
|
54707
|
+
if (storageLines.length > 0) {
|
|
54708
|
+
console.log(chalk3.bold(`
|
|
54709
|
+
Data Storage`));
|
|
54710
|
+
for (const line of storageLines)
|
|
54711
|
+
console.log(` ${line}`);
|
|
54712
|
+
}
|
|
54713
|
+
console.log(chalk3.dim(`
|
|
54714
|
+
More detail: connectors docs ${connector} --verbose | connectors docs ${connector} --raw | connectors docs ${connector} --json`));
|
|
54715
|
+
console.log();
|
|
54716
|
+
return;
|
|
54717
|
+
}
|
|
54247
54718
|
console.log(chalk3.bold(`
|
|
54248
54719
|
${meta.displayName} \u2014 Documentation`));
|
|
54249
|
-
console.log(chalk3.dim("
|
|
54720
|
+
console.log(chalk3.dim("-".repeat(50)));
|
|
54250
54721
|
if (docs.overview) {
|
|
54251
54722
|
console.log(chalk3.bold(`
|
|
54252
54723
|
Overview`));
|
|
@@ -54343,7 +54814,18 @@ import chalk4 from "chalk";
|
|
|
54343
54814
|
import { existsSync as existsSync20, readFileSync as readFileSync11 } from "fs";
|
|
54344
54815
|
import { join as join20 } from "path";
|
|
54345
54816
|
function registerCommands3(program2) {
|
|
54346
|
-
program2.command("status").option("--json", "Output as JSON", false).description("Show auth status of all configured connectors (project + global)").action((options) => {
|
|
54817
|
+
program2.command("status").option("--json", "Output as JSON", false).option("--limit <n>", "Limit rows per section in human output").option("--offset <n>", "Skip first N rows per section in human output").option("-v, --verbose", "Show all human rows", false).description("Show auth status of all configured connectors (project + global)").action((options) => {
|
|
54818
|
+
const parsedLimit = parseNonNegativeInt(options.limit, "--limit");
|
|
54819
|
+
const parsedOffset = parseNonNegativeInt(options.offset, "--offset");
|
|
54820
|
+
if (parsedLimit.error || parsedOffset.error) {
|
|
54821
|
+
const error2 = parsedLimit.error || parsedOffset.error || "Invalid pagination options";
|
|
54822
|
+
if (options.json)
|
|
54823
|
+
console.log(JSON.stringify({ error: error2 }));
|
|
54824
|
+
else
|
|
54825
|
+
console.log(chalk4.red(error2));
|
|
54826
|
+
process.exit(1);
|
|
54827
|
+
return;
|
|
54828
|
+
}
|
|
54347
54829
|
const installed = getInstalledConnectors();
|
|
54348
54830
|
const configDir = getConnectorsHome();
|
|
54349
54831
|
const seen = new Set;
|
|
@@ -54463,28 +54945,52 @@ function registerCommands3(program2) {
|
|
|
54463
54945
|
console.log(chalk4.bold(`
|
|
54464
54946
|
Connector Status
|
|
54465
54947
|
`));
|
|
54948
|
+
const humanLimit = options.verbose ? undefined : parsedLimit.value ?? DEFAULT_COMPACT_LIMIT;
|
|
54949
|
+
const humanOffset = parsedOffset.value ?? 0;
|
|
54466
54950
|
if (configuredList.length > 0) {
|
|
54467
|
-
|
|
54951
|
+
const page = pageItems(configuredList, { offset: humanOffset, limit: humanLimit });
|
|
54952
|
+
const title = page.limit === null ? ` Configured (${configuredList.length})` : ` Configured (showing ${page.items.length} of ${configuredList.length})`;
|
|
54953
|
+
console.log(chalk4.green.bold(`${title}
|
|
54468
54954
|
`));
|
|
54469
54955
|
printHeader();
|
|
54470
|
-
for (const s of
|
|
54956
|
+
for (const s of page.items) {
|
|
54471
54957
|
printRow(s);
|
|
54472
54958
|
}
|
|
54959
|
+
if (page.nextOffset !== null) {
|
|
54960
|
+
console.log(chalk4.dim(` More configured rows: connectors status --offset ${page.nextOffset}`));
|
|
54961
|
+
}
|
|
54473
54962
|
console.log();
|
|
54474
54963
|
}
|
|
54475
54964
|
if (unconfiguredList.length > 0) {
|
|
54476
|
-
|
|
54965
|
+
const page = pageItems(unconfiguredList, { offset: humanOffset, limit: humanLimit });
|
|
54966
|
+
const title = page.limit === null ? ` Unconfigured (${unconfiguredList.length})` : ` Unconfigured (showing ${page.items.length} of ${unconfiguredList.length})`;
|
|
54967
|
+
console.log(chalk4.red.bold(`${title}
|
|
54477
54968
|
`));
|
|
54478
54969
|
printHeader();
|
|
54479
|
-
for (const s of
|
|
54970
|
+
for (const s of page.items) {
|
|
54480
54971
|
printRow(s);
|
|
54481
54972
|
}
|
|
54973
|
+
if (page.nextOffset !== null) {
|
|
54974
|
+
console.log(chalk4.dim(` More unconfigured rows: connectors status --offset ${page.nextOffset}`));
|
|
54975
|
+
}
|
|
54482
54976
|
console.log();
|
|
54483
54977
|
}
|
|
54484
54978
|
console.log(chalk4.dim(` Total: ${allStatuses.length} | Configured: ${configuredList.length} | Unconfigured: ${unconfiguredList.length}`));
|
|
54979
|
+
console.log(chalk4.dim(" More detail: connectors status --verbose | connectors status --json"));
|
|
54485
54980
|
console.log();
|
|
54486
54981
|
});
|
|
54487
|
-
program2.command("doctor").option("--json", "Output as JSON", false).description("Check all installed connectors for issues and output a health report").action((options) => {
|
|
54982
|
+
program2.command("doctor").option("--json", "Output as JSON", false).option("--limit <n>", "Limit rows in human output").option("--offset <n>", "Skip first N rows in human output").option("-v, --verbose", "Show all human rows and full suggestions", false).description("Check all installed connectors for issues and output a health report").action((options) => {
|
|
54983
|
+
const parsedLimit = parseNonNegativeInt(options.limit, "--limit");
|
|
54984
|
+
const parsedOffset = parseNonNegativeInt(options.offset, "--offset");
|
|
54985
|
+
if (parsedLimit.error || parsedOffset.error) {
|
|
54986
|
+
const error2 = parsedLimit.error || parsedOffset.error || "Invalid pagination options";
|
|
54987
|
+
if (options.json)
|
|
54988
|
+
console.log(JSON.stringify({ error: error2 }));
|
|
54989
|
+
else
|
|
54990
|
+
console.log(chalk4.red(error2));
|
|
54991
|
+
process.exit(1);
|
|
54992
|
+
return;
|
|
54993
|
+
}
|
|
54488
54994
|
const installed = getInstalledConnectors();
|
|
54489
54995
|
if (installed.length === 0) {
|
|
54490
54996
|
if (options.json) {
|
|
@@ -54556,7 +55062,11 @@ Connector Status
|
|
|
54556
55062
|
console.log(chalk4.bold(`
|
|
54557
55063
|
Connector Health Report
|
|
54558
55064
|
`));
|
|
54559
|
-
|
|
55065
|
+
const page = pageItems(results, {
|
|
55066
|
+
offset: parsedOffset.value ?? 0,
|
|
55067
|
+
limit: options.verbose ? undefined : parsedLimit.value ?? DEFAULT_COMPACT_LIMIT
|
|
55068
|
+
});
|
|
55069
|
+
for (const r of page.items) {
|
|
54560
55070
|
let icon;
|
|
54561
55071
|
if (r.level === "healthy") {
|
|
54562
55072
|
icon = chalk4.green("\u2713");
|
|
@@ -54569,12 +55079,20 @@ Connector Health Report
|
|
|
54569
55079
|
if (r.issues.length === 0) {
|
|
54570
55080
|
console.log(` ${icon} ${nameStr} \u2014 ${chalk4.green("healthy")}`);
|
|
54571
55081
|
} else {
|
|
54572
|
-
console.log(` ${icon} ${nameStr} \u2014 ${r.issues.join(", ")}`);
|
|
54573
|
-
|
|
54574
|
-
|
|
55082
|
+
console.log(` ${icon} ${nameStr} \u2014 ${truncateText(r.issues.join(", "), options.verbose ? 200 : 120)}`);
|
|
55083
|
+
const suggestions = options.verbose ? r.suggestions : r.suggestions.slice(0, 2);
|
|
55084
|
+
for (const suggestion of suggestions) {
|
|
55085
|
+
console.log(chalk4.dim(` -> ${truncateText(suggestion, options.verbose ? 200 : 120)}`));
|
|
55086
|
+
}
|
|
55087
|
+
if (!options.verbose && r.suggestions.length > suggestions.length) {
|
|
55088
|
+
console.log(chalk4.dim(` ... ${r.suggestions.length - suggestions.length} more suggestion(s)`));
|
|
54575
55089
|
}
|
|
54576
55090
|
}
|
|
54577
55091
|
}
|
|
55092
|
+
if (page.nextOffset !== null) {
|
|
55093
|
+
console.log(chalk4.dim(`
|
|
55094
|
+
More rows: connectors doctor --offset ${page.nextOffset}`));
|
|
55095
|
+
}
|
|
54578
55096
|
const parts = [];
|
|
54579
55097
|
if (summary.healthy > 0)
|
|
54580
55098
|
parts.push(chalk4.green(`${summary.healthy} healthy`));
|
|
@@ -55746,7 +56264,7 @@ complete -F _connectors connectors`);
|
|
|
55746
56264
|
console.log(output);
|
|
55747
56265
|
}
|
|
55748
56266
|
});
|
|
55749
|
-
program2.command("presets").option("--json", "Output as JSON", false).description("List available connector preset bundles").action((options) => {
|
|
56267
|
+
program2.command("presets").option("--json", "Output as JSON", false).option("-v, --verbose", "Show every connector in each preset", false).description("List available connector preset bundles").action((options) => {
|
|
55750
56268
|
if (options.json) {
|
|
55751
56269
|
console.log(JSON.stringify(Object.entries(PRESETS).map(([name, p]) => ({
|
|
55752
56270
|
name,
|
|
@@ -55761,13 +56279,16 @@ Available presets:
|
|
|
55761
56279
|
`));
|
|
55762
56280
|
for (const [name, preset] of Object.entries(PRESETS)) {
|
|
55763
56281
|
console.log(` ${chalk6.cyan(name.padEnd(12))} ${preset.description}`);
|
|
55764
|
-
|
|
56282
|
+
const visible = options.verbose ? preset.connectors : preset.connectors.slice(0, 5);
|
|
56283
|
+
const suffix = !options.verbose && preset.connectors.length > visible.length ? `, ... +${preset.connectors.length - visible.length} more` : "";
|
|
56284
|
+
console.log(chalk6.dim(` ${"".padEnd(12)} ${visible.join(", ")}${suffix}`));
|
|
55765
56285
|
console.log();
|
|
55766
56286
|
}
|
|
55767
|
-
console.log(chalk6.dim(` Install with: connectors install --preset <name
|
|
56287
|
+
console.log(chalk6.dim(` Install with: connectors install --preset <name>`));
|
|
56288
|
+
console.log(chalk6.dim(` More detail: connectors presets --verbose | connectors presets --json
|
|
55768
56289
|
`));
|
|
55769
56290
|
});
|
|
55770
|
-
program2.command("whoami").option("--json", "Output as JSON", false).description("Show current setup: config dir, installed connectors, auth status").action((options) => {
|
|
56291
|
+
program2.command("whoami").option("--json", "Output as JSON", false).option("-v, --verbose", "Show all connector rows", false).description("Show current setup: config dir, installed connectors, auth status").action((options) => {
|
|
55771
56292
|
const configDir = getConnectorsHome();
|
|
55772
56293
|
const installed = getInstalledConnectors();
|
|
55773
56294
|
const version2 = "0.3.1";
|
|
@@ -55840,32 +56361,46 @@ Connectors Setup
|
|
|
55840
56361
|
const projectConnectors = connectorDetails.filter((c) => c.source === "project");
|
|
55841
56362
|
const globalConnectors = connectorDetails.filter((c) => c.source === "global");
|
|
55842
56363
|
if (projectConnectors.length > 0) {
|
|
56364
|
+
const page = pageItems(projectConnectors, {
|
|
56365
|
+
limit: options.verbose ? undefined : DEFAULT_COMPACT_LIMIT
|
|
56366
|
+
});
|
|
55843
56367
|
console.log(chalk6.bold(`
|
|
55844
|
-
Project Connectors:
|
|
56368
|
+
Project Connectors (${page.items.length}/${projectConnectors.length}):
|
|
55845
56369
|
`));
|
|
55846
56370
|
const nameWidth = Math.max(10, ...projectConnectors.map((c) => c.name.length)) + 2;
|
|
55847
|
-
for (const c of
|
|
56371
|
+
for (const c of page.items) {
|
|
55848
56372
|
const status = c.configured ? chalk6.green("\u2713") : chalk6.red("\u2717");
|
|
55849
56373
|
const profileLabel = c.profile !== "default" ? chalk6.dim(` [${c.profile}]`) : "";
|
|
55850
|
-
console.log(` ${status} ${chalk6.cyan(c.name.padEnd(nameWidth))}${c.authType.padEnd(8)}${profileLabel}`);
|
|
56374
|
+
console.log(` ${status} ${chalk6.cyan(truncateText(c.name, nameWidth - 2).padEnd(nameWidth))}${c.authType.padEnd(8)}${profileLabel}`);
|
|
56375
|
+
}
|
|
56376
|
+
if (page.nextOffset !== null) {
|
|
56377
|
+
console.log(chalk6.dim(` ... ${projectConnectors.length - page.items.length} more (use --verbose)`));
|
|
55851
56378
|
}
|
|
55852
56379
|
}
|
|
55853
56380
|
if (globalConnectors.length > 0) {
|
|
56381
|
+
const page = pageItems(globalConnectors, {
|
|
56382
|
+
limit: options.verbose ? undefined : DEFAULT_COMPACT_LIMIT
|
|
56383
|
+
});
|
|
55854
56384
|
console.log(chalk6.bold(`
|
|
55855
|
-
Global Connectors`) + chalk6.dim(" (~/.hasna/connectors)") + chalk6.bold(`:
|
|
56385
|
+
Global Connectors (${page.items.length}/${globalConnectors.length})`) + chalk6.dim(" (~/.hasna/connectors)") + chalk6.bold(`:
|
|
55856
56386
|
`));
|
|
55857
56387
|
const nameWidth = Math.max(10, ...globalConnectors.map((c) => c.name.length)) + 2;
|
|
55858
|
-
for (const c of
|
|
56388
|
+
for (const c of page.items) {
|
|
55859
56389
|
const status = c.configured ? chalk6.green("\u2713") : chalk6.red("\u2717");
|
|
55860
56390
|
const profileLabel = c.profile !== "default" ? chalk6.dim(` [${c.profile}]`) : "";
|
|
55861
|
-
console.log(` ${status} ${chalk6.cyan(c.name.padEnd(nameWidth))}${c.authType.padEnd(8)}${profileLabel}`);
|
|
56391
|
+
console.log(` ${status} ${chalk6.cyan(truncateText(c.name, nameWidth - 2).padEnd(nameWidth))}${c.authType.padEnd(8)}${profileLabel}`);
|
|
56392
|
+
}
|
|
56393
|
+
if (page.nextOffset !== null) {
|
|
56394
|
+
console.log(chalk6.dim(` ... ${globalConnectors.length - page.items.length} more (use --verbose)`));
|
|
55862
56395
|
}
|
|
55863
56396
|
}
|
|
55864
56397
|
if (connectorDetails.length === 0) {
|
|
55865
56398
|
console.log(chalk6.dim(`
|
|
55866
56399
|
No connectors installed or configured.`));
|
|
55867
56400
|
}
|
|
55868
|
-
console.log(
|
|
56401
|
+
console.log(chalk6.dim(`
|
|
56402
|
+
More detail: connectors whoami --verbose | connectors whoami --json
|
|
56403
|
+
`));
|
|
55869
56404
|
});
|
|
55870
56405
|
program2.command("test").argument("[connector]", "Connector to test (default: all installed)").option("--json", "Output as JSON", false).option("--timeout <ms>", "Request timeout in milliseconds", "10000").description("Verify API credentials by making a real request to the connector's API").action(async (connector, options) => {
|
|
55871
56406
|
const timeout = parseInt(options.timeout, 10) || 1e4;
|
|
@@ -56058,6 +56593,18 @@ init_registry2();
|
|
|
56058
56593
|
init_auth();
|
|
56059
56594
|
init_runner();
|
|
56060
56595
|
import chalk7 from "chalk";
|
|
56596
|
+
function argsRequestJson(args) {
|
|
56597
|
+
for (let i = 0;i < args.length; i++) {
|
|
56598
|
+
const arg = args[i];
|
|
56599
|
+
if (arg === "--json")
|
|
56600
|
+
return true;
|
|
56601
|
+
if ((arg === "--format" || arg === "-f") && args[i + 1] === "json")
|
|
56602
|
+
return true;
|
|
56603
|
+
if (arg === "--format=json" || arg === "-f=json")
|
|
56604
|
+
return true;
|
|
56605
|
+
}
|
|
56606
|
+
return false;
|
|
56607
|
+
}
|
|
56061
56608
|
function registerCommands6(program2) {
|
|
56062
56609
|
program2.command("ops").description("List available API operations for a connector").argument("<name>", "Connector name (e.g. stripe, gmail)").argument("[command]", "Get detailed help for a specific subcommand").option("--json", "Output as JSON").action(async (name, command, options) => {
|
|
56063
56610
|
const meta = getConnector(name);
|
|
@@ -56111,7 +56658,7 @@ ${meta.displayName} operations:
|
|
|
56111
56658
|
}
|
|
56112
56659
|
}
|
|
56113
56660
|
});
|
|
56114
|
-
program2.command("run").description("Execute an API operation on a connector").argument("<name>", "Connector name (e.g. stripe, gmail)").argument("[args...]", "Command arguments (e.g. products list --limit 5)").option("--timeout <ms>", "Timeout in milliseconds", "30000").passThroughOptions().action(async (name, args, options) => {
|
|
56661
|
+
program2.command("run").description("Execute an API operation on a connector").argument("<name>", "Connector name (e.g. stripe, gmail)").argument("[args...]", "Command arguments (e.g. products list --limit 5)").option("--timeout <ms>", "Timeout in milliseconds", "30000").option("-v, --verbose", "Print full command output without truncation", false).passThroughOptions().action(async (name, args, options) => {
|
|
56115
56662
|
const meta = getConnector(name);
|
|
56116
56663
|
if (!meta) {
|
|
56117
56664
|
console.error(chalk7.red(`Connector '${name}' not found.`));
|
|
@@ -56129,7 +56676,12 @@ ${meta.displayName} operations:
|
|
|
56129
56676
|
}
|
|
56130
56677
|
const result = await runConnectorCommand2(name, args, parseInt(options.timeout));
|
|
56131
56678
|
if (result.stdout) {
|
|
56132
|
-
|
|
56679
|
+
const preserveMachineOutput = argsRequestJson(args);
|
|
56680
|
+
const output = maybeTruncateOutput(result.stdout, {
|
|
56681
|
+
enabled: !options.verbose && !preserveMachineOutput,
|
|
56682
|
+
hint: "Use `connectors run --verbose <connector> ...` for full output."
|
|
56683
|
+
});
|
|
56684
|
+
console.log(output.text);
|
|
56133
56685
|
}
|
|
56134
56686
|
if (result.stderr) {
|
|
56135
56687
|
console.error(result.stderr);
|
|
@@ -56346,6 +56898,15 @@ init_workflow_runner();
|
|
|
56346
56898
|
init_database();
|
|
56347
56899
|
init_registry2();
|
|
56348
56900
|
import chalk8 from "chalk";
|
|
56901
|
+
function parsePagingOptions(options) {
|
|
56902
|
+
const parsedLimit = parseNonNegativeInt(options.limit, "--limit");
|
|
56903
|
+
const parsedOffset = parseNonNegativeInt(options.offset, "--offset");
|
|
56904
|
+
return {
|
|
56905
|
+
limit: parsedLimit.value,
|
|
56906
|
+
offset: parsedOffset.value ?? 0,
|
|
56907
|
+
error: parsedLimit.error || parsedOffset.error
|
|
56908
|
+
};
|
|
56909
|
+
}
|
|
56349
56910
|
function registerCommands7(program2) {
|
|
56350
56911
|
program2.command("hot").description("Show top connectors by usage").option("--limit <n>", "Max results", "10").option("--days <n>", "Time window in days", "7").option("--json", "Output as JSON").action((options) => {
|
|
56351
56912
|
const { getTopConnectors: getTopConnectors2 } = (init_usage(), __toCommonJS(exports_usage));
|
|
@@ -56403,21 +56964,74 @@ Top connectors (last ${options.days} days):
|
|
|
56403
56964
|
}
|
|
56404
56965
|
console.log(chalk8.green("\u2713") + ` Job created: ${job.name} (${job.cron})`);
|
|
56405
56966
|
});
|
|
56406
|
-
jobsCmd.command("list").description("List all jobs").option("--json", "Output as JSON").action((options) => {
|
|
56967
|
+
jobsCmd.command("list").description("List all jobs").option("--limit <n>", "Limit rows").option("--offset <n>", "Skip first N rows").option("-v, --verbose", "Show all rows in human output", false).option("--json", "Output as JSON").action((options) => {
|
|
56968
|
+
const paging = parsePagingOptions(options);
|
|
56969
|
+
if (paging.error) {
|
|
56970
|
+
if (options.json)
|
|
56971
|
+
console.log(JSON.stringify({ error: paging.error }));
|
|
56972
|
+
else
|
|
56973
|
+
console.log(chalk8.red(paging.error));
|
|
56974
|
+
process.exit(1);
|
|
56975
|
+
return;
|
|
56976
|
+
}
|
|
56407
56977
|
const jobs = listJobs(getDatabase());
|
|
56978
|
+
const page = pageItems(jobs, {
|
|
56979
|
+
offset: paging.offset,
|
|
56980
|
+
limit: paging.limit ?? (options.verbose ? undefined : DEFAULT_COMPACT_LIMIT)
|
|
56981
|
+
});
|
|
56408
56982
|
if (options.json) {
|
|
56409
|
-
|
|
56983
|
+
const data = options.limit || options.offset ? page.items : jobs;
|
|
56984
|
+
console.log(JSON.stringify(data));
|
|
56410
56985
|
return;
|
|
56411
56986
|
}
|
|
56412
56987
|
if (jobs.length === 0) {
|
|
56413
56988
|
console.log(chalk8.dim("No jobs configured."));
|
|
56414
56989
|
return;
|
|
56415
56990
|
}
|
|
56416
|
-
|
|
56991
|
+
console.log(chalk8.bold(`
|
|
56992
|
+
Jobs (showing ${page.items.length} of ${jobs.length})
|
|
56993
|
+
`));
|
|
56994
|
+
for (const j of page.items) {
|
|
56417
56995
|
const status = j.enabled ? chalk8.green("enabled") : chalk8.dim("disabled");
|
|
56418
56996
|
const strip = j.strip ? chalk8.cyan(" [strip]") : "";
|
|
56419
56997
|
console.log(` ${j.name.padEnd(20)} ${j.connector}.${j.command.padEnd(16)} ${j.cron.padEnd(15)} ${status}${strip}`);
|
|
56420
56998
|
}
|
|
56999
|
+
if (page.nextOffset !== null)
|
|
57000
|
+
console.log(chalk8.dim(`
|
|
57001
|
+
More rows: connectors jobs list --offset ${page.nextOffset}`));
|
|
57002
|
+
console.log(chalk8.dim(" More detail: connectors jobs show <name> | connectors jobs list --verbose | connectors jobs list --json"));
|
|
57003
|
+
});
|
|
57004
|
+
jobsCmd.command("show").alias("inspect").description("Show full details for one job").argument("<name>", "Job name").option("--json", "Output as JSON").action((name, options) => {
|
|
57005
|
+
const db = getDatabase();
|
|
57006
|
+
const job = getJobByName(name, db);
|
|
57007
|
+
if (!job) {
|
|
57008
|
+
console.error(chalk8.red(`Job "${name}" not found`));
|
|
57009
|
+
process.exit(1);
|
|
57010
|
+
}
|
|
57011
|
+
const latestRun = getLatestRun(job.id, db);
|
|
57012
|
+
if (options.json) {
|
|
57013
|
+
console.log(JSON.stringify({ job, latestRun }, null, 2));
|
|
57014
|
+
return;
|
|
57015
|
+
}
|
|
57016
|
+
console.log(chalk8.bold(`
|
|
57017
|
+
Job: ${job.name}
|
|
57018
|
+
`));
|
|
57019
|
+
console.log(` Connector: ${job.connector}`);
|
|
57020
|
+
console.log(` Command: ${job.command}${job.args.length ? ` ${job.args.join(" ")}` : ""}`);
|
|
57021
|
+
console.log(` Cron: ${job.cron}`);
|
|
57022
|
+
console.log(` Enabled: ${job.enabled ? "yes" : "no"}`);
|
|
57023
|
+
console.log(` Strip: ${job.strip ? "yes" : "no"}`);
|
|
57024
|
+
if (latestRun) {
|
|
57025
|
+
console.log(chalk8.bold(`
|
|
57026
|
+
Latest Run`));
|
|
57027
|
+
console.log(` Started: ${latestRun.started_at}`);
|
|
57028
|
+
console.log(` Exit: ${latestRun.exit_code ?? "?"}`);
|
|
57029
|
+
const latestOutput = latestRun.stripped_output ?? latestRun.raw_output;
|
|
57030
|
+
if (latestOutput)
|
|
57031
|
+
console.log(` Output: ${truncateText(latestOutput, 160)}`);
|
|
57032
|
+
}
|
|
57033
|
+
console.log(chalk8.dim(`
|
|
57034
|
+
More detail: connectors jobs show ${name} --json | connectors jobs logs ${name}`));
|
|
56421
57035
|
});
|
|
56422
57036
|
jobsCmd.command("run").description("Manually trigger a job").argument("<name>", "Job name").option("--json", "Output as JSON").action(async (name, options) => {
|
|
56423
57037
|
const db = getDatabase();
|
|
@@ -56435,8 +57049,13 @@ Top connectors (last ${options.days} days):
|
|
|
56435
57049
|
}
|
|
56436
57050
|
const icon = result.exit_code === 0 ? chalk8.green("\u2713") : chalk8.red("\u2717");
|
|
56437
57051
|
console.log(`${icon} Run ${result.run_id} \u2014 exit ${result.exit_code}`);
|
|
56438
|
-
if (result.output)
|
|
56439
|
-
|
|
57052
|
+
if (result.output) {
|
|
57053
|
+
const output = maybeTruncateOutput(result.output, {
|
|
57054
|
+
maxChars: 2000,
|
|
57055
|
+
hint: `Run connectors jobs run ${name} --json for structured full output.`
|
|
57056
|
+
});
|
|
57057
|
+
console.log(output.text);
|
|
57058
|
+
}
|
|
56440
57059
|
});
|
|
56441
57060
|
jobsCmd.command("logs").description("Show recent runs for a job").argument("<name>", "Job name").option("--limit <n>", "Max results", "10").option("--json", "Output as JSON").action((name, options) => {
|
|
56442
57061
|
const db = getDatabase();
|
|
@@ -56505,20 +57124,63 @@ Top connectors (last ${options.days} days):
|
|
|
56505
57124
|
}
|
|
56506
57125
|
console.log(chalk8.green("\u2713") + ` Workflow "${wf.name}" created (${wf.steps.length} steps)`);
|
|
56507
57126
|
});
|
|
56508
|
-
workflowsCmd.command("list").description("List all workflows").option("--json", "Output as JSON").action((options) => {
|
|
57127
|
+
workflowsCmd.command("list").description("List all workflows").option("--limit <n>", "Limit rows").option("--offset <n>", "Skip first N rows").option("-v, --verbose", "Show all rows in human output", false).option("--json", "Output as JSON").action((options) => {
|
|
57128
|
+
const paging = parsePagingOptions(options);
|
|
57129
|
+
if (paging.error) {
|
|
57130
|
+
if (options.json)
|
|
57131
|
+
console.log(JSON.stringify({ error: paging.error }));
|
|
57132
|
+
else
|
|
57133
|
+
console.log(chalk8.red(paging.error));
|
|
57134
|
+
process.exit(1);
|
|
57135
|
+
return;
|
|
57136
|
+
}
|
|
56509
57137
|
const wfs = listWorkflows(getDatabase());
|
|
57138
|
+
const page = pageItems(wfs, {
|
|
57139
|
+
offset: paging.offset,
|
|
57140
|
+
limit: paging.limit ?? (options.verbose ? undefined : DEFAULT_COMPACT_LIMIT)
|
|
57141
|
+
});
|
|
56510
57142
|
if (options.json) {
|
|
56511
|
-
|
|
57143
|
+
const data = options.limit || options.offset ? page.items : wfs;
|
|
57144
|
+
console.log(JSON.stringify(data));
|
|
56512
57145
|
return;
|
|
56513
57146
|
}
|
|
56514
57147
|
if (wfs.length === 0) {
|
|
56515
57148
|
console.log(chalk8.dim("No workflows configured."));
|
|
56516
57149
|
return;
|
|
56517
57150
|
}
|
|
56518
|
-
|
|
57151
|
+
console.log(chalk8.bold(`
|
|
57152
|
+
Workflows (showing ${page.items.length} of ${wfs.length})
|
|
57153
|
+
`));
|
|
57154
|
+
for (const wf of page.items) {
|
|
56519
57155
|
const status = wf.enabled ? chalk8.green("enabled") : chalk8.dim("disabled");
|
|
56520
57156
|
console.log(` ${wf.name.padEnd(20)} ${String(wf.steps.length).padStart(2)} steps ${status}`);
|
|
56521
57157
|
}
|
|
57158
|
+
if (page.nextOffset !== null)
|
|
57159
|
+
console.log(chalk8.dim(`
|
|
57160
|
+
More rows: connectors workflows list --offset ${page.nextOffset}`));
|
|
57161
|
+
console.log(chalk8.dim(" More detail: connectors workflows show <name> | connectors workflows list --verbose | connectors workflows list --json"));
|
|
57162
|
+
});
|
|
57163
|
+
workflowsCmd.command("show").alias("inspect").description("Show full details for one workflow").argument("<name>", "Workflow name").option("--json", "Output as JSON").action((name, options) => {
|
|
57164
|
+
const wf = getWorkflowByName(name, getDatabase());
|
|
57165
|
+
if (!wf) {
|
|
57166
|
+
console.error(chalk8.red(`Workflow "${name}" not found`));
|
|
57167
|
+
process.exit(1);
|
|
57168
|
+
}
|
|
57169
|
+
if (options.json) {
|
|
57170
|
+
console.log(JSON.stringify(wf, null, 2));
|
|
57171
|
+
return;
|
|
57172
|
+
}
|
|
57173
|
+
console.log(chalk8.bold(`
|
|
57174
|
+
Workflow: ${wf.name}
|
|
57175
|
+
`));
|
|
57176
|
+
console.log(` Enabled: ${wf.enabled ? "yes" : "no"}`);
|
|
57177
|
+
console.log(` Steps: ${wf.steps.length}`);
|
|
57178
|
+
for (const [index, step] of wf.steps.entries()) {
|
|
57179
|
+
const args = Array.isArray(step.args) && step.args.length > 0 ? ` ${step.args.join(" ")}` : "";
|
|
57180
|
+
console.log(` ${String(index + 1).padStart(2)}. ${step.connector} ${step.command}${args}`);
|
|
57181
|
+
}
|
|
57182
|
+
console.log(chalk8.dim(`
|
|
57183
|
+
More detail: connectors workflows show ${name} --json`));
|
|
56522
57184
|
});
|
|
56523
57185
|
workflowsCmd.command("run").description("Run a workflow").argument("<name>", "Workflow name").option("--json", "Output as JSON").action(async (name, options) => {
|
|
56524
57186
|
const wf = getWorkflowByName(name, getDatabase());
|