@coreplane/switchboard 1.203.0 → 1.204.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/assets/package-lock.json +3 -3
- package/dist/assets/package.json +1 -1
- package/dist/assets/project.json +1 -1
- package/dist/assets/source.json +3 -3
- package/dist/cli.js +133 -37
- package/package.json +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchboard",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.204.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "switchboard",
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.204.0",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"workspaces": [
|
|
12
12
|
"web",
|
|
@@ -18806,7 +18806,7 @@
|
|
|
18806
18806
|
},
|
|
18807
18807
|
"packages/switchboard": {
|
|
18808
18808
|
"name": "@coreplane/switchboard",
|
|
18809
|
-
"version": "1.
|
|
18809
|
+
"version": "1.204.0",
|
|
18810
18810
|
"license": "Apache-2.0",
|
|
18811
18811
|
"dependencies": {
|
|
18812
18812
|
"@anthropic-ai/sdk": "^0.124.0",
|
package/dist/assets/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchboard",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.204.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Mention it in Slack and an agent reviews the PR, ships the fix, or answers the question — on the model you choose, with its tools running where you decide.",
|
|
6
6
|
"license": "Apache-2.0",
|
package/dist/assets/project.json
CHANGED
|
@@ -212,7 +212,7 @@
|
|
|
212
212
|
"when": "Part of `check:consistency`."
|
|
213
213
|
},
|
|
214
214
|
"load": {
|
|
215
|
-
"does": "Load harness: `-- history|resident|sandbox|e2e|cards|provider`.",
|
|
215
|
+
"does": "Load harness: `-- history|resident|sandbox|e2e|cards|provider|pi`.",
|
|
216
216
|
"when": "Capacity receipts (docs/reference/specs/load-harness.md)."
|
|
217
217
|
}
|
|
218
218
|
}
|
package/dist/assets/source.json
CHANGED
package/dist/cli.js
CHANGED
|
@@ -1485,6 +1485,9 @@ var init_contract = __esm({
|
|
|
1485
1485
|
});
|
|
1486
1486
|
|
|
1487
1487
|
// ../../src/agents/registry.ts
|
|
1488
|
+
function machineNeedsRepo(machine) {
|
|
1489
|
+
return machine === "repo-cold" || machine === "repo-resident";
|
|
1490
|
+
}
|
|
1488
1491
|
function getAgent(name) {
|
|
1489
1492
|
const a = AGENTS[name];
|
|
1490
1493
|
if (!a) {
|
|
@@ -1654,12 +1657,13 @@ You cannot run commands, clone repositories, edit code, or review pull requests,
|
|
|
1654
1657
|
description: "Default assistant on the configured model: answers directly, reads the org's repos and manages their issues over GitHub, reads URLs. No workspace or shell.",
|
|
1655
1658
|
system: GENERAL_SYSTEM,
|
|
1656
1659
|
toolset: "assistant",
|
|
1660
|
+
// The GitHub tools are REST in the bot process, so a general ask never
|
|
1661
|
+
// provisions a workspace or sandbox (docs/reference/specs/agent-general.md item 4).
|
|
1662
|
+
machine: "none",
|
|
1657
1663
|
maxTurns: 8,
|
|
1658
1664
|
// a repo read is 2-3 calls (repos → tree → file); an issue action 1-2; still fast
|
|
1659
1665
|
maxTokens: 16e3,
|
|
1660
1666
|
maxMinutes: 5
|
|
1661
|
-
// No `resources`: the GitHub tools are REST in the bot process, so a
|
|
1662
|
-
// general ask still never provisions a workspace or sandbox (item 4).
|
|
1663
1667
|
},
|
|
1664
1668
|
coding: {
|
|
1665
1669
|
name: "coding",
|
|
@@ -1677,7 +1681,7 @@ You cannot run commands, clone repositories, edit code, or review pull requests,
|
|
|
1677
1681
|
cacheTtl: "1h",
|
|
1678
1682
|
// No built-in effort: the deployment decides (`defaults.efforts.coding`,
|
|
1679
1683
|
// `config set channel efforts.coding=…`, or `effort:` per request).
|
|
1680
|
-
|
|
1684
|
+
machine: "repo-resident"
|
|
1681
1685
|
},
|
|
1682
1686
|
review: {
|
|
1683
1687
|
name: "review",
|
|
@@ -1685,7 +1689,7 @@ You cannot run commands, clone repositories, edit code, or review pull requests,
|
|
|
1685
1689
|
system: REVIEW_SYSTEM,
|
|
1686
1690
|
residentSystem: REVIEW_SYSTEM_RESIDENT,
|
|
1687
1691
|
toolset: "readonly",
|
|
1688
|
-
|
|
1692
|
+
machine: "repo-resident",
|
|
1689
1693
|
maxTurns: 30,
|
|
1690
1694
|
// backstop only; wall clock is the real budget (12 bound at ~4 min in practice)
|
|
1691
1695
|
maxTokens: 64e3,
|
|
@@ -1701,22 +1705,22 @@ You cannot run commands, clone repositories, edit code, or review pull requests,
|
|
|
1701
1705
|
// pipeline orchestrator (src/core/shipPipeline.ts), whose child rounds run
|
|
1702
1706
|
// on the coding/review defs above — runAgent is never called with THIS def.
|
|
1703
1707
|
system: "You are Switchboard's ship pipeline. This prompt is never sent to a model \u2014 the pipeline orchestrates coding and review child runs on their own definitions.",
|
|
1704
|
-
// Full toolset
|
|
1705
|
-
// coding; placeholder budgets — the pipeline
|
|
1706
|
-
// caps and by each child's own budgets
|
|
1707
|
-
// never by these numbers.
|
|
1708
|
+
// Full toolset and the coding machine class, so repo and PR resolution
|
|
1709
|
+
// gate a ship thread like a coding one; placeholder budgets — the pipeline
|
|
1710
|
+
// is bounded by the `ship` config caps and by each child's own budgets
|
|
1711
|
+
// clipped to the remaining wall clock, never by these numbers.
|
|
1708
1712
|
toolset: "full",
|
|
1713
|
+
machine: "repo-resident",
|
|
1709
1714
|
maxTurns: 1,
|
|
1710
1715
|
maxTokens: 16e3,
|
|
1711
|
-
maxMinutes: 5
|
|
1712
|
-
resources: { repo: "required" }
|
|
1716
|
+
maxMinutes: 5
|
|
1713
1717
|
},
|
|
1714
1718
|
research: {
|
|
1715
1719
|
name: "research",
|
|
1716
1720
|
description: "Answers questions with web search, URL reading, and read access to the org's repos and issues over GitHub. No workspace.",
|
|
1717
1721
|
system: RESEARCH_SYSTEM,
|
|
1718
1722
|
toolset: "web",
|
|
1719
|
-
|
|
1723
|
+
machine: "none",
|
|
1720
1724
|
// web I/O only; no workspace is provisioned
|
|
1721
1725
|
maxTurns: 12,
|
|
1722
1726
|
maxTokens: 24e3,
|
|
@@ -8901,9 +8905,19 @@ var init_residentState = __esm({
|
|
|
8901
8905
|
import { resolve as resolve7 } from "node:path";
|
|
8902
8906
|
import { mkdirSync as mkdirSync7 } from "node:fs";
|
|
8903
8907
|
async function makeExecutor(opts, ctx, span) {
|
|
8904
|
-
|
|
8908
|
+
const machine = ctx.agent.machine;
|
|
8909
|
+
if (machine === "none") {
|
|
8905
8910
|
return { executor: new NullExecutor(ctx.agent.name), backend: "local" };
|
|
8906
8911
|
}
|
|
8912
|
+
if (machine === "blank") {
|
|
8913
|
+
return {
|
|
8914
|
+
executor: await makePerThreadExecutor(opts, { threadKey: ctx.threadKey, resolveEnvs: async () => ({}) }),
|
|
8915
|
+
backend: perThreadBackend(opts)
|
|
8916
|
+
};
|
|
8917
|
+
}
|
|
8918
|
+
if (machine === "repo-cold") {
|
|
8919
|
+
return { executor: await makePerThreadExecutor(opts, perThreadCheckout(ctx)), backend: perThreadBackend(opts) };
|
|
8920
|
+
}
|
|
8907
8921
|
let note;
|
|
8908
8922
|
let failedAttach;
|
|
8909
8923
|
if (ctx.repo && opts.execution?.resident) {
|
|
@@ -8946,7 +8960,7 @@ async function makeExecutor(opts, ctx, span) {
|
|
|
8946
8960
|
}
|
|
8947
8961
|
}
|
|
8948
8962
|
return {
|
|
8949
|
-
executor: await makePerThreadExecutor(opts, ctx),
|
|
8963
|
+
executor: await makePerThreadExecutor(opts, perThreadCheckout(ctx)),
|
|
8950
8964
|
note,
|
|
8951
8965
|
backend: perThreadBackend(opts),
|
|
8952
8966
|
...failedAttach ? { trace: failedAttach.steps } : {}
|
|
@@ -9041,8 +9055,11 @@ function localWorkspaceDir(baseDir, threadKey) {
|
|
|
9041
9055
|
const safe = threadKey.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
9042
9056
|
return resolve7(baseDir, safe);
|
|
9043
9057
|
}
|
|
9044
|
-
|
|
9045
|
-
|
|
9058
|
+
function perThreadCheckout(ctx) {
|
|
9059
|
+
return { threadKey: ctx.threadKey, repo: ctx.repo, ref: ctx.ref, resolveEnvs: () => githubEnvs(ctx.agent) };
|
|
9060
|
+
}
|
|
9061
|
+
async function makePerThreadExecutor(opts, input) {
|
|
9062
|
+
const { threadKey } = input;
|
|
9046
9063
|
const type = opts.execution?.type ?? "local";
|
|
9047
9064
|
if (type === "local") {
|
|
9048
9065
|
const dir = localWorkspaceDir(opts.workspaceDir, threadKey);
|
|
@@ -9058,9 +9075,9 @@ async function makePerThreadExecutor(opts, ctx) {
|
|
|
9058
9075
|
threadKey,
|
|
9059
9076
|
timeoutMs: (opts.execution?.timeoutMinutes ?? 30) * 6e4,
|
|
9060
9077
|
statePath: resolve7(opts.dataDir, "sandboxes.json"),
|
|
9061
|
-
resolveEnvs:
|
|
9062
|
-
repo:
|
|
9063
|
-
ref:
|
|
9078
|
+
resolveEnvs: input.resolveEnvs,
|
|
9079
|
+
repo: input.repo,
|
|
9080
|
+
ref: input.ref
|
|
9064
9081
|
});
|
|
9065
9082
|
}
|
|
9066
9083
|
if (type === "cloudflare") {
|
|
@@ -9074,16 +9091,18 @@ async function makePerThreadExecutor(opts, ctx) {
|
|
|
9074
9091
|
url: opts.execution.url,
|
|
9075
9092
|
token: token.reveal(),
|
|
9076
9093
|
threadKey,
|
|
9077
|
-
resolveEnvs:
|
|
9078
|
-
repo:
|
|
9079
|
-
ref:
|
|
9094
|
+
resolveEnvs: input.resolveEnvs,
|
|
9095
|
+
repo: input.repo,
|
|
9096
|
+
ref: input.ref
|
|
9080
9097
|
});
|
|
9081
9098
|
}
|
|
9082
9099
|
throw new Error(`Unknown execution.type "${type}" (valid: local, e2b, cloudflare)`);
|
|
9083
9100
|
}
|
|
9101
|
+
function githubTokenScopeFor(agent) {
|
|
9102
|
+
return agent.toolset === "readonly" ? "read" : "write";
|
|
9103
|
+
}
|
|
9084
9104
|
async function githubEnvs(agent) {
|
|
9085
|
-
const
|
|
9086
|
-
const token = await resolveGithubToken(scope);
|
|
9105
|
+
const token = await resolveGithubToken(githubTokenScopeFor(agent));
|
|
9087
9106
|
return token ? { GH_TOKEN: token } : {};
|
|
9088
9107
|
}
|
|
9089
9108
|
function perThreadBackend(opts) {
|
|
@@ -9113,7 +9132,7 @@ var init_factory = __esm({
|
|
|
9113
9132
|
agentName;
|
|
9114
9133
|
fail() {
|
|
9115
9134
|
throw new Error(
|
|
9116
|
-
`Agent "${this.agentName}"
|
|
9135
|
+
`Agent "${this.agentName}" runs on machine class "none", so it has no execution workspace. Declare a machine class that provisions one (\`repo-resident\`, \`repo-cold\` or \`blank\`) if its tools need one.`
|
|
9117
9136
|
);
|
|
9118
9137
|
}
|
|
9119
9138
|
async exec() {
|
|
@@ -20442,10 +20461,10 @@ function safePredicate(isResident, slug) {
|
|
|
20442
20461
|
return false;
|
|
20443
20462
|
}
|
|
20444
20463
|
}
|
|
20445
|
-
async function safeProbe(
|
|
20446
|
-
if (!
|
|
20464
|
+
async function safeProbe(probe, slug) {
|
|
20465
|
+
if (!probe) return true;
|
|
20447
20466
|
try {
|
|
20448
|
-
const answer = await
|
|
20467
|
+
const answer = await probe(slug);
|
|
20449
20468
|
return answer === true || answer === "unreachable" ? answer : false;
|
|
20450
20469
|
} catch {
|
|
20451
20470
|
return "unreachable";
|
|
@@ -20454,7 +20473,7 @@ async function safeProbe(isResident, slug) {
|
|
|
20454
20473
|
function repoFromThread(history, isResident) {
|
|
20455
20474
|
return threadSignals(history, isResident).repo;
|
|
20456
20475
|
}
|
|
20457
|
-
async function resolveRepoContext(msg, history = [],
|
|
20476
|
+
async function resolveRepoContext(msg, history = [], probe, residentSlugs) {
|
|
20458
20477
|
const s = extractSignals(msg.text);
|
|
20459
20478
|
const thread = threadSignals(history);
|
|
20460
20479
|
let rejected;
|
|
@@ -20463,7 +20482,7 @@ async function resolveRepoContext(msg, history = [], isResident, residentSlugs)
|
|
|
20463
20482
|
const vet = async (cand) => {
|
|
20464
20483
|
let p = vetted.get(cand);
|
|
20465
20484
|
if (!p) {
|
|
20466
|
-
p = safeProbe(
|
|
20485
|
+
p = safeProbe(probe, cand);
|
|
20467
20486
|
vetted.set(cand, p);
|
|
20468
20487
|
}
|
|
20469
20488
|
const answer = await p;
|
|
@@ -20479,7 +20498,7 @@ async function resolveRepoContext(msg, history = [], isResident, residentSlugs)
|
|
|
20479
20498
|
return slugsOnce;
|
|
20480
20499
|
};
|
|
20481
20500
|
const resolveAddressed = async (a) => {
|
|
20482
|
-
if (a.slug !== void 0) return
|
|
20501
|
+
if (a.slug !== void 0) return probe && await vet(a.slug) ? a.slug : void 0;
|
|
20483
20502
|
const matches = (await listSlugs() ?? []).filter((slug) => slug.split("/")[1] === a.name);
|
|
20484
20503
|
return matches.length === 1 ? matches[0] : void 0;
|
|
20485
20504
|
};
|
|
@@ -25111,6 +25130,44 @@ var init_directives = __esm({
|
|
|
25111
25130
|
}
|
|
25112
25131
|
});
|
|
25113
25132
|
|
|
25133
|
+
// ../../src/execution/githubRepoProbe.ts
|
|
25134
|
+
function githubRepoProbe(opts) {
|
|
25135
|
+
const fetchImpl = opts.fetch ?? fetch;
|
|
25136
|
+
const token = opts.token ?? ((scope) => resolveGithubToken(scope));
|
|
25137
|
+
return async (slug) => {
|
|
25138
|
+
if (!SLUG.test(slug)) return false;
|
|
25139
|
+
let bearer;
|
|
25140
|
+
try {
|
|
25141
|
+
bearer = await token(opts.scope);
|
|
25142
|
+
} catch {
|
|
25143
|
+
return "unreachable";
|
|
25144
|
+
}
|
|
25145
|
+
const headers = { accept: "application/vnd.github+json", "user-agent": "switchboard" };
|
|
25146
|
+
if (bearer) headers.authorization = `Bearer ${bearer}`;
|
|
25147
|
+
let res;
|
|
25148
|
+
try {
|
|
25149
|
+
res = await fetchImpl(`https://api.github.com/repos/${slug}`, {
|
|
25150
|
+
headers,
|
|
25151
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS6)
|
|
25152
|
+
});
|
|
25153
|
+
} catch {
|
|
25154
|
+
return "unreachable";
|
|
25155
|
+
}
|
|
25156
|
+
if (res.ok) return true;
|
|
25157
|
+
if (res.status === 404) return false;
|
|
25158
|
+
return "unreachable";
|
|
25159
|
+
};
|
|
25160
|
+
}
|
|
25161
|
+
var REQUEST_TIMEOUT_MS6, SLUG;
|
|
25162
|
+
var init_githubRepoProbe = __esm({
|
|
25163
|
+
"../../src/execution/githubRepoProbe.ts"() {
|
|
25164
|
+
"use strict";
|
|
25165
|
+
init_githubApp();
|
|
25166
|
+
REQUEST_TIMEOUT_MS6 = 1e4;
|
|
25167
|
+
SLUG = /^[A-Za-z0-9][A-Za-z0-9-]*\/[A-Za-z0-9._-]+$/;
|
|
25168
|
+
}
|
|
25169
|
+
});
|
|
25170
|
+
|
|
25114
25171
|
// ../../src/core/dispatch/resolve.ts
|
|
25115
25172
|
async function readRequest(ctx) {
|
|
25116
25173
|
const { msg, io, root } = ctx;
|
|
@@ -25136,28 +25193,29 @@ function resolveTarget(deps, ctx) {
|
|
|
25136
25193
|
const { msg, history, agent, resolved, resume, root } = ctx;
|
|
25137
25194
|
const { provider: providerName, model } = parseModelRef(resolved.modelRef);
|
|
25138
25195
|
const provider = deps.providers.get(providerName);
|
|
25139
|
-
const needsRepo = agent.
|
|
25196
|
+
const needsRepo = machineNeedsRepo(agent.machine);
|
|
25140
25197
|
const repoCtxP = root.span(
|
|
25141
25198
|
"dispatch.repo_context",
|
|
25142
25199
|
() => resume ? Promise.resolve(resume.repoCtx) : needsRepo ? Promise.resolve(
|
|
25143
|
-
deps.resolveRepoContext ? deps.resolveRepoContext(msg, history) : resolveRepoContext(
|
|
25144
|
-
msg,
|
|
25145
|
-
history,
|
|
25146
|
-
residentOnboardedProbe(deps.config.config.execution?.resident),
|
|
25147
|
-
residentSlugsLister(deps.config.config.execution?.resident)
|
|
25148
|
-
)
|
|
25200
|
+
deps.resolveRepoContext ? deps.resolveRepoContext(msg, history) : resolveRepoContext(msg, history, ...repoVetFor(agent, deps.config.config.execution?.resident))
|
|
25149
25201
|
).then((ctx2) => ctx2 ?? {}) : Promise.resolve({})
|
|
25150
25202
|
);
|
|
25151
25203
|
repoCtxP.catch(() => {
|
|
25152
25204
|
});
|
|
25153
25205
|
return { provider, model, needsRepo, repoCtxP };
|
|
25154
25206
|
}
|
|
25207
|
+
function repoVetFor(agent, resident) {
|
|
25208
|
+
if (agent.machine === "repo-cold") return [githubRepoProbe({ scope: githubTokenScopeFor(agent) }), void 0];
|
|
25209
|
+
return [residentOnboardedProbe(resident), residentSlugsLister(resident)];
|
|
25210
|
+
}
|
|
25155
25211
|
var init_resolve = __esm({
|
|
25156
25212
|
"../../src/core/dispatch/resolve.ts"() {
|
|
25157
25213
|
"use strict";
|
|
25214
|
+
init_registry();
|
|
25158
25215
|
init_directives();
|
|
25159
25216
|
init_types3();
|
|
25160
25217
|
init_factory();
|
|
25218
|
+
init_githubRepoProbe();
|
|
25161
25219
|
init_repoContext();
|
|
25162
25220
|
}
|
|
25163
25221
|
});
|
|
@@ -25178,6 +25236,41 @@ async function authorizeAgent(deps, ctx) {
|
|
|
25178
25236
|
}
|
|
25179
25237
|
async function authorizeRepo(deps, ctx) {
|
|
25180
25238
|
const { msg, io, refuse: refuse3, card, shell, closeLines, clock: clock2, agent, needsRepo, repoCtx } = ctx;
|
|
25239
|
+
if (agent.machine === "repo-cold" && needsRepo && !repoCtx.repo) {
|
|
25240
|
+
if (repoCtx.rejectedRepo) {
|
|
25241
|
+
const slug = repoCtx.rejectedRepo;
|
|
25242
|
+
console.log(`[dispatch] ${msg.threadKey} not started: repo not visible (${slug}: GitHub answered 404)`);
|
|
25243
|
+
await refuse3("repo_not_visible", async () => {
|
|
25244
|
+
await card.done(
|
|
25245
|
+
shell.close({ kind: "not_started", icon: "\u{1F4E6}", reason: "repo not visible", ...closeLines(clock2(), false) })
|
|
25246
|
+
);
|
|
25247
|
+
await io.reply(
|
|
25248
|
+
`\u{1F4E6} \`${slug}\` is not a repository this installation can see \u2014 GitHub answered 404 \u2014 so I did not start ${aRun(agent.name)} for it. The repository is outside the Switchboard GitHub App installation (\`github_repos\` lists the reachable ones), or the name is wrong.`
|
|
25249
|
+
);
|
|
25250
|
+
});
|
|
25251
|
+
return { kind: "refused", reason: "repo_not_visible" };
|
|
25252
|
+
}
|
|
25253
|
+
if (repoCtx.unverifiedRepo) {
|
|
25254
|
+
const slug = repoCtx.unverifiedRepo;
|
|
25255
|
+
console.log(
|
|
25256
|
+
`[dispatch] ${msg.threadKey} not started: repo could not be verified (${slug}: GitHub did not answer)`
|
|
25257
|
+
);
|
|
25258
|
+
await refuse3("repo_unverified", async () => {
|
|
25259
|
+
await card.done(
|
|
25260
|
+
shell.close({
|
|
25261
|
+
kind: "not_started",
|
|
25262
|
+
icon: "\u{1F4E6}",
|
|
25263
|
+
reason: "repo could not be verified",
|
|
25264
|
+
...closeLines(clock2(), false)
|
|
25265
|
+
})
|
|
25266
|
+
);
|
|
25267
|
+
await io.reply(
|
|
25268
|
+
`\u26A0\uFE0F I couldn't verify \`${slug}\` against GitHub \u2014 it didn't answer \u2014 so I did not start ${aRun(agent.name)} rather than guess which repository you meant. Try again in a minute.`
|
|
25269
|
+
);
|
|
25270
|
+
});
|
|
25271
|
+
return { kind: "refused", reason: "repo_unverified" };
|
|
25272
|
+
}
|
|
25273
|
+
}
|
|
25181
25274
|
if (deps.capabilities.residents && needsRepo && !repoCtx.repo && repoCtx.rejectedRepo) {
|
|
25182
25275
|
const slug = repoCtx.rejectedRepo;
|
|
25183
25276
|
console.log(`[dispatch] ${msg.threadKey} not started: repo not onboarded (${slug})`);
|
|
@@ -25226,6 +25319,9 @@ async function authorizeRepo(deps, ctx) {
|
|
|
25226
25319
|
}
|
|
25227
25320
|
return { kind: "allowed" };
|
|
25228
25321
|
}
|
|
25322
|
+
function aRun(agentName) {
|
|
25323
|
+
return `${/^[aeiou]/i.test(agentName) ? "an" : "a"} *${agentName}* run`;
|
|
25324
|
+
}
|
|
25229
25325
|
async function authorizePrHead(ctx) {
|
|
25230
25326
|
const { msg, io, refuse: refuse3, card, shell, closeLines, clock: clock2, agent, directives, repoCtx } = ctx;
|
|
25231
25327
|
const preflight = checkPrHeadPreflight({ agent, requestText: directives.text, repoCtx });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreplane/switchboard",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.204.0",
|
|
4
4
|
"description": "Mention it in Slack and an agent reviews the PR, ships the fix, or answers the question — on the model you choose, with its tools running where you decide.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://openswitchboard.dev",
|