@bongos/core 1.19.792 → 1.19.793
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 +17 -17
- package/.claude/skills/builder-reauth/SKILL.md +4 -4
- package/bin/bongos.js +12 -1
- package/docs/api/openapi.json +1 -1
- package/docs/module-api-changelog.md +2 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/paste-token.js +4 -2
- package/scripts/gds/reauth.js +2 -2
- package/src/bongos/routes/auth.js +10 -2
- package/src/module-api.js +1 -1
- package/tests/bongos_cli.mjs +28 -0
- package/tests/cli_token_reissue.mjs +29 -5
package/.bongos-core.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"artifact": "bongos-core",
|
|
3
3
|
"manifest_schema": 1,
|
|
4
4
|
"generator": "scripts/gds/package-core.js",
|
|
5
|
-
"core_version": "1.19.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.793",
|
|
6
|
+
"core_contract": "1.19.793",
|
|
7
|
+
"source_commit": "877a1e0befbf245c4ac50b28d0bc72c785dc9d27",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-09-17T00:
|
|
9
|
+
"built_at": "2026-09-17T00:41:15.216Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 486,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
19
|
"file_count": 2690,
|
|
20
|
-
"tree_sha256": "
|
|
20
|
+
"tree_sha256": "17b680447915370ad9005373e97e6a90d25f03ebdf58f52e2902501c26fe403a",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
{
|
|
78
78
|
"path": ".claude/skills/builder-reauth/SKILL.md",
|
|
79
79
|
"mode": "0000644",
|
|
80
|
-
"sha256": "
|
|
80
|
+
"sha256": "f54f3355d1f034fe99735a73ce62936d7d1582e751754bbe12023a4bf8a2d17c"
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
"path": ".claude/skills/builder-redteam/SKILL.md",
|
|
@@ -342,7 +342,7 @@
|
|
|
342
342
|
{
|
|
343
343
|
"path": "bin/bongos.js",
|
|
344
344
|
"mode": "0000644",
|
|
345
|
-
"sha256": "
|
|
345
|
+
"sha256": "36d11612cace3d69bd2e98c8f7b5b7d737d8bba5fd8fe1a0554a85e3cb1973ca"
|
|
346
346
|
},
|
|
347
347
|
{
|
|
348
348
|
"path": "clients/bongos-client/README.md",
|
|
@@ -1972,7 +1972,7 @@
|
|
|
1972
1972
|
{
|
|
1973
1973
|
"path": "docs/api/openapi.json",
|
|
1974
1974
|
"mode": "0000644",
|
|
1975
|
-
"sha256": "
|
|
1975
|
+
"sha256": "1442772c691bb7447cb13e4e63b062dd41913d8bb06555cee814069434556ae5"
|
|
1976
1976
|
},
|
|
1977
1977
|
{
|
|
1978
1978
|
"path": "docs/architecture.md",
|
|
@@ -2527,7 +2527,7 @@
|
|
|
2527
2527
|
{
|
|
2528
2528
|
"path": "docs/module-api-changelog.md",
|
|
2529
2529
|
"mode": "0000644",
|
|
2530
|
-
"sha256": "
|
|
2530
|
+
"sha256": "5a46ed6753d0b49d3a65f6f58972a5159a115ac6fa0022d628942cb48b80be95"
|
|
2531
2531
|
},
|
|
2532
2532
|
{
|
|
2533
2533
|
"path": "docs/modules-contract.md",
|
|
@@ -7692,12 +7692,12 @@
|
|
|
7692
7692
|
{
|
|
7693
7693
|
"path": "package-lock.json",
|
|
7694
7694
|
"mode": "0000644",
|
|
7695
|
-
"sha256": "
|
|
7695
|
+
"sha256": "88ee2ff930be2d84d19733724ddfeee1842cba1b890422713c9012466fa0739a"
|
|
7696
7696
|
},
|
|
7697
7697
|
{
|
|
7698
7698
|
"path": "package.json",
|
|
7699
7699
|
"mode": "0000644",
|
|
7700
|
-
"sha256": "
|
|
7700
|
+
"sha256": "f7f66eb317b78a0b652addc0c31a67500a80ed2109807a89898128d6a15a481b"
|
|
7701
7701
|
},
|
|
7702
7702
|
{
|
|
7703
7703
|
"path": "public-docs/index.html",
|
|
@@ -8532,7 +8532,7 @@
|
|
|
8532
8532
|
{
|
|
8533
8533
|
"path": "scripts/gds/paste-token.js",
|
|
8534
8534
|
"mode": "0000644",
|
|
8535
|
-
"sha256": "
|
|
8535
|
+
"sha256": "423b356f7ff60913af72ce2042fb8dd2fcefa26375864dbb428cb4e3b527bb82"
|
|
8536
8536
|
},
|
|
8537
8537
|
{
|
|
8538
8538
|
"path": "scripts/gds/portability-smoke-art.sh",
|
|
@@ -8637,7 +8637,7 @@
|
|
|
8637
8637
|
{
|
|
8638
8638
|
"path": "scripts/gds/reauth.js",
|
|
8639
8639
|
"mode": "0000644",
|
|
8640
|
-
"sha256": "
|
|
8640
|
+
"sha256": "ce20f84be283f2a97df7d410b56b40d1e0cd14be8349acc418aa645d702f4f45"
|
|
8641
8641
|
},
|
|
8642
8642
|
{
|
|
8643
8643
|
"path": "scripts/gds/recall.js",
|
|
@@ -9467,7 +9467,7 @@
|
|
|
9467
9467
|
{
|
|
9468
9468
|
"path": "src/bongos/routes/auth.js",
|
|
9469
9469
|
"mode": "0000644",
|
|
9470
|
-
"sha256": "
|
|
9470
|
+
"sha256": "a45868b46ab96fdedab3e7359259527e2d75e65b86a916865e5fff358f88a3b3"
|
|
9471
9471
|
},
|
|
9472
9472
|
{
|
|
9473
9473
|
"path": "src/bongos/routes/backup.js",
|
|
@@ -9577,7 +9577,7 @@
|
|
|
9577
9577
|
{
|
|
9578
9578
|
"path": "src/module-api.js",
|
|
9579
9579
|
"mode": "0000644",
|
|
9580
|
-
"sha256": "
|
|
9580
|
+
"sha256": "7db202b3ac70a0404e7cc0067828bb9d41eed6bfddf760e325773f629cd09dfc"
|
|
9581
9581
|
},
|
|
9582
9582
|
{
|
|
9583
9583
|
"path": "src/module-loader/catalog.js",
|
|
@@ -10012,7 +10012,7 @@
|
|
|
10012
10012
|
{
|
|
10013
10013
|
"path": "tests/bongos_cli.mjs",
|
|
10014
10014
|
"mode": "0000644",
|
|
10015
|
-
"sha256": "
|
|
10015
|
+
"sha256": "ef01af16d62c55325a3b12cc7968a9d797994d2f46364149668bf4e2839cb0e0"
|
|
10016
10016
|
},
|
|
10017
10017
|
{
|
|
10018
10018
|
"path": "tests/bongos_dispatch.mjs",
|
|
@@ -10292,7 +10292,7 @@
|
|
|
10292
10292
|
{
|
|
10293
10293
|
"path": "tests/cli_token_reissue.mjs",
|
|
10294
10294
|
"mode": "0000644",
|
|
10295
|
-
"sha256": "
|
|
10295
|
+
"sha256": "a82544c109464d884e44731cbdd73e9e141d31d8e18a9241222d6a26223e19c2"
|
|
10296
10296
|
},
|
|
10297
10297
|
{
|
|
10298
10298
|
"path": "tests/client_baseurl_guard.mjs",
|
|
@@ -25,10 +25,10 @@ What actually bounds a leaked token is **revocation**, and it is faster than any
|
|
|
25
25
|
2. **Relay the click-path verbatim.** The helper prints the exact steps; pass them to the user clearly (don't paraphrase the URL):
|
|
26
26
|
- Open `https://example.com/builders/settings` (the helper tries to open it automatically; if not, give them the link).
|
|
27
27
|
- They are already signed in there via the browser cookie. Under the **"CLI Access"** section, click **"Re-issue CLI token"**.
|
|
28
|
-
- Click **"Copy"** — it copies a one-line command of the form `
|
|
28
|
+
- Click **"Copy"** — it copies a one-line command of the form `bongos paste-token <token>`.
|
|
29
29
|
- Ask them to **paste that one line back into the chat**.
|
|
30
30
|
|
|
31
|
-
3. **Run the pasted command.** When the user pastes `
|
|
31
|
+
3. **Run the pasted command.** When the user pastes `bongos paste-token <token>`, run it exactly as given. `paste-token.js` verifies the token against `/api/gds/me` **before** touching the session file (a bad paste leaves the existing session intact) and preserves any `gemini_api_key`. On success it prints the builder login, rank, and confirms the session file was written.
|
|
32
32
|
|
|
33
33
|
4. **Confirm.** Relay the authenticated identity + rank back to the user, and tell them they can now re-run whatever `/builder-*` command they were trying.
|
|
34
34
|
|
|
@@ -41,13 +41,13 @@ What actually bounds a leaked token is **revocation**, and it is faster than any
|
|
|
41
41
|
|
|
42
42
|
## Constraints
|
|
43
43
|
|
|
44
|
-
- **The token briefly transits the chat — that's the known cost of guided-paste.** The user pastes `
|
|
44
|
+
- **The token briefly transits the chat — that's the known cost of guided-paste.** The user pastes `bongos paste-token <token>` into the conversation, so the bearer appears in the chat (and any log/context that captures it). That's the accepted trade-off Lars chose; the deferred zero-paste loopback flow removes it. So: treat the session log as sensitive, **never echo the token beyond running that one pasted command**, and never write it to any file other than `~/.config/otb/gds-session.json` (`paste-token.js` is the only thing that should write it — let it do the write). The token rotates whenever the builder clicks Re-issue again, so re-running this flow invalidates an exposed paste's usefulness for an attacker who lacks the browser cookie.
|
|
45
45
|
- **Don't re-auth a valid session.** If `reauth.js` exits 0, stop.
|
|
46
46
|
- **`GDS_API_BASE`** overrides the endpoint (default `https://example.com`); for local dev `GDS_API_BASE=http://localhost:3000`.
|
|
47
47
|
|
|
48
48
|
## Files this skill touches
|
|
49
49
|
|
|
50
50
|
- Runs: `node scripts/gds/reauth.js` (detect + open browser + print click-path)
|
|
51
|
-
- Runs: `
|
|
51
|
+
- Runs: `bongos paste-token <token>` (verify + write the new session)
|
|
52
52
|
- Reads/Writes (via paste-token.js): `~/.config/otb/gds-session.json`
|
|
53
53
|
- Calls: `GET /api/gds/me`; the Settings page (CLI Access) calls `POST /api/gds/auth/cli-token/issue`
|
package/bin/bongos.js
CHANGED
|
@@ -47,6 +47,10 @@ const BUNDLED_RUNNERS = {
|
|
|
47
47
|
'login.js': () => require('../scripts/gds/login.js'),
|
|
48
48
|
'setup.js': () => require('../scripts/gds/setup.js'),
|
|
49
49
|
'reauth.js': () => require('../scripts/gds/reauth.js'),
|
|
50
|
+
// Bundled for the same reason as reauth: they are two halves of one on-ramp
|
|
51
|
+
// (mint the token, then store it), and a builder recovering a dead session on a
|
|
52
|
+
// bare laptop has the standalone binary and nothing else (task 1003961).
|
|
53
|
+
'paste-token.js': () => require('../scripts/gds/paste-token.js'),
|
|
50
54
|
'api.js': () => require('../scripts/gds/api.js'),
|
|
51
55
|
'shell.js': () => require('../scripts/gds/shell.js'),
|
|
52
56
|
'code.js': () => require('../scripts/gds/code.js'),
|
|
@@ -84,6 +88,13 @@ const VERBS = {
|
|
|
84
88
|
login: { script: 'login.js', group: 'account', summary: 'Sign in to an instance (bongos login <url> — browser click, no paste)' },
|
|
85
89
|
setup: { script: 'setup.js', group: 'account', summary: 'Full builder setup on this instance (art key, disciplines, consent)' },
|
|
86
90
|
reauth: { script: 'reauth.js', group: 'account', summary: 'Refresh your session' },
|
|
91
|
+
// The second half of `reauth`: the hall mints a token, this stores it. A VERB
|
|
92
|
+
// rather than a path because the string is emitted by the SERVER and pasted on
|
|
93
|
+
// an INSTANCE, where `scripts/gds/` does not exist — the core is a dependency
|
|
94
|
+
// there, so the old `node scripts/gds/paste-token.js <token>` named a file the
|
|
95
|
+
// builder did not have (task 1003961). A verb also makes it allow-listable by
|
|
96
|
+
// name, the way claim/ship/release already are (ADR 0104).
|
|
97
|
+
'paste-token': { script: 'paste-token.js', group: 'account', summary: 'Finish re-auth: store the token copied from Settings (bongos paste-token <token>)' },
|
|
87
98
|
doctor: { script: 'doctor.js', group: 'account', summary: 'Check your local toolchain + session' },
|
|
88
99
|
box: { script: 'api.js', prefixArgs: ['POST', '/api/gds/box/ensure'], group: 'account', summary: 'Turn on / wake your cloud dev box' },
|
|
89
100
|
shell: { script: 'shell.js', group: 'account', summary: 'Open a terminal on your dev box (--local for a local clone)' },
|
|
@@ -239,7 +250,7 @@ function runBundled(verb, def, forwarded) {
|
|
|
239
250
|
` bongos code open VS Code on your cloud dev box (has everything)\n` +
|
|
240
251
|
` bongos shell open a terminal on your cloud dev box\n` +
|
|
241
252
|
` bongos init scaffold a new instance here\n\n` +
|
|
242
|
-
`The standalone binary covers the on-ramp: login, box, shell, code, init, reauth.\n`
|
|
253
|
+
`The standalone binary covers the on-ramp: login, box, shell, code, init, reauth, paste-token.\n`
|
|
243
254
|
);
|
|
244
255
|
return 2;
|
|
245
256
|
}
|
package/docs/api/openapi.json
CHANGED
|
@@ -1329,7 +1329,7 @@
|
|
|
1329
1329
|
"auth"
|
|
1330
1330
|
],
|
|
1331
1331
|
"summary": "POST /auth/cli-token/issue",
|
|
1332
|
-
"description": "POST /auth/cli-token/issue — V3.R91 / task 401. Issue a fresh CLI bearer for the requesting builder, gated on a WEB COOKIE session (not a bearer). The browser already proves identity via the gds_session cookie; this endpoint mints a separate cli-source session row the builder can paste into ~/.config/otb/gds-session.json via
|
|
1332
|
+
"description": "POST /auth/cli-token/issue — V3.R91 / task 401. Issue a fresh CLI bearer for the requesting builder, gated on a WEB COOKIE session (not a bearer). The browser already proves identity via the gds_session cookie; this endpoint mints a separate cli-source session row the builder can paste into ~/.config/otb/gds-session.json via `bongos paste-token`. Replaces the ~30-60s Device Flow when the CLI bearer has expired. rank: any-builder (own identity only) — no rank gate. auth source restriction: cookie ONLY. A bearer cannot mint a new bearer (a leaked CLI token shouldn't be able to extend its own lifetime; the httpOnly browser cookie is the harder-to-steal credential).\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
|
|
1333
1333
|
"x-rank": "any-builder",
|
|
1334
1334
|
"x-source": "src/bongos/routes/auth.js",
|
|
1335
1335
|
"responses": {
|
|
@@ -2058,5 +2058,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
2058
2058
|
landed since 1.19.790 with no explicit bump. run 35165066743. (task 1002620)
|
|
2059
2059
|
1.19.792 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2060
2060
|
landed since 1.19.791 with no explicit bump. run 35166486577. (task 1002620)
|
|
2061
|
+
1.19.793 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2062
|
+
landed since 1.19.792 with no explicit bump. run 35167484049. (task 1002620)
|
|
2061
2063
|
---------------------------------------------------------------------------
|
|
2062
2064
|
```
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.793",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.19.
|
|
9
|
+
"version": "1.19.793",
|
|
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.19.
|
|
3
|
+
"version": "1.19.793",
|
|
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",
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
// paste never silently un-registers a builder's Gemini key.
|
|
8
8
|
//
|
|
9
9
|
// Usage:
|
|
10
|
-
//
|
|
10
|
+
// bongos paste-token <token> # what the hall hands you (task 1003961)
|
|
11
|
+
// node scripts/gds/paste-token.js <token> # equivalent, inside a core checkout
|
|
11
12
|
//
|
|
12
13
|
// The portal returns the exact invocation as the "paste_command" field, so a
|
|
13
14
|
// builder can copy + paste a single line.
|
|
@@ -42,7 +43,8 @@ const API_BASE = ic.resolveApiBase();
|
|
|
42
43
|
function usage(extra) {
|
|
43
44
|
if (extra) console.error(extra);
|
|
44
45
|
console.error('');
|
|
45
|
-
console.error('Usage:
|
|
46
|
+
console.error('Usage: bongos paste-token <token>');
|
|
47
|
+
console.error(' (inside a core checkout: node scripts/gds/paste-token.js <token>)');
|
|
46
48
|
console.error('');
|
|
47
49
|
console.error('Get a token on your Settings page: ' + API_BASE + '/builders/settings');
|
|
48
50
|
console.error('— under "CLI Access" click "Re-issue CLI token" (you must be signed in).');
|
package/scripts/gds/reauth.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
// 2. Guide — open the builder's Settings page in the default browser (where
|
|
18
18
|
// the builder is already signed in via the httpOnly cookie) and print the
|
|
19
19
|
// exact click-path: Settings → CLI Access → Re-issue CLI token → Copy.
|
|
20
|
-
// The page hands back a one-liner: `
|
|
20
|
+
// The page hands back a one-liner: `bongos paste-token
|
|
21
21
|
// <token>`. The builder pastes that one line back into Claude; the
|
|
22
22
|
// /builder-reauth skill runs it (paste-token.js verifies + writes safely).
|
|
23
23
|
//
|
|
@@ -96,7 +96,7 @@ function printGuidance({ opened }) {
|
|
|
96
96
|
console.log(" you're already signed in there via your browser cookie)");
|
|
97
97
|
console.log(' 2. Under the "CLI Access" section, click "Re-issue CLI token".');
|
|
98
98
|
console.log(' 3. Click "Copy" — it copies a one-line command that looks like:');
|
|
99
|
-
console.log('
|
|
99
|
+
console.log(' bongos paste-token <token>');
|
|
100
100
|
console.log(' 4. Paste that one line back to Claude. It will run it for you,');
|
|
101
101
|
console.log(' verify the token, and write your new session.');
|
|
102
102
|
console.log('');
|
|
@@ -1025,7 +1025,7 @@ module.exports = function buildAuthRouter() {
|
|
|
1025
1025
|
// the requesting builder, gated on a WEB COOKIE session (not a bearer). The
|
|
1026
1026
|
// browser already proves identity via the gds_session cookie; this endpoint
|
|
1027
1027
|
// mints a separate cli-source session row the builder can paste into
|
|
1028
|
-
// ~/.config/otb/gds-session.json via
|
|
1028
|
+
// ~/.config/otb/gds-session.json via `bongos paste-token`. Replaces
|
|
1029
1029
|
// the ~30-60s Device Flow when the CLI bearer has expired.
|
|
1030
1030
|
//
|
|
1031
1031
|
// rank: any-builder (own identity only) — no rank gate.
|
|
@@ -1058,7 +1058,15 @@ module.exports = function buildAuthRouter() {
|
|
|
1058
1058
|
token,
|
|
1059
1059
|
expires_at: row.expires_at,
|
|
1060
1060
|
builder_login: req.builder.github_login,
|
|
1061
|
-
|
|
1061
|
+
// A VERB, never a path (task 1003961). This string is composed HERE and run
|
|
1062
|
+
// THERE — on an instance, where the core is an installed dependency and
|
|
1063
|
+
// `scripts/gds/` does not exist, so the previous
|
|
1064
|
+
// `node scripts/gds/paste-token.js <token>` named a file the builder did not
|
|
1065
|
+
// have and the copy button handed out a command that could not run. `bongos`
|
|
1066
|
+
// is on PATH in any installed instance, so the verb form is layout- and
|
|
1067
|
+
// directory-independent. Same discipline as configuredOAuthOrigin() above:
|
|
1068
|
+
// nothing about the RECIPIENT's filesystem may be assumed here.
|
|
1069
|
+
paste_command: `bongos paste-token ${token}`,
|
|
1062
1070
|
});
|
|
1063
1071
|
} catch (err) {
|
|
1064
1072
|
log.error('[gds] POST /auth/cli-token/issue', err);
|
package/src/module-api.js
CHANGED
|
@@ -71,7 +71,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
|
|
|
71
71
|
// there. scripts/gds/bump-version.js still rewrites the literal below; it appends
|
|
72
72
|
// the entry to that file. Look for a version's history there, not here.
|
|
73
73
|
// ---------------------------------------------------------------------------
|
|
74
|
-
const CORE_VERSION = '1.19.
|
|
74
|
+
const CORE_VERSION = '1.19.793'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
75
75
|
|
|
76
76
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
77
77
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
package/tests/bongos_cli.mjs
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import { strict as assert } from 'node:assert';
|
|
14
14
|
import { createRequire } from 'node:module';
|
|
15
15
|
import { spawnSync } from 'node:child_process';
|
|
16
|
+
import { readFileSync } from 'node:fs';
|
|
16
17
|
import { fileURLToPath } from 'node:url';
|
|
17
18
|
import { dirname, join } from 'node:path';
|
|
18
19
|
|
|
@@ -43,6 +44,33 @@ test('verbHelpText: names the verb, its summary, and the full-help pointer', ()
|
|
|
43
44
|
assert.match(out, /bongos help/);
|
|
44
45
|
});
|
|
45
46
|
|
|
47
|
+
// task 1003961 — the hall's re-auth copy button emits `bongos paste-token <token>`.
|
|
48
|
+
// That string is composed by the SERVER and run on an INSTANCE, so the verb has to
|
|
49
|
+
// exist here or the one-click path dead-ends on "unknown command". Pinned against
|
|
50
|
+
// the routes file so the two halves cannot drift apart.
|
|
51
|
+
test('paste-token is a registered verb wired to paste-token.js', () => {
|
|
52
|
+
const def = cli.VERBS['paste-token'];
|
|
53
|
+
assert.ok(def, 'bongos paste-token must be a registered verb');
|
|
54
|
+
assert.equal(def.script, 'paste-token.js');
|
|
55
|
+
assert.equal(def.group, 'account', 'it belongs with the other session verbs');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('paste-token is bundled into the standalone binary, like reauth', () => {
|
|
59
|
+
// Two halves of one on-ramp: reauth mints the token, paste-token stores it.
|
|
60
|
+
// A builder recovering a dead session on a bare laptop has only the binary.
|
|
61
|
+
assert.ok(cli.BUNDLED_RUNNERS['paste-token.js'],
|
|
62
|
+
'paste-token.js must be in BUNDLED_RUNNERS or the compiled binary refuses the verb');
|
|
63
|
+
assert.ok(cli.BUNDLED_RUNNERS['reauth.js'], 'reauth is the sibling this mirrors');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('the server emits exactly the verb the CLI registers', () => {
|
|
67
|
+
const routes = readFileSync(join(dirname(fileURLToPath(import.meta.url)), '..', 'src', 'bongos', 'routes', 'auth.js'), 'utf8');
|
|
68
|
+
const m = routes.match(/paste_command:\s*`([^`]+)`/);
|
|
69
|
+
assert.ok(m, 'auth.js should emit a paste_command template literal');
|
|
70
|
+
const verb = m[1].split(' ')[1];
|
|
71
|
+
assert.ok(cli.VERBS[verb], `server emits "bongos ${verb}" but the CLI has no such verb`);
|
|
72
|
+
});
|
|
73
|
+
|
|
46
74
|
test('VERBS: selfHelp is only claimed by scripts that really print their own usage', () => {
|
|
47
75
|
// Verified by reading each script (they all branch on --help/-h to a usage()
|
|
48
76
|
// printer). If a verb is added here, verify its script first — a wrong
|
|
@@ -119,16 +119,23 @@ const issueBlock = (() => {
|
|
|
119
119
|
return routeSrc.slice(start, start + 3000);
|
|
120
120
|
})();
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
// Refreshed for the current handler (task 1003961). These two assertions named
|
|
123
|
+
// `parseCookie(req, SESSION_COOKIE)` and `res.status(403)`, the shape BEFORE the
|
|
124
|
+
// handler moved to the `sessionCookieToken` helper and the `res.fail` envelope.
|
|
125
|
+
// They had been red on main ever since — invisible, because this file is in the
|
|
126
|
+
// runner's INTEGRATION set and self-skips in CI's DB-free lane. Left alone they
|
|
127
|
+
// would have masked the new assertions below: a file that is already red cannot
|
|
128
|
+
// tell you whether the test you just added passes.
|
|
129
|
+
t("the issue handler reads the session COOKIE (not just Authorization)", () => {
|
|
130
|
+
assert.ok(issueBlock.includes('sessionCookieToken(req)'),
|
|
131
|
+
'handler must resolve the browser cookie via sessionCookieToken(req)');
|
|
125
132
|
});
|
|
126
133
|
|
|
127
134
|
t('the issue handler rejects bearer-only callers with cookie_required', () => {
|
|
128
135
|
assert.ok(issueBlock.includes("cookie_required"),
|
|
129
136
|
"error code 'cookie_required' missing");
|
|
130
|
-
assert.ok(/status
|
|
131
|
-
'must respond
|
|
137
|
+
assert.ok(/status:\s*403/.test(issueBlock),
|
|
138
|
+
'must respond 403 when the cookie is missing (res.fail envelope carries `status: 403`)');
|
|
132
139
|
});
|
|
133
140
|
|
|
134
141
|
t("mints a session with source='cli' (CHECK constraint compliant)", () => {
|
|
@@ -141,6 +148,23 @@ t('returns a paste_command field the portal can show verbatim', () => {
|
|
|
141
148
|
'response should include paste_command for one-click UX');
|
|
142
149
|
});
|
|
143
150
|
|
|
151
|
+
// The regression this pins (task 1003961): paste_command is composed on the SERVER
|
|
152
|
+
// and run on an INSTANCE, where the core is an installed dependency and there is no
|
|
153
|
+
// `scripts/gds/` directory. Emitting a repo-relative script path handed every
|
|
154
|
+
// instance builder a command naming a file they did not have. A verb has no such
|
|
155
|
+
// coupling — `bongos` is on PATH wherever the core is installed.
|
|
156
|
+
t('paste_command names a CLI VERB, never a filesystem path', () => {
|
|
157
|
+
const m = issueBlock.match(/paste_command:\s*`([^`]+)`/);
|
|
158
|
+
assert.ok(m, 'paste_command should be a template literal the test can read');
|
|
159
|
+
const cmd = m[1];
|
|
160
|
+
assert.ok(/^bongos paste-token /.test(cmd),
|
|
161
|
+
`paste_command must start with the verb form, got: ${cmd}`);
|
|
162
|
+
assert.ok(!cmd.includes('/'),
|
|
163
|
+
`paste_command must contain no path separator — it runs where the layout differs. Got: ${cmd}`);
|
|
164
|
+
assert.ok(!/\bnode\b/.test(cmd),
|
|
165
|
+
`paste_command must not invoke node directly (that assumes a script on disk). Got: ${cmd}`);
|
|
166
|
+
});
|
|
167
|
+
|
|
144
168
|
// ---------------------------------------------------------------------------
|
|
145
169
|
|
|
146
170
|
console.log(`\n${passed} passed, ${failed} failed`);
|