@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 +56 -21
- package/docs/adr/0307-autobongos-a-deterministic-supervisor-and-agentic-workers.md +30 -0
- package/docs/module-api-changelog.md +2 -0
- package/modules/autonomy/gauge.js +25 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +6 -0
- package/scripts/bongos/autobongos-bootstrap.ps1 +169 -0
- package/scripts/bongos/autobongos-bootstrap.sh +151 -0
- package/scripts/bongos/autobongos-host.js +869 -0
- package/scripts/bongos/autobongos-run.js +7 -1
- package/scripts/bongos/autonomy-gauge.js +11 -3
- package/scripts/bongos/cli-lib.js +5 -1
- package/scripts/gds/autobongos-bootstrap.ps1 +8 -0
- package/scripts/gds/autobongos-bootstrap.sh +8 -0
- package/scripts/gds/autobongos-host.js +7 -0
- package/src/instance-config.js +22 -3
- package/src/module-api.js +1 -1
- package/tests/autobongos_host.mjs +619 -0
- package/tests/autobongos_loop.mjs +11 -0
- package/tests/autonomy_gauge.mjs +43 -0
- package/tests/cli_sessions.mjs +16 -0
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.
|
|
6
|
-
"core_contract": "1.24.
|
|
7
|
-
"source_commit": "
|
|
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-
|
|
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":
|
|
14
|
+
"functional_verbatim": 3927,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
11950
|
+
"sha256": "3407de417eaa11f0f2234084d5355de1f4113089bea94c3c85b94c510ae46874"
|
|
11951
11951
|
},
|
|
11952
11952
|
{
|
|
11953
11953
|
"path": "package.json",
|
|
11954
11954
|
"mode": "0000644",
|
|
11955
|
-
"sha256": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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",
|
package/release-notes.json
CHANGED
|
@@ -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
|