projecta-rrr 1.24.1 → 1.24.3

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/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ All notable changes to RRR will be documented in this file.
4
4
 
5
5
  Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
+ ## [1.24.3] - 2026-05-12
8
+
9
+ ### Fixed
10
+ - **Sprite GitHub auth** — live provisioning now passes a local `GITHUB_TOKEN`, `GH_TOKEN`, or `gh auth token` into every Git/GitHub Sprite command without writing the token into `.planning`.
11
+ - **Sprite checkout** — branch checkout now configures GitHub CLI's Git credential helper inside the same token-scoped command before running `git fetch`.
12
+ - **Sprite checkpoints** — provisioning only creates the clean-ready checkpoint after clone, checkout, RRR install, and setup all pass.
13
+
14
+ ## [1.24.2] - 2026-05-12
15
+
16
+ ### Fixed
17
+ - **Sprite exec apply path** — provisioning now inserts `--` before remote commands so Sprite does not parse `bash -lc`, `npx --global`, or setup flags as Sprite CLI flags.
18
+
7
19
  ## [1.24.1] - 2026-05-12
8
20
 
9
21
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "projecta-rrr",
3
- "version": "1.24.1",
3
+ "version": "1.24.3",
4
4
  "description": "A meta-prompting, context engineering and spec-driven development system for Claude Code by Projecta.ai",
