@kaddo/mcp 3.83.0 → 3.85.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +172 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11771,6 +11771,51 @@ function parseSecrets(raw, id, findings) {
|
|
|
11771
11771
|
}
|
|
11772
11772
|
return secrets;
|
|
11773
11773
|
}
|
|
11774
|
+
function toStringArray3(raw) {
|
|
11775
|
+
if (raw == null) return void 0;
|
|
11776
|
+
if (Array.isArray(raw)) return raw.filter((v) => typeof v === "string" && v.trim() !== "").map((v) => v.trim());
|
|
11777
|
+
if (typeof raw === "string" && raw.trim()) return [raw.trim()];
|
|
11778
|
+
return void 0;
|
|
11779
|
+
}
|
|
11780
|
+
function parseFilters(raw) {
|
|
11781
|
+
if (raw == null || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
11782
|
+
const o2 = raw;
|
|
11783
|
+
const filters = {};
|
|
11784
|
+
let hasAny = false;
|
|
11785
|
+
const types = toStringArray3(o2.types);
|
|
11786
|
+
if (types?.length) {
|
|
11787
|
+
filters.types = types;
|
|
11788
|
+
hasAny = true;
|
|
11789
|
+
}
|
|
11790
|
+
const statuses = toStringArray3(o2.statuses);
|
|
11791
|
+
if (statuses?.length) {
|
|
11792
|
+
filters.statuses = statuses;
|
|
11793
|
+
hasAny = true;
|
|
11794
|
+
}
|
|
11795
|
+
const labels = toStringArray3(o2.labels);
|
|
11796
|
+
if (labels?.length) {
|
|
11797
|
+
filters.labels = labels;
|
|
11798
|
+
hasAny = true;
|
|
11799
|
+
}
|
|
11800
|
+
const assignees = toStringArray3(o2.assignees);
|
|
11801
|
+
if (assignees?.length) {
|
|
11802
|
+
filters.assignees = assignees;
|
|
11803
|
+
hasAny = true;
|
|
11804
|
+
}
|
|
11805
|
+
if (typeof o2.updatedAfter === "string" && o2.updatedAfter.trim()) {
|
|
11806
|
+
filters.updatedAfter = o2.updatedAfter.trim();
|
|
11807
|
+
hasAny = true;
|
|
11808
|
+
}
|
|
11809
|
+
if (typeof o2.search === "string" && o2.search.trim()) {
|
|
11810
|
+
filters.search = o2.search.trim();
|
|
11811
|
+
hasAny = true;
|
|
11812
|
+
}
|
|
11813
|
+
if (typeof o2.providerQuery === "string" && o2.providerQuery.trim()) {
|
|
11814
|
+
filters.providerQuery = o2.providerQuery.trim();
|
|
11815
|
+
hasAny = true;
|
|
11816
|
+
}
|
|
11817
|
+
return hasAny ? filters : void 0;
|
|
11818
|
+
}
|
|
11774
11819
|
function parseIntegrationsConfig(raw, opts) {
|
|
11775
11820
|
const findings = [];
|
|
11776
11821
|
const integrations = [];
|
|
@@ -11804,8 +11849,9 @@ function parseIntegrationsConfig(raw, opts) {
|
|
|
11804
11849
|
const config = o2.config && typeof o2.config === "object" && !Array.isArray(o2.config) ? o2.config : {};
|
|
11805
11850
|
const credentials = parseCredentials(o2.credentials, id, findings);
|
|
11806
11851
|
const secrets = parseSecrets(o2.secrets, id, findings);
|
|
11852
|
+
const filters = parseFilters(o2.filters);
|
|
11807
11853
|
const timeoutMs = typeof o2.timeout_ms === "number" ? o2.timeout_ms : typeof o2.timeoutMs === "number" ? o2.timeoutMs : void 0;
|
|
11808
|
-
integrations.push({ id, adapter, enabled, config, credentials, secrets, timeoutMs });
|
|
11854
|
+
integrations.push({ id, adapter, enabled, config, credentials, secrets, filters, timeoutMs });
|
|
11809
11855
|
}
|
|
11810
11856
|
return { integrations, findings };
|
|
11811
11857
|
}
|
|
@@ -11825,6 +11871,20 @@ async function resolveAllCredentials(integration, resolver, env) {
|
|
|
11825
11871
|
}
|
|
11826
11872
|
return { credentials, missing };
|
|
11827
11873
|
}
|
|
11874
|
+
function mergeFilters(base, overlay) {
|
|
11875
|
+
if (!base && !overlay) return {};
|
|
11876
|
+
if (!base) return { ...overlay };
|
|
11877
|
+
if (!overlay) return { ...base };
|
|
11878
|
+
return {
|
|
11879
|
+
types: overlay.types?.length ? overlay.types : base.types,
|
|
11880
|
+
statuses: overlay.statuses?.length ? overlay.statuses : base.statuses,
|
|
11881
|
+
labels: overlay.labels?.length ? overlay.labels : base.labels,
|
|
11882
|
+
assignees: overlay.assignees?.length ? overlay.assignees : base.assignees,
|
|
11883
|
+
updatedAfter: overlay.updatedAfter ?? base.updatedAfter,
|
|
11884
|
+
search: overlay.search ?? base.search,
|
|
11885
|
+
providerQuery: overlay.providerQuery ?? base.providerQuery
|
|
11886
|
+
};
|
|
11887
|
+
}
|
|
11828
11888
|
|
|
11829
11889
|
// ../integrations/src/secrets.ts
|
|
11830
11890
|
import { readFileSync as readFileSync2, writeFileSync, mkdirSync, existsSync as existsSync2, unlinkSync } from "fs";
|
|
@@ -11941,6 +12001,7 @@ var DEFAULT_ITEMS = [
|
|
|
11941
12001
|
status: "Open",
|
|
11942
12002
|
url: "https://example.test/mock/EXT-001",
|
|
11943
12003
|
labels: ["registration", "beta"],
|
|
12004
|
+
assignees: [{ name: "Alice" }],
|
|
11944
12005
|
createdAt: "2026-01-05T10:00:00.000Z",
|
|
11945
12006
|
updatedAt: "2026-02-01T09:30:00.000Z",
|
|
11946
12007
|
rawMetadata: { board: "delivery" }
|
|
@@ -11954,8 +12015,86 @@ var DEFAULT_ITEMS = [
|
|
|
11954
12015
|
status: "To Do",
|
|
11955
12016
|
url: "https://example.test/mock/EXT-002",
|
|
11956
12017
|
labels: ["onboarding"],
|
|
12018
|
+
assignees: [{ name: "Bob" }],
|
|
11957
12019
|
createdAt: "2026-01-08T12:00:00.000Z",
|
|
11958
12020
|
updatedAt: "2026-01-20T15:00:00.000Z"
|
|
12021
|
+
},
|
|
12022
|
+
{
|
|
12023
|
+
externalId: "EXT-003",
|
|
12024
|
+
provider: MOCK_ADAPTER_ID,
|
|
12025
|
+
title: "Fix authentication error on mobile",
|
|
12026
|
+
description: "Users on iOS 17 see a blank screen after OAuth redirect.",
|
|
12027
|
+
type: "Bug",
|
|
12028
|
+
status: "In Progress",
|
|
12029
|
+
url: "https://example.test/mock/EXT-003",
|
|
12030
|
+
labels: ["auth", "mobile", "critical"],
|
|
12031
|
+
assignees: [{ name: "Alice" }],
|
|
12032
|
+
createdAt: "2026-02-10T08:00:00.000Z",
|
|
12033
|
+
updatedAt: "2026-03-01T14:00:00.000Z"
|
|
12034
|
+
},
|
|
12035
|
+
{
|
|
12036
|
+
externalId: "EXT-004",
|
|
12037
|
+
provider: MOCK_ADAPTER_ID,
|
|
12038
|
+
title: "Design system token audit",
|
|
12039
|
+
description: "Review and consolidate design tokens across the component library.",
|
|
12040
|
+
type: "Task",
|
|
12041
|
+
status: "To Do",
|
|
12042
|
+
url: "https://example.test/mock/EXT-004",
|
|
12043
|
+
labels: ["frontend", "design-system"],
|
|
12044
|
+
createdAt: "2026-02-15T10:00:00.000Z",
|
|
12045
|
+
updatedAt: "2026-02-20T11:00:00.000Z"
|
|
12046
|
+
},
|
|
12047
|
+
{
|
|
12048
|
+
externalId: "EXT-005",
|
|
12049
|
+
provider: MOCK_ADAPTER_ID,
|
|
12050
|
+
title: "Migrate billing service to new payment gateway",
|
|
12051
|
+
description: "Stripe v2 migration \u2014 switch from legacy Charges API to Payment Intents.",
|
|
12052
|
+
type: "Epic",
|
|
12053
|
+
status: "Open",
|
|
12054
|
+
url: "https://example.test/mock/EXT-005",
|
|
12055
|
+
labels: ["billing", "backend", "migration"],
|
|
12056
|
+
assignees: [{ name: "Carol" }],
|
|
12057
|
+
createdAt: "2026-01-20T09:00:00.000Z",
|
|
12058
|
+
updatedAt: "2026-03-05T16:00:00.000Z"
|
|
12059
|
+
},
|
|
12060
|
+
{
|
|
12061
|
+
externalId: "EXT-006",
|
|
12062
|
+
provider: MOCK_ADAPTER_ID,
|
|
12063
|
+
title: "Add CSV export to reports",
|
|
12064
|
+
description: "Users need to export analytics reports as CSV for external tools.",
|
|
12065
|
+
type: "Feature",
|
|
12066
|
+
status: "In Progress",
|
|
12067
|
+
url: "https://example.test/mock/EXT-006",
|
|
12068
|
+
labels: ["reports", "backend"],
|
|
12069
|
+
assignees: [{ name: "Bob" }],
|
|
12070
|
+
createdAt: "2026-02-25T13:00:00.000Z",
|
|
12071
|
+
updatedAt: "2026-03-10T10:00:00.000Z"
|
|
12072
|
+
},
|
|
12073
|
+
{
|
|
12074
|
+
externalId: "EXT-007",
|
|
12075
|
+
provider: MOCK_ADAPTER_ID,
|
|
12076
|
+
title: "Improve search relevance scoring",
|
|
12077
|
+
description: "Tweak TF-IDF weights and add trigram matching for better search results.",
|
|
12078
|
+
type: "Task",
|
|
12079
|
+
status: "Done",
|
|
12080
|
+
url: "https://example.test/mock/EXT-007",
|
|
12081
|
+
labels: ["search", "backend"],
|
|
12082
|
+
assignees: [{ name: "Alice" }],
|
|
12083
|
+
createdAt: "2026-01-12T07:00:00.000Z",
|
|
12084
|
+
updatedAt: "2026-02-28T17:00:00.000Z"
|
|
12085
|
+
},
|
|
12086
|
+
{
|
|
12087
|
+
externalId: "EXT-008",
|
|
12088
|
+
provider: MOCK_ADAPTER_ID,
|
|
12089
|
+
title: "Set up E2E test pipeline",
|
|
12090
|
+
description: "Configure Playwright tests running on every PR via GitHub Actions.",
|
|
12091
|
+
type: "Task",
|
|
12092
|
+
status: "Done",
|
|
12093
|
+
url: "https://example.test/mock/EXT-008",
|
|
12094
|
+
labels: ["testing", "ci"],
|
|
12095
|
+
assignees: [{ name: "Carol" }],
|
|
12096
|
+
createdAt: "2026-01-30T11:00:00.000Z",
|
|
12097
|
+
updatedAt: "2026-02-15T09:00:00.000Z"
|
|
11959
12098
|
}
|
|
11960
12099
|
];
|
|
11961
12100
|
function simulationOf(context, fallback) {
|
|
@@ -11987,6 +12126,16 @@ function createMockAdapter(opts = {}) {
|
|
|
11987
12126
|
displayName: "Mock Work Source",
|
|
11988
12127
|
version: "1.0.0",
|
|
11989
12128
|
description: "Deterministic offline reference adapter for validating the integration foundation.",
|
|
12129
|
+
icon: "mock",
|
|
12130
|
+
filterCapabilities: {
|
|
12131
|
+
types: { supported: true, multiple: true },
|
|
12132
|
+
statuses: { supported: true, multiple: true },
|
|
12133
|
+
labels: { supported: true, multiple: true },
|
|
12134
|
+
assignees: { supported: true, multiple: true },
|
|
12135
|
+
updatedAfter: { supported: true },
|
|
12136
|
+
search: { supported: true },
|
|
12137
|
+
providerQuery: { supported: false }
|
|
12138
|
+
},
|
|
11990
12139
|
configSchema: {
|
|
11991
12140
|
simulate: {
|
|
11992
12141
|
type: "select",
|
|
@@ -12005,7 +12154,7 @@ function createMockAdapter(opts = {}) {
|
|
|
12005
12154
|
},
|
|
12006
12155
|
secretSchema: {
|
|
12007
12156
|
token: {
|
|
12008
|
-
type: "
|
|
12157
|
+
type: "password",
|
|
12009
12158
|
required: false,
|
|
12010
12159
|
label: "API Token",
|
|
12011
12160
|
description: "Optional token for testing secret handling (not used by the mock adapter)."
|
|
@@ -12033,9 +12182,24 @@ function createMockAdapter(opts = {}) {
|
|
|
12033
12182
|
readFailure(simulationOf(request.context, defaultSim));
|
|
12034
12183
|
let pool = items;
|
|
12035
12184
|
const f3 = request.filters;
|
|
12036
|
-
if (f3?.
|
|
12037
|
-
|
|
12038
|
-
|
|
12185
|
+
if (f3?.statuses?.length) {
|
|
12186
|
+
const lower = f3.statuses.map((s) => s.toLowerCase());
|
|
12187
|
+
pool = pool.filter((i) => lower.includes((i.status ?? "").toLowerCase()));
|
|
12188
|
+
}
|
|
12189
|
+
if (f3?.types?.length) {
|
|
12190
|
+
const lower = f3.types.map((t) => t.toLowerCase());
|
|
12191
|
+
pool = pool.filter((i) => lower.includes((i.type ?? "").toLowerCase()));
|
|
12192
|
+
}
|
|
12193
|
+
if (f3?.labels?.length) {
|
|
12194
|
+
const lower = f3.labels.map((l2) => l2.toLowerCase());
|
|
12195
|
+
pool = pool.filter((i) => i.labels?.some((il) => lower.includes(il.toLowerCase())));
|
|
12196
|
+
}
|
|
12197
|
+
if (f3?.assignees?.length) {
|
|
12198
|
+
const lower = f3.assignees.map((a2) => a2.toLowerCase());
|
|
12199
|
+
pool = pool.filter((i) => i.assignees?.some((a2) => lower.includes((a2.name ?? "").toLowerCase())));
|
|
12200
|
+
}
|
|
12201
|
+
if (f3?.search) pool = pool.filter((i) => `${i.title} ${i.description ?? ""}`.toLowerCase().includes(f3.search.toLowerCase()));
|
|
12202
|
+
if (f3?.updatedAfter) pool = pool.filter((i) => (i.updatedAt ?? "") >= f3.updatedAfter);
|
|
12039
12203
|
const size = Math.max(1, request.pageSize ?? defaultPageSize);
|
|
12040
12204
|
const start = request.cursor ? Math.max(0, Number.parseInt(request.cursor, 10) || 0) : 0;
|
|
12041
12205
|
const slice = pool.slice(start, start + size);
|
|
@@ -12105,6 +12269,7 @@ function listIntegrations(dir) {
|
|
|
12105
12269
|
credentialRefs: Object.values(integration.credentials).map((c) => c.env),
|
|
12106
12270
|
secretRefs: Object.values(integration.secrets),
|
|
12107
12271
|
secretStatus: {},
|
|
12272
|
+
filters: integration.filters,
|
|
12108
12273
|
findings: findings.filter((f3) => f3.id === integration.id)
|
|
12109
12274
|
};
|
|
12110
12275
|
});
|
|
@@ -12171,7 +12336,8 @@ async function listExternalWorkItems(dir, id, opts = {}, env = process.env) {
|
|
|
12171
12336
|
const adapter = resolveAdapter(integration);
|
|
12172
12337
|
if (!adapter.capabilities.workItems.list) throw integrationError("UNSUPPORTED_CAPABILITY", `Adapter "${adapter.id}" cannot list work items.`);
|
|
12173
12338
|
const { context } = await buildContextWithSecrets(dir, integration, env);
|
|
12174
|
-
|
|
12339
|
+
const filters = mergeFilters(integration.filters, opts.filters);
|
|
12340
|
+
return withTimeout(adapter.listWorkItems({ context, cursor: opts.cursor, pageSize: opts.pageSize, filters }), context.timeoutMs);
|
|
12175
12341
|
}
|
|
12176
12342
|
async function getExternalWorkItem(dir, id, externalId, env = process.env) {
|
|
12177
12343
|
const { integration } = requireIntegration(dir, id);
|
package/package.json
CHANGED