@bongos/core 1.24.76 → 1.24.77

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/.bongos-core.json CHANGED
@@ -2,22 +2,22 @@
2
2
  "artifact": "bongos-core",
3
3
  "manifest_schema": 1,
4
4
  "generator": "scripts/bongos/package-core.js",
5
- "core_version": "1.24.76",
6
- "core_contract": "1.24.76",
7
- "source_commit": "2bbf5fc6aa56831623542e4e5e21eb82d0ec565e",
5
+ "core_version": "1.24.77",
6
+ "core_contract": "1.24.77",
7
+ "source_commit": "173fce6916dbd53657d18e5f132ff3b3540d647b",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-11-10T00:02:08.746Z",
9
+ "built_at": "2026-11-10T01:28:52.098Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 639,
13
13
  "agent_docs_stubbed": 32,
14
- "functional_verbatim": 3920,
14
+ "functional_verbatim": 3927,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 4592,
20
- "tree_sha256": "39b643b66343f5765016c84fe0eb536d718f516a21264ea4fed1d120e344c368",
19
+ "file_count": 4599,
20
+ "tree_sha256": "44e851fe33c0399bd0bb45be9fcb39e837ca19041fbc1b0f7231fa40d101a3f9",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/ask-for-help/SKILL.md",
@@ -2012,7 +2012,7 @@
2012
2012
  {
2013
2013
  "path": "docs/adr/0307-autobongos-a-deterministic-supervisor-and-agentic-workers.md",
2014
2014
  "mode": "0000644",
2015
- "sha256": "63031806792dd0ba4a8924d7bf73053dad1045633a9de29d1327866527799d69"
2015
+ "sha256": "a83d794a07569c0490894d5889c8616ceb4e973ca6879e3e68a3b1e7ad784bda"
2016
2016
  },
