spur-board 0.5.0 → 0.6.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/cli.mjs +4 -9
- package/dist/{client-BnkZmz1i.mjs → client-Dw9ZovyI.mjs} +1 -1
- package/dist/client.mjs +1 -1
- package/dist/{config-UyXnaekw.mjs → config-CeDZQlvy.mjs} +2 -2
- package/dist/daemon.mjs +79 -40
- package/dist/mcp.mjs +3 -3
- package/dist/{src-VWyX7Nwm.mjs → src-Cy74ZQfR.mjs} +44 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { R as configSchema, s as OPERATIONS, z as
|
|
2
|
-
import { a as renderCliError, i as errorExitCode, n as requestTokenEnrollment, o as escapeTerminalControls, r as CliError, t as requestOperation } from "./client-
|
|
3
|
-
import { i as resolveDaemonAddress, n as loadClientConfig, r as loadEnrollmentConfig, t as configFile } from "./config-
|
|
1
|
+
import { B as SLACK_BOT_SCOPES, R as configSchema, s as OPERATIONS, z as requiredSecretKeys } from "./src-Cy74ZQfR.mjs";
|
|
2
|
+
import { a as renderCliError, i as errorExitCode, n as requestTokenEnrollment, o as escapeTerminalControls, r as CliError, t as requestOperation } from "./client-Dw9ZovyI.mjs";
|
|
3
|
+
import { i as resolveDaemonAddress, n as loadClientConfig, r as loadEnrollmentConfig, t as configFile } from "./config-CeDZQlvy.mjs";
|
|
4
4
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
5
5
|
import { chmodSync, closeSync, constants, existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, readlinkSync, realpathSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { homedir, hostname, userInfo } from "node:os";
|
|
@@ -190,12 +190,7 @@ function localSecrets(config, path, ports) {
|
|
|
190
190
|
} catch {
|
|
191
191
|
names = {};
|
|
192
192
|
}
|
|
193
|
-
const
|
|
194
|
-
const required = [
|
|
195
|
-
"GITHUB_TOKEN",
|
|
196
|
-
...config.projects.some((project) => project.tracker.type === "jira") ? ["JIRA_EMAIL", "JIRA_API_TOKEN"] : [],
|
|
197
|
-
...slackConfigured ? ["SLACK_BOT_TOKEN", "SLACK_APP_TOKEN"] : []
|
|
198
|
-
];
|
|
193
|
+
const required = requiredSecretKeys(config);
|
|
199
194
|
const missing = required.filter((name) => !names[name]);
|
|
200
195
|
return {
|
|
201
196
|
...result("secrets", missing.length === 0, `Add ${missing.join(", ")} to the private secrets.env file.`),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as errorContextSchema, N as errorEnvelopeSchema, P as successEnvelopeSchema, j as ERRORS, l as renderJsonError } from "./src-
|
|
1
|
+
import { M as errorContextSchema, N as errorEnvelopeSchema, P as successEnvelopeSchema, j as ERRORS, l as renderJsonError } from "./src-Cy74ZQfR.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { request } from "node:http";
|
package/dist/client.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as requestTokenEnrollment, t as requestOperation } from "./client-
|
|
1
|
+
import { n as requestTokenEnrollment, t as requestOperation } from "./client-Dw9ZovyI.mjs";
|
|
2
2
|
export { requestOperation, requestTokenEnrollment };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as configSchema } from "./src-
|
|
2
|
-
import { r as CliError } from "./client-
|
|
1
|
+
import { R as configSchema } from "./src-Cy74ZQfR.mjs";
|
|
2
|
+
import { r as CliError } from "./client-Dw9ZovyI.mjs";
|
|
3
3
|
import { closeSync, constants, fstatSync, lstatSync, openSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
package/dist/daemon.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as taskKeySchema, C as sessionFactsSchema, D as errorCodeOf, E as encodeActorId, L as DEFAULT_SLACK_COMMAND, O as parseActorId, P as successEnvelopeSchema, R as configSchema, S as prRefSchema, T as actorIdSchema, _ as EVENT_KINDS, a as buildCatalogSnapshot, b as SESSION_STATUSES, c as renderHttpProblem, d as SPACE_IDS, f as conversationRefSchema, g as userIdSchema, h as messageRefSchema, i as sourceCursorSchema, j as ERRORS, k as parseRef$1, m as interactionRefSchema, n as batchSchema, o as roleCanUseOperation, p as inboundEventSchema, r as entityRefSchema, s as OPERATIONS, t as AdapterError, v as eventPayloadSchemas, w as ticketFactsSchema, x as prFactsSchema, y as SESSION_HEALTH_STATES, z as
|
|
1
|
+
import { A as taskKeySchema, B as SLACK_BOT_SCOPES, C as sessionFactsSchema, D as errorCodeOf, E as encodeActorId, L as DEFAULT_SLACK_COMMAND, O as parseActorId, P as successEnvelopeSchema, R as configSchema, S as prRefSchema, T as actorIdSchema, _ as EVENT_KINDS, a as buildCatalogSnapshot, b as SESSION_STATUSES, c as renderHttpProblem, d as SPACE_IDS, f as conversationRefSchema, g as userIdSchema, h as messageRefSchema, i as sourceCursorSchema, j as ERRORS, k as parseRef$1, m as interactionRefSchema, n as batchSchema, o as roleCanUseOperation, p as inboundEventSchema, r as entityRefSchema, s as OPERATIONS, t as AdapterError, v as eventPayloadSchemas, w as ticketFactsSchema, x as prFactsSchema, y as SESSION_HEALTH_STATES, z as requiredSecretKeys } from "./src-Cy74ZQfR.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import { closeSync, existsSync, fstatSync, ftruncateSync, mkdirSync, openSync, readFileSync, readdirSync, writeSync } from "node:fs";
|
|
@@ -12736,6 +12736,11 @@ function retryAt(headers, now) {
|
|
|
12736
12736
|
}
|
|
12737
12737
|
//#endregion
|
|
12738
12738
|
//#region ../adapters/src/github/client.ts
|
|
12739
|
+
function teamNameScopeDenied(error, query) {
|
|
12740
|
+
if (error.type !== "INSUFFICIENT_SCOPES" || !query.includes("... on Team { name }")) return false;
|
|
12741
|
+
if (error.path !== void 0) return error.path.includes("reviewRequests") && error.path.includes("requestedReviewer") && error.path.at(-1) === "name";
|
|
12742
|
+
return /\bname\b/i.test(error.message) && /\bread:(?:org|discussion)\b/i.test(error.message);
|
|
12743
|
+
}
|
|
12739
12744
|
function record$2(value) {
|
|
12740
12745
|
if (value === null || typeof value !== "object" || Array.isArray(value)) throw new AdapterError("transient", "Malformed GitHub response");
|
|
12741
12746
|
return value;
|
|
@@ -12824,6 +12829,8 @@ var GithubClient = class {
|
|
|
12824
12829
|
status: 429,
|
|
12825
12830
|
headers: response.headers
|
|
12826
12831
|
}, Date.now());
|
|
12832
|
+
if (errors.some((error) => teamNameScopeDenied(error, query))) throw new AdapterError("auth", "GitHub token needs read:org for team review requests");
|
|
12833
|
+
if (errors.some((error) => error.type === "INSUFFICIENT_SCOPES")) throw new AdapterError("auth", "GitHub token lacks a required GraphQL read scope");
|
|
12827
12834
|
const data = record$2(wire.data);
|
|
12828
12835
|
const rate = record$2(data.rateLimit);
|
|
12829
12836
|
const remaining = rate.remaining;
|
|
@@ -13056,6 +13063,12 @@ function githubSources(config, options) {
|
|
|
13056
13063
|
function scoped(errors, root) {
|
|
13057
13064
|
return errors.filter((error) => error.path?.[0] === root);
|
|
13058
13065
|
}
|
|
13066
|
+
function checkAccessDenied(errors) {
|
|
13067
|
+
return errors.some((error) => error.type === "FORBIDDEN" && error.path?.includes("statusCheckRollup") === true && error.path.includes("contexts"));
|
|
13068
|
+
}
|
|
13069
|
+
function requireCheckAccess(errors) {
|
|
13070
|
+
if (checkAccessDenied(errors)) throw new AdapterError("auth", "GitHub token lacks Checks read permission");
|
|
13071
|
+
}
|
|
13059
13072
|
function rejectUnscoped(errors, roots) {
|
|
13060
13073
|
if (errors.some((error) => error.path === void 0 || !roots.includes(String(error.path[0])))) throw new AdapterError("transient", "Unscoped GitHub GraphQL error");
|
|
13061
13074
|
}
|
|
@@ -13097,6 +13110,7 @@ async function fullPr(client, pr, owner, name, number, signal, budget) {
|
|
|
13097
13110
|
}, signal);
|
|
13098
13111
|
budget(response.budget);
|
|
13099
13112
|
rejectUnscoped(response.errors, ["repository"]);
|
|
13113
|
+
requireCheckAccess(response.errors);
|
|
13100
13114
|
if (response.errors.length > 0) return void 0;
|
|
13101
13115
|
const pagePr = record$2(nested(response.data, "repository", "pullRequest"));
|
|
13102
13116
|
const page = field === "contexts" ? contexts(pagePr) : record$2(pagePr[field]);
|
|
@@ -13154,6 +13168,7 @@ async function pollRepository({ id, repo, login, prefixes, client, ctx }) {
|
|
|
13154
13168
|
const found = discover(nodes, ctx.cursor, login);
|
|
13155
13169
|
const bootstrapCursor = bootstrap && discoveryOk ? latestUpdatedAt(connectionNodes(nested(response.data, "repository", "mergedBaseline")), found.cursor) ?? sourceCursorSchema.parse("1970-01-01T00:00:00.000Z") : void 0;
|
|
13156
13170
|
const process = async (number, wire, errors, ref) => {
|
|
13171
|
+
requireCheckAccess(errors);
|
|
13157
13172
|
const error = errors[0];
|
|
13158
13173
|
if (error !== void 0) {
|
|
13159
13174
|
const direct = error.path === void 0 || error.path.length <= 2;
|
|
@@ -13457,6 +13472,7 @@ function createGithubIssuesAdapter(options) {
|
|
|
13457
13472
|
//#endregion
|
|
13458
13473
|
//#region ../adapters/src/jira/jira.ts
|
|
13459
13474
|
const SEARCH_PAGE_LIMIT = 20;
|
|
13475
|
+
const MAX_GET_SEARCH_URL_LENGTH = 2e3;
|
|
13460
13476
|
const OUTSIDE_BATCH_SIZE = 50;
|
|
13461
13477
|
const FALLBACK_REQUEST_LIMIT = 100;
|
|
13462
13478
|
const SPRINT_SCHEMA = "com.pyxis.greenhopper.jira:gh-sprint";
|
|
@@ -13571,6 +13587,7 @@ function createJiraAdapter(options) {
|
|
|
13571
13587
|
if (signal.aborted) throw new AdapterError("transient", "Jira poll aborted");
|
|
13572
13588
|
throw new AdapterError("transient", "Jira request failed");
|
|
13573
13589
|
}
|
|
13590
|
+
if (response.status === 414 && options.searchMethod === "GET") throw new AdapterError("config", "Jira GET search URL is too long");
|
|
13574
13591
|
if (!response.ok) throw new JiraHttpError(response.status, classifyHttpFailure({
|
|
13575
13592
|
status: response.status,
|
|
13576
13593
|
headers: response.headers
|
|
@@ -13612,19 +13629,28 @@ function createJiraAdapter(options) {
|
|
|
13612
13629
|
const seen = /* @__PURE__ */ new Set();
|
|
13613
13630
|
for (let page = 0; page < SEARCH_PAGE_LIMIT; page += 1) {
|
|
13614
13631
|
beforePage?.();
|
|
13615
|
-
const
|
|
13632
|
+
const fields = [
|
|
13633
|
+
"summary",
|
|
13634
|
+
"status",
|
|
13635
|
+
"assignee",
|
|
13636
|
+
"labels",
|
|
13637
|
+
"updated",
|
|
13638
|
+
...sprintField === null ? [] : [sprintField]
|
|
13639
|
+
];
|
|
13640
|
+
const body = {
|
|
13616
13641
|
jql,
|
|
13617
13642
|
maxResults: 100,
|
|
13618
|
-
fields
|
|
13619
|
-
"summary",
|
|
13620
|
-
"status",
|
|
13621
|
-
"assignee",
|
|
13622
|
-
"labels",
|
|
13623
|
-
"updated",
|
|
13624
|
-
...sprintField === null ? [] : [sprintField]
|
|
13625
|
-
],
|
|
13643
|
+
fields,
|
|
13626
13644
|
...token === void 0 ? {} : { nextPageToken: token }
|
|
13627
|
-
}
|
|
13645
|
+
};
|
|
13646
|
+
const path = options.searchMethod === "GET" ? `/rest/api/3/search/jql?${new URLSearchParams({
|
|
13647
|
+
jql,
|
|
13648
|
+
maxResults: "100",
|
|
13649
|
+
fields: fields.join(","),
|
|
13650
|
+
...token === void 0 ? {} : { nextPageToken: token }
|
|
13651
|
+
}).toString()}` : "/rest/api/3/search/jql";
|
|
13652
|
+
if (options.searchMethod === "GET" && new URL(path, tracker.baseUrl).href.length > MAX_GET_SEARCH_URL_LENGTH) throw new AdapterError("config", `Jira GET search URL is too long (over ${String(MAX_GET_SEARCH_URL_LENGTH)} characters)`);
|
|
13653
|
+
const result = object$1(await request(tracker.baseUrl, path, signal, options.searchMethod === "GET" ? void 0 : body));
|
|
13628
13654
|
issues.push(...array(result["issues"]));
|
|
13629
13655
|
const next = result["nextPageToken"];
|
|
13630
13656
|
if (next == null || next === "") {
|
|
@@ -13878,9 +13904,15 @@ function applyEntityOutcomes(input) {
|
|
|
13878
13904
|
function startRunner(options) {
|
|
13879
13905
|
const startedAt = (options.now ?? Date.now)();
|
|
13880
13906
|
const sources = options.entries.map((entry) => runSource(entry, options, startedAt));
|
|
13881
|
-
return {
|
|
13882
|
-
|
|
13883
|
-
|
|
13907
|
+
return {
|
|
13908
|
+
firstAttempts: Promise.all(sources.map(async (source) => ({
|
|
13909
|
+
source: source.id,
|
|
13910
|
+
outcome: await source.firstAttempt
|
|
13911
|
+
}))),
|
|
13912
|
+
async stop() {
|
|
13913
|
+
await Promise.all(sources.map((source) => source.stop()));
|
|
13914
|
+
}
|
|
13915
|
+
};
|
|
13884
13916
|
}
|
|
13885
13917
|
function runSource(entry, options, runnerStartMs) {
|
|
13886
13918
|
const { adapter, reserveRemaining } = entry;
|
|
@@ -13954,7 +13986,7 @@ function runSource(entry, options, runnerStartMs) {
|
|
|
13954
13986
|
if (stopping) return;
|
|
13955
13987
|
pollTimer = setTimeout(() => {
|
|
13956
13988
|
pollTimer = void 0;
|
|
13957
|
-
current = poll();
|
|
13989
|
+
current = poll().then(() => void 0);
|
|
13958
13990
|
}, delayMs);
|
|
13959
13991
|
}
|
|
13960
13992
|
async function poll() {
|
|
@@ -14050,22 +14082,28 @@ function runSource(entry, options, runnerStartMs) {
|
|
|
14050
14082
|
now: now()
|
|
14051
14083
|
});
|
|
14052
14084
|
failures = delay.failures;
|
|
14053
|
-
armDeadline();
|
|
14085
|
+
if (!options.oneShot) armDeadline();
|
|
14054
14086
|
await report();
|
|
14055
|
-
schedule(delay.delayMs);
|
|
14087
|
+
if (!options.oneShot) schedule(delay.delayMs);
|
|
14088
|
+
return outcome;
|
|
14056
14089
|
}
|
|
14057
|
-
armDeadline();
|
|
14058
|
-
|
|
14059
|
-
|
|
14060
|
-
|
|
14061
|
-
|
|
14062
|
-
|
|
14063
|
-
|
|
14064
|
-
|
|
14065
|
-
|
|
14066
|
-
|
|
14067
|
-
|
|
14068
|
-
|
|
14090
|
+
if (!options.oneShot) armDeadline();
|
|
14091
|
+
const firstAttempt = poll();
|
|
14092
|
+
current = firstAttempt.then(() => void 0);
|
|
14093
|
+
return {
|
|
14094
|
+
id: source,
|
|
14095
|
+
firstAttempt,
|
|
14096
|
+
async stop() {
|
|
14097
|
+
stopping = true;
|
|
14098
|
+
clearTimeout(pollTimer);
|
|
14099
|
+
clearTimeout(deadlineTimer);
|
|
14100
|
+
clearTimeout(hardBoundTimer);
|
|
14101
|
+
pollTimer = deadlineTimer = hardBoundTimer = void 0;
|
|
14102
|
+
controller?.abort();
|
|
14103
|
+
await current;
|
|
14104
|
+
await reports;
|
|
14105
|
+
}
|
|
14106
|
+
};
|
|
14069
14107
|
}
|
|
14070
14108
|
/**
|
|
14071
14109
|
* Settles with `work`, or with undefined as soon as `signal` aborts, so `stop()` never waits
|
|
@@ -14325,7 +14363,8 @@ function startAdapters(config, core, options = {}) {
|
|
|
14325
14363
|
},
|
|
14326
14364
|
intervalMs: config.adapters.jira.intervalMs,
|
|
14327
14365
|
...options.fetch === void 0 ? {} : { fetch: options.fetch },
|
|
14328
|
-
warn: options.warn ?? (() => void 0)
|
|
14366
|
+
warn: options.warn ?? (() => void 0),
|
|
14367
|
+
...options.jiraSearchMethod === void 0 ? {} : { searchMethod: options.jiraSearchMethod }
|
|
14329
14368
|
}) : blindSource(id, config.adapters.jira.intervalMs, "Jira credential is missing") });
|
|
14330
14369
|
} else {
|
|
14331
14370
|
const id = `github-issues:${project.id}:${project.tracker.repo.toLowerCase()}`;
|
|
@@ -14362,12 +14401,16 @@ function startAdapters(config, core, options = {}) {
|
|
|
14362
14401
|
}) }],
|
|
14363
14402
|
core,
|
|
14364
14403
|
config,
|
|
14365
|
-
...options.now === void 0 ? {} : { now: options.now }
|
|
14404
|
+
...options.now === void 0 ? {} : { now: options.now },
|
|
14405
|
+
...options.oneShot === void 0 ? {} : { oneShot: options.oneShot }
|
|
14366
14406
|
});
|
|
14367
|
-
return {
|
|
14368
|
-
|
|
14369
|
-
|
|
14370
|
-
|
|
14407
|
+
return {
|
|
14408
|
+
firstAttempts: runner.firstAttempts,
|
|
14409
|
+
async stop() {
|
|
14410
|
+
await runner.stop();
|
|
14411
|
+
await Promise.allSettled([...notices]);
|
|
14412
|
+
}
|
|
14413
|
+
};
|
|
14371
14414
|
}
|
|
14372
14415
|
//#endregion
|
|
14373
14416
|
//#region ../gateway-slack/src/api.ts
|
|
@@ -15518,11 +15561,7 @@ async function runDaemonDoctor(ctx, productVersion, fetcher = fetch) {
|
|
|
15518
15561
|
const checks = [];
|
|
15519
15562
|
const jiraTrackers = config.projects.flatMap((project) => project.tracker.type === "jira" ? [project.tracker] : []);
|
|
15520
15563
|
const slackConfigured = Boolean(config.slack.channels.feed || config.slack.channels.orchestrators);
|
|
15521
|
-
const missing = [
|
|
15522
|
-
"GITHUB_TOKEN",
|
|
15523
|
-
...jiraTrackers.length > 0 ? ["JIRA_EMAIL", "JIRA_API_TOKEN"] : [],
|
|
15524
|
-
...slackConfigured ? ["SLACK_BOT_TOKEN", "SLACK_APP_TOKEN"] : []
|
|
15525
|
-
].filter((name) => !secrets[name]);
|
|
15564
|
+
const missing = requiredSecretKeys(config).filter((name) => !secrets[name]);
|
|
15526
15565
|
checks.push(check("secrets", missing.length === 0, `Add ${missing.join(", ")} to the private secrets.env file.`));
|
|
15527
15566
|
const jiraEmail = secrets["JIRA_EMAIL"];
|
|
15528
15567
|
const jiraToken = secrets["JIRA_API_TOKEN"];
|
package/dist/mcp.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { j as ERRORS, s as OPERATIONS, u as renderMcpError } from "./src-
|
|
2
|
-
import { r as CliError, t as requestOperation } from "./client-
|
|
3
|
-
import { n as loadClientConfig } from "./config-
|
|
1
|
+
import { j as ERRORS, s as OPERATIONS, u as renderMcpError } from "./src-Cy74ZQfR.mjs";
|
|
2
|
+
import { r as CliError, t as requestOperation } from "./client-Dw9ZovyI.mjs";
|
|
3
|
+
import { n as loadClientConfig } from "./config-CeDZQlvy.mjs";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { readFileSync } from "node:fs";
|
|
6
6
|
import { z } from "zod";
|
|
@@ -303,6 +303,49 @@ const configSchema = z.strictObject({
|
|
|
303
303
|
}).prefault({})
|
|
304
304
|
}).prefault({})
|
|
305
305
|
});
|
|
306
|
+
/** Recognized names in the private secrets.env file; values never belong in config.yaml. */
|
|
307
|
+
const SECRET_ENV_KEYS = [
|
|
308
|
+
{
|
|
309
|
+
name: "GITHUB_TOKEN",
|
|
310
|
+
requiredWhen: "always",
|
|
311
|
+
purpose: "Read GitHub repositories and check runs."
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
name: "JIRA_EMAIL",
|
|
315
|
+
requiredWhen: "jira",
|
|
316
|
+
purpose: "Jira account email."
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
name: "JIRA_API_TOKEN",
|
|
320
|
+
requiredWhen: "jira",
|
|
321
|
+
purpose: "Jira API token."
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
name: "SLACK_BOT_TOKEN",
|
|
325
|
+
requiredWhen: "slack",
|
|
326
|
+
purpose: "Slack bot Web API token."
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
name: "SLACK_APP_TOKEN",
|
|
330
|
+
requiredWhen: "slack",
|
|
331
|
+
purpose: "Slack app-level Socket Mode token."
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
name: "SLACK_APP_CONFIG_TOKEN",
|
|
335
|
+
requiredWhen: "optional",
|
|
336
|
+
purpose: "Verify the installed slash command through the Slack app manifest API."
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
name: "SLACK_API_URL",
|
|
340
|
+
requiredWhen: "optional",
|
|
341
|
+
purpose: "Override the Slack API URL for local testing."
|
|
342
|
+
}
|
|
343
|
+
];
|
|
344
|
+
function requiredSecretKeys(config) {
|
|
345
|
+
const jira = config.projects.some((project) => project.tracker.type === "jira");
|
|
346
|
+
const slack = Boolean(config.slack.channels.feed || config.slack.channels.orchestrators);
|
|
347
|
+
return SECRET_ENV_KEYS.filter(({ requiredWhen }) => requiredWhen === "always" || requiredWhen === "jira" && jira || requiredWhen === "slack" && slack).map(({ name }) => name);
|
|
348
|
+
}
|
|
306
349
|
//#endregion
|
|
307
350
|
//#region ../contracts/src/errors.ts
|
|
308
351
|
/**
|
|
@@ -2635,4 +2678,4 @@ var AdapterError = class extends Error {
|
|
|
2635
2678
|
}
|
|
2636
2679
|
};
|
|
2637
2680
|
//#endregion
|
|
2638
|
-
export { taskKeySchema as A, sessionFactsSchema as C, errorCodeOf as D, encodeActorId as E, DEFAULT_HTTP_PORT as F, DEFAULT_SLACK_APP_NAME as I, DEFAULT_SLACK_COMMAND as L, errorContextSchema as M, errorEnvelopeSchema as N, parseActorId as O, successEnvelopeSchema as P, configSchema as R, prRefSchema as S, actorIdSchema as T, EVENT_KINDS as _, buildCatalogSnapshot as a, SESSION_STATUSES as b, renderHttpProblem as c, SPACE_IDS as d, conversationRefSchema as f, userIdSchema as g, messageRefSchema as h, sourceCursorSchema as i, ERRORS as j, parseRef as k, renderJsonError as l, interactionRefSchema as m, batchSchema as n, roleCanUseOperation as o, inboundEventSchema as p, entityRefSchema as r, OPERATIONS as s, AdapterError as t, renderMcpError as u, eventPayloadSchemas as v, ticketFactsSchema as w, prFactsSchema as x, SESSION_HEALTH_STATES as y,
|
|
2681
|
+
export { taskKeySchema as A, SLACK_BOT_SCOPES as B, sessionFactsSchema as C, errorCodeOf as D, encodeActorId as E, DEFAULT_HTTP_PORT as F, DEFAULT_SLACK_APP_NAME as I, DEFAULT_SLACK_COMMAND as L, errorContextSchema as M, errorEnvelopeSchema as N, parseActorId as O, successEnvelopeSchema as P, configSchema as R, prRefSchema as S, actorIdSchema as T, EVENT_KINDS as _, buildCatalogSnapshot as a, SESSION_STATUSES as b, renderHttpProblem as c, SPACE_IDS as d, conversationRefSchema as f, userIdSchema as g, messageRefSchema as h, sourceCursorSchema as i, ERRORS as j, parseRef as k, renderJsonError as l, interactionRefSchema as m, batchSchema as n, roleCanUseOperation as o, inboundEventSchema as p, entityRefSchema as r, OPERATIONS as s, AdapterError as t, renderMcpError as u, eventPayloadSchemas as v, ticketFactsSchema as w, prFactsSchema as x, SESSION_HEALTH_STATES as y, requiredSecretKeys as z };
|