@bongos/core 1.17.0 → 1.17.2
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 +363 -312
- package/.claude/skills/blocker-review/SKILL.md +1 -1
- package/.claude/skills/builder-claim/SKILL.md +2 -0
- package/.claude/skills/builder-exit/SKILL.md +2 -2
- package/.claude/skills/builder-redteam/SKILL.md +3 -3
- package/.claude/skills/builder-setup/SKILL.md +2 -2
- package/.claude/skills/builder-start/SKILL.md +1 -1
- package/.claude/skills/dev/SKILL.md +1 -1
- package/.claude/skills/idea-triage/SKILL.md +2 -2
- package/.claude/skills/ideate/SKILL.md +1 -1
- package/.claude/skills/merge-mode/SKILL.md +1 -1
- package/.claude/skills/new-project/SKILL.md +3 -0
- package/.claude/skills/paint/SKILL.md +1 -1
- package/CLAUDE.md +11 -238
- package/GOVERNANCE.md +1 -1
- package/README.md +1 -1
- package/bin/bongos.js +1 -0
- package/clients/bongos-client/README.md +4 -4
- package/clients/bongos-client/bongos-client.global.js +14 -1
- package/clients/bongos-client/index.cjs +14 -1
- package/clients/bongos-client/index.d.ts +19 -2
- package/clients/bongos-client/index.mjs +11 -1
- package/clients/bongos-client/package.json +1 -1
- package/docs/adr/0001-stack-choice-single-vps.md +1 -1
- package/docs/adr/0008-google-chat-oauth-user-auth.md +1 -1
- package/docs/adr/0019-red-team-bounty-payout-table.md +3 -3
- package/docs/adr/0020-security-model-public-stub.md +1 -1
- package/docs/adr/0023-kind-multipliers-and-idea-bonus.md +1 -1
- package/docs/adr/0024-cloneable-repo-local-first-memory.md +1 -1
- package/docs/adr/0026-bfg-memory-hygiene-and-cross-builder-learning.md +4 -4
- package/docs/adr/0027-bfg-session-inefficiency-evaluator.md +3 -3
- package/docs/adr/0030-builders-hall-live-updates.md +1 -1
- package/docs/adr/0031-cloud-dev-environments-for-builders.md +4 -4
- package/docs/adr/0032-discord-mirror-of-gds.md +2 -2
- package/docs/adr/0034-thetes-graduated-newcomer-rank.md +1 -1
- package/docs/adr/0044-mediterranean-palette-replacement.md +1 -1
- package/docs/adr/0044-per-box-live-game-preview.md +1 -1
- package/docs/adr/0054-session-token-reward-cost-plus.md +10 -10
- package/docs/adr/0057-container-cost-ledger.md +3 -3
- package/docs/adr/0062-medusa-instance-model-decoupling.md +4 -4
- package/docs/adr/0065-agpl-nonprofit-ai-first-governance.md +2 -2
- package/docs/adr/0085-remove-default-per-builder-spend-cap.md +1 -1
- package/docs/adr/0086-goal-scoped-work-hierarchy.md +1 -1
- package/docs/adr/0096-require-reward-before-workable.md +9 -9
- package/docs/adr/0097-retroactive-reward-backfill.md +3 -3
- package/docs/adr/0100-two-repo-instance-model.md +1 -1
- package/docs/adr/0101-goal-hierarchy-phase-5-judge-membership-reward.md +3 -3
- package/docs/adr/0103-core-first-extraction-cloud-bongos-trunk.md +3 -3
- package/docs/adr/0107-module-upstreaming-contribution-to-core-catalog.md +1 -1
- package/docs/adr/0120-pay-on-land-and-builder-owned-rebase-gate.md +6 -6
- package/docs/adr/0133-github-app-manifest-onboarding-signin.md +2 -0
- package/docs/adr/0134-private-first-npm-distribution.md +20 -6
- package/docs/adr/0135-module-upstream-submission-interim-queue.md +34 -0
- package/docs/adr/0136-update-channel-subscription-policy.md +51 -0
- package/docs/adr/0137-upstream-publish-policy-manual-owner-gated.md +40 -0
- package/docs/adr/0138-bundled-module-deps-declared-per-module.md +45 -0
- package/docs/adr/README.md +14 -10
- package/docs/api/openapi.json +315 -6
- package/docs/api-reference.md +10 -5
- package/docs/architecture.md +3 -3
- package/docs/branding-contract.md +5 -4
- package/docs/canonical-permissions.md +1 -1
- package/docs/design/vanilla-hall-ui-redesign-scope.md +1 -1
- package/docs/file-map.md +20 -19
- package/docs/handoff-template.md +2 -2
- package/docs/modules-contract.md +8 -1
- package/docs/onboarding/diagrams/README.md +7 -7
- package/docs/onboarding/drachmae-and-karma.md +18 -18
- package/docs/onboarding/primer.md +9 -9
- package/docs/recipes/audit-replay.md +2 -2
- package/docs/recipes/builder-box-lifecycle.md +2 -2
- package/docs/recipes/claude-design-loop.md +1 -1
- package/docs/recipes/instance-deploy.md +4 -4
- package/docs/recipes/instance-first-run.md +51 -0
- package/docs/recipes/ops-gotchas.md +1 -1
- package/docs/recipes/packaging-the-core.md +5 -5
- package/docs/recipes/private-npm-distribution.md +39 -12
- package/docs/recipes/self-host.md +1 -1
- package/docs/recipes/staging-environment.md +1 -1
- package/docs/recipes/upgrading-the-core.md +63 -8
- package/docs/research/cursor-competitive-analysis.md +1 -1
- package/docs/research/llm-model-agnostic-and-cheaper-grader.md +1 -1
- package/migrations/core_191_module_submissions.sql +45 -0
- package/modules/autonomy/CLAUDE.md +11 -45
- package/modules/builder-settings/CLAUDE.md +11 -54
- package/modules/dev-box/CLAUDE.md +11 -34
- package/modules/discord/CLAUDE.md +11 -46
- package/modules/discord/module.json +2 -1
- package/modules/economy/CLAUDE.md +11 -44
- package/modules/economy/achievements.js +9 -1
- package/modules/economy/credits.js +10 -1
- package/modules/grading/CLAUDE.md +11 -38
- package/modules/hall-ui/CLAUDE.md +11 -57
- package/modules/hall-ui/public/builders.js +71 -4
- package/modules/hall-ui/public/goal-inbox.js +191 -0
- package/modules/hall-ui/public/goals-page.js +227 -22
- package/modules/hall-ui/public/goals.html +16 -0
- package/modules/hall-ui/public/hall-widgets.js +14 -1
- package/modules/hall-ui/public/index.html +3 -0
- package/modules/hall-ui/public/new-project-wizard.js +6 -4
- package/modules/hall-ui/public/style.css +43 -0
- package/modules/ideas/CLAUDE.md +11 -33
- package/modules/lifecycle/CLAUDE.md +11 -59
- package/modules/lifecycle/routes/goals.js +80 -0
- package/modules/memory/CLAUDE.md +11 -36
- package/modules/onboarding/CLAUDE.md +11 -51
- package/modules/provisioning/CLAUDE.md +15 -0
- package/modules/provisioning/migrations/provisioning_001_tables.sql +160 -0
- package/modules/provisioning/migrations/provisioning_002_standalone_shape.sql +11 -0
- package/modules/provisioning/migrations/provisioning_003_github_app_manifest.sql +95 -0
- package/modules/provisioning/module.json +17 -0
- package/modules/provisioning/onboard-plan.js +37 -0
- package/modules/provisioning/provisioning.js +539 -0
- package/modules/provisioning/rate-limit.js +35 -0
- package/modules/provisioning/routes/provisioning.js +607 -0
- package/modules/provisioning/tests/provisioning.mjs +232 -0
- package/modules/provisioning/ui/.gitkeep +0 -0
- package/modules/security/CLAUDE.md +11 -40
- package/modules/security/secret-scrub.js +10 -0
- package/modules/sessions/CLAUDE.md +11 -35
- package/modules/status-ui/CLAUDE.md +11 -43
- package/package-lock.json +2 -2
- package/package.json +7 -2
- package/public-landing/create.html +58 -12
- package/public-landing/index.html +40 -21
- package/scripts/discord/README.md +1 -1
- package/scripts/gds/CLAUDE.md +11 -140
- package/scripts/gds/claim.js +98 -48
- package/scripts/gds/claude-materialize.js +174 -20
- package/scripts/gds/claude-md-template.js +84 -0
- package/scripts/gds/cli-lib.js +112 -2
- package/scripts/gds/cutover-codemod.js +241 -0
- package/scripts/gds/fitness.js +54 -0
- package/scripts/gds/gen-api-client.js +10 -10
- package/scripts/gds/init.js +112 -16
- package/scripts/gds/lint-infra-exec.js +70 -0
- package/scripts/gds/lint-workflow-exec.js +63 -0
- package/scripts/gds/migration-namespace.js +1 -1
- package/scripts/gds/mirror-lineage-check.js +14 -5
- package/scripts/gds/mirror-redact.js +8 -0
- package/scripts/gds/module.js +118 -4
- package/scripts/gds/npmrc.js +93 -0
- package/scripts/gds/onboard.js +17 -24
- package/scripts/gds/package-core.js +74 -17
- package/scripts/gds/provision.js +102 -17
- package/scripts/gds/publish-manifest.js +60 -2
- package/scripts/gds/run-routine.js +51 -13
- package/scripts/gds/run-unit-tests.js +4 -0
- package/scripts/gds/seed-adopt-tasks.js +1 -1
- package/scripts/gds/status.js +6 -1
- package/scripts/gds/task.js +166 -0
- package/scripts/gds/update-channel.js +186 -0
- package/scripts/gds/upgrade.js +172 -25
- package/src/bongos/CLAUDE.md +11 -60
- package/src/bongos/auth.js +24 -0
- package/src/bongos/module-submissions.js +56 -0
- package/src/bongos/route-rank-check.js +6 -0
- package/src/bongos/routes/CLAUDE.md +11 -39
- package/src/bongos/routes/auth.js +6 -1
- package/src/bongos/routes/modules.js +123 -21
- package/src/bongos/serve-internal.js +10 -1
- package/src/branding.js +1 -0
- package/src/instance-config.js +1 -1
- package/src/module-api.js +24 -1
- package/src/module-loader/loader.js +36 -4
- package/src/module-loader/manifest-schema.js +16 -1
- package/tests/branding.mjs +11 -0
- package/tests/claim_error_surface.mjs +107 -0
- package/tests/claude_materialize.mjs +125 -0
- package/tests/consumer_layout_boot.mjs +302 -0
- package/tests/cutover_codemod.mjs +184 -0
- package/tests/device_flow_start.mjs +96 -0
- package/tests/first_run_engine_check.mjs +79 -0
- package/tests/goal_membership_requests.mjs +33 -3
- package/tests/hook_core_resolve.mjs +125 -0
- package/tests/hook_user_agents.mjs +62 -0
- package/tests/infra_exec_paths.mjs +104 -0
- package/tests/init.mjs +106 -6
- package/tests/instance_mismatch_guard.mjs +101 -0
- package/tests/mirror_lineage_proof.mjs +14 -0
- package/tests/module_cli.mjs +130 -2
- package/tests/module_loader.mjs +42 -0
- package/tests/module_manifest.mjs +19 -0
- package/tests/module_submissions.mjs +135 -0
- package/tests/npmrc.mjs +105 -0
- package/tests/onboard.mjs +62 -0
- package/tests/package_core.mjs +76 -22
- package/tests/platform_boot.mjs +5 -2
- package/tests/provision.mjs +107 -8
- package/tests/provisioning_github_app_routes.mjs +44 -2
- package/tests/publish_manifest.mjs +52 -1
- package/tests/run_routine.mjs +26 -1
- package/tests/run_routine_two_root.mjs +77 -0
- package/tests/scrubber_corpus.mjs +17 -0
- package/tests/served_paths_shipped.mjs +2 -2
- package/tests/task_cli.mjs +99 -0
- package/tests/update_channel.mjs +186 -0
- package/tests/upgrade.mjs +220 -25
- package/tests/workflow_exec_paths.mjs +98 -0
- package/docs/design/container-exterior-tiles.md +0 -49
- package/docs/design/container-exterior.md +0 -81
- package/docs/design/container-interior.md +0 -77
- package/docs/design/world-map-scroll.md +0 -41
- package/docs/recipes/claude-gemini-bongos-doors.md +0 -155
- package/docs/recipes/cloudbongos-staging-gate.md +0 -139
- package/docs/recipes/cloudbongos-standup.md +0 -111
- package/docs/recipes/parallel-load-results-2026-05-30.md +0 -63
- package/docs/recipes/parallel-load-test.md +0 -32
- package/docs/recipes/pixel-art-pipeline.md +0 -411
- package/docs/recipes/staging-data.md +0 -50
- package/migrations/instance/018_pms_v3_planning_seed.sql +0 -131
- package/migrations/instance/080_gds_v4_planning_seed.sql +0 -75
- package/migrations/instance/110_medusa_planning_seed.sql +0 -70
- package/migrations/instance/120_bongos_v1_planning_seed.sql +0 -69
- package/migrations/instance/144_bongos_v1_module_system_criterion.sql +0 -26
- package/migrations/instance/159_bongos_v1_goal_hierarchy_criterion.sql +0 -29
- package/migrations/instance/172_v2_world_planning_seed.sql +0 -163
- package/migrations/instance/173_bongos_v1_c7_core_modularized.sql +0 -33
- package/migrations/instance/182_gdsv4_bongos_consolidation.sql +0 -132
- package/migrations/instance/183_gdsv4_carryover_themed_goals.sql +0 -116
- package/migrations/instance/186_bongos_v1_governance_planning_seed.sql +0 -69
- package/scripts/gds/art-stage.js +0 -152
- package/server.js +0 -212
- package/tests/art_key.mjs +0 -121
- package/tests/day_cycle.mjs +0 -197
- package/tests/snapshot_picker.mjs +0 -233
- package/tests/sprite_facing.mjs +0 -35
- package/tests/terrain_picker.mjs +0 -298
- package/tests/turn_in_place.mjs +0 -280
- package/tests/walkability.mjs +0 -188
|
@@ -62,10 +62,24 @@ body{
|
|
|
62
62
|
text-transform:lowercase;color:var(--ink);text-decoration:none;
|
|
63
63
|
}
|
|
64
64
|
.top .mark span{color:var(--accent);}
|
|
65
|
+
.top-right{display:flex;align-items:center;gap:clamp(10px,2vw,18px);}
|
|
66
|
+
/* exit the wizard — Esc, or this button (task 2098). Nothing is created until the
|
|
67
|
+
final step, so leaving simply drops the in-progress project. */
|
|
68
|
+
.exit-wizard{
|
|
69
|
+
display:inline-flex;align-items:center;gap:7px;cursor:pointer;
|
|
70
|
+
background:transparent;border:1px solid rgba(42,31,23,0.16);border-radius:999px;
|
|
71
|
+
padding:7px 14px;font-family:var(--font-body);font-weight:600;font-size:13px;color:var(--ink-soft);
|
|
72
|
+
transition:background .14s ease,border-color .14s ease,color .14s ease;
|
|
73
|
+
}
|
|
74
|
+
.exit-wizard:hover{background:rgba(42,31,23,0.05);color:var(--ink);border-color:rgba(42,31,23,0.28);}
|
|
75
|
+
.exit-wizard kbd{font-family:var(--font-mono);font-size:10px;line-height:1;background:rgba(42,31,23,0.08);border-radius:4px;padding:2px 5px;color:var(--ink-faint);}
|
|
65
76
|
.who{display:flex;align-items:center;gap:10px;font-size:14px;font-weight:600;color:var(--ink-soft);min-height:34px;}
|
|
66
77
|
.who img{width:30px;height:30px;border-radius:50%;border:2px solid #fff;box-shadow:0 2px 8px rgba(42,31,23,0.12);}
|
|
67
78
|
.who a{color:var(--accent-deep);text-decoration:none;font-weight:700;}
|
|
68
79
|
.who a:hover{text-decoration:underline;}
|
|
80
|
+
/* switch to a different GitHub account from inside the wizard (task 2098) */
|
|
81
|
+
.who .switch-acct{font-size:12px;font-weight:600;color:var(--ink-faint);padding-left:10px;margin-left:2px;border-left:1px solid rgba(42,31,23,0.16);}
|
|
82
|
+
.who .switch-acct:hover{color:var(--accent-deep);}
|
|
69
83
|
|
|
70
84
|
/* ── layout ── */
|
|
71
85
|
.wrap{
|
|
@@ -304,7 +318,10 @@ input[type=text].bad{border-color:var(--err);}
|
|
|
304
318
|
|
|
305
319
|
<header class="top">
|
|
306
320
|
<a class="mark" href="/"><span data-brand-product>cloud bongos</span></a>
|
|
307
|
-
<div class="
|
|
321
|
+
<div class="top-right">
|
|
322
|
+
<button type="button" class="exit-wizard" id="exitWizard" title="Leave the wizard — nothing is created">Exit <kbd>esc</kbd></button>
|
|
323
|
+
<div class="who" id="who" aria-live="polite"></div>
|
|
324
|
+
</div>
|
|
308
325
|
</header>
|
|
309
326
|
|
|
310
327
|
<div class="wrap">
|
|
@@ -445,7 +462,8 @@ input[type=text].bad{border-color:var(--err);}
|
|
|
445
462
|
var API = '/api/bongos';
|
|
446
463
|
var b = (typeof window !== 'undefined' && window.__BRANDING__) || {};
|
|
447
464
|
var productName = (b.identity && b.identity.productName) || 'Cloud Bongos';
|
|
448
|
-
|
|
465
|
+
// (task 2094: the wizard no longer links into cloud bongos's own builders hall,
|
|
466
|
+
// so the buildersOrigin it used to render is gone.)
|
|
449
467
|
document.querySelectorAll('[data-brand-product]').forEach(function (n) { n.textContent = productName.toLowerCase(); });
|
|
450
468
|
document.querySelectorAll('[data-brand-product-inline]').forEach(function (n) { n.textContent = productName; });
|
|
451
469
|
|
|
@@ -697,24 +715,24 @@ input[type=text].bad{border-color:var(--err);}
|
|
|
697
715
|
var oa = state.domain ? oauthAppValues(state.domain) : null;
|
|
698
716
|
$('doneLede').innerHTML = 'Provisioning is requested for <strong>' + esc(state.name || state.slug) + '</strong>' +
|
|
699
717
|
(adopt ? ' — adopting your existing repo' : '') +
|
|
700
|
-
'. The platform stands up the server, database, and address on its own
|
|
718
|
+
'. The platform stands up the server, database, and address on its own — you can watch its live status right here.';
|
|
701
719
|
|
|
702
720
|
var steps = [];
|
|
703
721
|
var repoLabel = state.owner && state.repo ? '<strong>' + esc(state.owner + '/' + state.repo) + '</strong>' : 'your new repository';
|
|
704
722
|
steps.push(adopt
|
|
705
|
-
? '<li><b>Layer onto your existing repo</b><p>In your repo run <code style="font-family:var(--font-mono)">bongos init --adopt</code>. It shows a conflict pre-flight and writes <em>nothing</em> until you accept — your files and history stay yours, and your existing backlog is imported. Commit and push.</p></li>'
|
|
706
|
-
: '<li><b>Create the empty GitHub repo</b><p>On github.com: New repository → ' + repoLabel + ' → leave it completely empty.</p></li>');
|
|
723
|
+
? '<li data-onboard-step="github-repo"><b>Layer onto your existing repo</b><p>In your repo run <code style="font-family:var(--font-mono)">bongos init --adopt</code>. It shows a conflict pre-flight and writes <em>nothing</em> until you accept — your files and history stay yours, and your existing backlog is imported. Commit and push.</p></li>'
|
|
724
|
+
: '<li data-onboard-step="github-repo"><b>Create the empty GitHub repo</b><p>On github.com: New repository → ' + repoLabel + ' → leave it completely empty.</p></li>');
|
|
707
725
|
if (!state.domain) {
|
|
708
726
|
steps.push('<li><b>Add a domain you own</b><p>Sign-in on your new instance needs a real domain. When you have one, come back here or ask your hall — the address gets wired in minutes.</p></li>');
|
|
709
727
|
}
|
|
710
728
|
if (oa) {
|
|
711
|
-
steps.push('<li><b>Create the GitHub OAuth app</b><p>GitHub → <em>your account’s</em> Settings → Developer settings → OAuth Apps → New OAuth App. (Developer settings live under your account, not the repo.)</p>' +
|
|
729
|
+
steps.push('<li data-onboard-step="oauth-app"><b>Create the GitHub OAuth app</b><p>GitHub → <em>your account’s</em> Settings → Developer settings → OAuth Apps → New OAuth App. (Developer settings live under your account, not the repo.)</p>' +
|
|
712
730
|
'<div class="kv"><span class="kk">Homepage URL</span><code>' + esc(oa.homepageUrl) + '</code>' + copyBtn(oa.homepageUrl) + '</div>' +
|
|
713
731
|
'<div class="kv"><span class="kk">Callback URL</span><code>' + esc(oa.callbackUrl) + '</code>' + copyBtn(oa.callbackUrl) + '</div></li>');
|
|
714
732
|
var cmd = 'bongos oauth-secret place ' + state.slug + ' --client-id <id> --client-secret <secret> --apply';
|
|
715
733
|
steps.push('<li><b>Place the secret — verified</b><p>Never hand-edit the env file. On the control plane run the placement command; it checks the value is real and confirms sign-in works.</p>' +
|
|
716
734
|
'<div class="kv"><code>' + esc(cmd) + '</code>' + copyBtn(cmd) + '</div></li>');
|
|
717
|
-
steps.push('<li><b>First sign-in</b><p>Open <code style="font-family:var(--font-mono)">' + esc(oa.homepageUrl) + '</code> and sign in with GitHub once. That seats you as the owner — the founding Archon.</p></li>');
|
|
735
|
+
steps.push('<li data-onboard-step="first-sign-in"><b>First sign-in</b><p>Open <code style="font-family:var(--font-mono)">' + esc(oa.homepageUrl) + '</code> and sign in with GitHub once. That seats you as the owner — the founding Archon.</p></li>');
|
|
718
736
|
steps.push('<li><b>Verify</b><p><code style="font-family:var(--font-mono)">' + esc(oa.homepageUrl) + '/healthz</code> should report <code style="font-family:var(--font-mono)">auth_configured: true</code>. Then the hall is yours.</p></li>');
|
|
719
737
|
}
|
|
720
738
|
$('humanSteps').innerHTML = steps.join('');
|
|
@@ -760,7 +778,7 @@ input[type=text].bad{border-color:var(--err);}
|
|
|
760
778
|
} else if (s === 'error') {
|
|
761
779
|
el.innerHTML = progressMarkup(1, 1,
|
|
762
780
|
'The standup hit a snag' + (inst.error_note ? ': ' + esc(inst.error_note) : '') +
|
|
763
|
-
'. The platform keeps retrying
|
|
781
|
+
'. The platform keeps retrying — this page updates as it recovers.', 'isErr');
|
|
764
782
|
} else if (s === 'tearing_down' || s === 'torn_down') {
|
|
765
783
|
el.innerHTML = progressMarkup(-1, 0, 'This instance was torn down. You can start another project below.', 'isErr');
|
|
766
784
|
return true;
|
|
@@ -781,7 +799,7 @@ input[type=text].bad{border-color:var(--err);}
|
|
|
781
799
|
fetch(API + '/provisioning/instances/' + encodeURIComponent(id), { credentials: 'same-origin' })
|
|
782
800
|
.then(function (res) {
|
|
783
801
|
if (res.status === 401) { throw new Error('gone:Your session expired — <a href="' + API + '/auth/web/start?return=/create">sign in again</a> to keep watching.'); }
|
|
784
|
-
if (res.status === 404) { throw new Error('gone:Can’t see this instance any more —
|
|
802
|
+
if (res.status === 404) { throw new Error('gone:Can’t see this instance any more — it may have been torn down.'); }
|
|
785
803
|
if (!res.ok) throw new Error('soft');
|
|
786
804
|
return res.json();
|
|
787
805
|
})
|
|
@@ -821,15 +839,43 @@ input[type=text].bad{border-color:var(--err);}
|
|
|
821
839
|
}
|
|
822
840
|
wireAgain();
|
|
823
841
|
|
|
824
|
-
/* ──
|
|
842
|
+
/* ── exit the wizard (task 2098) ── Esc, or the header button. Nothing is
|
|
843
|
+
provisioned until the final Create step, and the named orb is client-only
|
|
844
|
+
on the gate, so leaving simply means the project is not created. The form
|
|
845
|
+
draft persists in sessionStorage, so an accidental exit loses no typing. */
|
|
846
|
+
function exitWizard() { window.location.assign('/gate/'); }
|
|
847
|
+
$('exitWizard').addEventListener('click', exitWizard);
|
|
848
|
+
document.addEventListener('keydown', function (e) {
|
|
849
|
+
if (e.key === 'Escape') { e.preventDefault(); exitWizard(); }
|
|
850
|
+
});
|
|
851
|
+
|
|
852
|
+
/* ── switch GitHub account from inside the wizard (task 2098) ── you are not
|
|
853
|
+
locked to the account you entered with: sign out of the Cloud Bongos session,
|
|
854
|
+
then restart GitHub sign-in so the wizard reloads under whichever account you
|
|
855
|
+
pick. (To land on a *different* GitHub account, switch accounts on GitHub's
|
|
856
|
+
side; this un-locks our session so the next sign-in is honored.) */
|
|
857
|
+
function switchAccount(e) {
|
|
858
|
+
if (e) e.preventDefault();
|
|
859
|
+
var back = API + '/auth/web/start?return=/create';
|
|
860
|
+
fetch(API + '/auth/logout', { method: 'POST', credentials: 'same-origin' })
|
|
861
|
+
.then(function () { window.location.assign(back); })
|
|
862
|
+
.catch(function () { window.location.assign(back); });
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
/* ── boot: who am I? ── (task 2094: the wizard shows the signed-in identity
|
|
866
|
+
ONLY — never a link into cloud bongos's own builders hall. A project
|
|
867
|
+
creator enters a hall from their own project's landing, not from here.
|
|
868
|
+
task 2098: + a "switch account" action so you're not locked in.) ── */
|
|
825
869
|
function renderWho() {
|
|
826
870
|
var w = $('who');
|
|
827
871
|
if (me) {
|
|
828
872
|
w.innerHTML = (me.avatar_url ? '<img src="' + esc(me.avatar_url) + '" alt="">' : '') +
|
|
829
873
|
'<span>' + esc(me.github_login || 'signed in') + '</span>' +
|
|
830
|
-
'<a href="
|
|
874
|
+
'<a href="#" class="switch-acct" id="switchAcct">switch account</a>';
|
|
875
|
+
var sw = $('switchAcct');
|
|
876
|
+
if (sw) sw.addEventListener('click', switchAccount);
|
|
831
877
|
} else {
|
|
832
|
-
w.innerHTML = '
|
|
878
|
+
w.innerHTML = '';
|
|
833
879
|
}
|
|
834
880
|
}
|
|
835
881
|
|
|
@@ -50,12 +50,15 @@ body{
|
|
|
50
50
|
/* a soft white glow behind the mascot so a white- or transparent-bg PNG blends */
|
|
51
51
|
.hero-mascot{
|
|
52
52
|
position:relative;width:min(540px,86vw);margin-bottom:6px;
|
|
53
|
+
/* cap by height on short viewports so the hall CTA + sign-in hint always clear
|
|
54
|
+
the fixed footer (task 2094); on tall desktops the width cap wins, unchanged */
|
|
55
|
+
max-height:50vh;display:flex;justify-content:center;
|
|
53
56
|
}
|
|
54
57
|
.hero-mascot::before{
|
|
55
58
|
content:"";position:absolute;inset:-6% -10%;z-index:-1;border-radius:50%;
|
|
56
59
|
background:radial-gradient(ellipse at center, rgba(255,255,255,0.95) 0%, rgba(255,255,255,0.7) 45%, rgba(255,255,255,0) 72%);
|
|
57
60
|
}
|
|
58
|
-
.hero-mascot img{display:block;width:100%;height:auto;}
|
|
61
|
+
.hero-mascot img{display:block;width:100%;height:auto;max-height:50vh;object-fit:contain;}
|
|
59
62
|
/* fallback shown if buddha.png is not present yet */
|
|
60
63
|
.mascot-fallback{
|
|
61
64
|
width:min(540px,86vw);aspect-ratio:1.6/1;border-radius:28px;
|
|
@@ -95,6 +98,9 @@ body{
|
|
|
95
98
|
font-size:14px;font-weight:600;color:var(--ink-soft);min-height:30px;
|
|
96
99
|
}
|
|
97
100
|
.who img{width:28px;height:28px;border-radius:50%;border:2px solid #fff;box-shadow:0 2px 8px rgba(42,31,23,0.14);}
|
|
101
|
+
.who a{color:var(--accent-deep);text-decoration:none;font-weight:700;}
|
|
102
|
+
.who a:hover{text-decoration:underline;}
|
|
103
|
+
.who .who-act{padding-left:10px;margin-left:2px;border-left:1px solid rgba(42,31,23,0.18);}
|
|
98
104
|
.foot{
|
|
99
105
|
position:fixed;bottom:18px;left:0;right:0;z-index:1;text-align:center;
|
|
100
106
|
color:var(--ink-soft);font-size:13px;opacity:0.8;
|
|
@@ -114,10 +120,9 @@ body{
|
|
|
114
120
|
<div class="wordmark" data-brand-product>cloud bongos</div>
|
|
115
121
|
<p class="tagline" data-brand-tagline>Building software is laying down a beat.</p>
|
|
116
122
|
<div class="cta-row">
|
|
117
|
-
<a class="btn
|
|
118
|
-
<a class="btn ghost" data-link-hall href="https://builders.cloudbongos.com">Enter the Hall →</a>
|
|
123
|
+
<a class="btn" id="hallBtn" data-link-hall href="https://builders.cloudbongos.com">Enter the Hall →</a>
|
|
119
124
|
</div>
|
|
120
|
-
<p class="signin-hint" id="signinHint" aria-live="polite"
|
|
125
|
+
<p class="signin-hint" id="signinHint" aria-live="polite"></p>
|
|
121
126
|
</main>
|
|
122
127
|
<div class="who" id="who" aria-live="polite"></div>
|
|
123
128
|
|
|
@@ -138,30 +143,44 @@ body{
|
|
|
138
143
|
if (dom.buildersOrigin) document.querySelectorAll('[data-link-hall]').forEach(function(n){ n.setAttribute('href', dom.buildersOrigin); });
|
|
139
144
|
}
|
|
140
145
|
|
|
141
|
-
/*
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
146
|
+
/* Membership-aware hall access (goal 35, task 2094). This is a PROJECT's own
|
|
147
|
+
landing page. Signed in as an admitted builder here → "Enter the Hall".
|
|
148
|
+
Otherwise → "Request access" (this project's own hall shows the request-
|
|
149
|
+
access card), with a quiet "already a builder? sign in" for returning
|
|
150
|
+
builders. Sign-in is itself gated to approved builders (auth.js), so a
|
|
151
|
+
newcomer who tries it is routed to request access anyway. The identity +
|
|
152
|
+
action live top-right. Degrades to the request-access visual when the API
|
|
153
|
+
is unreachable (static preview / standalone viewing). */
|
|
154
|
+
var hallHref = (b && b.domains && b.domains.buildersOrigin) || 'https://builders.cloudbongos.com';
|
|
155
|
+
var signInHref = '/api/bongos/auth/web/start?return=' + encodeURIComponent('/');
|
|
147
156
|
function esc(s) {
|
|
148
157
|
return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) {
|
|
149
158
|
return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c];
|
|
150
159
|
});
|
|
151
160
|
}
|
|
161
|
+
var hallBtn = document.getElementById('hallBtn');
|
|
162
|
+
var signinHint = document.getElementById('signinHint');
|
|
163
|
+
var who = document.getElementById('who');
|
|
164
|
+
|
|
165
|
+
function showSignedOut() {
|
|
166
|
+
if (hallBtn) { hallBtn.textContent = 'Request access'; hallBtn.setAttribute('href', hallHref); }
|
|
167
|
+
if (signinHint) signinHint.innerHTML = 'Already a builder here? <a href="' + signInHref + '">Sign in with GitHub</a>.';
|
|
168
|
+
if (who) who.innerHTML = '<a href="' + signInHref + '">Sign in with GitHub</a>';
|
|
169
|
+
}
|
|
170
|
+
function showMember(me) {
|
|
171
|
+
if (hallBtn) { hallBtn.textContent = 'Enter the Hall →'; hallBtn.setAttribute('href', hallHref); }
|
|
172
|
+
if (signinHint) signinHint.textContent = '';
|
|
173
|
+
if (who) who.innerHTML =
|
|
174
|
+
(me.avatar_url ? '<img src="' + esc(me.avatar_url) + '" alt="">' : '') +
|
|
175
|
+
'<span>' + esc(me.github_login || 'signed in') + '</span>' +
|
|
176
|
+
'<a class="who-act" href="' + hallHref + '">Enter hall →</a>';
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
showSignedOut(); // default until /me resolves (and the no-JS request-access intent)
|
|
152
180
|
fetch('/api/bongos/me', { credentials: 'same-origin' })
|
|
153
181
|
.then(function (res) { if (!res.ok) throw new Error(String(res.status)); return res.json(); })
|
|
154
|
-
.then(function (data) {
|
|
155
|
-
|
|
156
|
-
var btn = document.getElementById('createBtn');
|
|
157
|
-
btn.classList.remove('resting');
|
|
158
|
-
btn.setAttribute('href', '/create');
|
|
159
|
-
document.getElementById('signinHint').textContent = '';
|
|
160
|
-
document.getElementById('who').innerHTML =
|
|
161
|
-
(me.avatar_url ? '<img src="' + esc(me.avatar_url) + '" alt="">' : '') +
|
|
162
|
-
'<span>' + esc(me.github_login || 'signed in') + '</span>';
|
|
163
|
-
})
|
|
164
|
-
.catch(function () { /* signed out or unreachable: keep the resting door + hint */ });
|
|
182
|
+
.then(function (data) { showMember(data.builder || data.me || data); })
|
|
183
|
+
.catch(function () { /* signed out / not a member / unreachable: request-access visual stands */ });
|
|
165
184
|
})();
|
|
166
185
|
</script>
|
|
167
186
|
</body>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Discord integration (outbound)
|
|
2
2
|
|
|
3
|
-
Posts
|
|
3
|
+
Posts Example build updates into the team Discord. This replaced the
|
|
4
4
|
Google Chat outbound broadcast (Discord Phase 2, GDS task [#607](https://example.com/builders#/task/607)).
|
|
5
5
|
|
|
6
6
|
Discord is a **one-way window into the GDS** — these scripts only POST. No
|
package/scripts/gds/CLAUDE.md
CHANGED
|
@@ -1,144 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @bongos/core — installed platform dependency (not your project's CLAUDE.md)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This file is a placeholder shipped inside the **@bongos/core** package. The core's own
|
|
4
|
+
internal agent notes are intentionally omitted from the published artifact so they cannot
|
|
5
|
+
load into your instance's context.
|
|
4
6
|
|
|
5
|
-
**
|
|
7
|
+
**It does not govern this repository.** Your own root `CLAUDE.md`, your `.claude/`
|
|
8
|
+
directory, and the live Bongos database are the source of truth for how work happens here
|
|
9
|
+
and who may do what.
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
You are seeing this only because an agent opened a file under `node_modules/@bongos/core/`.
|
|
12
|
+
Nothing in here needs to be read to use the platform — run `bongos help` for commands.
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- `claim.js` → `/builder-claim N` — atomically claim a task; prints claim id + touches[] + relevant learnings/context-pack.
|
|
12
|
-
- `ship.js` → `/builder-ship` — **the big one (~151KB)**; 3-step lifecycle completed→confirmed (credits, smoke)→shipped (merge+deploy). Flags: `--no-merge`, `--skip-grade`, `--regrade`, `--force`, `--allow-empty`. The empty-diff/phantom-ship guard runs **regardless of `--skip-grade`** (task 1365 closed the task-1363 hole where `--skip-grade` bypassed it and a never-committed deliverable confirmed + reconciler-shipped with no artifact on main); a no-artifact/DB-only ship now needs explicit `--allow-empty`, which is still **refused if the working tree is dirty/untracked** (that means you forgot to commit).
|
|
13
|
-
- `release.js` → `/builder-release N` — cancel a claim (no credits); task returns to `ready`.
|
|
14
|
-
- `capture.js` → idea_inbox — file an idea (`--kind`, `--body-file`, `--version`); `recall.js` → `/recall` — lexical (FTS+trigram/RRF) rank-scoped knowledge search; `learning-capture.js` — durable short-form learning into the DB.
|
|
15
|
-
- `gen-diagrams.js` — regenerate the 5 onboarding `.mmd`/`.svg`/`.png` + `assertions.json` from live facts; `gen-repo-map.js` — regenerate the code symbol skeleton (`docs/repo-map.md` + the generated factual block in each nested CLAUDE.md; ADR 0063); `gen-session-index.js` — regenerate the session-log index (`docs/session-log-index.md` + the bounded CLAUDE.md §13 snippet) from `docs/session-logs/*.md` (ADR 0062 §8, task 1226); `gen-file-map.js` — regenerate the `.claude/skills/` + `.claude/scheduled-tasks/` sections of `docs/file-map.md` from disk, notes sourced from `docs/file-map.notes.json` (ADR 0066, task 1276; `--check` fails on drift or an undescribed skill/routine); `fitness.js` — architecture fitness gate (core↔host boundary, CLAUDE.md budget, nested-doc presence, rank-guard, generated-artifact freshness; ADR 0062 §9, enforced via `tests/fitness.mjs`); `architect-audit.js` — MAS Phase 5 bounded first-principles `--scope` audit → `docs/audits/`; `linkify-refs.js` — rewrite bare `#NNN` refs into hall links so GitHub doesn't mis-autolink.
|
|
16
|
-
- `box.js` — operator/control-plane dev-box lifecycle (`provision`/`park`/`wake`/`deprovision`/`sweep-*`/`status`); rank-gated against live DB rank. **Runs on the control plane, never inside a box.**
|
|
17
|
-
- `provision.js` — the **instance-provisioning** control-plane runner (ADR 0111 §2/§3, [#1944](https://example.com/builders#/task/1944)); a sibling of `box.js`. Sole holder of the DO/Cloudflare tokens; drains `provisioning_intents` (the web tier only enqueues) and composes the [`cloudbongos-standup`](../../docs/recipes/cloudbongos-standup.md) runbook — server (co-tenant port OR dedicated droplet) → `createdb` + GDS-only migrate → per-instance `/etc/<slug>/web.env` → systemd unit → per-instance Caddy snippet + reload → `/healthz` — **idempotent, dry-run-default** (nothing mutates without `--apply`), drift-reconciling. Driven by `infra/provision-intent-runner.timer`. Commands: `run-intents`/`provision <slug>`/`teardown <slug>`/`reconcile`/`status`/`dns-check <domain>` (the task-[#1980](https://example.com/builders#/task/1980) DNS token-scope PREFLIGHT — read-only, verifies the CF token reaches the domain's zone before the address step; provisioning also fail-fasts on it up front). Reuses `do-api.js` + `modules/provisioning/provisioning.js`. **Runs on the control plane, never inside the web tier.** The runner is `User=lars` (non-root), so the privileged steps (write `/etc`, `systemctl`, `createdb`/`migrate`) escalate via `sudo` (temp-file + `sudo install`, `sudo systemctl`, `sudo -u postgres`) **only under `PROVISION_SUDO=1`** — the runner unit sets it ([ADR 0128](../../docs/adr/<redacted>.md)); default OFF keeps CLI/test runs bare. The unit must NOT set `NoNewPrivileges=true` (it blocks `sudo`). With `PROVISION_REMOTE_HOST` set it also runs the box-mutating steps on a remote co-hosting box over `ssh` (control plane orchestrates co-tenants that live elsewhere → zero cloud tokens on that box), while the Cloudflare DNS hook stays local via `controlExec` ([ADR 0130](../../docs/adr/<redacted>.md), task 2065); default OFF = all-local, unchanged. The `cohost-*` control-plane runner units + the SSH DB tunnel that read the co-hosting box's queues over `127.0.0.1:5433` to activate this end-to-end are [ADR 0132](../../docs/adr/<redacted>.md) / task 2071.
|
|
18
|
-
- `oauth-secret.js` — **verified, shell-independent OAuth-secret placement** for a provisioned instance (ADR 0111, [#1979](https://example.com/builders#/task/1979)); the onboarding step every form (skill/CLI/hall) drives. `place <slug> --client-id --client-secret [--apply]`: VALIDATES the creds (length/charset — catches the silent 26-char truncation `authConfigured()` misses, since it only checks presence), rewrites `/etc/<slug>/web.env` via Node (never a fragile `read -s`/`sed -i`), restarts the unit, then PROBES `/healthz` for `auth_configured:true`. Dry-run-default; control-plane only.
|
|
19
|
-
- `do-api.js` · `cf-tunnel.js` · `http-api-client.js` — the **shared control-plane network clients** (DigitalOcean v2 · Cloudflare named-tunnel · their JSON-HTTP skeleton). Operator-CLI-only (never the web tier), injectable-transport + **dry-run-by-default**. Moved here from `modules/dev-box/` in BV1 task [#1943](https://example.com/builders#/task/1943) ([ADR 0111](../../docs/adr/<redacted>.md) §2) so both `box.js` AND the instance-provisioning runner `provision.js` (task #1944) reuse the DO client without a module→module import. (The Cloudflare **DNS-record** hook stays at `infra/box-dns-cloudflare.sh`, invoked by path via `BOX_DNS_HOOK`.)
|
|
20
|
-
- `seed-v3-tasks.js` / `seed-gds-v4-tasks.js` — idempotent planning-session task seeders (skip on existing `source_ref`); `newcomer-floor.*` — deterministic copy-stamp replenisher for newcomer chores (`.js` + `.config.json` + `.templates.json` + `.test.js`).
|
|
21
|
-
|
|
22
|
-
**Gotchas / invariants.**
|
|
23
|
-
- `ship.js` is huge — search by phase keyword, don't read end-to-end. Every change here still needs a claimed GDS task (no admin loophole).
|
|
24
|
-
- Cross-platform = no bash-isms in the `.js` path; keep `process.execPath`/`os.homedir()` patterns.
|
|
25
|
-
- Never hand-edit generated `.mmd`/`assertions.json` — run `gen-diagrams.js`. Never hand-edit `linkify-refs.js`'s output by adding bare `#NNN`.
|
|
26
|
-
- **The guardrails are two-root aware ([ADR 0108](../../docs/adr/<redacted>.md) §Consequences #4).** `fitness.js`, `gen-repo-map.js`, `gen-file-map.js` resolve `resolveCoreRoot()` (core code + the src/bongos·scripts/gds nested docs) vs `resolveInstanceRoot()` (the root CLAUDE.md, `.claude/`, instance modules + migrations); modules are scanned across both. Today both roots are the one checkout (byte-identical); post-split each inspects the right tree. **Do not reintroduce a hardcoded `path.resolve(__dirname,'..','..')`** in these files — it re-fuses the boundary and would point into `node_modules` post-split. `tests/fitness_two_root.mjs` diverges the roots to prove it.
|
|
27
|
-
- **Migration filenames are namespaced by source ([ADR 0108](../../docs/adr/<redacted>.md) §5, `migration-namespace.js`).** A NEW core migration is `migrations/core_NNN_slug.sql`; a NEW module migration is `modules/<key>/migrations/<key>_NNN_slug.sql`; instance seeds stay bare `migrations/instance/NNN_slug.sql`. This is what lets the core repo and the instance repo version independently without their migrations colliding on the stem-keyed `schema_migrations`. Existing bare files are grandfathered (never rename one — it re-runs on prod). `fitness.js` Check 11b + `tests/migration_namespace.mjs` enforce it; `claim.js`/`next-number.js` suggest the namespaced form. `migrate.sh` merges three roots (core-package / instance / module) resolved via `resolveCoreRoot()`/`resolveInstanceRoot()`.
|
|
28
|
-
- Many other files here are not slash-command entry points: smoke tests (`smoke-*.sh`/`smoke-gds.js`), audits (`audit-*`, `main-audit.js`, `gate-review.js`), session tooling (`session*.js`, `pulse.js`), and systemd units (`gds-db-*.{service,timer}`).
|
|
29
|
-
|
|
30
|
-
<!-- BEGIN GENERATED REPO-MAP (scripts/gds/gen-repo-map.js — do not hand-edit) -->
|
|
31
|
-
**Symbol skeleton (generated from the code — do not hand-edit; refresh: `node scripts/gds/gen-repo-map.js`).** Exported signatures, most-referenced first. The interpretive notes above are hand-written; this factual list is regenerated on deploy so it can't drift ([ADR 0063](../../docs/adr/<redacted>.md)).
|
|
32
|
-
|
|
33
|
-
- `adopt-detect.js` — `detectStack({ dir, fs = nodeFs, path = nodePath } = {})`, `formatStackSummary(s)`, `detectPackageManager(exists, hasPkg)`
|
|
34
|
-
- `adopt-import.js` — `DEFAULT_MAX`, `parseBacklogFile(text)`, `resolveBacklogTasks({ dir, repo = {}, githubToken, backlogFile, fetchImpl, fs = nodeFs, path = nodePath, max =…)`, `BACKLOG_FILENAMES`, `fetchGitHubIssues({ owner, repo, token, fetchImpl = globalThis.fetch, max = DEFAULT_MAX, onWarn = ()`, `findBacklogFile(dir, fs = nodeFs, path = nodePath)`, `parseGitHubIssues(issues)`
|
|
35
|
-
- `adopt-preflight.js` — `SEV`, `formatPreflight(report)`, `INCOMING_PATHS`, `preflightAdopt({ dir, stack = {}, fs = nodeFs, path = nodePath } = {})`, `checkCiCollisions(workflows = [])`, `checkFitnessBoundary({ topLevelDirs = [], hasSrcBongos = false } = {})`, `checkMigrationNamespace(basenames = [])`, `checkProtectedPaths(incoming = INCOMING_PATHS)`, `CORE_EXPECTED_CHECKS`
|
|
36
|
-
- `architect-audit.js` — `slug(scope)`, `buildPrompt({ scope, fileList, fileBlocks, version })`, `PROMPT_HEADER`, `pickValidKind(kind)`, `validateSeedIdeas(raw)`
|
|
37
|
-
- `art-stage.js` — `waitHealthy(healthUrl, deps = {})`, `affectedTiles(explicit, deps = {})`, `copyAtlasToServed(deps = {})`, `rebuildAtlas(deps = {})` _(+1 more)_
|
|
38
|
-
- `audit-deps.js` — `classify(tTouches, oTouches)`, `OPEN`, `findMissingDeps(tasks, { open = OPEN, isBlocker = isUnshippedBlocker } = {})`, `HOTSPOTS`, `isUnshippedBlocker(s)`
|
|
39
|
-
- `audit-exports.js` — `TARGETS`, `buildCorpus()`, `classifyExports(targetAbsPath, exportNames, corpus)` _(+1 more)_
|
|
40
|
-
- `audit-ships.js` — `findCommitForTask(taskId)`, `gitDiffStatsForCommit(sha)`, `filesTouchedByCommit(sha)`, `downstreamImpact(sha, files)`, `fetchShipped(days)`, `fetchFullTask(id)`, `fetchLearning(taskId)`
|
|
41
|
-
- `autonomy-gate.js` — `decide({ enabled, routine = '', claimableCount = 0, openIdeasCount = 0, mtdSpendUsd = 0, ceiling …)`, `precheck(routine, deps = {})`, `isEnabled(env = process.env)`, `gatherSignals(routine, deps = {})`, `AUTONOMY_FLAG`, `DEFAULT_CEILING_USD`, `ceilingUsd(env = process.env)`, `autofixAllowed({ enabled = false, graderBypassOn = true, isProtected = true, confidence = 'low', fileCoun…)`
|
|
42
|
-
- `backfill-cost.js` — `findLedger(argPath)`, `parseLedger(filePath)`, `postCost(row, sourceRef)`
|
|
43
|
-
- `backfill-sessions.js` — `entryText(entry)`, `extractTaskIds(entries)`, `inScope(dirName)`, `PROJECT_TOKENS`, `TASK_MARKERS`
|
|
44
|
-
- `backfill-task-rewards.js` — `BACKFILL_REASON`, `backfillKey(taskId)`, `computeTaskReward(taskId, rawCredits, kind)`, `netForBuilder(wouldBeTotal, costPlusAlreadyPaid)`, `planForBuilder(builderId, taskRewards, costPlusAlreadyPaid, alreadyBackfilled = new Set()`, `TOKEN_REWARD_REASON`
|
|
45
|
-
- `backup.js` — `fmtBytes(n)`, `fetchStatus()`, `printStatus(data)`, `trigger()`
|
|
46
|
-
- `box-auth-check.js` — `onBox()`, `decideBoxAuth({ onBox, hasToken, isBoxScoped, meStatus })`, `printReauth({ boxScoped })`, `printSetup()`
|
|
47
|
-
- `box-connect-lib.js` — `RANK_ORDER`, `WORKSPACE`, `binPresent(bin, versionArgs = ['--version'])`, `buildKnownHostsUpsert(existing, hostname, hostKeysRaw)`, `buildRemoteShellCommand({ firstRun = false, workdir = WORKSPACE } = {})`, `buildSshAliasBlock({ hostname, identityFile })`, `CLAUDE_VSCODE_EXTENSION`, `fetchRank()`, `isFirstLogin(hostname)`, `parseEnsure(data)` _(+8 more)_
|
|
48
|
-
- `box.js` — `deprovisionOne(pool, boxes, doApi, box, { actor, login, sleepFn } = {})`, `cmdProvision(pool, boxes, boxOnboard, ref, { apply })`, `markErrorUnlessDestroyed(pool, boxes, builderId, errNote)`, `runDnsHook(hostname, ip, hook = CONFIG.dnsHook)`, `deleteWithRetry(fn, { tries = 3, sleepMs = 2000, sleepFn } = {})`, `runDnsHookBlackhole(hostname, hook = CONFIG.dnsHook)`, `cmdReconcileDrift(pool, boxes, { apply })`
|
|
49
|
-
- `build-bongos.js` — `VERSION`, `TARGETS`
|
|
50
|
-
- `capture.js` — `resolveDefaultVersion()`
|
|
51
|
-
- `cf-tunnel.js` — `class CfTunnelApi`, `terminalHostname(login, zone)`, `CfApiError`, `previewHostname(login, zone)`, `CF_API_BASE`, `CACHE_BYPASS_RULE_DESC`, `tunnelName(login)`, `CACHE_BYPASS_EXPRESSION`, `CFARGO_SUFFIX`, `GAME_SERVICE` _(+1 more)_
|
|
52
|
-
- `ci-grade.js` — `git(args)`
|
|
53
|
-
- `claim-recall.js` — `printClaimRecall(task, { excludeKeys = [] } = {})`, `RECALL_LIMIT`, `claimRecallQuery(task)`, `formatRecallSources(results, { limit = RECALL_LIMIT, excludeKeys = [], currentTaskId = null } = {})`, `rowKeys(row)`
|
|
54
|
-
- `claim.js` — `printRelevantLearnings(task)`, `printDisciplineMode(task)`, `captureHeadSha()`, `warnIfToolingStale()`, `printClaimCard(task, widgetsEnabled = true)`
|
|
55
|
-
- `classify-discipline.js` — `pad(s, n)`, `emoji(d)`
|
|
56
|
-
- `claude-materialize.js` — `bongosify(text, verbs = VERBS)`, `materializeClaude({ coreRoot, instanceDir, dryRun = false, overwrite = true, log = ()`, `copyTreeTransformed(srcDir, destDir, { dryRun, onFile, overwrite = true } = {})`, `GDS_INVOCATION_RE`, `scriptToVerb(verbs = VERBS)`, `transformSettings(srcPath)`
|
|
57
|
-
- `cli-lib.js` — `cliClient(opts = {})`, `arg(name, args = process.argv.slice(2)`, `requireSession()`, `API_BASE`, `hasFlag(name, args = process.argv.slice(2)`, `SESSION_PATH`, `apiCall(method, urlPath, body = null, opts = {})`, `loadSession()`, `fmtUsd(n)`, `fmtMinutes(m)` _(+13 more)_
|
|
58
|
-
- `code.js` — `repoRoot()`, `runCode(args, { inherit = true } = {})`, `runLocal({ log })`
|
|
59
|
-
- `codemod-rename-src-gds.js` — `segReplace(s)`, `isSrcTopLevel(rel)`, `gitMv()`, `isBinary(buf)`
|
|
60
|
-
- `conductor-dispatch.js` — `autoDispatch(deps = {})`, `bestMatchingClaim(claims, changedFiles)`, `pickSpecialists(changedFiles)`, `selectAutonomousDispatch(gate, claimable)`
|
|
61
|
-
- `context-pack.js` — `contextPack({ activeClaims = [], currentTaskId = null } = {})`, `formatContextPack(pack)`, `buildContextPack({)`, `formatContextPackCompact(pack)`, `apiContract()`, `formatClaims(claims)`, `formatOs(os)`, `normalizeClaims(activeClaims, currentTaskId)`, `osFacts({ platform, runWhich })`, `resolveWorktreeRoot({ runGit, cwd })`
|
|
62
|
-
- `design-sync.js` — `arg(flag, args)`, `collectFiles(dir, root)`
|
|
63
|
-
- `diagnose-achievements.js` — `backfill()`
|
|
64
|
-
- `diagram-facts.js` — `repoSlug(repo)`, `gatherFacts({ repo })`, `defaultRank(migs)`, `readMigrations(repo)`, `CONCEPTUAL_TASK_IDS`, `conceptualFacts({ repo, migs })`, `DEV_BOX_TASK_IDS`, `liveVersions()`, `rankEnum(migs)`, `readGdsSource(repo)` _(+5 more)_
|
|
65
|
-
- `do-api.js` — `class DoApi`, `DoApiError`, `DO_API_BASE`
|
|
66
|
-
- `docs-entropy.js` — `parseFile(absPath)`, `collectMarkdownFiles()`, `scanStaleLinks(relFiles)`, `scanDuplicateProse(relFiles)`, `toSlug(heading)`
|
|
67
|
-
- `doctor.js` — `section(title)`, `gitOut(cmd, opts = {})`, `checkSession()`, `checkToolchain()`, `checkGitPlumbing()`, `checkRepoState()`, `checkEnvironment()`, `checkDeployTooling()`
|
|
68
|
-
- `feedback-latest.js` — `parseArgs(argv)`
|
|
69
|
-
- `fetch-sound-prefs.js` — `writeAtomic(targetPath, contents)`
|
|
70
|
-
- `figma-design-sync.js` — `arg(flag, args)`, `collectFiles(dir, root)`
|
|
71
|
-
- `fitness.js` — `KERNEL_FILES`, `discoveredModuleKeys(modulesDir)`, `scanScopeMapSource(src)`, `checkCoreHostBoundary()`, `checkScopeMapImportsProtected()`, `moduleImportViolation(fromAbsFile, spec)`, `moduleNamespace(key)`, `moduleOwnerOf(absFile)`, `checkClaudeMdBudget(opts = {})`, `checkCoreCarriesNoModuleCode()` _(+20 more)_
|
|
72
|
-
- `gate-review.js` — `classifyChanges({ files, blobAt, diffBytes = 0 } = {})`, `matchesHardFloor(f)`, `HARD_FLOOR_GLOBS`, `isCanonicalPath(p)`, `resolveAction({ verdict, trusted, ownerApproved })`, `certifyAllowlistNarrowing(base, head)`, `certifyRunUnitTestsNarrowing(base, head)`
|
|
73
|
-
- `gating.js` — `repoSlug()`, `getProtection(repo)`, `toPutBody(p)`, `putProtection(repo, putBody)`, `deleteProtection(repo)`, `workflowState(repo, wf)`, `setWorkflow(repo, wf, enable)`, `readSnapshot()`, `writeSnapshot(obj)`, `summarize(putBody)` _(+3 more)_
|
|
74
|
-
- `gen-api-client.js` — `build()`, `buildModel(spec)`, `camel(s)`, `groupByTag(ops)`, `renderClientJs(spec, ops)`, `renderTypes(spec, ops)`, `pascal(s)`
|
|
75
|
-
- `gen-api-docs.js` — `build()`, `pathParams(route)`, `resolveScalar(expr, constants = {})`, `captureBalanced(str, from)`, `splitTopLevel(inner)`, `extractModel()`, `extractResponse(lines, i)`, `pascalCase(s)`, `requestSchemaFor(r)`, `resolveArray(expr, constants = {})` _(+18 more)_
|
|
76
|
-
- `gen-atlas.js` — `buildContextView()`, `buildModuleView()`
|
|
77
|
-
- `gen-diagrams.js` — `brand()`, `cap(s)`, `lifecycleMmd(f)`, `rankLadderMmd(f)`, `versioningMmd(f)`, `drachmaeKarmaMmd(f)`, `architectureMmd(f)`, `rebuildAssertions(prev, f)`
|
|
78
|
-
- `gen-file-map.js` — `end(id)`, `buildModel()`, `begin(id)`, `SECTIONS`, `renderSection(model)`, `computeWrites()`, `injectSection(existing, model)`, `buildSection(section, notes)`
|
|
79
|
-
- `gen-repo-map.js` — `BEGIN`, `END`, `buildModel()`, `NESTED_DIRS`, `injectBlock(existing, block)`, `renderNestedBlock(model, dir)`, `renderRepoMap(model)`
|
|
80
|
-
- `gen-session-index.js` — `BEGIN`, `END`, `computeWrites()`, `collectEntries(dir = LOGS_DIR)`, `injectSnippet(existing, snippet)`, `renderIndex(entries)`, `SESSION_FILE_RE`, `cleanTitle(rawHeading)`, `parseEntry(filename, content)`, `renderSnippet(entries, count = SNIPPET_COUNT)` _(+1 more)_
|
|
81
|
-
- `git-merge-regen.js` — `REGENERABLE`, `regenerateResolved(relpath, { base = '', ours = '', theirs = '' } = {})`, `resolveInWorktree(relpath)`, `hasMarkers(s)`, `threeWayMerge(base, ours, theirs)`, `MARKER_RE`
|
|
82
|
-
- `grade-smoke.js` — `summarize(result, label)`
|
|
83
|
-
- `http-api-client.js` — `class JsonHttpApi`, `makeApiError(name, code)`
|
|
84
|
-
- `init.js` — `CORE_PKG`, `slugify(s, fallback = 'goal')`, `interview({ adopt = false } = {})`, `HOSTING_SHAPES`, `KNOWN_MODULES`, `coreVersionSafe()`, `coreDepRange()`, `provisioningRequest(spec)`, `seedViaApi(spec, { dryRun, log = console.log, api = apiCall } = {})`, `writeConfigs(spec, { dir, force, dryRun, coreDep, log = console.log })` _(+15 more)_
|
|
85
|
-
- `install-git-hooks.js` — `activate()`, `registerMergeDriver(root)`, `MERGE_DRIVER_NAME`, `configuredHooksDir()`
|
|
86
|
-
- `key-card.js` — `wrap(text, width)`, `esc(s)`, `safeBrand()`, `emitKeyCard(model, { log = console.log, widgetsEnabled = true } = {})`, `buildKeyCardModel(input = {})`, `renderKeyCardHtml(model)`, `renderMonospaceKeyCard(model)`
|
|
87
|
-
- `key-status.js` — `KEYS`, `KEY_LIKE_RE`, `refuseIfKeyPasted(argv)`
|
|
88
|
-
- `land-watch.js` — `watch({ nowMs = Date.now()`, `PENDING_DIR`, `readBreadcrumbs()`, `classifyLand(task, ageMs, { staleMs = DEFAULT_STALE_MS } = {})`, `DEFAULT_STALE_MS`, `writeBreadcrumb(taskId, data = {})`, `buildShippedEnvelope(crumb, task)`, `removeBreadcrumb(fileOrId)`
|
|
89
|
-
- `learning-capture.js` — `csv(v)`, `readStdin()`, `autoDetectFiles()`
|
|
90
|
-
- `linkify-refs.js` — `RESOLVER_BASE`, `linkifyText(text, ids, stats)`, `discoverDocs()`, `classifyKind(left, carried, prevKind)`, `linkifySegment(segment, ids, leftContext, stats)`, `RESOLVER_BASE_BLOCKER`, `RESOLVER_BASE_IDEA`, `upgradeLineCodeSpans(line, ids, stats)`, `normalizeIdSets(ids)`, `unlinkEntitySegment(segment, leftContext, stats)`
|
|
91
|
-
- `local-preview-lib.js` — `start(deps = {})`, `REPO_ROOT`, `stop(deps = {})`, `restart(deps = {})`, `health(deps = {})`, `healthUrl(deps = {})`, `HOST`, `onBox(deps = {})`, `BOX_ENV_PATH`, `localUrl(deps = {})` _(+11 more)_
|
|
92
|
-
- `local-preview.js` — `pollHealthy(ms = 20_000)`, `warnIfOnBox()`
|
|
93
|
-
- `login.js` — `runDeviceFlow(base, { log })`, `normalizeInstanceBase(raw)`, `pollDecision(body)`
|
|
94
|
-
- `main-audit.js` — `analyzeCommits(commits, rankByIdentity, { strict = false } = {})`, `parseCommits(range)`, `resolveRank(c, rankByIdentity)`
|
|
95
|
-
- `memory-map.js` — `entries(text)`, `estTokens(bytes)`, `measure(text)`, `applyCompaction(mapPath, expectedText, newText, deps = {})`, `keepAlways(meta)`, `metaOf(file, memoryDir, deps = {})`, `parseLines(text)`, `planCompaction(text, opts = {})`, `WARN_BYTES`, `isRule(type)` _(+4 more)_
|
|
96
|
-
- `merge-lock.js` — `mainWorktreeRoot()`
|
|
97
|
-
- `migration-namespace.js` — `CORE_NS`, `INSTANCE_NS`, `filenameViolation(source, basename, { moduleKey } = {})`, `migrationNumberOf(basename)`, `stemCollisions(files)`, `nextInNamespace(basenames)`, `parseMigrationName(basename)`, `LEGACY_BARE_CORE_MAX`, `LEGACY_BARE_MODULES`, `sqlNamespace(moduleKey)` _(+2 more)_
|
|
98
|
-
- `mirror-lineage-check.js` — `MIGRATION_BASENAME_RE`, `migrationNumbersFromPaths(paths)`, `parseEnumChecks(sql)`, `proveLineage({ publishableFiles, privateMigrationNumbers, ctx })`, `buildRedactionContext()`, `enumDrift(files)`, `numberingDivergence(privateSet, mirrorSet)`, `runSimulation()`
|
|
99
|
-
- `mirror-redact.js` — `findLeaks(text, sensitiveLiterals)`, `buildRedactionRules(branding = {}, extra = {})`, `collectSensitiveLiterals(branding = {}, extra = {})`, `findSecretLeak(text, extraSecrets = [])`, `REDACTED_IP`, `escapeRegExp(s)`, `redactText(text, rules)`, `NEUTRAL_TOKEN`, `deriveInstanceLiterals(branding = {}, extra = {})`, `firstPublicIP(text)` _(+7 more)_
|
|
100
|
-
- `module.js` — `coreVersion()`, `MODULES_DIR`, `camel(key)`, `printHelp(out = console.log)`, `cmdUpgrade(_args, { log = console.log, errlog = console.error, gather = gatherUpgrade } = {})`, `evaluateUpgrade({ rows = [], errors = [], core } = {})`, `gatherUpgrade({ modulesDir = MODULES_DIR, core = coreVersion()`, `buildManifest(key, { core = coreVersion()`, `checkModulePublishability(key, { modulesDir = MODULES_DIR } = {})`, `claudeMdTemplate(key, manifest)` _(+8 more)_
|
|
101
|
-
- `newcomer-floor.js` — `VALID_DISCIPLINES`, `computeTemplateDeficits(supply, templatesByDisc, floorDefaults, { only = null } = {})`, `templateFloor(template, discipline, floorDefaults)`, `buildProposalFromTemplate(template, seq, { discipline } = {})`, `HARD_MAX_MINUTES`, `parseSeq(ref, discipline, templateId)`, `SOURCE_TAG`, `loadTemplates(templatesPath)`, `nextSeq(existingRefs, discipline, templateId)`, `parseRef(ref)` _(+3 more)_
|
|
102
|
-
- `newcomer-floor.test.js` — `test(name, fn)`, `deficitFor(rows, templateId)`
|
|
103
|
-
- `next-number.js` — `padMig(n)`, `nextFree(numberSet, start = 1)`, `padAdr(n)`, `nextNumbers({ runGit = defaultRunGit, readDir = defaultReadDir } = {})`, `computeNextNumbers({ committedPaths = [], localPaths = [], startAdr = 1, startMigration = 1 } = {})`, `gitTreePaths(ref, dirs, runGit)`, `parseNumbers(basenames, re)`
|
|
104
|
-
- `oauth-secret.js` — `webEnvPath(slug, { etcBase = ETC_BASE } = {})`, `provisionedEnvPrefix()`, `validateClientId(id)`, `validateClientSecret(secret)`, `CLIENT_ID_MIN_LEN`, `parseHealthzAuth(stdout)`, `SECRET_MIN_LEN`, `fillOAuthEnv(body, { prefix, clientId, clientSecret })`, `portFromEnv(body)`
|
|
105
|
-
- `onboard.js` — `oauthAppInstructions(domain)`, `buildInitSpec(a = {})`, `healthzUrl(domain)`, `onboardPlan(mode = 'greenfield')`
|
|
106
|
-
- `onboarding-analyze.js` — `acquireLock()`, `releaseLock()`, `analyzeOne(name, entry)`
|
|
107
|
-
- `onboarding-config.js` — `encodeProjectPath(absPath)`, `ensureDir(dir)`, `SPOOL_DIR`, `windowDays()`, `CONFIG_DIR`, `CONSENT_PATH`, `listTranscripts(dir)`, `readConsent()`, `MANIFEST_PATH`, `needsSpool(manifest, file)` _(+7 more)_
|
|
108
|
-
- `package-core.js` — `coreVersion()`, `octal(n, width)`, `TAR_ROOT`, `normalizeMode(mode)`, `ARTIFACT_NAME`, `MANIFEST_SCHEMA`, `processCoreFile({ pathRel, raw, rules, sensitiveLiterals, envSecrets })`, `sha256hex(buf)`, `buildPackageJson({ version, sourceDeps, sourceOverrides })`, `ustarHeader({ name, prefix = '', mode, size, typeflag })` _(+14 more)_
|
|
109
|
-
- `provision.js` — `CONFIG`, `standaloneRoot(inst, { base = CONFIG.standaloneBase } = {})`, `MAX_INTENT_ATTEMPTS`, `checkDnsTokenScope(domain, { token = <redacted>, zoneOverride = process.env.CLOUDFLARE_…)`, `webEnvPath(inst, { etcBase = CONFIG.etcBase } = {})`, `cmdRunIntents(deps)`, `cmdStatus(deps)`, `coreVersionSafe()`, `dnsUpsertEnv(inst, { publicIp, zone, proxied = false } = {})`, `provisionInstance(inst, deps)` _(+26 more)_
|
|
110
|
-
- `publish-manifest.js` — `isPublishable(relPath)`, `normalize(p)`, `matchesDeny(relPath)`, `PUBLISH_ALLOWLIST`, `PUBLISH_DENYLIST`, `PROTECTED_TOPOLOGY_EXCLUDE`, `INSTANCE_EXCLUDE`, `matchesAllow(relPath)`, `CONTENT_EXCLUDE`, `SENSITIVE_DOC_EXCLUDE` _(+1 more)_
|
|
111
|
-
- `pulse.js` — `loadDeps()`, `parseThresholdHours(args)`, `postDiscordPing(text)`, `releaseStale({ thresholdHours, dryRun })`
|
|
112
|
-
- `push-main.js` — `pushMain(extra = [])`
|
|
113
|
-
- `read-session-export.js` — `render(data, opts)`, `reduce(records)`, `loadExport(zipPath)`, `openZip(filePath)`, `readEntry(fd, entry)`
|
|
114
|
-
- `reauth.js` — `openInBrowser(url)`, `printGuidance({ opened })`
|
|
115
|
-
- `recall.js` — `parseArgs(argv)`, `truncate(s, n)`
|
|
116
|
-
- `render-ideas.js` — `fmtTimestamp(iso)`, `daysAgo(iso)`, `renderIdea(idea)`, `renderSection(heading, ideas, emptyMsg)`, `fetchAllIdeas()`, `partition(ideas)`, `render(ideas)`
|
|
117
|
-
- `repo-metrics.js` — `gatherFileSizes()`, `summarizeSizes(sizes)`, `scanDeadCode()`, `scanBranchHygiene()`, `countConfirmedUnshipped(pool)`, `upsertSnapshot(pool, snap)`
|
|
118
|
-
- `run-routine.js` — `VALID_MODES`, `parseRoutineFrontmatter(skillMd)`, `VALID_SINKS`, `tokenize(cmd)`
|
|
119
|
-
- `run-unit-tests.js` — `discoverModuleTests({ modulesDir = MODULES_DIR, isEnabled = isModuleEnabled } = {})`
|
|
120
|
-
- `sandbox-stage.js` — `stage({ taskId } = {}, deps = {})`, `BOX_ENV_PATH`, `BOX_SERVED_ROOT`, `resolvePreviewContext(deps = {})`, `computeTreeStamp(deps = {})`, `PREVIEWABLE_PATHSPECS`, `markerPath(deps = {})`, `previewUrl(deps = {})`, `runShipGate({ taskId, files, skipStage, tty, approved }, deps = {})`, `verifyServedFresh(deps = {})` _(+11 more)_
|
|
121
|
-
- `search-ingest-db.js` — `buildRows({ sourceRef, title, body, minRank = 'xenos', ownerBuilderId = null, scrub = false })`, `requirePool()`, `SOURCES`, `recentCommitRows(limit = 80)`
|
|
122
|
-
- `search-ingest-md.js` — `SENSITIVE_DOC_GLOBS`, `requirePool()`, `collectMarkdown(dir, root, out = [])`, `minRankForDoc(rel)`, `chunkFile(abs)`, `ingestFile(client, rows, sourceRef)`
|
|
123
|
-
- `<redacted>.js` — `post(path, body)`
|
|
124
|
-
- `<redacted>.js` — `post(path, body)`
|
|
125
|
-
- `seed-module-upstreaming.js` — `findOrCreateGoal()`
|
|
126
|
-
- `seed-provisioning-tasks.js` — `post(path, body)`
|
|
127
|
-
- `seed-v2-world-tasks.js` — `withRetry(fn)`
|
|
128
|
-
- `session-cost.js` — `addTiers(acc, t)`, `emptyTiers()`, `newestTranscriptFor(cwd)`, `priceTranscript(transcriptPath)`, `roundTiers(t)`, `listJsonlRecursive(dir)`, `looksLikeGraderTranscript(file)`, `priceSubagents(sessionDir)`, `addComponents(acc, components)`
|
|
129
|
-
- `session-digest.js` — `parseHookInput(stdinRaw, opts = {})`
|
|
130
|
-
- `session-eval.js` — `computeOverhead(detail)`, `evaluateSession(record)`, `detectFootguns(detail, overhead = {}, opts = {})`, `FINDING_TEMPLATES`, `findingsByBuilder(evaluated)`, `verdictFor(overheadRatio)`, `classifyTurn(turn, opts = {})`, `interpretCorpusSearch(count, opts = {})`, `summarizeSystemicFindings(evaluated, opts = {})`
|
|
131
|
-
- `session.js` — `readArgv(argv)`, `builderLocalHour(timezone)`, `isOvernightHour(hour)`, `recentShipsAllOvernightSafe(me)`, `suggestDefaults(me)`, `ask(rl, q, fallback)`, `interactive(defaults)`, `callOptimizer({ timeBudgetMin, mode, parallel })`, `fitsMode(task, mode)`, `disjointTouches(a, b)` _(+5 more)_
|
|
132
|
-
- `setup.js` — `dryRunStep(msg)`, `promptGeminiKey()`, `readLocalAnthropicAccount()`, `promptAnthropicLink()`, `promptDisciplines()`, `promptOnboardingConsent()`
|
|
133
|
-
- `shell.js` — `repoRoot()`, `runLocal({ remoteCmd, log })`
|
|
134
|
-
- `ship.js` — `buildSessionDigest(entries, opts = {})`, `computeChangedFiles(baseline)`, `sanitizeGitHubRefs(text)`, `computeGraderBaseline(claim)`, `recordUploadSkip(taskId, { code, reason }, opts = {})`, `runSubagentGrader({ task, valueSummary, baseline, changedFiles: precomputedChanged })`, `buildMergeArgv(branch, valueSummary)`, `gradeAndRecord({ taskId, task, summary, baseline, committedFiles })`, `snippetOf(text, extraSecrets, max = 160)`, `buildGradePayload(gradeResult, committedFiles = null)` _(+9 more)_
|
|
135
|
-
- `smoke-gds.js` — `isLocalTarget(hostname)`, `probeListener(host, port, timeoutMs = 1500)`
|
|
136
|
-
- `start.js` — `progressBar(percent, width = 10)`, `formatVersionsRow(progress)`, `formatCostRow(cost)`, `formatRecentRow({ recentShipped, inboxCount, blockerCount })`, `statusParts({ progress, recentShipped, inboxCount, blockerCount })`, `quietStatusLine(header)`, `estimateShort(t)`, `clip(s, n)`, `cell(s)`, `disciplineLabel(t)` _(+10 more)_
|
|
137
|
-
- `status.js` — `parseArgs(argv)`, `renderStatusWidget(data, criterion)`, `renderStatusMarkdown(data, criterion)`
|
|
138
|
-
- `triage.js` — `formatDevelopment(block)`, `loadDevelopment(path)`, `parseDevelopment(text)`, `resolveDevelopmentPath(argv = process.argv, env = process.env)`
|
|
139
|
-
- `upgrade.js` — `parseArgs(argv)`, `CORE_PKG`, `ARTIFACT`, `npmInstall(instanceDir, run = spawnSync)`, `readInstalledCoreVersion(instanceDir, fsImpl = fs)`, `regenerateApiArtifacts({ instanceDir, coreRoot }, run = spawnSync, fsImpl = fs)`, `vendorTarball({ instanceDir, fromTgz, targetVersion }, fsImpl = fs)`, `versionFromTgzPath(p)`, `gitTreeClean(instanceDir, run = spawnSync)`, `pollHealth(healthUrl, deps = {})` _(+8 more)_
|
|
140
|
-
- `validate-design.js` — `readJson(filePath, label)`, `deepMerge(base, override)`, `isUri(s)`, `dirExists(p)`, `fileExists(p)`, `listDirs(p)`
|
|
141
|
-
- `version-close.js` — `parseArgs(argv)`, `buildCommitMessage({ versionId, nextVersionId, shippedCount, carryCount })`, `buildManualSql({ versionId, versionName, nextVersionId, nextScopeDocPath, carryOverTasks, nextVersionExis…)`, `buildNextVersionStub({ nextVersionId, prevVersionId, carryOverTasks })`, `buildShippedArchive({ versionId, versionName, scopeDocPath, shippedTasks, originalScopeBody, shippedAt })`, `deriveNextScopePath(currentPath, nextVersionId)`, `deriveNextVersionId(currentId)`, `deriveShippedPath(currentPath, versionId)`
|
|
142
|
-
<!-- END GENERATED REPO-MAP -->
|
|
143
|
-
|
|
144
|
-
**See also.** `.claude/skills/builder-*` skill docs · [ADR 0061](../../docs/adr/<redacted>.md) · [docs/recipes/ops-gotchas.md](../../docs/recipes/ops-gotchas.md) · [src/bongos/](../../src/bongos/) (the server side these call).
|
|
14
|
+
_To work ON the platform core itself, use the standalone @bongos/core source repository,
|
|
15
|
+
not this vendored copy._
|
package/scripts/gds/claim.js
CHANGED
|
@@ -143,7 +143,88 @@ function printClaimCard(task, widgetsEnabled = true) {
|
|
|
143
143
|
} catch (_) { /* never block a claim on the card */ }
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
// task 1476: render a failed claim as GUIDANCE, not a raw object dump. The API
|
|
147
|
+
// returns the R01 error envelope (ADR 0116): { error: { code, message, details } }.
|
|
148
|
+
// Older paths returned a flat { error: 'CODE', ...fields } shape. This normalizes
|
|
149
|
+
// BOTH — without it `r.data.error` is now an object (never === a string), so every
|
|
150
|
+
// branch below silently missed and the refusal printed as `[object Object]`. Pure
|
|
151
|
+
// (no console / no process.exit) + exported so it can be unit-tested against the
|
|
152
|
+
// real envelope shapes. Returns { lines, exit }.
|
|
153
|
+
function formatClaimFailure(r, taskId) {
|
|
154
|
+
const lines = [];
|
|
155
|
+
const errRaw = r && r.data ? r.data.error : undefined;
|
|
156
|
+
const isEnvelope = errRaw !== null && typeof errRaw === 'object';
|
|
157
|
+
const code = isEnvelope ? errRaw.code : errRaw;
|
|
158
|
+
const message = isEnvelope ? errRaw.message : undefined;
|
|
159
|
+
// Structured fields live under .details in the envelope; fall back to the
|
|
160
|
+
// top-level body for the legacy flat shape (so both keep working).
|
|
161
|
+
const d = { ...(r && r.data ? r.data : {}), ...((isEnvelope && errRaw.details) || {}) };
|
|
162
|
+
|
|
163
|
+
// #766: a generic onboarding stage gate (kept rendering cleanly, not as raw JSON).
|
|
164
|
+
if (code === 'stage_required') {
|
|
165
|
+
lines.push(`Task #${taskId} can't be claimed yet.`);
|
|
166
|
+
lines.push(` ${d.what_to_do || `Clear "${d.required_stage_label || d.required_stage}" first.`}`);
|
|
167
|
+
return { lines, exit: 1 };
|
|
168
|
+
}
|
|
169
|
+
// task 1476 (the core case): a session may hold at most ONE active claim
|
|
170
|
+
// (task 1642 / ADR 0097). This is the most common refusal and previously fell
|
|
171
|
+
// straight through to the raw dump — the exact "reads like you can't hold more
|
|
172
|
+
// than one task" complaint from idea 218. Surface it as guidance AND teach how
|
|
173
|
+
// to parallelize (a separate worktree/session per task, or the hall bulk-claim).
|
|
174
|
+
if (code === 'session_already_has_active_claim' || code === 'session_claim_check_failed') {
|
|
175
|
+
const n = d.active_task_id;
|
|
176
|
+
lines.push(n
|
|
177
|
+
? `This session already holds task #${n}${d.active_task_title ? `: ${d.active_task_title}` : ''}.`
|
|
178
|
+
: 'This session already holds an active claim.');
|
|
179
|
+
lines.push(` ${d.what_to_do || (n
|
|
180
|
+
? `Run /builder-ship ${n} (or /builder-release ${n}) first, or open a fresh worktree/session for this task.`
|
|
181
|
+
: 'Ship or release the in-flight claim, or start a fresh worktree/session.')}`);
|
|
182
|
+
lines.push(' One claim per session keeps each ship isolated (task 1642). To work tasks in PARALLEL, open a separate worktree/session per task — each holds its own single claim — or use the hall work board’s multi-select bulk-claim.');
|
|
183
|
+
return { lines, exit: 1 };
|
|
184
|
+
}
|
|
185
|
+
if (code === 'newcomer_must_ship_first') {
|
|
186
|
+
lines.push(`Task #${taskId} can't be claimed yet — your first work isn't shipped.`);
|
|
187
|
+
lines.push(` You're holding an active claim on #${d.active_task_id}: ${d.active_task_title}`);
|
|
188
|
+
lines.push(` ${d.what_to_do || 'Ship or release the current claim first.'}`);
|
|
189
|
+
return { lines, exit: 1 };
|
|
190
|
+
}
|
|
191
|
+
if (code === 'ALREADY_CLAIMED') {
|
|
192
|
+
lines.push(`Task #${taskId} was just claimed by another session. Try a different task.`);
|
|
193
|
+
return { lines, exit: 1 };
|
|
194
|
+
}
|
|
195
|
+
if (code === 'MODULE_CONFLICT') {
|
|
196
|
+
lines.push(`Task #${taskId} has module_key='${d.module_key}', but another active claim already owns that module:`);
|
|
197
|
+
for (const t of d.conflictTaskTitles || []) lines.push(` - ${t}`);
|
|
198
|
+
lines.push('Two tasks in the same module cannot run concurrently. Ship or release the in-flight claim first.');
|
|
199
|
+
return { lines, exit: 1 };
|
|
200
|
+
}
|
|
201
|
+
if (code === 'TOUCHES_CONFLICT') {
|
|
202
|
+
lines.push(`Task #${taskId} touches files currently in flight on another claim:`);
|
|
203
|
+
for (const t of d.conflictTaskTitles || []) lines.push(` - ${t}`);
|
|
204
|
+
lines.push('Pick a task with disjoint touches[], or run it in a separate session once the other ships.');
|
|
205
|
+
return { lines, exit: 1 };
|
|
206
|
+
}
|
|
207
|
+
if (code === 'TASK_NOT_READY') {
|
|
208
|
+
lines.push(`Task #${taskId} is not ready (current status: ${d.currentStatus}).`);
|
|
209
|
+
if (d.hint) lines.push(` ${d.hint}`);
|
|
210
|
+
return { lines, exit: 1 };
|
|
211
|
+
}
|
|
212
|
+
if (code === 'TASK_NOT_FOUND') {
|
|
213
|
+
lines.push(`Task #${taskId} not found — check the id (run /builder-start to list claimable tasks).`);
|
|
214
|
+
return { lines, exit: 1 };
|
|
215
|
+
}
|
|
216
|
+
if (code === 'DEPS_NOT_SHIPPED') {
|
|
217
|
+
lines.push(`Task #${taskId} can't be claimed yet — these dependencies are not shipped:`);
|
|
218
|
+
for (const dep of d.deps || []) lines.push(` - #${dep.id} [${dep.status}] ${dep.title}`);
|
|
219
|
+
lines.push('Ship those first (or release them) and try again.');
|
|
220
|
+
return { lines, exit: 1 };
|
|
221
|
+
}
|
|
222
|
+
// Fallback — still readable: the message + code, never a raw [object Object].
|
|
223
|
+
lines.push(`Claim failed (${r ? r.status : '?'})${code ? ` [${code}]` : ''}${message ? `: ${message}` : ''}.`);
|
|
224
|
+
return { lines, exit: 1 };
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async function main() {
|
|
147
228
|
await requireSession();
|
|
148
229
|
const args = process.argv.slice(2);
|
|
149
230
|
const taskId = Number(args[0]);
|
|
@@ -283,51 +364,20 @@ function printClaimCard(task, widgetsEnabled = true) {
|
|
|
283
364
|
printClaimCard(task, widgetsEnabled);
|
|
284
365
|
return;
|
|
285
366
|
}
|
|
286
|
-
//
|
|
287
|
-
//
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
console.error(
|
|
298
|
-
process.exit(1);
|
|
299
|
-
}
|
|
300
|
-
if (r.data?.error === 'ALREADY_CLAIMED') {
|
|
301
|
-
console.error(`Task #${taskId} was just claimed by another session. Try a different task.`);
|
|
302
|
-
process.exit(1);
|
|
303
|
-
}
|
|
304
|
-
if (r.data?.error === 'MODULE_CONFLICT') {
|
|
305
|
-
console.error(`Task #${taskId} has module_key='${r.data.module_key}', but another active claim already owns that module:`);
|
|
306
|
-
for (const t of r.data.conflictTaskTitles || []) console.error(` - ${t}`);
|
|
307
|
-
console.error('Two tasks in the same module cannot run concurrently. Ship or release the in-flight claim first.');
|
|
308
|
-
process.exit(1);
|
|
309
|
-
}
|
|
310
|
-
if (r.data?.error === 'TOUCHES_CONFLICT') {
|
|
311
|
-
console.error(`Task #${taskId} touches files currently in flight on another claim:`);
|
|
312
|
-
for (const t of r.data.conflictTaskTitles || []) console.error(` - ${t}`);
|
|
313
|
-
console.error('Pick a task with disjoint touches[].');
|
|
314
|
-
process.exit(1);
|
|
315
|
-
}
|
|
316
|
-
if (r.data?.error === 'TASK_NOT_READY') {
|
|
317
|
-
console.error(`Task #${taskId} is not ready (current status: ${r.data.currentStatus}).`);
|
|
318
|
-
process.exit(1);
|
|
319
|
-
}
|
|
320
|
-
if (r.data?.error === 'DEPS_NOT_SHIPPED') {
|
|
321
|
-
console.error(`Task #${taskId} can't be claimed yet — these dependencies are not shipped:`);
|
|
322
|
-
for (const d of r.data.deps || []) {
|
|
323
|
-
console.error(` - #${d.id} [${d.status}] ${d.title}`);
|
|
324
|
-
}
|
|
325
|
-
console.error('Ship those first (or release them) and try again.');
|
|
367
|
+
// Any non-201 comes here. formatClaimFailure normalizes the R01 error envelope
|
|
368
|
+
// and renders the refusal as guidance (task 1476) — one place, unit-tested.
|
|
369
|
+
const failure = formatClaimFailure(r, taskId);
|
|
370
|
+
for (const line of failure.lines) console.error(line);
|
|
371
|
+
process.exit(failure.exit);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Only auto-run when invoked directly (`node claim.js …`); a `require()` (the
|
|
375
|
+
// unit test) just imports formatClaimFailure without executing the claim flow.
|
|
376
|
+
if (require.main === module) {
|
|
377
|
+
main().catch((err) => {
|
|
378
|
+
console.error('fatal:', err);
|
|
326
379
|
process.exit(1);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
console.error('fatal:', err);
|
|
332
|
-
process.exit(1);
|
|
333
|
-
});
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
module.exports = { formatClaimFailure };
|