2017
2017
  {
2018
2018
  "path": "docs/adr/0308-an-eleventh-working-area.md",
@@ -3007,7 +3007,7 @@
3007
3007
  {
3008
3008
  "path": "docs/module-api-changelog.md",
3009
3009
  "mode": "0000644",
3010
- "sha256": "45d2223305c6f77d97b989f3c97759555cc4c790eb905601b3b8ba6c76c4cf18"
3010
+ "sha256": "06cdc4704a3ea353cb13e35c2be7fb6f3ac9e87b84cf8b870e09b7086a1165ef"
3011
3011
  },
3012
3012
  {
3013
3013
  "path": "docs/modules-contract.md",
@@ -4542,7 +4542,7 @@
4542
4542
  {
4543
4543
  "path": "modules/autonomy/gauge.js",
4544
4544
  "mode": "0000644",
4545
- "sha256": "cb534feb4dc4c55d941973e5918c58ccc07a13a50b9a4a50ef6c7370420330b1"
4545
+ "sha256": "aa4987901ee688fc9f33b5a81058bfe70a79df8bf8a5c720e42de0a21a8dafdb"
4546
4546
  },
4547
4547
  {
4548
4548
  "path": "modules/autonomy/governor-docket.js",
@@ -11947,12 +11947,12 @@
11947
11947
  {
11948
11948
  "path": "package-lock.json",
11949
11949
  "mode": "0000644",
11950
- "sha256": "c155b0b7a1b2435d38d085ee0b88504031ed463eb7bd6f5de82b1c6aa459e271"
11950
+ "sha256": "3407de417eaa11f0f2234084d5355de1f4113089bea94c3c85b94c510ae46874"
11951
11951
  },
11952
11952
  {
11953
11953
  "path": "package.json",
11954
11954
  "mode": "0000644",
11955
- "sha256": "3fb08cfc1ebf6b0719b4f826b9b4e317ac3419bae8c9032a14f3684308ea3b38"
11955
+ "sha256": "f9e06cafeea2ebf151c36023bda87156efafd3965ec1245e8781072ac4f51134"
11956
11956
  },
11957
11957
  {
11958
11958
  "path": "public-docs/index.html",
@@ -11972,7 +11972,7 @@
11972
11972
  {
11973
11973
  "path": "release-notes.json",
11974
11974
  "mode": "0000644",
11975
- "sha256": "6bb5daade7507fe469acc3b41fecb047261fcbf2c99496dd31f6a62aeb9ef84a"
11975
+ "sha256": "99def2fcf254ad4bcfca53ce46e3c21ee8ab543c9f84a4e676864b94cb91d2a3"
11976
11976
  },
11977
11977
  {
11978
11978
  "path": "scripts/bongos/CLAUDE.md",
@@ -12089,6 +12089,16 @@
12089
12089
  "mode": "0000644",
12090
12090
  "sha256": "d2a3106b277543f052fd37cc967dcc9d2942f8b782806b30efc2238c40d4780d"
12091
12091
  },
12092
+ {
12093
+ "path": "scripts/bongos/autobongos-bootstrap.ps1",
12094
+ "mode": "0000644",
12095
+ "sha256": "712801bf62bb00d07de067659f5a0df13dd57623e03ce5869bbaf33edc3ac083"
12096
+ },
12097
+ {
12098
+ "path": "scripts/bongos/autobongos-bootstrap.sh",
12099
+ "mode": "0000755",
12100
+ "sha256": "3a919b371e76491935049a90196d95600b3c953e4ce04c9ed77a0274b1ec0afb"
12101
+ },
12092
12102
  {
12093
12103
  "path": "scripts/bongos/autobongos-digest.js",
12094
12104
  "mode": "0000644",
@@ -12099,6 +12109,11 @@
12099
12109
  "mode": "0000644",
12100
12110
  "sha256": "9fcb0b301b6889dbd5da8b11a4ffbe579229663a481b3ece4a4feb5df5d2885c"
12101
12111
  },
12112
+ {
12113
+ "path": "scripts/bongos/autobongos-host.js",
12114
+ "mode": "0000755",
12115
+ "sha256": "25141335ab8a56b9c2897f5cd7bdcaf1e97294d9dcb21359dbeb220146fe524e"
12116
+ },
12102
12117
  {
12103
12118
  "path": "scripts/bongos/autobongos-loop.js",
12104
12119
  "mode": "0000644",
@@ -12107,7 +12122,7 @@
12107
12122
  {
12108
12123
  "path": "scripts/bongos/autobongos-run.js",
12109
12124
  "mode": "0000644",
12110
- "sha256": "4a4db82b0d110c8e790f230d63ea2ba8e54327d6c3c94a0256bdf45cd1126d6d"
12125
+ "sha256": "f7ca5670e45a5f1cbdee91868e364e9e933b7a0ec1764f98634be500df4ba0e2"
12111
12126
  },
12112
12127
  {
12113
12128
  "path": "scripts/bongos/autobongos-service.cmd",
@@ -12142,7 +12157,7 @@
12142
12157
  {
12143
12158
  "path": "scripts/bongos/autonomy-gauge.js",
12144
12159
  "mode": "0000644",
12145
- "sha256": "f9be35a9a47983069b629e9b1d6bda987228a25121f524321dcd931e9e2c2214"
12160
+ "sha256": "4047f967d935643220a383cca857b602e0e457ad21d71640aa4f233aa654c258"
12146
12161
  },
12147
12162
  {
12148
12163
  "path": "scripts/bongos/backfill-cost.js",
@@ -12247,7 +12262,7 @@
12247
12262
  {
12248
12263
  "path": "scripts/bongos/cli-lib.js",
12249
12264
  "mode": "0000644",
12250
- "sha256": "bbfd061637439ce86bd261fd39e243f1701247ea6669c7ae4775d1e59c94a3a9"
12265
+ "sha256": "7f00d2ce761ee775341e21cce68e64b8346f2f2c4bcd5cd41b16b9e8404f926e"
12251
12266
  },
12252
12267
  {
12253
12268
  "path": "scripts/bongos/client-baseurl-guard.js",
@@ -13794,6 +13809,16 @@
13794
13809
  "mode": "0000644",
13795
13810
  "sha256": "a83480ea44a33424c2d0ef5832d99ecd66956ef47b0e5992fc39d4c2361a68ec"
13796
13811
  },
13812
+ {
13813
+ "path": "scripts/gds/autobongos-bootstrap.ps1",
13814
+ "mode": "0000644",
13815
+ "sha256": "c6eaeab922ba3da0c944f0ad7ecdba515f5935f49fbdcf6daf10afc60fd6ad94"
13816
+ },
13817
+ {
13818
+ "path": "scripts/gds/autobongos-bootstrap.sh",
13819
+ "mode": "0000644",
13820
+ "sha256": "9dda7da8b15ee5c86e96ddb9a2ba5cfed6f64e70e7d7d2ed0b50e018a1c3f98e"
13821
+ },
13797
13822
  {
13798
13823
  "path": "scripts/gds/autobongos-digest.js",
13799
13824
  "mode": "0000644",
@@ -13804,6 +13829,11 @@
13804
13829
  "mode": "0000644",
13805
13830
  "sha256": "9b4dd6e35b2eb252be774d29610c4ab3602ca2fc8babf1beecb4b30f35f50a9d"
13806
13831
  },
13832
+ {
13833
+ "path": "scripts/gds/autobongos-host.js",
13834
+ "mode": "0000644",
13835
+ "sha256": "5009910c0b169817139af01bf2a9ed0f7c120fd4088252eafdd533b314b49a3d"
13836
+ },
13807
13837
  {
13808
13838
  "path": "scripts/gds/autobongos-loop.js",
13809
13839
  "mode": "0000644",
@@ -15927,7 +15957,7 @@
15927
15957
  {
15928
15958
  "path": "src/instance-config.js",
15929
15959
  "mode": "0000644",
15930
- "sha256": "b123541932f206894a652aebf64a13ed0794a4b44e68936a11d65bf49c7a2fc9"
15960
+ "sha256": "379813150afa1aa6636a231dfa0f4534d6bdd55c09e88f42b71345467b1a527d"
15931
15961
  },
15932
15962
  {
15933
15963
  "path": "src/link-preview.js",
@@ -15937,7 +15967,7 @@
15937
15967
  {
15938
15968
  "path": "src/module-api.js",
15939
15969
  "mode": "0000644",
15940
- "sha256": "82edc72fcfea9701d271efc5f6792fe8403d9af7a882b01808230539b1105e6d"
15970
+ "sha256": "206b745de49507349a5db6f044f6b7a841d736ae399dbee94e847a5d45a12bcc"
15941
15971
  },
15942
15972
  {
15943
15973
  "path": "src/module-loader/catalog.js",
@@ -16494,6 +16524,11 @@
16494
16524
  "mode": "0000644",
16495
16525
  "sha256": "d2d6f12d2e1abc8485b50f2ae2fd89b408be676ef0044025e92252fd22c87fe8"
16496
16526
  },
16527
+ {
16528
+ "path": "tests/autobongos_host.mjs",
16529
+ "mode": "0000644",
16530
+ "sha256": "6f3f7a7c473403851c34e608472121a51f6db14c11bd9134aa9a0a8c6820b972"
16531
+ },
16497
16532
  {
16498
16533
  "path": "tests/autobongos_host_access.mjs",
16499
16534
  "mode": "0000644",
@@ -16502,7 +16537,7 @@
16502
16537
  {
16503
16538
  "path": "tests/autobongos_loop.mjs",
16504
16539
  "mode": "0000644",
16505
- "sha256": "bf70586b9144fd5b162647ad08fb07c5a9c810a145ebf55fa7cc7c99e44c4a4f"
16540
+ "sha256": "da645ffd57bd16423e7e5004472c8813d4e1f804579a2133f2f34ebfdbd02bee"
16506
16541
  },
16507
16542
  {
16508
16543
  "path": "tests/autobongos_runner_login.mjs",
@@ -16577,7 +16612,7 @@
16577
16612
  {
16578
16613
  "path": "tests/autonomy_gauge.mjs",
16579
16614
  "mode": "0000644",
16580
- "sha256": "45f7bb8abb53b6248bf8f9110599817767969d3c2df0844566d714ca5de3d854"
16615
+ "sha256": "2c9497f481414f0d51a6c91658b70584dea5d0f6b2e1e8ecd718fccb985a2de2"
16581
16616
  },
16582
16617
  {
16583
16618
  "path": "tests/autonomy_runner_health.mjs",
@@ -16967,7 +17002,7 @@
16967
17002
  {
16968
17003
  "path": "tests/cli_sessions.mjs",
16969
17004
  "mode": "0000644",
16970
- "sha256": "55d72cc2926ab8574e290ca16e40702759c8c6b0453a8ebd4aa9f09ae77f880d"
17005
+ "sha256": "d3b12216c23fb74a7646815e1d2c169164b16538b257dfeb503a2c5d0be7b835"
16971
17006
  },
16972
17007
  {
16973
17008
  "path": "tests/cli_surface.mjs",
@@ -112,6 +112,36 @@ match the **exact worktree name the runner generates**, not an `autobongos-`
112
112
  prefix: the loose form matched a human's hand-named tree and released their live
113
113
  claim out from under them, twice, during the task that added it.
114
114
 
115
+ **Any device, not one always-on PC** (task 1005095, goal 1000139; owner direction
116
+ 2026-11-09). The host above was written for a single Windows box: a scheduled task
117
+ registered from an Administrator shell, started at boot. The owner's rule is now
118
+ that the runner runs on any device, Windows or Mac, always-on or a laptop, from one
119
+ button. Four decisions carry that, in `scripts/bongos/autobongos-host.js`:
120
+
121
+ - **It starts at sign-in, as the person, with no administrator.** A per-user Run
122
+ entry on Windows and a per-user launchd agent on a Mac. Boot-time start needs an
123
+ elevated registration on Windows and cannot reach the login keychain on a Mac,
124
+ where the Claude sign-in lives; sign-in start needs neither. A laptop that
125
+ sleeps stops checking in and resumes when it wakes, and the hall already reads
126
+ silence as silence. The boot-time task stays as the opt-in for an always-on PC.
127
+ - **One Node program replaces the `.cmd` wrapper on this path**, so Windows and
128
+ Mac cannot drift: refresh the runner's copy, launch the supervisor, relaunch on
129
+ its upgrade exit, restart after a crash with a growing wait. Stop and uninstall
130
+ watch the processes exit before saying so.
131
+ - **The runner keeps its own files** (`BONGOS_CONFIG_ROOT`, passed on to every
132
+ worker). A runner's own login in the builder's one session slot would sign the
133
+ builder's own tools out; a root of its own also means the runner can never fall
134
+ back to the builder's session.
135
+ - **A device with no gauge at all works until the usage limit** (`absentMeansGo`,
136
+ passed only by the supervisor). §2's writer is a terminal statusLine, so a
137
+ device whose owner uses the desktop app never has a reading, and "unknown, so
138
+ hold" left it armed and idle forever. This is the 2026-09-30 ruling — hit the
139
+ limit, wait for its reset, resume — with nothing to read first. A reading that
140
+ exists and cannot be vouched for still holds.
141
+
142
+ The program hard-resets its checkout on every start, so it refuses to run anywhere
143
+ but a copy the setup marked as the runner's own.
144
+
115
145
  ### 6. The fence, and where it is enforced
116
146
 
117
147
  The allowlist of goals lives in the database and is edited from the hall, never
@@ -3402,5 +3402,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
3402
3402
  landed since 1.24.73 with no explicit bump. run 42715090111. (task 1002620)
3403
3403
  1.24.76 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3404
3404
  landed since 1.24.74 with no explicit bump. run 42724956677. (task 1002620)
3405
+ 1.24.77 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3406
+ landed since 1.24.76 with no explicit bump. run 42735935883. (task 1002620)
3405
3407
  ---------------------------------------------------------------------------
3406
3408
  ```
@@ -116,7 +116,12 @@ function reserveFor(nowEpochS, config = {}) {
116
116
  // decide identically and a caller that has to enumerate them will miss one.
117
117
  function readGauge(raw, nowEpochS, config = {}) {
118
118
  const c = cfg(config);
119
- if (!raw || typeof raw !== 'object') return { known: false, reason: 'no gauge file — the statusline writer has never run' };
119
+ // `absent` marks the one shape that is not a bad reading but NO reading: this
120
+ // device has never had a gauge at all (see decideCapacity, task 1005095).
121
+ // Only NOTHING is absent. A file that is there but is not a gauge — torn, or
122
+ // not JSON — is a bad reading like any other, and must never read as "none".
123
+ if (raw === null || raw === undefined) return { known: false, absent: true, reason: 'no gauge file — the statusline writer has never run' };
124
+ if (typeof raw !== 'object') return { known: false, reason: 'the gauge file is there but cannot be read as a gauge' };
120
125
 
121
126
  const writtenAt = Number(raw.written_at);
122
127
  if (!Number.isFinite(writtenAt)) return { known: false, reason: 'gauge file has no readable written_at' };
@@ -239,6 +244,25 @@ function decideCapacity({ gauge, now, config = {} } = {}) {
239
244
  const c = cfg(config);
240
245
  const g = readGauge(gauge, now, c);
241
246
 
247
+ // A DEVICE WITH NO GAUGE AT ALL (task 1005095, owner direction 2026-11-09: the
248
+ // runner must run on any device from one button). The gauge's only writer is a
249
+ // terminal statusLine, so a laptop whose owner uses the desktop app, or a PC
250
+ // set up five minutes ago, has no file and never will — and "unknown, so hold"
251
+ // left such a runner armed, checking in and idle forever. The owner already
252
+ // ruled (2026-09-30, task 1004454) that running until the usage limit is hit
253
+ // and resuming at its reset is acceptable; a device with no gauge is that same
254
+ // bargain with nothing to read first. So when the CALLER asks for it
255
+ // (`absentMeansGo`, which only the supervisor passes), no file is a go, marked
256
+ // `absent` and `derived` so the log says which kind of go it was. Everything
257
+ // else that cannot be vouched for — malformed, future-dated, aged out inside a
258
+ // window still running — is still UNKNOWN, and the default is unchanged: the
259
+ // gauge CLI and any other caller never default to go.
260
+ if (!g.known && g.absent && c.absentMeansGo === true) {
261
+ return {
262
+ go: true, unknown: false, sleepUntil: null, absent: true, derived: true, derivedSince: null,
263
+ reason: 'no usage gauge on this device — working until the usage limit says stop, then waiting for its reset',
264
+ };
265
+ }
242
266
  if (!g.known) return { go: false, unknown: true, sleepUntil: null, reason: g.reason };
243
267
 
244
268
  if (g.sevenDay) {
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.24.76",
3
+ "version": "1.24.77",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.24.76",
9
+ "version": "1.24.77",
10
10
  "license": "AGPL-3.0-or-later",
11
11
  "dependencies": {
12
12
  "express": "^4.21.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.24.76",
3
+ "version": "1.24.77",
4
4
  "description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "main": "src/platform-server.js",
@@ -11487,5 +11487,11 @@
11487
11487
  "id": "1005121",
11488
11488
  "text": "Closing a project-setup stage is now one step: if the founder alone decides, the stage closes and the project moves on at once; if others must vote, the answer says who and what to do next instead of falsely reporting success."
11489
11489
  }
11490
+ ],
11491
+ "1.24.77": [
11492
+ {
11493
+ "id": "1005095",
11494
+ "text": "The Autobongos runner can now be set up on any Windows PC or Mac, including a laptop, with no administrator step. One program installs it, starts it whenever you sign in to the device, keeps it running, updates it by itself, a"
11495
+ }
11490
11496
  ]
11491
11497
  }
@@ -0,0 +1,169 @@
1
+ # scripts/bongos/autobongos-bootstrap.ps1 -- the first lines of Autobongos setup
2
+ # on a Windows PC (tasks 1005095, 1005094; goal 1000139).
3
+ #
4
+ # autobongos-bootstrap.ps1 -Code abr_... -ApiBase https://... -Repo https://github.com/owner/name
5
+ #
6
+ # and, as the hall hands it out, with no file on the PC at all:
7
+ #
8
+ # & ([scriptblock]::Create((irm 'https://<project>/api/bongos/autonomy/runner-setup.ps1'))) -Code '...' -ApiBase '...' -Repo '...'
9
+ #
10
+ # WHY THIS IS POWERSHELL AND SO SHORT. Everything that sets a runner up is one
11
+ # Node program (autobongos-host.js), the same on Windows and Mac. But Node cannot
12
+ # install Node, and the program lives in a copy of the project that does not exist
13
+ # yet. So this does only what must happen before Node can take over: find or
14
+ # install git, Node and Claude Code, make the runner ITS OWN copy of the project,
15
+ # and hand over. The hall serves this file and Settings puts the one-time code in
16
+ # the command, so the person copies one line.
17
+ #
18
+ # NO ADMINISTRATOR SHELL. It runs as the person, in an ordinary PowerShell window.
19
+ # winget may show Windows' own "allow this app to make changes" prompt while it
20
+ # installs git or Node; that is the installer asking, not this script.
21
+ #
22
+ # EVERY STOP IS A SENTENCE. A failure it cannot fix itself ends with what
23
+ # happened and what to do, never a stack trace. Safe to run again: each step
24
+ # checks before it acts, and a copy that already exists is brought current
25
+ # instead of cloned twice.
26
+ #
27
+ # IT NEVER CALLS exit WHEN IT WAS PASTED (task 1005094). Run as a script block --
28
+ # which is how the pasted line runs it -- `exit` ends the PowerShell WINDOW, so
29
+ # the person would see their window vanish instead of the sentence telling them
30
+ # what to do. Every stop therefore unwinds to the bottom of this file, which
31
+ # calls `exit` only when this is running as a file.
32
+
33
+ [CmdletBinding()]
34
+ param(
35
+ [string]$Code,
36
+ [string]$ApiBase,
37
+ [string]$Repo,
38
+ # Where the runner keeps its own files. One folder, so removing the runner is
39
+ # deleting it. $HOME, not $env:USERPROFILE: it is the same folder on Windows,
40
+ # and it also exists where this file is only ever tested (PowerShell on Linux
41
+ # has no USERPROFILE, and a null default stops the script before its first line).
42
+ [string]$RunnerHome = (Join-Path $HOME '.cloudbongos-runner'),
43
+ # Say what would be done and stop before changing anything.
44
+ [switch]$DryRun
45
+ )
46
+
47
+ $ErrorActionPreference = 'Stop'
48
+ $StopMark = 'autobongos-setup-stopped'
49
+
50
+ function Stop-Setup([string]$What, [string]$Fix) {
51
+ Write-Host ''
52
+ Write-Host "Autobongos setup stopped here: $What" -ForegroundColor Yellow
53
+ Write-Host "What to do: $Fix"
54
+ throw $StopMark
55
+ }
56
+
57
+ function Say([string]$Text) { Write-Host $Text }
58
+
59
+ # A fresh install changes PATH in the registry, not in this window.
60
+ function Update-PathFromRegistry {
61
+ $machine = [Environment]::GetEnvironmentVariable('Path', 'Machine')
62
+ $user = [Environment]::GetEnvironmentVariable('Path', 'User')
63
+ $env:Path = (@($machine, $user) | Where-Object { $_ }) -join ';'
64
+ }
65
+
66
+ function Test-Tool([string]$Name) { return [bool](Get-Command $Name -ErrorAction SilentlyContinue) }
67
+
68
+ # Find a tool, or install it with winget and look again.
69
+ function Assert-Tool([string]$Name, [string]$WingetId, [string]$Url) {
70
+ if (Test-Tool $Name) { Say " found $Name"; return }
71
+ if ($DryRun) { Say " would install $Name ($WingetId)"; return }
72
+ if (-not (Test-Tool 'winget')) {
73
+ Stop-Setup "$Name is not installed, and this PC has no winget to install it with." "Install $Name from $Url, open a new PowerShell window, and paste the setup command again."
74
+ }
75
+ Say " installing $Name (Windows may ask you to allow it)..."
76
+ & winget install --id $WingetId -e --source winget --accept-package-agreements --accept-source-agreements --silent | Out-Null
77
+ Update-PathFromRegistry
78
+ if (-not (Test-Tool $Name)) {
79
+ Stop-Setup "$Name did not install." "Install $Name from $Url, open a new PowerShell window, and paste the setup command again."
80
+ }
81
+ Say " installed $Name"
82
+ }
83
+
84
+ # The whole setup, in the open (not a function): what node and git print must
85
+ # reach the person as it happens, and node must keep the keyboard for the Claude
86
+ # sign-in. A stop it can explain throws $StopMark and lands in the catch below.
87
+ $SetupExit = 1
88
+ try {
89
+ if (-not $Code -or -not $ApiBase -or -not $Repo) {
90
+ Stop-Setup 'the setup command is incomplete.' 'Copy the whole command again from Settings > Your Autobongos runner.'
91
+ }
92
+ if ($Repo -notmatch '^https://[A-Za-z0-9.-]+/[A-Za-z0-9._/-]+$') {
93
+ Stop-Setup 'the project address in the command does not look right.' 'Copy the whole command again from Settings > Your Autobongos runner.'
94
+ }
95
+ # The one-time code is sent to this address and the runner's login comes back
96
+ # from it, so it must be https. Plain http is for this machine alone (a
97
+ # developer's own instance); autobongos-host.js applies the same rule again.
98
+ if ($ApiBase -notmatch '^https://[A-Za-z0-9.-]+(:\d+)?/?$' -and $ApiBase -notmatch '^http://(localhost|127\.0\.0\.1)(:\d+)?/?$') {
99
+ Stop-Setup "the project's address in the command is not a secure (https) address." 'Copy the whole command again from Settings > Your Autobongos runner.'
100
+ }
101
+
102
+ Say 'Setting this PC up as an Autobongos runner.'
103
+ Say 'It gets its own copy of the project and its own sign-in; your own work on this PC is not touched.'
104
+ Say ''
105
+ Say 'Checking the three programs it needs...'
106
+ Assert-Tool 'git' 'Git.Git' 'https://git-scm.com/download/win'
107
+ Assert-Tool 'node' 'OpenJS.NodeJS.LTS' 'https://nodejs.org'
108
+
109
+ if (Test-Tool 'claude') {
110
+ Say ' found claude'
111
+ } elseif ($DryRun) {
112
+ Say ' would install Claude Code'
113
+ } else {
114
+ Say ' installing Claude Code...'
115
+ # npm.cmd, not npm: PowerShell blocks npm.ps1 by default (task 1005033).
116
+ & npm.cmd install -g '@anthropic-ai/claude-code' | Out-Null
117
+ Update-PathFromRegistry
118
+ if (-not (Test-Tool 'claude')) {
119
+ Stop-Setup 'Claude Code did not install.' 'Install it from https://claude.com/claude-code, open a new PowerShell window, and paste the setup command again.'
120
+ }
121
+ Say ' installed Claude Code'
122
+ }
123
+
124
+ $RepoDir = Join-Path $RunnerHome 'repo'
125
+ Say ''
126
+ if ($DryRun) {
127
+ Say "Would make the runner's copy of the project in $RepoDir and hand over to autobongos-host.js."
128
+ $SetupExit = 0
129
+ } else {
130
+
131
+ New-Item -ItemType Directory -Force -Path $RunnerHome | Out-Null
132
+ if (Test-Path (Join-Path $RepoDir '.git')) {
133
+ Say "The runner's copy is already here; bringing it up to date..."
134
+ & git -C $RepoDir fetch --quiet origin main
135
+ if ($LASTEXITCODE -ne 0) {
136
+ Stop-Setup "this PC could not fetch the project's code from GitHub." 'Sign in to GitHub when Windows asks, then paste the setup command again.'
137
+ }
138
+ & git -C $RepoDir reset --quiet --hard origin/main
139
+ } else {
140
+ Say "Making the runner's own copy of the project (GitHub may ask you to sign in)..."
141
+ & git clone --quiet $Repo $RepoDir
142
+ if ($LASTEXITCODE -ne 0) {
143
+ Stop-Setup 'this PC could not copy the project from GitHub.' 'Sign in to GitHub in the window that opens (use an account that can see the project), then paste the setup command again.'
144
+ }
145
+ }
146
+
147
+ $HostJs = Join-Path $RepoDir 'scripts\bongos\autobongos-host.js'
148
+ if (-not (Test-Path $HostJs)) {
149
+ Stop-Setup "the project's copy has no runner program in it." 'The project is on an older version. Ask the project owner to update it, then try again.'
150
+ }
151
+
152
+ $env:AUTOBONGOS_HOME = $RunnerHome
153
+ & node $HostJs setup --code $Code --api-base $ApiBase --mark-runner-copy
154
+ $SetupExit = $LASTEXITCODE
155
+
156
+ }
157
+ } catch {
158
+ if ("$($_.Exception.Message)" -ne $StopMark) {
159
+ Write-Host ''
160
+ Write-Host 'Autobongos setup stopped on something unexpected.' -ForegroundColor Yellow
161
+ Write-Host 'What to do: paste the setup command again. If it stops here twice, tell the project owner.'
162
+ }
163
+ $SetupExit = 1
164
+ }
165
+
166
+ # As a FILE, report the result the way a script does. PASTED (a script block has
167
+ # no file of its own), leave the window open and only record the result.
168
+ if ($MyInvocation.MyCommand.Path) { exit $SetupExit }
169
+ $global:LASTEXITCODE = $SetupExit