5
5
  "bin": {
6
6
  "projecta-rrr": "bin/install.js",
@@ -213,7 +213,7 @@ function buildSpriteProvisionPlan(projectRoot, options) {
213
213
  const cloneCommand = repo
214
214
  ? `gh repo clone ${repo} ${workdir}`
215
215
  : `git clone <repo-url> ${workdir}`;
216
- const checkoutCommand = `git fetch origin && git checkout -B ${teamConfig.branch} origin/${config.github.base_branch}`;
216
+ const checkoutCommand = `gh auth setup-git >/dev/null 2>&1 || true; git fetch origin && git checkout -B ${teamConfig.branch} origin/${config.github.base_branch}`;
217
217
 
218
218
  rows.push({
219
219
  team,
@@ -227,11 +227,12 @@ function buildSpriteProvisionPlan(projectRoot, options) {
227
227
  checks,
228
228
  commands: [
229
229
  `sprite create ${teamConfig.sprite} --skip-console`,
230
- `sprite exec -s ${teamConfig.sprite} mkdir -p /home/sprite/work`,
231
- `sprite exec -s ${teamConfig.sprite} bash -lc 'test -d ${workdir}/.git || ${cloneCommand}'`,
232
- `sprite exec -s ${teamConfig.sprite} --dir ${workdir} bash -lc '${checkoutCommand}'`,
233
- `sprite exec -s ${teamConfig.sprite} --dir ${workdir} npx projecta-rrr@latest --global --yes`,
234
- ...setup.map(cmd => `sprite exec -s ${teamConfig.sprite} --dir ${workdir} bash -lc '${cmd}'`),
230
+ `sprite exec -s ${teamConfig.sprite} -- mkdir -p /home/sprite/work`,
231
+ `sprite exec -s ${teamConfig.sprite} --env GITHUB_TOKEN=$GITHUB_TOKEN -- bash -lc 'gh auth status || echo "Run gh auth login in this Sprite, or apply provisioning from a machine with GITHUB_TOKEN/GH_TOKEN/gh auth token"'`,
232
+ `sprite exec -s ${teamConfig.sprite} --env GITHUB_TOKEN=$GITHUB_TOKEN -- bash -lc 'test -d ${workdir}/.git || ${cloneCommand}'`,
233
+ `sprite exec -s ${teamConfig.sprite} --dir ${workdir} --env GITHUB_TOKEN=$GITHUB_TOKEN -- bash -lc '${checkoutCommand}'`,
234
+ `sprite exec -s ${teamConfig.sprite} --dir ${workdir} -- npx projecta-rrr@latest --global --yes`,
235
+ ...setup.map(cmd => `sprite exec -s ${teamConfig.sprite} --dir ${workdir} -- bash -lc '${cmd}'`),
235
236
  `sprite checkpoint create -s ${teamConfig.sprite} --comment "rrr clean-ready ${config.milestone} ${team}"`
236
237
  ]
237
238
  });
@@ -316,32 +317,85 @@ function execCapture(command, args, options) {
316
317
  }
317
318
  }
318
319
 
320
+ function normalizeCreateResult(result) {
321
+ if (!result.ok && /already exists/i.test(result.output || '')) {
322
+ return { ...result, ok: true, output: result.output || 'sprite already exists' };
323
+ }
324
+ return result;
325
+ }
326
+
327
+ function localGitHubToken(projectRoot) {
328
+ if (process.env.GITHUB_TOKEN) return process.env.GITHUB_TOKEN;
329
+ if (process.env.GH_TOKEN) return process.env.GH_TOKEN;
330
+ const token = execCapture('gh', ['auth', 'token'], { cwd: projectRoot });
331
+ return token.ok && token.output ? token.output.trim() : '';
332
+ }
333
+
334
+ function githubTokenEnvArgs(token) {
335
+ return token ? ['--env', `GITHUB_TOKEN=${token}`] : [];
336
+ }
337
+
338
+ function githubAuthStep(row, token) {
339
+ if (token) {
340
+ return execCapture('sprite', [
341
+ 'exec',
342
+ '-s',
343
+ row.sprite,
344
+ ...githubTokenEnvArgs(token),
345
+ '--',
346
+ 'gh',
347
+ 'auth',
348
+ 'status'
349
+ ]);
350
+ }
351
+ return execCapture('sprite', ['exec', '-s', row.sprite, '--', 'gh', 'auth', 'status']);
352
+ }
353
+
354
+ function gitExecArgs(row, token) {
355
+ return [
356
+ 'exec',
357
+ '-s',
358
+ row.sprite,
359
+ ...githubTokenEnvArgs(token)
360
+ ];
361
+ }
362
+
363
+ function gitExecArgsInWorkdir(row, token) {
364
+ return [
365
+ 'exec',
366
+ '-s',
367
+ row.sprite,
368
+ '--dir',
369
+ row.workdir,
370
+ ...githubTokenEnvArgs(token)
371
+ ];
372
+ }
373
+
319
374
  function applySpriteProvisionPlan(projectRoot, options) {
320
375
  const plan = buildSpriteProvisionPlan(projectRoot, options);
321
376
  const results = [];
322
377
  for (const row of plan.rows) {
378
+ const token = localGitHubToken(projectRoot);
323
379
  const teamResults = [];
324
- const create = execCapture('sprite', ['create', row.sprite, '--skip-console']);
380
+ const create = normalizeCreateResult(execCapture('sprite', ['create', row.sprite, '--skip-console']));
325
381
  teamResults.push({ step: 'create', ...create });
326
- execCapture('sprite', ['exec', '-s', row.sprite, 'mkdir', '-p', '/home/sprite/work']);
382
+ execCapture('sprite', ['exec', '-s', row.sprite, '--', 'mkdir', '-p', '/home/sprite/work']);
383
+ const auth = githubAuthStep(row, token);
384
+ teamResults.push({ step: 'github-auth', ...auth, output: auth.ok ? 'authenticated' : auth.output });
327
385
  const clone = execCapture('sprite', [
328
- 'exec',
329
- '-s',
330
- row.sprite,
386
+ ...gitExecArgs(row, token),
387
+ '--',
331
388
  'bash',
332
389
  '-lc',
333
390
  `test -d ${row.workdir}/.git || gh repo clone ${row.repo} ${row.workdir}`
334
391
  ]);
335
392
  teamResults.push({ step: 'clone', ...clone });
336
393
  const checkout = execCapture('sprite', [
337
- 'exec',
338
- '-s',
339
- row.sprite,
340
- '--dir',
341
- row.workdir,
394
+ ...gitExecArgsInWorkdir(row, token),
395
+ '--',
342
396
  'bash',
343
397
  '-lc',
344
- `git fetch origin && git checkout -B ${row.branch} origin/${plan.config.github.base_branch}`
398
+ `gh auth setup-git >/dev/null 2>&1 || true; git fetch origin && git checkout -B ${row.branch} origin/${plan.config.github.base_branch}`
345
399
  ]);
346
400
  teamResults.push({ step: 'checkout', ...checkout });
347
401
  const rrr = execCapture('sprite', [
@@ -350,6 +404,7 @@ function applySpriteProvisionPlan(projectRoot, options) {
350
404
  row.sprite,
351
405
  '--dir',
352
406
  row.workdir,
407
+ '--',
353
408
  'npx',
354
409
  'projecta-rrr@latest',
355
410
  '--global',
@@ -357,17 +412,20 @@ function applySpriteProvisionPlan(projectRoot, options) {
357
412
  ]);
358
413
  teamResults.push({ step: 'rrr-install', ...rrr });
359
414
  for (const command of row.setup || []) {
360
- const setup = execCapture('sprite', ['exec', '-s', row.sprite, '--dir', row.workdir, 'bash', '-lc', command]);
415
+ const setup = execCapture('sprite', ['exec', '-s', row.sprite, '--dir', row.workdir, '--', 'bash', '-lc', command]);
361
416
  teamResults.push({ step: `setup: ${command}`, ...setup });
362
417
  }
363
- const checkpoint = execCapture('sprite', [
364
- 'checkpoint',
365
- 'create',
366
- '-s',
367
- row.sprite,
368
- '--comment',
369
- `rrr clean-ready ${plan.config.milestone} ${row.team}`
370
- ]);
418
+ const readyForCheckpoint = teamResults.every(result => result.ok);
419
+ const checkpoint = readyForCheckpoint
420
+ ? execCapture('sprite', [
421
+ 'checkpoint',
422
+ 'create',
423
+ '-s',
424
+ row.sprite,
425
+ '--comment',
426
+ `rrr clean-ready ${plan.config.milestone} ${row.team}`
427
+ ])
428
+ : { ok: false, output: 'skipped because bootstrap failed' };
371
429
  teamResults.push({ step: 'checkpoint', ...checkpoint });
372
430
  results.push({ team: row.team, sprite: row.sprite, results: teamResults });
373
431
  }
@@ -402,6 +460,7 @@ function readSpriteStatus(projectRoot, options) {
402
460
  row.sprite,
403
461
  '--dir',
404
462
  row.workdir,
463
+ '--',
405
464
  'bash',
406
465
  '-lc',
407
466
  'printf "branch="; git branch --show-current; printf "\\nhead="; git rev-parse --short HEAD; printf "\\nclaude="; claude --version 2>/dev/null || true; printf "\\ngsd="; gsd-browser --version 2>/dev/null || true'