@sweny-ai/core 0.1.77 → 0.1.79
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/browser.d.ts +11 -5
- package/dist/browser.js +11 -11
- package/dist/claude.d.ts +16 -0
- package/dist/claude.js +98 -9
- package/dist/cli/config.d.ts +22 -0
- package/dist/cli/config.js +56 -9
- package/dist/cli/main.d.ts +1 -1
- package/dist/cli/main.js +56 -57
- package/dist/cli/marketplace.js +35 -9
- package/dist/cli/publish.d.ts +10 -0
- package/dist/cli/publish.js +22 -14
- package/dist/loader.d.ts +40 -0
- package/dist/loader.js +73 -0
- package/dist/mcp-catalog.d.ts +47 -0
- package/dist/mcp-catalog.js +304 -0
- package/dist/mcp.d.ts +6 -9
- package/dist/mcp.js +24 -314
- package/dist/schema.d.ts +183 -151
- package/dist/schema.js +49 -7
- package/dist/skills/custom-loader.d.ts +40 -0
- package/dist/skills/custom-loader.js +107 -32
- package/dist/skills/index.d.ts +13 -1
- package/dist/skills/index.js +12 -3
- package/dist/studio.js +4 -1
- package/dist/templates.d.ts +29 -8
- package/dist/templates.js +30 -20
- package/dist/types.d.ts +12 -0
- package/dist/verify.js +96 -7
- package/package.json +8 -4
- package/dist/__tests__/cascade.test.d.ts +0 -11
- package/dist/__tests__/cascade.test.js +0 -452
- package/dist/__tests__/claude.test.d.ts +0 -1
- package/dist/__tests__/claude.test.js +0 -427
- package/dist/__tests__/custom-loader.test.d.ts +0 -1
- package/dist/__tests__/custom-loader.test.js +0 -116
- package/dist/__tests__/executor.test.d.ts +0 -1
- package/dist/__tests__/executor.test.js +0 -1635
- package/dist/__tests__/integration/datadog.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/datadog.integration.test.js +0 -23
- package/dist/__tests__/integration/e2e-workflow.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/e2e-workflow.integration.test.js +0 -75
- package/dist/__tests__/integration/github.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/github.integration.test.js +0 -37
- package/dist/__tests__/integration/harness.d.ts +0 -24
- package/dist/__tests__/integration/harness.js +0 -34
- package/dist/__tests__/integration/linear.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/linear.integration.test.js +0 -15
- package/dist/__tests__/integration/sentry.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/sentry.integration.test.js +0 -20
- package/dist/__tests__/integration/slack.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/slack.integration.test.js +0 -22
- package/dist/__tests__/integration/sources.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/sources.integration.test.js +0 -123
- package/dist/__tests__/publish.test.d.ts +0 -1
- package/dist/__tests__/publish.test.js +0 -180
- package/dist/__tests__/requires.test.d.ts +0 -1
- package/dist/__tests__/requires.test.js +0 -82
- package/dist/__tests__/retry.test.d.ts +0 -1
- package/dist/__tests__/retry.test.js +0 -213
- package/dist/__tests__/schema.test.d.ts +0 -1
- package/dist/__tests__/schema.test.js +0 -600
- package/dist/__tests__/skill-config-integration.test.d.ts +0 -1
- package/dist/__tests__/skill-config-integration.test.js +0 -204
- package/dist/__tests__/skills-index.test.d.ts +0 -1
- package/dist/__tests__/skills-index.test.js +0 -119
- package/dist/__tests__/skills.test.d.ts +0 -1
- package/dist/__tests__/skills.test.js +0 -565
- package/dist/__tests__/spec-conformance.test.d.ts +0 -18
- package/dist/__tests__/spec-conformance.test.js +0 -1084
- package/dist/__tests__/studio.test.d.ts +0 -1
- package/dist/__tests__/studio.test.js +0 -403
- package/dist/__tests__/templates.test.d.ts +0 -1
- package/dist/__tests__/templates.test.js +0 -49
- package/dist/__tests__/testing.test.d.ts +0 -1
- package/dist/__tests__/testing.test.js +0 -242
- package/dist/__tests__/verify.test.d.ts +0 -1
- package/dist/__tests__/verify.test.js +0 -517
- package/dist/__tests__/version-consistency.test.d.ts +0 -1
- package/dist/__tests__/version-consistency.test.js +0 -312
- package/dist/__tests__/workflow-builder.test.d.ts +0 -1
- package/dist/__tests__/workflow-builder.test.js +0 -110
- package/dist/__tests__/workflow-yaml.test.d.ts +0 -1
- package/dist/__tests__/workflow-yaml.test.js +0 -201
- package/dist/cli/__tests__/diagram.test.d.ts +0 -1
- package/dist/cli/__tests__/diagram.test.js +0 -225
- package/dist/cli/__tests__/report-cloud.test.d.ts +0 -1
- package/dist/cli/__tests__/report-cloud.test.js +0 -165
- package/dist/cli/__tests__/upgrade.test.d.ts +0 -1
- package/dist/cli/__tests__/upgrade.test.js +0 -317
- package/dist/cli/__tests__/version-check.test.d.ts +0 -1
- package/dist/cli/__tests__/version-check.test.js +0 -209
- package/dist/cli/config.test.d.ts +0 -1
- package/dist/cli/config.test.js +0 -200
- package/dist/cli/credentials.test.d.ts +0 -1
- package/dist/cli/credentials.test.js +0 -172
- package/dist/cli/e2e.test.d.ts +0 -1
- package/dist/cli/e2e.test.js +0 -690
- package/dist/cli/marketplace.test.d.ts +0 -1
- package/dist/cli/marketplace.test.js +0 -355
- package/dist/cli/new.test.d.ts +0 -1
- package/dist/cli/new.test.js +0 -1043
- package/dist/cli/output.test.d.ts +0 -1
- package/dist/cli/output.test.js +0 -180
- package/dist/cli/publish.test.d.ts +0 -1
- package/dist/cli/publish.test.js +0 -610
- package/dist/cli/renderer.test.d.ts +0 -1
- package/dist/cli/renderer.test.js +0 -302
- package/dist/executor.test.d.ts +0 -1
- package/dist/executor.test.js +0 -618
- package/dist/mcp.test.d.ts +0 -1
- package/dist/mcp.test.js +0 -735
- package/dist/mermaid.test.d.ts +0 -1
- package/dist/mermaid.test.js +0 -256
- package/dist/sources.test.d.ts +0 -1
- package/dist/sources.test.js +0 -265
- package/dist/sources.validation.test.d.ts +0 -12
- package/dist/sources.validation.test.js +0 -380
- package/dist/workflow-builder.test.d.ts +0 -1
- package/dist/workflow-builder.test.js +0 -123
package/dist/cli/config.test.js
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { validateInputs, parseCliInputs } from "./config.js";
|
|
3
|
-
/**
|
|
4
|
-
* Focused tests for validateInputs() — specifically the notification-provider
|
|
5
|
-
* switch. Regressions here break every `swenyai/triage` action run because
|
|
6
|
-
* that action passes --notification-provider github-summary by default.
|
|
7
|
-
*/
|
|
8
|
-
function baseConfig(overrides = {}) {
|
|
9
|
-
return {
|
|
10
|
-
codingAgentProvider: "claude",
|
|
11
|
-
anthropicApiKey: "sk-ant-test",
|
|
12
|
-
claudeOauthToken: "",
|
|
13
|
-
openaiApiKey: "",
|
|
14
|
-
geminiApiKey: "",
|
|
15
|
-
observabilityProviders: ["file"],
|
|
16
|
-
observabilityCredentials: { file: {} },
|
|
17
|
-
issueTrackerProvider: "file",
|
|
18
|
-
linearApiKey: "",
|
|
19
|
-
linearTeamId: "",
|
|
20
|
-
linearBugLabelId: "",
|
|
21
|
-
linearTriageLabelId: "",
|
|
22
|
-
linearStateBacklog: "",
|
|
23
|
-
linearStateInProgress: "",
|
|
24
|
-
linearStatePeerReview: "",
|
|
25
|
-
timeRange: "24h",
|
|
26
|
-
severityFocus: "errors",
|
|
27
|
-
serviceFilter: "*",
|
|
28
|
-
investigationDepth: "standard",
|
|
29
|
-
maxInvestigateTurns: 50,
|
|
30
|
-
maxImplementTurns: 30,
|
|
31
|
-
baseBranch: "main",
|
|
32
|
-
prLabels: ["agent"],
|
|
33
|
-
issueLabels: [],
|
|
34
|
-
dryRun: false,
|
|
35
|
-
reviewMode: "review",
|
|
36
|
-
noveltyMode: true,
|
|
37
|
-
issueOverride: "",
|
|
38
|
-
additionalInstructions: "",
|
|
39
|
-
serviceMapPath: ".github/service-map.yml",
|
|
40
|
-
githubToken: "ghp_test",
|
|
41
|
-
botToken: "",
|
|
42
|
-
sourceControlProvider: "github",
|
|
43
|
-
jiraBaseUrl: "",
|
|
44
|
-
jiraEmail: "",
|
|
45
|
-
jiraApiToken: "",
|
|
46
|
-
gitlabToken: "",
|
|
47
|
-
gitlabProjectId: "",
|
|
48
|
-
gitlabBaseUrl: "https://gitlab.com",
|
|
49
|
-
notificationProvider: "console",
|
|
50
|
-
notificationWebhookUrl: "",
|
|
51
|
-
sendgridApiKey: "",
|
|
52
|
-
emailFrom: "",
|
|
53
|
-
emailTo: "",
|
|
54
|
-
webhookSigningSecret: "",
|
|
55
|
-
repository: "acme/app",
|
|
56
|
-
repositoryOwner: "",
|
|
57
|
-
json: false,
|
|
58
|
-
stream: false,
|
|
59
|
-
bell: false,
|
|
60
|
-
cacheDir: ".sweny/cache",
|
|
61
|
-
cacheTtl: 86400,
|
|
62
|
-
noCache: false,
|
|
63
|
-
outputDir: ".sweny/output",
|
|
64
|
-
mcpServers: {},
|
|
65
|
-
workspaceTools: [],
|
|
66
|
-
rules: [],
|
|
67
|
-
context: [],
|
|
68
|
-
offline: false,
|
|
69
|
-
fetchAuth: {},
|
|
70
|
-
cloudToken: "",
|
|
71
|
-
...overrides,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
describe("validateInputs — notification provider", () => {
|
|
75
|
-
it("accepts console (no credentials required)", () => {
|
|
76
|
-
const errors = validateInputs(baseConfig({ notificationProvider: "console" }));
|
|
77
|
-
expect(errors.filter((e) => e.includes("notification-provider"))).toEqual([]);
|
|
78
|
-
});
|
|
79
|
-
it("accepts github-summary (no credentials required)", () => {
|
|
80
|
-
// Regression guard: the `swenyai/triage` composite action passes this as
|
|
81
|
-
// its default. If the validator stops accepting it every scheduled run
|
|
82
|
-
// across every consumer immediately breaks.
|
|
83
|
-
const errors = validateInputs(baseConfig({ notificationProvider: "github-summary" }));
|
|
84
|
-
expect(errors.filter((e) => e.includes("notification-provider"))).toEqual([]);
|
|
85
|
-
});
|
|
86
|
-
it("accepts file (no credentials required)", () => {
|
|
87
|
-
const errors = validateInputs(baseConfig({ notificationProvider: "file" }));
|
|
88
|
-
expect(errors.filter((e) => e.includes("notification-provider"))).toEqual([]);
|
|
89
|
-
});
|
|
90
|
-
it("requires NOTIFICATION_WEBHOOK_URL for slack", () => {
|
|
91
|
-
const errors = validateInputs(baseConfig({ notificationProvider: "slack", notificationWebhookUrl: "" }));
|
|
92
|
-
expect(errors.some((e) => e.includes("NOTIFICATION_WEBHOOK_URL"))).toBe(true);
|
|
93
|
-
});
|
|
94
|
-
it("accepts slack when NOTIFICATION_WEBHOOK_URL is set", () => {
|
|
95
|
-
const errors = validateInputs(baseConfig({
|
|
96
|
-
notificationProvider: "slack",
|
|
97
|
-
notificationWebhookUrl: "https://hooks.slack.com/services/T/B/X",
|
|
98
|
-
}));
|
|
99
|
-
expect(errors.filter((e) => e.includes("notification"))).toEqual([]);
|
|
100
|
-
});
|
|
101
|
-
it("requires sendgrid credentials for email", () => {
|
|
102
|
-
const errors = validateInputs(baseConfig({ notificationProvider: "email" }));
|
|
103
|
-
expect(errors.some((e) => e.includes("SENDGRID_API_KEY"))).toBe(true);
|
|
104
|
-
expect(errors.some((e) => e.includes("EMAIL_FROM"))).toBe(true);
|
|
105
|
-
expect(errors.some((e) => e.includes("EMAIL_TO"))).toBe(true);
|
|
106
|
-
});
|
|
107
|
-
it("rejects unknown providers and lists github-summary in the error", () => {
|
|
108
|
-
const errors = validateInputs(baseConfig({ notificationProvider: "bogus" }));
|
|
109
|
-
const err = errors.find((e) => e.includes("Unknown --notification-provider"));
|
|
110
|
-
expect(err).toBeDefined();
|
|
111
|
-
expect(err).toContain("github-summary");
|
|
112
|
-
expect(err).toContain("console");
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
describe("validateInputs — observability provider", () => {
|
|
116
|
-
it("accepts 'none' without requiring any credentials", () => {
|
|
117
|
-
const errors = validateInputs(baseConfig({ observabilityProviders: [], observabilityCredentials: {} }));
|
|
118
|
-
expect(errors.filter((e) => e.includes("DD_") || e.includes("observability"))).toEqual([]);
|
|
119
|
-
});
|
|
120
|
-
it("requires DD keys when explicitly set to datadog", () => {
|
|
121
|
-
const errors = validateInputs(baseConfig({ observabilityProviders: ["datadog"], observabilityCredentials: {} }));
|
|
122
|
-
expect(errors.some((e) => e.includes("DD_API_KEY"))).toBe(true);
|
|
123
|
-
expect(errors.some((e) => e.includes("DD_APP_KEY"))).toBe(true);
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
describe("parseCliInputs — observability provider default", () => {
|
|
127
|
-
it("defaults to empty array when no provider is configured", () => {
|
|
128
|
-
const config = parseCliInputs({}, {});
|
|
129
|
-
expect(config.observabilityProviders).toEqual([]);
|
|
130
|
-
});
|
|
131
|
-
it("respects explicit datadog provider", () => {
|
|
132
|
-
const config = parseCliInputs({ observabilityProvider: "datadog" }, {});
|
|
133
|
-
expect(config.observabilityProviders).toEqual(["datadog"]);
|
|
134
|
-
});
|
|
135
|
-
it("supports comma-separated multiple providers", () => {
|
|
136
|
-
const config = parseCliInputs({ observabilityProvider: "loki,sentry" }, {});
|
|
137
|
-
expect(config.observabilityProviders).toEqual(["loki", "sentry"]);
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
describe("fetch.auth + offline parsing", () => {
|
|
141
|
-
it("parses offline flag", () => {
|
|
142
|
-
const config = parseCliInputs({ offline: true }, {});
|
|
143
|
-
expect(config.offline).toBe(true);
|
|
144
|
-
});
|
|
145
|
-
it("defaults fetchAuth to {} and offline to false", () => {
|
|
146
|
-
const config = parseCliInputs({}, {});
|
|
147
|
-
expect(config.offline).toBe(false);
|
|
148
|
-
expect(config.fetchAuth).toEqual({});
|
|
149
|
-
});
|
|
150
|
-
it("parses fetch.auth from file config", () => {
|
|
151
|
-
const config = parseCliInputs({}, { "fetch.auth": { "api.example.com": "MY_TOKEN" } });
|
|
152
|
-
expect(config.fetchAuth).toEqual({ "api.example.com": "MY_TOKEN" });
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
describe("parseCliInputs — cloud token", () => {
|
|
156
|
-
it("reads SWENY_CLOUD_TOKEN from env", () => {
|
|
157
|
-
const original = process.env.SWENY_CLOUD_TOKEN;
|
|
158
|
-
process.env.SWENY_CLOUD_TOKEN = "sweny_pk_test123";
|
|
159
|
-
try {
|
|
160
|
-
const config = parseCliInputs({});
|
|
161
|
-
expect(config.cloudToken).toBe("sweny_pk_test123");
|
|
162
|
-
}
|
|
163
|
-
finally {
|
|
164
|
-
if (original === undefined)
|
|
165
|
-
delete process.env.SWENY_CLOUD_TOKEN;
|
|
166
|
-
else
|
|
167
|
-
process.env.SWENY_CLOUD_TOKEN = original;
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
it("reads cloud-token from config file", () => {
|
|
171
|
-
const config = parseCliInputs({}, { "cloud-token": "sweny_pk_fromfile" });
|
|
172
|
-
expect(config.cloudToken).toBe("sweny_pk_fromfile");
|
|
173
|
-
});
|
|
174
|
-
it("env var overrides config file", () => {
|
|
175
|
-
const original = process.env.SWENY_CLOUD_TOKEN;
|
|
176
|
-
process.env.SWENY_CLOUD_TOKEN = "sweny_pk_env";
|
|
177
|
-
try {
|
|
178
|
-
const config = parseCliInputs({}, { "cloud-token": "sweny_pk_file" });
|
|
179
|
-
expect(config.cloudToken).toBe("sweny_pk_env");
|
|
180
|
-
}
|
|
181
|
-
finally {
|
|
182
|
-
if (original === undefined)
|
|
183
|
-
delete process.env.SWENY_CLOUD_TOKEN;
|
|
184
|
-
else
|
|
185
|
-
process.env.SWENY_CLOUD_TOKEN = original;
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
it("defaults to empty string", () => {
|
|
189
|
-
const original = process.env.SWENY_CLOUD_TOKEN;
|
|
190
|
-
delete process.env.SWENY_CLOUD_TOKEN;
|
|
191
|
-
try {
|
|
192
|
-
const config = parseCliInputs({});
|
|
193
|
-
expect(config.cloudToken).toBe("");
|
|
194
|
-
}
|
|
195
|
-
finally {
|
|
196
|
-
if (original !== undefined)
|
|
197
|
-
process.env.SWENY_CLOUD_TOKEN = original;
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { buildCredentialMap } from "./credentials.js";
|
|
3
|
-
import { buildSkillMcpServers } from "../mcp.js";
|
|
4
|
-
// ─────────────────────────────────────────────────────────────────────
|
|
5
|
-
// Integration tests: env vars → buildCredentialMap → buildSkillMcpServers
|
|
6
|
-
// ─────────────────────────────────────────────────────────────────────
|
|
7
|
-
//
|
|
8
|
-
// These tests catch env-var name drift between:
|
|
9
|
-
// - the user-facing env var name (what docs / new.ts / config.ts read)
|
|
10
|
-
// - the canonical key the MCP wiring functions look up
|
|
11
|
-
//
|
|
12
|
-
// Unit tests in mcp.test.ts inject the credentials map directly. That
|
|
13
|
-
// validates each MCP wiring path but cannot catch a buildCredentialMap
|
|
14
|
-
// that puts the value under the wrong key. THESE tests close that gap
|
|
15
|
-
// by going through the real env-var → canonical-key translation.
|
|
16
|
-
//
|
|
17
|
-
// If a future contributor renames an env var and forgets to update both
|
|
18
|
-
// sides, one of these will fail loudly.
|
|
19
|
-
describe("buildCredentialMap ↔ buildSkillMcpServers integration", () => {
|
|
20
|
-
// ── New Relic: NR_API_KEY user-facing → NEW_RELIC_API_KEY canonical ──
|
|
21
|
-
it("user setting NR_API_KEY auto-wires the New Relic MCP", () => {
|
|
22
|
-
const creds = buildCredentialMap({ NR_API_KEY: "NRAK-abc" });
|
|
23
|
-
expect(creds.NEW_RELIC_API_KEY).toBe("NRAK-abc");
|
|
24
|
-
const mcps = buildSkillMcpServers({
|
|
25
|
-
referencedSkills: new Set(["newrelic"]),
|
|
26
|
-
credentials: creds,
|
|
27
|
-
});
|
|
28
|
-
expect(mcps.newrelic).toBeDefined();
|
|
29
|
-
expect(mcps.newrelic?.url).toBe("https://mcp.newrelic.com/mcp/");
|
|
30
|
-
});
|
|
31
|
-
it("user setting NR_REGION=eu picks the EU New Relic endpoint", () => {
|
|
32
|
-
const creds = buildCredentialMap({ NR_API_KEY: "NRAK-abc", NR_REGION: "eu" });
|
|
33
|
-
const mcps = buildSkillMcpServers({
|
|
34
|
-
referencedSkills: new Set(["newrelic"]),
|
|
35
|
-
credentials: creds,
|
|
36
|
-
});
|
|
37
|
-
expect(mcps.newrelic?.url).toBe("https://mcp.eu.newrelic.com/mcp/");
|
|
38
|
-
});
|
|
39
|
-
it("user setting NEW_RELIC_API_KEY (canonical name) also works", () => {
|
|
40
|
-
const creds = buildCredentialMap({ NEW_RELIC_API_KEY: "NRAK-xyz" });
|
|
41
|
-
expect(creds.NEW_RELIC_API_KEY).toBe("NRAK-xyz");
|
|
42
|
-
});
|
|
43
|
-
// ── Sentry: SENTRY_BASE_URL user-facing → SENTRY_URL canonical ──
|
|
44
|
-
it("user setting SENTRY_BASE_URL for self-hosted reaches the MCP layer", () => {
|
|
45
|
-
const creds = buildCredentialMap({
|
|
46
|
-
SENTRY_AUTH_TOKEN: "sntrys_abc",
|
|
47
|
-
SENTRY_BASE_URL: "https://sentry.acme.com",
|
|
48
|
-
});
|
|
49
|
-
expect(creds.SENTRY_URL).toBe("https://sentry.acme.com");
|
|
50
|
-
const mcps = buildSkillMcpServers({
|
|
51
|
-
referencedSkills: new Set(["sentry"]),
|
|
52
|
-
credentials: creds,
|
|
53
|
-
});
|
|
54
|
-
expect(mcps.sentry).toBeDefined();
|
|
55
|
-
expect(mcps.sentry?.env?.SENTRY_HOST).toBe("sentry.acme.com");
|
|
56
|
-
});
|
|
57
|
-
it("user setting SENTRY_URL (canonical name) also reaches MCP layer", () => {
|
|
58
|
-
const creds = buildCredentialMap({
|
|
59
|
-
SENTRY_AUTH_TOKEN: "sntrys_abc",
|
|
60
|
-
SENTRY_URL: "https://sentry.acme.com",
|
|
61
|
-
});
|
|
62
|
-
expect(creds.SENTRY_URL).toBe("https://sentry.acme.com");
|
|
63
|
-
});
|
|
64
|
-
it("default sentry.io URL does not set SENTRY_HOST", () => {
|
|
65
|
-
const creds = buildCredentialMap({ SENTRY_AUTH_TOKEN: "sntrys_abc" });
|
|
66
|
-
const mcps = buildSkillMcpServers({
|
|
67
|
-
referencedSkills: new Set(["sentry"]),
|
|
68
|
-
credentials: creds,
|
|
69
|
-
});
|
|
70
|
-
expect(mcps.sentry).toBeDefined();
|
|
71
|
-
expect(mcps.sentry?.env?.SENTRY_HOST).toBeUndefined();
|
|
72
|
-
});
|
|
73
|
-
// ── Jira: JIRA_BASE_URL user-facing → JIRA_URL canonical ──
|
|
74
|
-
it("user setting JIRA_BASE_URL auto-wires the Jira MCP", () => {
|
|
75
|
-
const creds = buildCredentialMap({
|
|
76
|
-
JIRA_BASE_URL: "https://acme.atlassian.net",
|
|
77
|
-
JIRA_EMAIL: "alice@acme.com",
|
|
78
|
-
JIRA_API_TOKEN: "tok_abc",
|
|
79
|
-
});
|
|
80
|
-
expect(creds.JIRA_URL).toBe("https://acme.atlassian.net");
|
|
81
|
-
const mcps = buildSkillMcpServers({
|
|
82
|
-
referencedSkills: new Set(["jira"]),
|
|
83
|
-
credentials: creds,
|
|
84
|
-
});
|
|
85
|
-
expect(mcps.jira).toBeDefined();
|
|
86
|
-
expect(mcps.jira?.env?.JIRA_URL).toBe("https://acme.atlassian.net");
|
|
87
|
-
});
|
|
88
|
-
it("user setting JIRA_URL (canonical name) also auto-wires Jira", () => {
|
|
89
|
-
const creds = buildCredentialMap({
|
|
90
|
-
JIRA_URL: "https://acme.atlassian.net",
|
|
91
|
-
JIRA_EMAIL: "alice@acme.com",
|
|
92
|
-
JIRA_API_TOKEN: "tok_abc",
|
|
93
|
-
});
|
|
94
|
-
const mcps = buildSkillMcpServers({
|
|
95
|
-
referencedSkills: new Set(["jira"]),
|
|
96
|
-
credentials: creds,
|
|
97
|
-
});
|
|
98
|
-
expect(mcps.jira).toBeDefined();
|
|
99
|
-
});
|
|
100
|
-
it("Jira MCP is NOT wired without all 3 creds", () => {
|
|
101
|
-
const creds = buildCredentialMap({
|
|
102
|
-
JIRA_BASE_URL: "https://acme.atlassian.net",
|
|
103
|
-
JIRA_EMAIL: "alice@acme.com",
|
|
104
|
-
// missing JIRA_API_TOKEN
|
|
105
|
-
});
|
|
106
|
-
const mcps = buildSkillMcpServers({
|
|
107
|
-
referencedSkills: new Set(["jira"]),
|
|
108
|
-
credentials: creds,
|
|
109
|
-
});
|
|
110
|
-
expect(mcps.jira).toBeUndefined();
|
|
111
|
-
});
|
|
112
|
-
// ── Notion: both env-var spellings ──
|
|
113
|
-
it("user setting NOTION_API_KEY (official Notion name) auto-wires Notion MCP", () => {
|
|
114
|
-
const creds = buildCredentialMap({ NOTION_API_KEY: "secret_abc" });
|
|
115
|
-
expect(creds.NOTION_API_KEY).toBe("secret_abc");
|
|
116
|
-
const mcps = buildSkillMcpServers({
|
|
117
|
-
referencedSkills: new Set(["notion"]),
|
|
118
|
-
credentials: creds,
|
|
119
|
-
});
|
|
120
|
-
expect(mcps.notion).toBeDefined();
|
|
121
|
-
expect(mcps.notion?.env?.NOTION_TOKEN).toBe("secret_abc");
|
|
122
|
-
});
|
|
123
|
-
it("user setting NOTION_TOKEN auto-wires Notion MCP", () => {
|
|
124
|
-
const creds = buildCredentialMap({ NOTION_TOKEN: "secret_xyz" });
|
|
125
|
-
const mcps = buildSkillMcpServers({
|
|
126
|
-
referencedSkills: new Set(["notion"]),
|
|
127
|
-
credentials: creds,
|
|
128
|
-
});
|
|
129
|
-
expect(mcps.notion?.env?.NOTION_TOKEN).toBe("secret_xyz");
|
|
130
|
-
});
|
|
131
|
-
// ── BetterStack token fallbacks ──
|
|
132
|
-
it("user setting BETTERSTACK_API_TOKEN auto-wires BetterStack MCP", () => {
|
|
133
|
-
const creds = buildCredentialMap({ BETTERSTACK_API_TOKEN: "bs_abc" });
|
|
134
|
-
const mcps = buildSkillMcpServers({
|
|
135
|
-
referencedSkills: new Set(["betterstack"]),
|
|
136
|
-
credentials: creds,
|
|
137
|
-
});
|
|
138
|
-
expect(mcps.betterstack).toBeDefined();
|
|
139
|
-
expect(mcps.betterstack?.headers?.Authorization).toBe("Bearer bs_abc");
|
|
140
|
-
});
|
|
141
|
-
it("user setting BETTERSTACK_TELEMETRY_TOKEN reaches the MCP layer", () => {
|
|
142
|
-
const creds = buildCredentialMap({ BETTERSTACK_TELEMETRY_TOKEN: "bs_tel_abc" });
|
|
143
|
-
const mcps = buildSkillMcpServers({
|
|
144
|
-
referencedSkills: new Set(["betterstack"]),
|
|
145
|
-
credentials: creds,
|
|
146
|
-
});
|
|
147
|
-
expect(mcps.betterstack?.headers?.Authorization).toBe("Bearer bs_tel_abc");
|
|
148
|
-
});
|
|
149
|
-
// ── Happy-path: all the common providers at once ──
|
|
150
|
-
it("end-to-end: a typical SRE triage env wires every expected MCP", () => {
|
|
151
|
-
const creds = buildCredentialMap({
|
|
152
|
-
GITHUB_TOKEN: "ghp_abc",
|
|
153
|
-
LINEAR_API_KEY: "lin_abc",
|
|
154
|
-
DD_API_KEY: "dd_api",
|
|
155
|
-
DD_APP_KEY: "dd_app",
|
|
156
|
-
SLACK_BOT_TOKEN: "xoxb-abc",
|
|
157
|
-
});
|
|
158
|
-
const mcps = buildSkillMcpServers({
|
|
159
|
-
referencedSkills: new Set(["github", "linear", "datadog", "slack"]),
|
|
160
|
-
credentials: creds,
|
|
161
|
-
});
|
|
162
|
-
expect(Object.keys(mcps).sort()).toEqual(["datadog", "github", "linear", "slack"]);
|
|
163
|
-
});
|
|
164
|
-
it("returns empty creds for an empty env", () => {
|
|
165
|
-
expect(buildCredentialMap({})).toEqual({});
|
|
166
|
-
});
|
|
167
|
-
it("ignores empty-string env values (treats them as unset)", () => {
|
|
168
|
-
const creds = buildCredentialMap({ GITHUB_TOKEN: "", LINEAR_API_KEY: "lin_abc" });
|
|
169
|
-
expect(creds.GITHUB_TOKEN).toBeUndefined();
|
|
170
|
-
expect(creds.LINEAR_API_KEY).toBe("lin_abc");
|
|
171
|
-
});
|
|
172
|
-
});
|
package/dist/cli/e2e.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|