@bongos/core 1.21.48 → 1.21.50

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.
@@ -808,11 +808,11 @@
808
808
  ? `Stuck on any step? <a href="${API}/auth/discord/start">Join our Discord</a> and ask in <strong>#support</strong>.`
809
809
  : `Stuck on any step? See the project's README and docs.`;
810
810
  const setupSteps = `
811
- <p class="setup__intro">Build from your own machine — clone the repository, run the platform locally, and sign in from the terminal.</p>
811
+ <p class="setup__intro">Build from your own machine — get a copy of the project, sign in once, then work in Claude.</p>
812
812
  <ol class="setup__steps">
813
813
  <li><strong>Clone the repository</strong> and install dependencies (<code>npm install</code>).</li>
814
- <li><strong><a href="https://claude.com/download" target="_blank" rel="noopener noreferrer">Download Claude</a></strong> (or use the Claude Code CLI) and open the project.</li>
815
- <li><strong>Run <code>/builder-setup</code></strong> to authenticate this machine, then <code>/builder-start</code> to claim your first task.</li>
814
+ <li><strong>Run <code>npx bongos setup</code></strong> in that folder to sign this machine in.</li>
815
+ <li><strong><a href="https://claude.com/download" target="_blank" rel="noopener noreferrer">Download Claude</a></strong> (or use the Claude Code CLI), open the project, and run <code>/builder-start</code> to claim your first task.</li>
816
816
  </ol>
817
817
  `;
818
818
  // task 469: a "Set up your machine / get the code" door. The steps above
@@ -821,24 +821,26 @@
821
821
  // how do I get it onto my own laptop?". It's the hall mirror of the primer's
822
822
  // "Step 0 — get the project onto your machine". Collapsed by default so it
823
823
  // doesn't crowd the recommended path; the clone block is click-to-copy
824
- // (copy-on-click.js picks up .welcome__paste). The commands mirror
825
- // scripts/setup-builder.sh's own header verbatim so they can't drift.
824
+ // (copy-on-click.js picks up .welcome__paste). Sign-in is `npx bongos setup`
825
+ // (bin/bongos.js → scripts/gds/setup.js), one line on every OS — bare
826
+ // `bongos` is not on a fresh clone's PATH, `npx` finds the repo's own bin.
826
827
  // The clone commands come from the instance's own repo coords (loaded from
827
828
  // GET /api/bongos/instance), not a hardcoded repo, so a fresh instance's newcomer
828
829
  // clones ITS project (ADR 0062 §3, task 1705). Falls back to generic guidance
829
830
  // until the coords load (or if they're unavailable).
830
831
  const cloneBlock = ctx.instanceRepo
831
- ? `git clone ${escapeHtml(ctx.instanceRepo.url)}.git\ncd ${escapeHtml(ctx.instanceRepo.repo)}\n./scripts/setup-builder.sh`
832
- : `# clone your instance's repository, cd into it, then run:\n./scripts/setup-builder.sh`;
832
+ ? `git clone ${escapeHtml(ctx.instanceRepo.url)}.git\ncd ${escapeHtml(ctx.instanceRepo.repo)}\nnpm install\nnpx bongos setup`
833
+ : `# clone your instance's repository, cd into it, then run:\nnpm install\nnpx bongos setup`;
833
834
  const getCode = `
834
835
  <details class="setup__getcode">
835
836
  <summary class="setup__getcode-summary">Set up your machine / get the code</summary>
836
837
  <div class="setup__getcode-body">
837
- <p class="setup__hint">First install <a href="https://git-scm.com/downloads" target="_blank" rel="noopener noreferrer">Git</a>
838
+ <p class="setup__hint">First install <a href="https://git-scm.com/downloads" target="_blank" rel="noopener noreferrer">Git</a>,
839
+ <a href="https://nodejs.org" target="_blank" rel="noopener noreferrer">Node</a> (version 22 or newer)
838
840
  and <a href="https://claude.com/download" target="_blank" rel="noopener noreferrer">Claude Code</a> — that's all the tooling you need up front.</p>
839
- <p class="setup__getcode-lede">Then copy the project onto your machine and run the one-shot bootstrap (it checks your setup, installs dependencies, and signs you in):</p>
841
+ <p class="setup__getcode-lede">Then copy the project onto your machine, install its dependencies, and sign in:</p>
840
842
  <code class="welcome__paste">${cloneBlock}</code>
841
- <p class="setup__hint">On Windows, run <code>node scripts/setup-builder.js</code> instead of the last line. New to the steps? The
843
+ <p class="setup__hint">The same commands work on Mac, Windows and Linux. New to the steps? The
842
844
  <a href="/primer">primer</a> walks the whole path in plain language.</p>
843
845
  </div>
844
846
  </details>`;
