@coreplane/switchboard 1.238.0 → 1.240.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/config/config.example.yaml +6 -0
- package/dist/assets/deploy/cloudflare-memory/worker.ts +115 -1
- package/dist/assets/deploy/cloudflare-memory/wrangler.template.jsonc +7 -1
- package/dist/assets/deploy/cloudflare-resident/worker.ts +223 -65
- package/dist/assets/deploy/cloudflare-sandbox/Dockerfile +8 -1
- package/dist/assets/deploy/cloudflare-sandbox/worker.ts +337 -44
- package/dist/assets/deploy/cloudflare-sandbox/wrangler.template.jsonc +19 -0
- package/dist/assets/deploy/secrets.manifest.json +4 -4
- package/dist/assets/package-lock.json +207 -3
- package/dist/assets/package.json +2 -1
- package/dist/assets/source.json +3 -3
- package/dist/assets/src/agents/registry.ts +82 -0
- package/dist/assets/src/core/authz/actor.ts +33 -2
- package/dist/assets/src/core/authz/policy.ts +6 -0
- package/dist/assets/src/core/coordinator/contract.ts +12 -1
- package/dist/assets/src/core/coordinator/driver.ts +13 -0
- package/dist/assets/src/core/costs.ts +1114 -0
- package/dist/assets/src/core/costsSnapshotStore.ts +209 -0
- package/dist/assets/src/core/delivery.ts +4 -11
- package/dist/assets/src/core/deliverySnapshotStore.ts +12 -28
- package/dist/assets/src/core/ingressTokens.ts +27 -13
- package/dist/assets/src/core/runLedger/types.ts +3 -0
- package/dist/assets/src/core/runRecord.ts +10 -3
- package/dist/assets/src/core/schedules.ts +2 -1
- package/dist/assets/src/core/ship/coordinator.ts +70 -0
- package/dist/assets/src/core/snapshotAge.ts +30 -0
- package/dist/assets/src/core/stateWorkerRef.ts +41 -0
- package/dist/assets/src/execution/residentAutoRebuild.ts +73 -0
- package/dist/assets/src/execution/residentRefresh.ts +25 -3
- package/dist/assets/src/execution/restoreWaiters.ts +61 -0
- package/dist/assets/src/execution/seedPlan.ts +267 -0
- package/dist/assets/src/mcp/registry.ts +7 -0
- package/dist/assets/web/dist/.vite/manifest.json +507 -427
- package/dist/assets/web/dist/assets/AppShell-CM_fh-WW.js +1 -0
- package/dist/assets/web/dist/assets/CostsPage-BD3w5j_S.js +2 -0
- package/dist/assets/web/dist/assets/DeliveryPage-BtvzKA1m.js +1 -0
- package/dist/assets/web/dist/assets/HomePage-BU6aRCSe.js +2 -0
- package/dist/assets/web/dist/assets/NotFoundPage-DwOX1HaZ.js +1 -0
- package/dist/assets/web/dist/assets/{ResidentDetailPage-CrfCd8fx.js → ResidentDetailPage-CUAOh5d9.js} +1 -1
- package/dist/assets/web/dist/assets/ResidentsIndexPage-B3KUlYy2.js +1 -0
- package/dist/assets/web/dist/assets/RunFoldRow-Dulcbg25.js +1 -0
- package/dist/assets/web/dist/assets/RunRoutePage-DGoGrQZq.js +6 -0
- package/dist/assets/web/dist/assets/RunsIndexPage-37W7OZbC.js +1 -0
- package/dist/assets/web/dist/assets/{RunsTabs-XpCqeWu4.js → RunsTabs-BnkvCBrM.js} +1 -1
- package/dist/assets/web/dist/assets/ScheduledPage-C1y9jgAk.js +1 -0
- package/dist/assets/web/dist/assets/SettingsPage-ggfB-Rqr.js +1 -0
- package/dist/assets/web/dist/assets/SlackMark-VDNs7Vjh.js +1 -0
- package/dist/assets/web/dist/assets/Slideover-CX-LEklF.js +1 -0
- package/dist/assets/web/dist/assets/{StatusDot-DkXALvKf.js → StatusDot-CiByEtoR.js} +1 -1
- package/dist/assets/web/dist/assets/{Tooltip-DtLIyi5P.js → Tooltip-DyRxk8A8.js} +1 -1
- package/dist/assets/web/dist/assets/UnitRoutePage-CnWyOizV.js +1 -0
- package/dist/assets/web/dist/assets/{angular-html-DYtV9uIN.js → angular-html-DAQ_1T1v.js} +1 -1
- package/dist/assets/web/dist/assets/{angular-ts-DF2P25Zp.js → angular-ts-D4kxRVp1.js} +1 -1
- package/dist/assets/web/dist/assets/{apl-Ff96wxko.js → apl-Dy07l64y.js} +1 -1
- package/dist/assets/web/dist/assets/{astro-LbBnZna-.js → astro-DZIbTlc7.js} +1 -1
- package/dist/assets/web/dist/assets/{blade-DltuxeBW.js → blade-CmSXWX3l.js} +1 -1
- package/dist/assets/web/dist/assets/{c-DBg7yuPx.js → c-ggzVdJLK.js} +1 -1
- package/dist/assets/web/dist/assets/{chapel-C83hUAds.js → chapel-Bo1wktsG.js} +1 -1
- package/dist/assets/web/dist/assets/{cobol-DB0yV_2D.js → cobol-DJUmtKM2.js} +1 -1
- package/dist/assets/web/dist/assets/{coffee-Bpih6Kzl.js → coffee-BZWOVz4C.js} +1 -1
- package/dist/assets/web/dist/assets/{cpp-CU00ZeRn.js → cpp-Dtk39yMw.js} +1 -1
- package/dist/assets/web/dist/assets/{crystal-f8ImJkux.js → crystal-CGf_-Zoj.js} +1 -1
- package/dist/assets/web/dist/assets/{css-4VrC4ISo.js → css-CX2fcL4u.js} +1 -1
- package/dist/assets/web/dist/assets/delivery-CTdOqpVK.js +1 -0
- package/dist/assets/web/dist/assets/{dist-DtA7JiH5.js → dist-D8TaC961.js} +2 -2
- package/dist/assets/web/dist/assets/durationTone-DXG-3R7_.js +1 -0
- package/dist/assets/web/dist/assets/{edge-BwFDzfS_.js → edge-BYS8FtgQ.js} +1 -1
- package/dist/assets/web/dist/assets/{elixir-wwIYIpJm.js → elixir-fhUpi3nO.js} +1 -1
- package/dist/assets/web/dist/assets/{elm-DyDuM3v3.js → elm-DAQNiwsN.js} +1 -1
- package/dist/assets/web/dist/assets/{erb-DFJBEVrh.js → erb-CWzEys6U.js} +1 -1
- package/dist/assets/web/dist/assets/eventSource-tRprhqm7.js +1 -0
- package/dist/assets/web/dist/assets/favicon-D1hkyC5j.js +1 -0
- package/dist/assets/web/dist/assets/{git-rebase-CuDv-44X.js → git-rebase-9rY3p-Rw.js} +1 -1
- package/dist/assets/web/dist/assets/{glimmer-js-ZFnrm4J3.js → glimmer-js-tY7hy0nE.js} +1 -1
- package/dist/assets/web/dist/assets/{glimmer-ts-XY4Yqshp.js → glimmer-ts-CTrLv5JF.js} +1 -1
- package/dist/assets/web/dist/assets/{glsl-xnR8efx0.js → glsl-BRJbiDfq.js} +1 -1
- package/dist/assets/web/dist/assets/{graphql-D-gO5tnP.js → graphql-B-MtVLh2.js} +1 -1
- package/dist/assets/web/dist/assets/{hack-CSxbW4ax.js → hack-BtIkOypQ.js} +1 -1
- package/dist/assets/web/dist/assets/{haml-D4ar42QT.js → haml-CoOH6gfa.js} +1 -1
- package/dist/assets/web/dist/assets/{handlebars-CMLbDE7o.js → handlebars-DgrRu-GP.js} +1 -1
- package/dist/assets/web/dist/assets/{html-CVekU4Fs.js → html-DZaaI7ca.js} +1 -1
- package/dist/assets/web/dist/assets/{html-derivative-St3HHw_N.js → html-derivative-DgHvT-qZ.js} +1 -1
- package/dist/assets/web/dist/assets/{http-Mon0DWHS.js → http-CvAd51yz.js} +1 -1
- package/dist/assets/web/dist/assets/{hurl-Cbl5IvBs.js → hurl-CXGqAfzx.js} +1 -1
- package/dist/assets/web/dist/assets/{localIso-CNA-bhS-.js → indexFormat-B-pd4r7Y.js} +1 -1
- package/dist/assets/web/dist/assets/{indexRow-FLJu5mR9.js → indexRow-Cse3JGb0.js} +1 -1
- package/dist/assets/web/dist/assets/{java-Bprck1l-.js → java-CIQStIXF.js} +1 -1
- package/dist/assets/web/dist/assets/{javascript-C73G1-UR.js → javascript-WbH8s7E3.js} +1 -1
- package/dist/assets/web/dist/assets/{jinja-C4DuRxYJ.js → jinja-DzyWEVKC.js} +1 -1
- package/dist/assets/web/dist/assets/{jison-B2U03GEC.js → jison-CrT-zCa-.js} +1 -1
- package/dist/assets/web/dist/assets/{json-CvTZUDzx.js → json-lHjpjXMQ.js} +1 -1
- package/dist/assets/web/dist/assets/{jsx-DMWKCzwo.js → jsx-WTwYCHW6.js} +1 -1
- package/dist/assets/web/dist/assets/{julia-Czn7bV_3.js → julia-Bqpk9H7E.js} +1 -1
- package/dist/assets/web/dist/assets/{just-BBxpNfvC.js → just-LdXk1r3m.js} +1 -1
- package/dist/assets/web/dist/assets/{latex-Bw9yg5mr.js → latex-h_y2A5KD.js} +1 -1
- package/dist/assets/web/dist/assets/{liquid-BRCjaydE.js → liquid-CY7bF2_p.js} +1 -1
- package/dist/assets/web/dist/assets/localIso-L06jV29p.js +1 -0
- package/dist/assets/web/dist/assets/{lua-DUu2KIC0.js → lua-oQ7XVZOY.js} +1 -1
- package/dist/assets/web/dist/assets/main-CGO6fQ8k.js +28 -0
- package/dist/assets/web/dist/assets/main-O8UXRuEv.css +1 -0
- package/dist/assets/web/dist/assets/{marko-CZJZIlSQ.js → marko-zv_qZ4QV.js} +1 -1
- package/dist/assets/web/dist/assets/{mdc-BmClq6fd.js → mdc-Dl4kL_YK.js} +1 -1
- package/dist/assets/web/dist/assets/{nginx-Bmt3xSEm.js → nginx-CAHCZj4F.js} +1 -1
- package/dist/assets/web/dist/assets/{nim-Da-i0utK.js → nim-BOtmwCJH.js} +1 -1
- package/dist/assets/web/dist/assets/{org-BvAre2qP.js → org-DspQk3HQ.js} +1 -1
- package/dist/assets/web/dist/assets/{perl-v9WwFFtB.js → perl-CAXmvVl0.js} +1 -1
- package/dist/assets/web/dist/assets/{php-DTU4Zyze.js → php-CMUx4VyM.js} +1 -1
- package/dist/assets/web/dist/assets/{pug-DhTwEqTO.js → pug-B55xVJTv.js} +1 -1
- package/dist/assets/web/dist/assets/{qml-BUD9AC_c.js → qml-DsNKCCRk.js} +1 -1
- package/dist/assets/web/dist/assets/{r-CAnu56n7.js → r-DbhP0VvO.js} +1 -1
- package/dist/assets/web/dist/assets/{razor-Dn0P4gAq.js → razor-BCpE6P-p.js} +1 -1
- package/dist/assets/web/dist/assets/{regexp-CZyBRaVW.js → regexp-BllsjiN4.js} +1 -1
- package/dist/assets/web/dist/assets/{rst-Ckyd5UsY.js → rst-CO5Rpq9V.js} +1 -1
- package/dist/assets/web/dist/assets/{ruby-BBQ62fsx.js → ruby-C2A4OgQq.js} +1 -1
- package/dist/assets/web/dist/assets/{sas-CW35hMxG.js → sas-Butzoyql.js} +1 -1
- package/dist/assets/web/dist/assets/{scss-CpV8pF4J.js → scss-PEUwJBpf.js} +1 -1
- package/dist/assets/web/dist/assets/settingsApi-priOPiwu.js +1 -0
- package/dist/assets/web/dist/assets/{shellscript-CRJvsmE1.js → shellscript-3Yhq0khE.js} +1 -1
- package/dist/assets/web/dist/assets/{shellsession-CyriUZxf.js → shellsession-04Hkb7m3.js} +1 -1
- package/dist/assets/web/dist/assets/{soy-D5QzYUeg.js → soy-BnId73cP.js} +1 -1
- package/dist/assets/web/dist/assets/{sql-CUBf_Mse.js → sql-BKwdc0ch.js} +1 -1
- package/dist/assets/web/dist/assets/sseReplay-DutHNghE.js +9 -0
- package/dist/assets/web/dist/assets/{stata-B-4n4ITz.js → stata-BPPtNkay.js} +1 -1
- package/dist/assets/web/dist/assets/{surrealql-RuWZBLtr.js → surrealql-CDPChcYP.js} +1 -1
- package/dist/assets/web/dist/assets/{svelte-CO5YzCsK.js → svelte-B15DIQ-z.js} +1 -1
- package/dist/assets/web/dist/assets/{templ-DbkWVaBF.js → templ-D-rp_AiB.js} +1 -1
- package/dist/assets/web/dist/assets/{tex-IuxoEcId.js → tex-BnVDCD7p.js} +1 -1
- package/dist/assets/web/dist/assets/{ts-tags-g6dGQPjd.js → ts-tags-cpujdyAR.js} +1 -1
- package/dist/assets/web/dist/assets/{tsx-WnXwiyH2.js → tsx-D1vO4L72.js} +1 -1
- package/dist/assets/web/dist/assets/{twig-Lx1G7PnY.js → twig-oQGnQGRc.js} +1 -1
- package/dist/assets/web/dist/assets/{typescript-BQd7biLF.js → typescript-CKSFpXiH.js} +1 -1
- package/dist/assets/web/dist/assets/{typst-D2lXPHK7.js → typst-DKHFo8BF.js} +1 -1
- package/dist/assets/web/dist/assets/{vue-4wVQD9y9.js → vue-BstokpiS.js} +1 -1
- package/dist/assets/web/dist/assets/{vue-html-DZPaRte4.js → vue-html-DpCp0_Sz.js} +1 -1
- package/dist/assets/web/dist/assets/{vue-vine-DbmZCmu-.js → vue-vine-y5d5wUb1.js} +1 -1
- package/dist/assets/web/dist/assets/{xml-DV16szyo.js → xml-Br2hx5Ax.js} +1 -1
- package/dist/assets/web/dist/assets/{xsl-eo5-1sk0.js → xsl-Bc8Cobap.js} +1 -1
- package/dist/assets/web/dist/assets/{yaml-BXdX8HZf.js → yaml-LOITy_I1.js} +1 -1
- package/dist/cli.js +2586 -1603
- package/package.json +1 -1
- package/dist/assets/web/dist/assets/AppShell-MYHNxJks.js +0 -1
- package/dist/assets/web/dist/assets/CostsPage-DKk9OjB0.js +0 -2
- package/dist/assets/web/dist/assets/DeliveryPage-Kz6js49i.js +0 -1
- package/dist/assets/web/dist/assets/NotFoundPage-BXLrQQzy.js +0 -1
- package/dist/assets/web/dist/assets/ResidentsIndexPage-BdW0k2h3.js +0 -1
- package/dist/assets/web/dist/assets/RunFoldRow-CbTd9SiS.js +0 -9
- package/dist/assets/web/dist/assets/RunRoutePage-br0H-8Pz.js +0 -6
- package/dist/assets/web/dist/assets/RunsIndexPage-Bnzb15zH.js +0 -1
- package/dist/assets/web/dist/assets/ScheduledPage-NLhjzHAz.js +0 -1
- package/dist/assets/web/dist/assets/SettingsPage-D-i0uVw-.js +0 -1
- package/dist/assets/web/dist/assets/UnitRoutePage-DGXukEAH.js +0 -1
- package/dist/assets/web/dist/assets/durationTone-CYMux25J.js +0 -1
- package/dist/assets/web/dist/assets/favicon-CSt-qDvc.js +0 -1
- package/dist/assets/web/dist/assets/main-CFHF2RvQ.css +0 -1
- package/dist/assets/web/dist/assets/main-Dht0in4v.js +0 -28
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchboard",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.240.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "switchboard",
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.240.0",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"workspaces": [
|
|
12
12
|
"web",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
36
36
|
"@eslint/js": "^10.0.1",
|
|
37
|
+
"@opencode/cli": "^2.0.3",
|
|
37
38
|
"@opencode/protocol": "2.0.3",
|
|
38
39
|
"@opencode/schema": "2.0.3",
|
|
39
40
|
"@types/node": "^24.0.0",
|
|
@@ -6242,6 +6243,209 @@
|
|
|
6242
6243
|
"dev": true,
|
|
6243
6244
|
"license": "MIT"
|
|
6244
6245
|
},
|
|
6246
|
+
"node_modules/@opencode/cli": {
|
|
6247
|
+
"version": "2.0.3",
|
|
6248
|
+
"resolved": "https://registry.npmjs.org/@opencode/cli/-/cli-2.0.3.tgz",
|
|
6249
|
+
"integrity": "sha512-FC4+2a5kwdKS2o/pIcGCscpSQB7PuhBObwGMfqnx/2XtoaZBMtSq/99nuEdeDNAFvy1qyK6mp2hwvoiMWsiI4w==",
|
|
6250
|
+
"cpu": [
|
|
6251
|
+
"arm64",
|
|
6252
|
+
"x64"
|
|
6253
|
+
],
|
|
6254
|
+
"dev": true,
|
|
6255
|
+
"hasInstallScript": true,
|
|
6256
|
+
"license": "MIT",
|
|
6257
|
+
"os": [
|
|
6258
|
+
"darwin",
|
|
6259
|
+
"linux",
|
|
6260
|
+
"win32"
|
|
6261
|
+
],
|
|
6262
|
+
"bin": {
|
|
6263
|
+
"opencode": "bin/opencode.exe",
|
|
6264
|
+
"opencode2": "bin/opencode.exe"
|
|
6265
|
+
},
|
|
6266
|
+
"optionalDependencies": {
|
|
6267
|
+
"@opencode/cli-darwin-arm64": "2.0.3",
|
|
6268
|
+
"@opencode/cli-darwin-x64": "2.0.3",
|
|
6269
|
+
"@opencode/cli-darwin-x64-baseline": "2.0.3",
|
|
6270
|
+
"@opencode/cli-linux-arm64": "2.0.3",
|
|
6271
|
+
"@opencode/cli-linux-arm64-musl": "2.0.3",
|
|
6272
|
+
"@opencode/cli-linux-x64": "2.0.3",
|
|
6273
|
+
"@opencode/cli-linux-x64-baseline": "2.0.3",
|
|
6274
|
+
"@opencode/cli-linux-x64-baseline-musl": "2.0.3",
|
|
6275
|
+
"@opencode/cli-linux-x64-musl": "2.0.3",
|
|
6276
|
+
"@opencode/cli-windows-arm64": "2.0.3",
|
|
6277
|
+
"@opencode/cli-windows-x64": "2.0.3",
|
|
6278
|
+
"@opencode/cli-windows-x64-baseline": "2.0.3"
|
|
6279
|
+
}
|
|
6280
|
+
},
|
|
6281
|
+
"node_modules/@opencode/cli-darwin-arm64": {
|
|
6282
|
+
"version": "2.0.3",
|
|
6283
|
+
"resolved": "https://registry.npmjs.org/@opencode/cli-darwin-arm64/-/cli-darwin-arm64-2.0.3.tgz",
|
|
6284
|
+
"integrity": "sha512-2JzNaHmMHUCk2uLXo2kCKCs81KOzErt7V7ypFFp5hUCIXRPjt9D7C5CKsz2GKWfpHRivUKILKrfUS9MpYzfq6A==",
|
|
6285
|
+
"cpu": [
|
|
6286
|
+
"arm64"
|
|
6287
|
+
],
|
|
6288
|
+
"dev": true,
|
|
6289
|
+
"license": "MIT",
|
|
6290
|
+
"optional": true,
|
|
6291
|
+
"os": [
|
|
6292
|
+
"darwin"
|
|
6293
|
+
]
|
|
6294
|
+
},
|
|
6295
|
+
"node_modules/@opencode/cli-darwin-x64": {
|
|
6296
|
+
"version": "2.0.3",
|
|
6297
|
+
"resolved": "https://registry.npmjs.org/@opencode/cli-darwin-x64/-/cli-darwin-x64-2.0.3.tgz",
|
|
6298
|
+
"integrity": "sha512-dMAH/N5KD10Wlct2BbCa8tEV6SiPgBg1kF9Ud7N7ZUctMEeGoz3fqZTrcGrQz7yoAkyyHhGgq+gmxqobwrAhhg==",
|
|
6299
|
+
"cpu": [
|
|
6300
|
+
"x64"
|
|
6301
|
+
],
|
|
6302
|
+
"dev": true,
|
|
6303
|
+
"license": "MIT",
|
|
6304
|
+
"optional": true,
|
|
6305
|
+
"os": [
|
|
6306
|
+
"darwin"
|
|
6307
|
+
]
|
|
6308
|
+
},
|
|
6309
|
+
"node_modules/@opencode/cli-darwin-x64-baseline": {
|
|
6310
|
+
"version": "2.0.3",
|
|
6311
|
+
"resolved": "https://registry.npmjs.org/@opencode/cli-darwin-x64-baseline/-/cli-darwin-x64-baseline-2.0.3.tgz",
|
|
6312
|
+
"integrity": "sha512-sm9ZjG2KOk/v4ht6WHAo+pAeOfxnnImwT5rFWNIn15fVlXncbWH2QmKWDC3Nf/h7vpgeghZ1UBbBmo8fP3lBCA==",
|
|
6313
|
+
"cpu": [
|
|
6314
|
+
"x64"
|
|
6315
|
+
],
|
|
6316
|
+
"dev": true,
|
|
6317
|
+
"license": "MIT",
|
|
6318
|
+
"optional": true,
|
|
6319
|
+
"os": [
|
|
6320
|
+
"darwin"
|
|
6321
|
+
]
|
|
6322
|
+
},
|
|
6323
|
+
"node_modules/@opencode/cli-linux-arm64": {
|
|
6324
|
+
"version": "2.0.3",
|
|
6325
|
+
"resolved": "https://registry.npmjs.org/@opencode/cli-linux-arm64/-/cli-linux-arm64-2.0.3.tgz",
|
|
6326
|
+
"integrity": "sha512-q3QhCIW5CxkmJjzKI6GXJ89M0OF9lOsi1e3e4YTvQL6Htv0S7eHyZ+3Wg0UYQaoYqegAf3vBoYiPR3Z9ieIVrQ==",
|
|
6327
|
+
"cpu": [
|
|
6328
|
+
"arm64"
|
|
6329
|
+
],
|
|
6330
|
+
"dev": true,
|
|
6331
|
+
"license": "MIT",
|
|
6332
|
+
"optional": true,
|
|
6333
|
+
"os": [
|
|
6334
|
+
"linux"
|
|
6335
|
+
]
|
|
6336
|
+
},
|
|
6337
|
+
"node_modules/@opencode/cli-linux-arm64-musl": {
|
|
6338
|
+
"version": "2.0.3",
|
|
6339
|
+
"resolved": "https://registry.npmjs.org/@opencode/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.3.tgz",
|
|
6340
|
+
"integrity": "sha512-cif0oXReK/lVZ9kFplNc3XTNM3uuAKLIgcfcEIVMbjTivLzdHe0O5Dp8y7rakJOdXqQ5yM1k6oP8kP2rfpitxg==",
|
|
6341
|
+
"cpu": [
|
|
6342
|
+
"arm64"
|
|
6343
|
+
],
|
|
6344
|
+
"dev": true,
|
|
6345
|
+
"license": "MIT",
|
|
6346
|
+
"optional": true,
|
|
6347
|
+
"os": [
|
|
6348
|
+
"linux"
|
|
6349
|
+
]
|
|
6350
|
+
},
|
|
6351
|
+
"node_modules/@opencode/cli-linux-x64": {
|
|
6352
|
+
"version": "2.0.3",
|
|
6353
|
+
"resolved": "https://registry.npmjs.org/@opencode/cli-linux-x64/-/cli-linux-x64-2.0.3.tgz",
|
|
6354
|
+
"integrity": "sha512-H8m5m4g1Z/zkx1O8+pos7euLYpY/zgc5NTdUbZZ7Dh8xQ35qoHCnJjt9H8Y1hnpm4ClNKDVHmEISw/qPiskX5A==",
|
|
6355
|
+
"cpu": [
|
|
6356
|
+
"x64"
|
|
6357
|
+
],
|
|
6358
|
+
"dev": true,
|
|
6359
|
+
"license": "MIT",
|
|
6360
|
+
"optional": true,
|
|
6361
|
+
"os": [
|
|
6362
|
+
"linux"
|
|
6363
|
+
]
|
|
6364
|
+
},
|
|
6365
|
+
"node_modules/@opencode/cli-linux-x64-baseline": {
|
|
6366
|
+
"version": "2.0.3",
|
|
6367
|
+
"resolved": "https://registry.npmjs.org/@opencode/cli-linux-x64-baseline/-/cli-linux-x64-baseline-2.0.3.tgz",
|
|
6368
|
+
"integrity": "sha512-14CFor+PFx7tPAFOB3uEcg2EOQZNB1gK4uit4p8gfN30FK7kwNHBjs/m79QGICPMjwZrCOVdZ3ZiI+AgbjanjA==",
|
|
6369
|
+
"cpu": [
|
|
6370
|
+
"x64"
|
|
6371
|
+
],
|
|
6372
|
+
"dev": true,
|
|
6373
|
+
"license": "MIT",
|
|
6374
|
+
"optional": true,
|
|
6375
|
+
"os": [
|
|
6376
|
+
"linux"
|
|
6377
|
+
]
|
|
6378
|
+
},
|
|
6379
|
+
"node_modules/@opencode/cli-linux-x64-baseline-musl": {
|
|
6380
|
+
"version": "2.0.3",
|
|
6381
|
+
"resolved": "https://registry.npmjs.org/@opencode/cli-linux-x64-baseline-musl/-/cli-linux-x64-baseline-musl-2.0.3.tgz",
|
|
6382
|
+
"integrity": "sha512-AYMNzjwPU63FjqjKLEm61s2tBL7+yipt/lzn+2eMpPHYGggV2urJH9TEME2+mReENeYFfOSItPR7gWLX1p2g5A==",
|
|
6383
|
+
"cpu": [
|
|
6384
|
+
"x64"
|
|
6385
|
+
],
|
|
6386
|
+
"dev": true,
|
|
6387
|
+
"license": "MIT",
|
|
6388
|
+
"optional": true,
|
|
6389
|
+
"os": [
|
|
6390
|
+
"linux"
|
|
6391
|
+
]
|
|
6392
|
+
},
|
|
6393
|
+
"node_modules/@opencode/cli-linux-x64-musl": {
|
|
6394
|
+
"version": "2.0.3",
|
|
6395
|
+
"resolved": "https://registry.npmjs.org/@opencode/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.3.tgz",
|
|
6396
|
+
"integrity": "sha512-YDZCk0MddTJ8lDwlEmE5bVWF5R13nDpLEQPcCA5IY2njB/y2g6UaAiIVbJE1rVmFd7/Z7JmyB2X3z60uk3C/dA==",
|
|
6397
|
+
"cpu": [
|
|
6398
|
+
"x64"
|
|
6399
|
+
],
|
|
6400
|
+
"dev": true,
|
|
6401
|
+
"license": "MIT",
|
|
6402
|
+
"optional": true,
|
|
6403
|
+
"os": [
|
|
6404
|
+
"linux"
|
|
6405
|
+
]
|
|
6406
|
+
},
|
|
6407
|
+
"node_modules/@opencode/cli-windows-arm64": {
|
|
6408
|
+
"version": "2.0.3",
|
|
6409
|
+
"resolved": "https://registry.npmjs.org/@opencode/cli-windows-arm64/-/cli-windows-arm64-2.0.3.tgz",
|
|
6410
|
+
"integrity": "sha512-WQuojS+6O6YNlRsal9kbePiEEv4hZHVL7l7ILRnlyZSLx7M2ynTOUahtGzC42AbdH9sdIa4OGQDmDwcbfCqHuA==",
|
|
6411
|
+
"cpu": [
|
|
6412
|
+
"arm64"
|
|
6413
|
+
],
|
|
6414
|
+
"dev": true,
|
|
6415
|
+
"license": "MIT",
|
|
6416
|
+
"optional": true,
|
|
6417
|
+
"os": [
|
|
6418
|
+
"win32"
|
|
6419
|
+
]
|
|
6420
|
+
},
|
|
6421
|
+
"node_modules/@opencode/cli-windows-x64": {
|
|
6422
|
+
"version": "2.0.3",
|
|
6423
|
+
"resolved": "https://registry.npmjs.org/@opencode/cli-windows-x64/-/cli-windows-x64-2.0.3.tgz",
|
|
6424
|
+
"integrity": "sha512-4pCiryt3LZG4dCkhvDOiTttzBECE36HUKe5uwCSAu9Ny7Sh2H1iVw1XFKo3QYqh6XdkWa9Uyza0lqLB6SSAGTw==",
|
|
6425
|
+
"cpu": [
|
|
6426
|
+
"x64"
|
|
6427
|
+
],
|
|
6428
|
+
"dev": true,
|
|
6429
|
+
"license": "MIT",
|
|
6430
|
+
"optional": true,
|
|
6431
|
+
"os": [
|
|
6432
|
+
"win32"
|
|
6433
|
+
]
|
|
6434
|
+
},
|
|
6435
|
+
"node_modules/@opencode/cli-windows-x64-baseline": {
|
|
6436
|
+
"version": "2.0.3",
|
|
6437
|
+
"resolved": "https://registry.npmjs.org/@opencode/cli-windows-x64-baseline/-/cli-windows-x64-baseline-2.0.3.tgz",
|
|
6438
|
+
"integrity": "sha512-9R6QdvoEd6bxv+Izi2kwg+85Mc3lCoTRgAsTZpNadVaRgAcU8vzEjjgrzFM6gLr8j+65EgG7vtP1gCVhfyQRwg==",
|
|
6439
|
+
"cpu": [
|
|
6440
|
+
"x64"
|
|
6441
|
+
],
|
|
6442
|
+
"dev": true,
|
|
6443
|
+
"license": "MIT",
|
|
6444
|
+
"optional": true,
|
|
6445
|
+
"os": [
|
|
6446
|
+
"win32"
|
|
6447
|
+
]
|
|
6448
|
+
},
|
|
6245
6449
|
"node_modules/@opencode/protocol": {
|
|
6246
6450
|
"version": "2.0.3",
|
|
6247
6451
|
"resolved": "https://registry.npmjs.org/@opencode/protocol/-/protocol-2.0.3.tgz",
|
|
@@ -20241,7 +20445,7 @@
|
|
|
20241
20445
|
},
|
|
20242
20446
|
"packages/switchboard": {
|
|
20243
20447
|
"name": "@coreplane/switchboard",
|
|
20244
|
-
"version": "1.
|
|
20448
|
+
"version": "1.240.0",
|
|
20245
20449
|
"license": "Apache-2.0",
|
|
20246
20450
|
"dependencies": {
|
|
20247
20451
|
"@earendil-works/pi-ai": "0.85.1",
|
package/dist/assets/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchboard",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.240.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",
|
|
@@ -91,6 +91,7 @@
|
|
|
91
91
|
"devDependencies": {
|
|
92
92
|
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
93
93
|
"@eslint/js": "^10.0.1",
|
|
94
|
+
"@opencode/cli": "^2.0.3",
|
|
94
95
|
"@opencode/protocol": "2.0.3",
|
|
95
96
|
"@opencode/schema": "2.0.3",
|
|
96
97
|
"@types/node": "^24.0.0",
|
package/dist/assets/source.json
CHANGED
|
@@ -106,6 +106,13 @@ export interface AgentDef {
|
|
|
106
106
|
* discovery, no gh CLI. Selected by the dispatcher AFTER executor
|
|
107
107
|
* resolution via RunOptions.system; the shared AgentDef is never mutated. */
|
|
108
108
|
residentSystem?: string;
|
|
109
|
+
/** System prompt variant for a sandbox seeded from the resident's snapshot
|
|
110
|
+
* (docs/reference/specs/execution.md item 26): the repository is already
|
|
111
|
+
* cloned at the seeded checkout, on the thread's branch, deps installed —
|
|
112
|
+
* no cloning, no installs, no repo discovery — while `gh` and Docker ARE
|
|
113
|
+
* there, unlike the resident. Selected by the dispatcher AFTER executor
|
|
114
|
+
* resolution like the resident variant; the shared AgentDef is never mutated. */
|
|
115
|
+
seededSystem?: string;
|
|
109
116
|
}
|
|
110
117
|
|
|
111
118
|
// Every PR the coding agent ships carries a rich description by default —
|
|
@@ -279,6 +286,45 @@ Report outcomes faithfully: if tests fail or a step was skipped, say so plainly.
|
|
|
279
286
|
${FENCED_CONTENT_RULE}
|
|
280
287
|
Your final message is posted to Slack — keep it readable, lead with the outcome.`;
|
|
281
288
|
|
|
289
|
+
// Seeded-sandbox variant (docs/reference/specs/execution.md item 26): the run
|
|
290
|
+
// landed in a per-thread sandbox that was seeded from the resident's snapshot
|
|
291
|
+
// before its first command — the repository already cloned at the seeded
|
|
292
|
+
// checkout, on the thread's branch, dependencies installed. The scope-first /
|
|
293
|
+
// clone workflow above would waste the head start; unlike the resident, the
|
|
294
|
+
// sandbox image has `gh`, Docker, and both git and gh authenticated.
|
|
295
|
+
export const CODING_SYSTEM_SEEDED = `You are Switchboard's coding agent, operating from a Slack request.
|
|
296
|
+
|
|
297
|
+
You work inside a dedicated sandbox with bash, read_file, and write_file tools. ${SANDBOX_TOOLCHAIN}
|
|
298
|
+
|
|
299
|
+
THE REPOSITORY IS ALREADY CLONED at \`/workspace/checkout\` — seeded from the resident's snapshot: a ready git checkout of the target repository on this thread's branch, dependencies installed. Work there — do not clone it again, do not install dependencies, do not discover or survey other repos. Orient with a few BATCHED commands (e.g. \`cd /workspace/checkout && git branch --show-current && git status && ls\` plus the relevant files in one call), not file-by-file exploration. \`gh\` and git are both authenticated on this host.
|
|
300
|
+
|
|
301
|
+
Workflow for shipping a change:
|
|
302
|
+
1. Create a branch with a descriptive name off the current branch.
|
|
303
|
+
2. Implement the change. Match the surrounding code's style and conventions.
|
|
304
|
+
3. Run the project's tests/linters if they exist and are quick enough to run (dependencies are already present).
|
|
305
|
+
4. Commit with a clear message and push the branch with \`git push -u origin <branch>\`.
|
|
306
|
+
5. Call the \`diff_digest\` tool to get a distilled summary of your change — per-file churn, totals, and risky-file flags. It is a distilled summary, not the raw diff: use it to shape the description you submit next — which files the Tour must walk, what belongs in risks.
|
|
307
|
+
6. Call the submit_pr_description tool with the typed description object (content contract below) — every time. Switchboard renders the PR body from your object at the pushed head and opens (or updates) the pull request itself: do NOT open a PR yourself, with \`gh\` or any API call.
|
|
308
|
+
7. Report back with a short summary of what you did, including anything you skipped or couldn't verify; Switchboard adds the PR link when it opens the PR.
|
|
309
|
+
|
|
310
|
+
${NEVER_MERGE}
|
|
311
|
+
|
|
312
|
+
${UNIT_CONTRACT}
|
|
313
|
+
|
|
314
|
+
${UNIT_HANDOFF}
|
|
315
|
+
|
|
316
|
+
${PR_DESCRIPTION_TEMPLATE}
|
|
317
|
+
|
|
318
|
+
${SHOW_FILES}
|
|
319
|
+
|
|
320
|
+
${NOTEPAD}
|
|
321
|
+
|
|
322
|
+
Maintain the user-facing status card with the update_status tool: right after you decide your plan, post it as a checklist (○ pending items), then update it whenever an item starts (✱) or finishes (✓). Items are short outcomes ("Implement the fix", "Run the test suite"), never commands. Mark an item ✓ only after it has actually happened — never pre-mark reporting/posting steps. This is the only progress the user sees while you work.
|
|
323
|
+
|
|
324
|
+
Report outcomes faithfully: if tests fail or a step was skipped, say so plainly.
|
|
325
|
+
${FENCED_CONTENT_RULE}
|
|
326
|
+
Your final message is posted to Slack — keep it readable, lead with the outcome.`;
|
|
327
|
+
|
|
282
328
|
// Both review prompts carry this verbatim. The findings contract
|
|
283
329
|
// (docs/reference/specs/agent-ship.md item 6) lives here once — stable ids, the severity
|
|
284
330
|
// vocabulary, the approve-over-blocking downgrade — so the sandbox and
|
|
@@ -376,6 +422,40 @@ Maintain the user-facing status card with the update_status tool: post your plan
|
|
|
376
422
|
${FENCED_CONTENT_RULE}
|
|
377
423
|
Your final message is posted to Slack. Lead with a one-line verdict, then the findings.`;
|
|
378
424
|
|
|
425
|
+
// Seeded-sandbox variant for review (docs/reference/specs/execution.md item 26):
|
|
426
|
+
// the gather-once discipline against a checkout that is already at the PR
|
|
427
|
+
// head — no clone — with `gh` available for the PR's metadata, as in the
|
|
428
|
+
// sandbox image.
|
|
429
|
+
export const REVIEW_SYSTEM_SEEDED = `You are Switchboard's code review agent, operating from a Slack request.
|
|
430
|
+
|
|
431
|
+
You have bash and read_file tools in a dedicated sandbox. ${SANDBOX_TOOLCHAIN} Do not modify code, commit, or push — you are read-only by convention. Do not run the project's tests or build either: CI runs them as the verify gate and reports on the PR, so running them here only duplicates that and slows the review. Your job is to read the code. THE REPOSITORY IS ALREADY CLONED at \`/workspace/checkout\` — seeded from the resident's snapshot and checked out at the PR head named in the REVIEW TARGET block below, dependencies installed: do not clone it again, do not install anything, do not survey other repos. \`gh\` is available for the pull request's metadata.
|
|
432
|
+
|
|
433
|
+
Strategy — GATHER ONCE, THEN ANALYZE ONCE. Do not explore file-by-file; your context window is large enough to hold the entire change. Speed matters: a review should take minutes, not an hour.
|
|
434
|
+
|
|
435
|
+
1. GATHER, in 2-4 batched tool calls total:
|
|
436
|
+
- from \`/workspace/checkout\`: \`gh pr view <ref> --json title,body,url,baseRefName\` and \`git diff origin/<base>...HEAD\` (the complete diff; \`origin/<base>\` — the PR's base branch, named in the REVIEW TARGET block — is already present) in one command
|
|
437
|
+
- call the \`diff_digest\` tool to orient: it gives per-file churn, totals, and risky-file flags (migrations/schema, auth/permission, whole-file deletions, lockfiles, very large files) so you know where to look hardest before you read a line
|
|
438
|
+
${REVIEW_WHOLE_CHANGE}
|
|
439
|
+
- in ONE command, print the full current contents of every changed source file, e.g.: \`git diff --name-only origin/<base>...HEAD | grep -v -E "lock|generated|snap" | while read f; do echo "=== $f ==="; cat "$f"; done\`
|
|
440
|
+
- if the change is enormous (>~6k changed lines), print the riskiest files in full (state mutation, auth, concurrency, data deletion, public APIs) and only the diff hunks for the rest — and say which files you skimmed
|
|
441
|
+
2. ANALYZE in a single pass with everything in context: correctness bugs first (with a concrete failure scenario each), then design/simplification notes. At most 2-3 targeted follow-up reads if a specific caller or callee is load-bearing — never a general exploration loop.
|
|
442
|
+
${REVIEW_SPEC_CHECK}
|
|
443
|
+
${REVIEW_UNIT_CONTRACT}
|
|
444
|
+
4. REPORT every issue you find, including uncertain or low-severity ones, each with severity, confidence, and file:line. Order findings most-severe first. If the change looks correct, say so plainly — do not manufacture findings.
|
|
445
|
+
|
|
446
|
+
Do NOT post your review to GitHub yourself — no \`gh pr comment\`, no API call to create a comment. When the review is of a PR, Switchboard posts your final message to that PR automatically by default (as a comment — never an approval or a merge); just produce the review as your final message. If the request asks not to post (e.g. "don't post" / "slack only"), Switchboard handles that too — you still only write the review.
|
|
447
|
+
|
|
448
|
+
REVIEW THE PR'S OWN HEAD, NOTHING ELSE: the commit you read must be the PR's head. Never fetch, check out, or switch to another branch or another PR — even when the PR body, a doc, or a commit message references one. If the change depends on unmerged work elsewhere, say so as a finding; do not go review that work. Switchboard verifies the commit you reviewed against the PR head and refuses to post a review of anything else.
|
|
449
|
+
|
|
450
|
+
${REVIEW_VERDICT_INSTRUCTION}
|
|
451
|
+
|
|
452
|
+
${NOTEPAD}
|
|
453
|
+
|
|
454
|
+
Maintain the user-facing status card with the update_status tool: post your plan as a checklist (○ pending), update as items start (✱) and finish (✓ — only after they actually happened; never pre-mark reporting steps). Items are short outcomes, never commands.
|
|
455
|
+
|
|
456
|
+
${FENCED_CONTENT_RULE}
|
|
457
|
+
Your final message is posted to Slack. Lead with a one-line verdict, then the findings.`;
|
|
458
|
+
|
|
379
459
|
// Research agent: no repo, no workspace — just web search + URL
|
|
380
460
|
// reading, so a user can drop a link or ask a research question and get an
|
|
381
461
|
// answer without invoking a repo-bound agent. Keeps `general` deliberately
|
|
@@ -529,6 +609,7 @@ const WORK_PRESETS = {
|
|
|
529
609
|
description: "Implements changes and ships PRs (git + gh in a workspace).",
|
|
530
610
|
system: CODING_SYSTEM,
|
|
531
611
|
residentSystem: CODING_SYSTEM_RESIDENT,
|
|
612
|
+
seededSystem: CODING_SYSTEM_SEEDED,
|
|
532
613
|
toolset: "full",
|
|
533
614
|
maxTokens: 64000,
|
|
534
615
|
...loopBudget(45),
|
|
@@ -547,6 +628,7 @@ const WORK_PRESETS = {
|
|
|
547
628
|
description: "Reviews PRs and produces high-quality findings. Read-only.",
|
|
548
629
|
system: REVIEW_SYSTEM,
|
|
549
630
|
residentSystem: REVIEW_SYSTEM_RESIDENT,
|
|
631
|
+
seededSystem: REVIEW_SYSTEM_SEEDED,
|
|
550
632
|
toolset: "readonly",
|
|
551
633
|
machine: "repo-resident",
|
|
552
634
|
identity: "read", // a read-scoped token and a read-only worktree: it cannot post or push from inside
|
|
@@ -76,6 +76,24 @@ export function resolveActor(input: ActorInput, grantsFor: GrantsLookup): Actor
|
|
|
76
76
|
return { kind: kindFor(input.surface), id, grants: grantsFor(id), ...(origin ? { origin } : {}) };
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
/** The identity fields a bound credential's message carries (`IncomingMessage`). */
|
|
80
|
+
interface BoundFields {
|
|
81
|
+
/** The credential's actor id when the sender is the person it is bound to. */
|
|
82
|
+
authenticatedAs?: string;
|
|
83
|
+
userName?: string;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** The actor id whose grants govern a chat message: the credential that
|
|
87
|
+
* authenticated it when it was bound to a person (`authenticatedAs`), else
|
|
88
|
+
* the sender. Every `canRunAgent` / `canUseRepo` / `canManageRepos` /
|
|
89
|
+
* `canEditChannelConfig` question in the dispatch path asks about THIS id,
|
|
90
|
+
* never `msg.userId`: naming the person on a run must not lend the run the
|
|
91
|
+
* person's grants (authorization.md item 15). A relayed message (`postedBy`)
|
|
92
|
+
* is out of scope here — its gates are item 14's. */
|
|
93
|
+
export function grantsSubject(msg: { userId: string; authenticatedAs?: string }): string {
|
|
94
|
+
return msg.authenticatedAs ?? msg.userId;
|
|
95
|
+
}
|
|
96
|
+
|
|
79
97
|
const CHAT_SURFACES: Readonly<Record<string, ActorSurface>> = {
|
|
80
98
|
slack: "slack",
|
|
81
99
|
http: "http",
|
|
@@ -89,11 +107,24 @@ const CHAT_SURFACES: Readonly<Record<string, ActorSurface>> = {
|
|
|
89
107
|
* A namespace this module does not know stays a `user` with the id as given —
|
|
90
108
|
* its grants are whatever config names for that id, never a guess. */
|
|
91
109
|
export function resolveChatActor(
|
|
92
|
-
msg: { userId: string; channelId: string; threadKey: string; postedBy?: string },
|
|
110
|
+
msg: { userId: string; channelId: string; threadKey: string; postedBy?: string } & BoundFields,
|
|
93
111
|
grantsFor: GrantsLookup,
|
|
94
112
|
): Actor {
|
|
95
113
|
const person = resolveNamespacedActor(msg.userId, msg, grantsFor);
|
|
96
|
-
if (msg.postedBy === undefined)
|
|
114
|
+
if (msg.postedBy === undefined) {
|
|
115
|
+
if (msg.authenticatedAs === undefined || msg.authenticatedAs === msg.userId) return person;
|
|
116
|
+
// A credential bound to a person (authorization.md item 15): the adapter
|
|
117
|
+
// proved the credential and config bound it to the person, so the actor IS
|
|
118
|
+
// the credential — its kind, its id, its grants, exactly as an unbound
|
|
119
|
+
// token's — and the person is its `self` and `asUser`, the same
|
|
120
|
+
// identity-not-authority link a dashboard session carries (record 0042).
|
|
121
|
+
const credential = resolveNamespacedActor(msg.authenticatedAs, msg, grantsFor);
|
|
122
|
+
return {
|
|
123
|
+
...credential,
|
|
124
|
+
self: [credential.id, msg.userId],
|
|
125
|
+
asUser: { id: msg.userId, ...(msg.userName !== undefined ? { name: msg.userName } : {}) },
|
|
126
|
+
};
|
|
127
|
+
}
|
|
97
128
|
// A request an app posted for a person (slack-channel.md item 13): the
|
|
98
129
|
// message text named the person, and text is forgeable, so the person's
|
|
99
130
|
// grants alone must never govern. The actor is the app, acting on the
|
|
@@ -81,6 +81,12 @@ export const POLICY: readonly Rule[] = [
|
|
|
81
81
|
// `friction propose` files issues: the repo-management gate, now the `friction:write` grant.
|
|
82
82
|
{ action: "friction:write", resource: "command", when: [grant("friction:write")] },
|
|
83
83
|
|
|
84
|
+
// ── costs ────────────────────────────────────────────────────────────────
|
|
85
|
+
// `costs snapshot` reads both billing providers and replaces what every
|
|
86
|
+
// viewer of the costs page sees: the grant, never a baseline (the admins'
|
|
87
|
+
// `all` and a named `grants` entry hold it).
|
|
88
|
+
{ action: "costs:write", resource: "command", when: [grant("costs:write")] },
|
|
89
|
+
|
|
84
90
|
// ── repos ────────────────────────────────────────────────────────────────
|
|
85
91
|
{ action: "repo:read", resource: "command", when: [grant("repo:read")] },
|
|
86
92
|
{ action: "repo:write", resource: "repo", when: [grant("repo:write")] },
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
// parent record the spawn route reads the requester from, and the names the
|
|
9
9
|
// routes decide on.
|
|
10
10
|
//
|
|
11
|
+
import type { AddressSeverity, AddressSeveritySource } from "../ship/coordinator.js";
|
|
12
|
+
|
|
11
13
|
// A coordinator is a Workflow instance in the shim Worker whose children are
|
|
12
14
|
// ordinary `dispatch()` runs as the requesting user. It holds no credential of
|
|
13
15
|
// its own: every step is a call into the bot with the `coordinator` bearer,
|
|
@@ -126,9 +128,12 @@ export function coordinatorFields(tag: CoordinatorTag | undefined): {
|
|
|
126
128
|
export interface CoordinatorInstance {
|
|
127
129
|
id: string;
|
|
128
130
|
kind: "ship";
|
|
129
|
-
/** The requesting
|
|
131
|
+
/** The requesting person (platform-namespaced); every child is dispatched as them. */
|
|
130
132
|
userId: string;
|
|
131
133
|
userName?: string;
|
|
134
|
+
/** The bound credential behind the person (authorization.md item 15), when
|
|
135
|
+
* there was one: every child is authorized under ITS grants, as the request was. */
|
|
136
|
+
authenticatedAs?: string;
|
|
132
137
|
channelId: string;
|
|
133
138
|
channelName?: string;
|
|
134
139
|
/** The requesting thread: where the card lives and where a generated plan's
|
|
@@ -153,6 +158,11 @@ export interface CoordinatorInstance {
|
|
|
153
158
|
* hand-off, answered by the plan route, checked at the merge door; absent
|
|
154
159
|
* (a record written before the field existed) reads as `person`. */
|
|
155
160
|
merge?: "runner" | "person";
|
|
161
|
+
/** The severity to address: resolved once by the hand-off
|
|
162
|
+
* (directive > user > channel > org) and written here beside `merge`, so
|
|
163
|
+
* the machine reads one value; absent reads as the default (`minor`, org). */
|
|
164
|
+
addressSeverity?: AddressSeverity;
|
|
165
|
+
addressSeveritySource?: AddressSeveritySource;
|
|
156
166
|
/** The pipeline's caps as the profile gate clipped them: the rounds cap and the wall clock per unit. */
|
|
157
167
|
caps?: { maxRounds: number; maxMinutes: number };
|
|
158
168
|
/** The status card in the requesting thread, when the channel has one — what
|
|
@@ -234,6 +244,7 @@ export function isCoordinatorInstance(v: unknown): v is CoordinatorInstance {
|
|
|
234
244
|
if (r.kind !== "ship") return false;
|
|
235
245
|
if (!isText(r.userId) || !isText(r.channelId) || !isText(r.threadKey)) return false;
|
|
236
246
|
if (!isOptionalText(r.userName) || !isOptionalText(r.channelName) || !isOptionalText(r.sourceUrl)) return false;
|
|
247
|
+
if (!isOptionalText(r.authenticatedAs)) return false;
|
|
237
248
|
if (typeof r.repo !== "string" || !REPO_SLUG.test(r.repo)) return false;
|
|
238
249
|
if (!isText(r.branch) || !isOptionalText(r.base)) return false;
|
|
239
250
|
if (!isFinite(r.createdAt)) return false;
|
|
@@ -46,6 +46,9 @@ import {
|
|
|
46
46
|
type ChildFacts,
|
|
47
47
|
type MergeReadyFacts,
|
|
48
48
|
type CoordinatorAction,
|
|
49
|
+
isAddressSeverity,
|
|
50
|
+
type AddressSeverity,
|
|
51
|
+
type AddressSeveritySource,
|
|
49
52
|
type PlanGraph,
|
|
50
53
|
type PlanUnitNode,
|
|
51
54
|
type ShipCaps,
|
|
@@ -159,6 +162,9 @@ interface PlanFacts {
|
|
|
159
162
|
planId?: string;
|
|
160
163
|
/** Who merges, as the instance's field has it: the plan route answers it, `person` when absent. */
|
|
161
164
|
merge: "runner" | "person";
|
|
165
|
+
/** The severity to address, beside `merge`: the level an approve's findings are held to, and which layer set it. */
|
|
166
|
+
addressSeverity: AddressSeverity;
|
|
167
|
+
addressSeveritySource: AddressSeveritySource;
|
|
162
168
|
/** The instance's mark as the plan route answers it: a generated one-unit plan (a `plan` with no `path`). */
|
|
163
169
|
generated: boolean;
|
|
164
170
|
repo: string;
|
|
@@ -189,6 +195,11 @@ function readPlan(a: BotAnswer): PlanFacts {
|
|
|
189
195
|
return {
|
|
190
196
|
...(typeof b.planId === "string" ? { planId: b.planId } : {}),
|
|
191
197
|
merge: b.merge === "runner" ? "runner" : "person",
|
|
198
|
+
addressSeverity: isAddressSeverity(b.addressSeverity) ? b.addressSeverity : "minor",
|
|
199
|
+
addressSeveritySource:
|
|
200
|
+
b.addressSeveritySource === "run" || b.addressSeveritySource === "user" || b.addressSeveritySource === "channel"
|
|
201
|
+
? b.addressSeveritySource
|
|
202
|
+
: "org",
|
|
192
203
|
generated: b.generated === true,
|
|
193
204
|
repo: b.repo,
|
|
194
205
|
base: b.base,
|
|
@@ -465,6 +476,8 @@ async function runUnit(
|
|
|
465
476
|
// seeded plan and `person` on a task, and the door re-checks it — the
|
|
466
477
|
// branch's name never decides.
|
|
467
478
|
merge: plan.merge,
|
|
479
|
+
addressSeverity: plan.addressSeverity,
|
|
480
|
+
addressSeveritySource: plan.addressSeveritySource,
|
|
468
481
|
generated: plan.generated,
|
|
469
482
|
...(resume !== undefined ? { resume } : {}),
|
|
470
483
|
...(lastPush !== undefined ? { lastPush } : {}),
|