@@ -898,7 +900,7 @@
898
900
  <span class="onboarding-item__mark" aria-hidden="true">›</span>
899
901
  <div class="onboarding-item__body">
900
902
  <p class="onboarding-item__label">First — obtain the repo</p>
901
- <p class="onboarding-item__hint">Clone the project to your machine. The build commands live inside the repo, so this comes first. The remaining steps below are tracked automatically.</p>
903
+ <p class="onboarding-item__hint">Clone the project to your machine and run <code>npm install</code> in it. The build commands live inside the repo, so this comes first. The remaining steps below are tracked automatically.</p>
902
904
  </div>
903
905
  </li>`;
904
906
 
@@ -140,13 +140,13 @@
140
140
  <section class="scroll" id="cli-scroll" aria-labelledby="cli-h" data-group="access" hidden>
141
141
  <h2 id="cli-h" class="scroll__h">CLI access</h2>
142
142
  <p class="scroll__lede">
143
- Mint a fresh CLI token using this browser session and paste it into
144
- your terminal — the quick way back in when a <code>/builder-*</code>
145
- command says your session expired.
143
+ Mint a fresh CLI token using this browser session and paste the
144
+ command it gives you into a terminal in your project folder — the quick
145
+ way back in when a <code>/builder-*</code> command says your session expired.
146
146
  </p>
147
147
  <div class="settings-card">
148
148
  <button type="button" class="settings-btn" id="cli-reissue-btn">Re-issue CLI token</button>
149
- <span class="settings-card__hint">paste it into your terminal — bypasses Device Flow.</span>
149
+ <span class="settings-card__hint">no GitHub code to type in.</span>
150
150
  <div id="cli-reissue-result" class="cli-result" hidden></div>
151
151
  </div>
152
152
  <p class="section-note">Tokens refresh on use; re-issuing never signs you out anywhere else.</p>
@@ -792,7 +792,7 @@
792
792
  // three out of the copy registry, blinding the artist's queue to this panel.
793
793
  const el = (tag, cls) => Object.assign(document.createElement(tag), { className: cls });
794
794
  const say = el('p', 'cli-result__say');
795
- say.textContent = 'Fresh CLI token issued. Paste it in your terminal:';
795
+ say.textContent = 'Fresh CLI token issued. Paste this into a terminal in your project folder:';
796
796
  const eyebrow = el('p', 'quote__eyebrow');
797
797
  eyebrow.textContent = 'paste command';
798
798
  const pre = el('pre', 'quote__pre');
@@ -3206,6 +3206,15 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
3206
3206
  padding: 8px 12px;
3207
3207
  overflow-x: auto;
3208
3208
  }
3209
+ /* The get-the-code block is several commands, one per line. Without `pre` the
3210
+ line breaks collapse on screen AND in copy-on-click (it copies innerText),
3211
+ so a builder pasted every command onto one line. Both axes named: see the
3212
+ one-axis-strip rule in this module's CLAUDE.md. */
3213
+ .setup__getcode .welcome__paste {
3214
+ display: block;
3215
+ white-space: pre;
3216
+ overflow-y: hidden;
3217
+ }
3209
3218
 
3210
3219
  .setup { margin-top: 12px; }
3211
3220
  .setup__intro { font-size: 13px; color: var(--ink-soft); }
@@ -92,7 +92,7 @@ const ALL_STAGES = [...STAGES, GRADUATED];
92
92
  const PRE_AUTH_STEP = {
93
93
  id: 'obtain_repo',
94
94
  label: 'Obtain the repo',
95
- hint: 'Clone the project to thy machine. The build commands live inside the repo, so this comes first.',
95
+ hint: 'Clone the project to thy machine and run npm install in it. The build commands live inside the repo, so this comes first.',
96
96
  informational: true,
97
97
  };
98
98
 
@@ -126,7 +126,7 @@ const STAGE_LABELS = {
126
126
  // onboarding model never named that step, so the hint now points at it ahead of
127
127
  // the sign-in itself. See PRE_AUTH_STEP below for the standalone representation.
128
128
  const STAGE_HINTS = {
129
- auth_complete: 'First obtain the repo — clone it — then sign in via GitHub Device Flow or the web sign-in.',
129
+ auth_complete: 'First obtain the repo — clone it — then sign in with npx bongos setup in that folder.',
130
130
  pick_disciplines: 'Pick the work that calls thee — engineer, artist, ideator, or any mix.',
131
131
  first_start: 'Run /builder-start to see claimable works.',
132
132
  first_claim: 'Claim a task with /builder-claim N — it is thine alone until thou shippest it.',
@@ -153,7 +153,7 @@ function isKnownStage(stage) {
153
153
  // clears the step. `source: 'discord'`.
154
154
  // 2. pick_disciplines — the real engine stage, cleared by the craft picker.
155
155
  // 3. cli_setup — cleared once the builder has authenticated the CLI
156
- // (ran /builder-setup, which mints a source='cli'
156
+ // (ran `npx bongos setup`, which mints a source='cli'
157
157
  // session). Detected via db.hasCliSession; passed in as
158
158
  // `cliAuthed`. `source: 'cli'`.
159
159
  // 4. ship_three — the real engine stage. Auto, live "N of 3" counter,
@@ -178,14 +178,14 @@ const DISPLAY_STEPS = [
178
178
  const DISPLAY_LABELS = {
179
179
  join_discord: 'Join the Discord server',
180
180
  pick_disciplines: 'Choose thy craft — engineer, artist, or ideator',
181
- cli_setup: 'Run /builder-setup',
181
+ cli_setup: 'Run npx bongos setup',
182
182
  ship_three: 'Ship three works — and rise to Thetes',
183
183
  };
184
184
 
185
185
  const DISPLAY_HINTS = {
186
186
  join_discord: 'Connect Discord — thou art auto-joined to the city\'s server and given thy rank.',
187
187
  pick_disciplines: 'Pick the work that calls thee — engineer, artist, ideator, or any mix.',
188
- cli_setup: 'Sign the CLI in with /builder-setup — this ticks itself once thou art signed in.',
188
+ cli_setup: 'In thy copy of the project, run npx bongos setup — this ticks itself once thou art signed in.',
189
189
  ship_three: 'Carry three tasks through with /builder-ship — the third makes thee a Thetes.',
190
190
  };
191
191
 
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.21.48",
3
+ "version": "1.21.50",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.21.48",
9
+ "version": "1.21.50",
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.21.48",
3
+ "version": "1.21.50",
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",
@@ -9056,5 +9056,17 @@
9056
9056
  "id": "1004573",
9057
9057
  "text": "A project brought in from an existing repo now always picks up the sign-in and settings the platform gives it, instead of silently ignoring them."
9058
9058
  }
9059
+ ],
9060
+ "1.21.49": [
9061
+ {
9062
+ "id": "1004575",
9063
+ "text": "New builders get setup steps that actually work end to end: the sign-in commands in Settings and the primer now run from a fresh copy of the project, the primer's terminal commands display properly, and the setup no longer lea"
9064
+ }
9065
+ ],
9066
+ "1.21.50": [
9067
+ {
9068
+ "id": "1004574",
9069
+ "text": "The builders hall now tells newcomers one sign-in command, npx bongos setup, the same on Mac, Windows and Linux — and copying the setup commands now pastes them line by line instead of jammed onto one line."
9070
+ }
9059
9071
  ]
9060
9072
  }
@@ -346,6 +346,9 @@ const STARTER_COMMANDS = [
346
346
  'bongos release:*',
347
347
  'bongos reauth:*',
348
348
  'bongos paste-token:*',
349
+ // What Settings → CLI access hands out since task 1004575: a clone has no
350
+ // bare `bongos` on PATH, so the copied command runs through npx.
351
+ 'npx bongos paste-token:*',
349
352
  'bongos exec scripts/gds/api.js:*',
350
353
  // The read-only subset (task 1003992, ADR 0304). `git branch` and `git fetch`
351
354
  // are exact forms on purpose: a flag turns either into a write or an exec. No
@@ -1306,17 +1306,18 @@ module.exports = function buildAuthRouter() {
1306
1306
  // THERE — on an instance, where the core is an installed dependency and
1307
1307
  // `scripts/gds/` does not exist, so the previous
1308
1308
  // `node scripts/gds/paste-token.js <token>` named a file the builder did not
1309
- // have and the copy button handed out a command that could not run. `bongos`
1310
- // is on PATH in any installed instance, so the verb form is layout- and
1311
- // directory-independent.
1309
+ // have and the copy button handed out a command that could not run. The verb
1310
+ // is run through `npx` (task 1004575): a builder's clone does not put bare
1311
+ // `bongos` on PATH, and `npx bongos` resolves the project's own bin there.
1312
+ // The hall tells them to paste it in their project folder.
1312
1313
  //
1313
1314
  // The --api-base flag carries the issuer above. Omitted when this instance
1314
1315
  // cannot state its own origin, because a flag with an empty value would be
1315
1316
  // worse than none: paste-token would take '' as an explicit instruction and
1316
1317
  // stop falling back to the resolution that works today.
1317
1318
  paste_command: issuer
1318
- ? `bongos paste-token ${token} --api-base ${issuer}`
1319
- : `bongos paste-token ${token}`,
1319
+ ? `npx bongos paste-token ${token} --api-base ${issuer}`
1320
+ : `npx bongos paste-token ${token}`,
1320
1321
  });
1321
1322
  } catch (err) {
1322
1323
  log.error('[gds] POST /auth/cli-token/issue', err);
package/src/module-api.js CHANGED
@@ -75,7 +75,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
75
75
  // MAJOR (see allowBoxScope below): passes the request through untouched.
76
76
  function deprecatedNoopMiddleware(_req, _res, next) { next(); }
77
77
 
78
- const CORE_VERSION = '1.21.48'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
78
+ const CORE_VERSION = '1.21.50'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
79
79
 
80
80
  // A namespaced logger so a module's log lines are attributable + consistent.
81
81
  // Usage: const log = api.logger('discord'); log.info('mounted');
@@ -75,7 +75,8 @@ test('the server emits exactly the verb the CLI registers', () => {
75
75
  const cmds = [...tail.matchAll(/`([^`]*bongos paste-token[^`]*)`/g)].map((x) => x[1]);
76
76
  assert.ok(cmds.length > 0, 'auth.js should emit at least one paste_command template literal');
77
77
  for (const cmd of cmds) {
78
- const verb = cmd.split(' ')[1];
78
+ // `npx bongos <verb> …` since task 1004575 — a clone has no bare `bongos` on PATH.
79
+ const verb = cmd.replace(/^npx /, '').split(' ')[1];
79
80
  assert.ok(cli.VERBS[verb], `server emits "bongos ${verb}" but the CLI has no such verb`);
80
81
  }
81
82
  });
@@ -210,6 +210,10 @@ const GIT_GH_COMMANDS = [
210
210
  'git branch --list', 'git branch --show-current', 'git branch -a', 'git branch -vv',
211
211
  'git fetch', 'git fetch origin', 'git fetch origin main',
212
212
  'gh pr view:*', 'gh pr checks:*', 'gh pr list:*', 'gh run view:*', 'gh run list:*',
213
+ // Not git/gh, but the one non-script verb a session is handed to paste: Settings →
214
+ // CLI access gives `npx bongos paste-token <token>` (task 1004575), a blessed writer
215
+ // (see BLESSED_WRITERS) spelled the way a clone can run it.
216
+ 'npx bongos paste-token:*',
213
217
  ];
214
218
  // gds CLIs audited read-only under EVERY flag they take — a prefix rule allows them all.
215
219
  // Audited and left OUT: backlog-review.js (POSTs from its default walk) and
@@ -176,8 +176,10 @@ t('paste_command names a CLI VERB, never a filesystem path', () => {
176
176
  const cmds = [...tail.matchAll(/`([^`]*bongos paste-token[^`]*)`/g)].map((m) => m[1]);
177
177
  assert.equal(cmds.length, 2, `expected both ternary branches, got ${cmds.length}`);
178
178
  for (const cmd of cmds) {
179
- assert.ok(/^bongos paste-token /.test(cmd),
180
- `paste_command must start with the verb form, got: ${cmd}`);
179
+ // Through npx (task 1004575): a builder's clone does not put bare `bongos` on
180
+ // PATH, so a bare verb was "command not found" when pasted in the project folder.
181
+ assert.ok(/^npx bongos paste-token /.test(cmd),
182
+ `paste_command must start with the npx verb form, got: ${cmd}`);
181
183
  // The invariant is "names no FILE ON THE RECIPIENT'S DISK", which the original
182
184
  // spelling approximated as "contains no slash". That was too broad once the command
183
185
  // had to carry the issuer URL (task 1003722) — `https://host` is not a filesystem
@@ -208,7 +210,7 @@ t('paste_command carries the issuing instance, so the CLI cannot guess wrong', (
208
210
  t('an instance that cannot state its own origin omits the flag rather than sending an empty one', () => {
209
211
  // `--api-base ''` would read at the far end as an explicit instruction and suppress
210
212
  // the fallback that works today — strictly worse than sending no flag at all.
211
- assert.ok(/:\s*`bongos paste-token \$\{token\}`/.test(issueBlock),
213
+ assert.ok(/:\s*`npx bongos paste-token \$\{token\}`/.test(issueBlock),
212
214
  'there must be a flagless branch for the empty-issuer case');
213
215
  });
214
216
 
@@ -0,0 +1,101 @@
1
+ // task 1004574 — every builders-hall onboarding surface names ONE sign-in
2
+ // command, `npx bongos setup`, the same on every OS. Bare `bongos` is not on a
3
+ // fresh clone's PATH; `npx` resolves the repo's own bin after `npm install`.
4
+ // The old three (`/builder-setup`, `./scripts/setup-builder.sh`,
5
+ // `node scripts/setup-builder.js`) must not come back on these surfaces.
6
+ import { test } from 'node:test';
7
+ import assert from 'node:assert/strict';
8
+ import fs from 'node:fs';
9
+ import path from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+ import { execFileSync } from 'node:child_process';
12
+
13
+ const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
14
+ const read = (p) => fs.readFileSync(path.join(ROOT, p), 'utf8');
15
+ const OLD = /\/builder-setup|setup-builder\.(sh|js)/;
16
+
17
+ // The welcome panel's markup, from the setupSteps literal to the panel's innerHTML.
18
+ function welcomeMarkup() {
19
+ const src = read('modules/hall-ui/public/hall-render.js');
20
+ const start = src.indexOf('const setupSteps = `');
21
+ const end = src.indexOf('body.innerHTML = `', start);
22
+ assert.ok(start > 0 && end > start, 'welcome panel markup located');
23
+ return src.slice(start, end).split('\n').filter((l) => !/^\s*\/\//.test(l)).join('\n');
24
+ }
25
+
26
+ test('welcome panel: the steps and the clone block say npx bongos setup', () => {
27
+ const w = welcomeMarkup();
28
+ assert.match(w, /Run <code>npx bongos setup<\/code>/);
29
+ assert.match(w, /\\nnpm install\\nnpx bongos setup`/, 'clone block ends npm install + npx bongos setup');
30
+ assert.doesNotMatch(w, OLD, 'no legacy setup command on the welcome panel');
31
+ assert.doesNotMatch(w, /On Windows, run/, 'one command on every OS — no Windows-only line');
32
+ assert.match(w, /nodejs\.org/, 'the tooling list names Node, which npm install needs');
33
+ });
34
+
35
+ test('onboarding checklist: the cli_setup step names npx bongos setup', () => {
36
+ const src = read('modules/onboarding/onboarding-state.js');
37
+ const labels = src.slice(src.indexOf('const DISPLAY_LABELS'), src.indexOf('function nextStage'));
38
+ assert.match(labels, /cli_setup:\s+'Run npx bongos setup'/);
39
+ assert.match(labels, /cli_setup:\s+'[^']*npx bongos setup[^']*'/);
40
+ assert.doesNotMatch(labels, OLD);
41
+ });
42
+
43
+ test('primer: both routes sign in with npx bongos setup', () => {
44
+ const md = read('docs/onboarding/primer.md');
45
+ assert.match(md, /```sh\nnpm install\nnpx bongos setup\n```/);
46
+ // Not inside a `>` quote: the hall's reader garbles a fence there (task 1004575).
47
+ assert.doesNotMatch(md, /^> ```/m);
48
+ assert.match(md, /run `npx bongos setup` again/);
49
+ assert.doesNotMatch(md, OLD);
50
+ });
51
+
52
+ test('the get-the-code block keeps one command per line (screen and copy)', () => {
53
+ const css = read('modules/hall-ui/public/style.css');
54
+ const m = /\.setup__getcode \.welcome__paste\s*\{([^}]*)\}/.exec(css);
55
+ assert.ok(m, 'scoped rule present');
56
+ assert.match(m[1], /white-space:\s*pre/, 'copy-on-click reads innerText, so pre is what keeps the line breaks');
57
+ assert.match(m[1], /overflow-y:\s*hidden/, 'a one-axis strip names both axes');
58
+ });
59
+
60
+ // task 1004575 — the audit of the above, across the rest of the hall.
61
+
62
+ test('bin/bongos.js is committed executable, so npx leaves a fresh clone clean', () => {
63
+ // Committed 100644, `npx bongos` chmods it on first run: the clone then reads as
64
+ // changed, and a reverted mode makes the next run fail "Permission denied".
65
+ const entry = execFileSync('git', ['ls-files', '-s', 'bin/bongos.js'], { cwd: ROOT, encoding: 'utf8' });
66
+ assert.match(entry, /^100755 /, `expected mode 100755, got: ${entry.trim()}`);
67
+ });
68
+
69
+ test('welcome intro and checklist lead ask only for what a builder needs', () => {
70
+ const src = read('modules/hall-ui/public/hall-render.js');
71
+ assert.doesNotMatch(src, /run the platform locally/, 'a builder does not run the platform');
72
+ assert.match(src, /Clone the project to your machine and run <code>npm install<\/code> in it\./);
73
+ const st = read('modules/onboarding/onboarding-state.js');
74
+ assert.doesNotMatch(st, /Device Flow or the web sign-in/);
75
+ assert.match(st, /auth_complete:\s+'[^']*npx bongos setup[^']*'/);
76
+ });
77
+
78
+ test('primer no-terminal route installs dependencies (and Node) before signing in', () => {
79
+ const md = read('docs/onboarding/primer.md');
80
+ assert.match(md, /Node\*\* \(version 22 or newer\)/);
81
+ assert.match(md, /send this one message — \*Install this project's dependencies, then run npx bongos setup\.\* —/);
82
+ assert.match(md, /have four things ready/);
83
+ });
84
+
85
+ test('Settings CLI access says where to paste the npx command', () => {
86
+ const html = read('modules/hall-ui/public/settings.html');
87
+ const js = read('modules/hall-ui/public/settings.js');
88
+ assert.match(html, /into a terminal in your project folder/);
89
+ assert.doesNotMatch(html, /bypasses Device Flow/);
90
+ assert.match(js, /Paste this into a terminal in your project folder:/);
91
+ });
92
+
93
+ test('the npx paste command Settings hands out is pre-approved for a Claude session', () => {
94
+ // Both lists: the core's own settings (Bash + PowerShell twins) and the starter
95
+ // list materialized into every instance. Without them the copied command prompts.
96
+ const settings = JSON.parse(read('.claude/settings.json'));
97
+ for (const tool of ['Bash', 'PowerShell']) {
98
+ assert.ok(settings.permissions.allow.includes(`${tool}(npx bongos paste-token:*)`), `${tool} twin`);
99
+ }
100
+ assert.match(read('scripts/gds/claude-materialize.js'), /^\s*'npx bongos paste-token:\*',$/m);
101
+ });