@bongos/core 1.17.0
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 +5727 -0
- package/.claude/skills/blocker-review/SKILL.md +91 -0
- package/.claude/skills/blocker-solve/SKILL.md +96 -0
- package/.claude/skills/builder-backup/SKILL.md +54 -0
- package/.claude/skills/builder-box/SKILL.md +45 -0
- package/.claude/skills/builder-claim/SKILL.md +76 -0
- package/.claude/skills/builder-connect/SKILL.md +59 -0
- package/.claude/skills/builder-cost/SKILL.md +47 -0
- package/.claude/skills/builder-end/SKILL.md +81 -0
- package/.claude/skills/builder-exit/SKILL.md +88 -0
- package/.claude/skills/builder-key/SKILL.md +40 -0
- package/.claude/skills/builder-reauth/SKILL.md +50 -0
- package/.claude/skills/builder-redteam/SKILL.md +109 -0
- package/.claude/skills/builder-release/SKILL.md +41 -0
- package/.claude/skills/builder-setup/SKILL.md +62 -0
- package/.claude/skills/builder-ship/SKILL.md +79 -0
- package/.claude/skills/builder-stage/SKILL.md +51 -0
- package/.claude/skills/builder-start/SKILL.md +46 -0
- package/.claude/skills/close-box/SKILL.md +43 -0
- package/.claude/skills/design-sync/SKILL.md +69 -0
- package/.claude/skills/dev/SKILL.md +49 -0
- package/.claude/skills/feedback/SKILL.md +32 -0
- package/.claude/skills/figma-design-sync/SKILL.md +74 -0
- package/.claude/skills/goal-review/SKILL.md +89 -0
- package/.claude/skills/idea-triage/SKILL.md +144 -0
- package/.claude/skills/ideate/SKILL.md +82 -0
- package/.claude/skills/merge-mode/SKILL.md +169 -0
- package/.claude/skills/new-project/SKILL.md +108 -0
- package/.claude/skills/otb-character-review/SKILL.md +71 -0
- package/.claude/skills/otb-design-review/SKILL.md +47 -0
- package/.claude/skills/otb-feedback-capture/SKILL.md +45 -0
- package/.claude/skills/otb-figma-sync/SKILL.md +54 -0
- package/.claude/skills/otb-tile-generate/SKILL.md +45 -0
- package/.claude/skills/paint/SKILL.md +70 -0
- package/.claude/skills/planning-session/SKILL.md +299 -0
- package/.claude/skills/priority-session/SKILL.md +134 -0
- package/.claude/skills/read-session-export/SKILL.md +58 -0
- package/.claude/skills/recall/SKILL.md +52 -0
- package/.claude/skills/session-handoff/SKILL.md +46 -0
- package/.claude/skills/status/SKILL.md +33 -0
- package/.devcontainer/Dockerfile +69 -0
- package/.devcontainer/README.md +73 -0
- package/.devcontainer/devcontainer-lock.json +19 -0
- package/.devcontainer/devcontainer.json +93 -0
- package/.devcontainer/healthcheck.sh +84 -0
- package/.devcontainer/init-firewall.sh +198 -0
- package/.devcontainer/post-create.sh +153 -0
- package/.dockerignore +36 -0
- package/.env.local.example +32 -0
- package/.gitattributes +83 -0
- package/.gitignore +91 -0
- package/CLAUDE.md +242 -0
- package/CODE_OF_CONDUCT.md +46 -0
- package/CONTRIBUTING.md +51 -0
- package/Dockerfile +46 -0
- package/GOVERNANCE.md +44 -0
- package/LICENSE +661 -0
- package/README.md +88 -0
- package/bin/bongos.js +222 -0
- package/clients/bongos-client/README.md +48 -0
- package/clients/bongos-client/bongos-client.global.js +617 -0
- package/clients/bongos-client/examples/hello-world.mjs +62 -0
- package/clients/bongos-client/index.cjs +619 -0
- package/clients/bongos-client/index.d.ts +793 -0
- package/clients/bongos-client/index.mjs +614 -0
- package/clients/bongos-client/package.json +32 -0
- package/config/branding.neutral.json +60 -0
- package/config/design-tokens.neutral.json +51 -0
- package/config/design-tokens.schema.json +96 -0
- package/config/modules.neutral.json +9 -0
- package/docker-compose.yml +52 -0
- package/docker-entrypoint.sh +30 -0
- package/docs/adr/0001-stack-choice-single-vps.md +45 -0
- package/docs/adr/0002-digitalocean-over-hetzner.md +27 -0
- package/docs/adr/0003-cloudflare-origin-cert-over-letsencrypt.md +35 -0
- package/docs/adr/0004-amazonprimea-name-and-trademark-acceptance.md +45 -0
- package/docs/adr/0005-invisible-other-players-in-v1.md +37 -0
- package/docs/adr/0006-singleton-worldroom-plus-queueroom.md +30 -0
- package/docs/adr/0007-persistent-identity-via-localstorage-uuid.md +31 -0
- package/docs/adr/0008-family-based-tile-generation.md +86 -0
- package/docs/adr/0008-google-chat-oauth-user-auth.md +37 -0
- package/docs/adr/0009-autotile-architecture.md +181 -0
- package/docs/adr/0010-pms-architecture.md +70 -0
- package/docs/adr/0011-terrain-id-rendering-model.md +174 -0
- package/docs/adr/0012-ground-object-cell-split.md +208 -0
- package/docs/adr/0013-paths-as-object-overlays-with-autotile-dispatch.md +158 -0
- package/docs/adr/0014-families-canonical-over-vocabulary.md +103 -0
- package/docs/adr/0015-task-dependencies-and-auto-promotion.md +125 -0
- package/docs/adr/0016-trust-boundary-server-enforced-permissions.md +132 -0
- package/docs/adr/0017-code-simplification-and-repo-cleanliness.md +74 -0
- package/docs/adr/0018-three-rank-model-goes-live.md +97 -0
- package/docs/adr/0019-red-team-bounty-payout-table.md +52 -0
- package/docs/adr/0020-security-model-public-stub.md +70 -0
- package/docs/adr/0021-per-builder-skill-model-preferences.md +99 -0
- package/docs/adr/0022-secrets-policy.md +124 -0
- package/docs/adr/0023-kind-multipliers-and-idea-bonus.md +118 -0
- package/docs/adr/0024-cloneable-repo-local-first-memory.md +277 -0
- package/docs/adr/0024-multi-agent-system-architecture.md +125 -0
- package/docs/adr/0025-offsite-backup-vendor-digitalocean-spaces.md +59 -0
- package/docs/adr/0025-structured-criterion-task-link.md +44 -0
- package/docs/adr/0026-bfg-memory-hygiene-and-cross-builder-learning.md +117 -0
- package/docs/adr/0027-bfg-session-inefficiency-evaluator.md +170 -0
- package/docs/adr/0028-honest-llm-spend-accounting.md +109 -0
- package/docs/adr/0029-status-page-outage-resilience.md +59 -0
- package/docs/adr/0030-builders-hall-live-updates.md +59 -0
- package/docs/adr/0031-cloud-dev-environments-for-builders.md +222 -0
- package/docs/adr/0032-discord-mirror-of-gds.md +50 -0
- package/docs/adr/0033-discord-bot-service-principal.md +82 -0
- package/docs/adr/0034-thetes-graduated-newcomer-rank.md +53 -0
- package/docs/adr/0035-builder-onboarding-three-paths.md +128 -0
- package/docs/adr/0036-builders-subdomain-and-ui-reorg.md +40 -0
- package/docs/adr/0037-discord-channel-management.md +51 -0
- package/docs/adr/0038-chromebook-ttyd-cloudflare-tunnel.md +111 -0
- package/docs/adr/0039-setup-first-onboarding-ux.md +49 -0
- package/docs/adr/0040-remote-control-default-browser-onramp.md +47 -0
- package/docs/adr/0041-temporary-grader-bypass-killswitch.md +40 -0
- package/docs/adr/0042-builder-self-deploy-ci-auto-merge.md +82 -0
- package/docs/adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md +74 -0
- package/docs/adr/0044-mediterranean-palette-replacement.md +73 -0
- package/docs/adr/0044-per-box-live-game-preview.md +57 -0
- package/docs/adr/0045-devbox-desktop-app.md +133 -0
- package/docs/adr/0046-sandbox-first-review-gate.md +72 -0
- package/docs/adr/0047-discord-bugs-intake-anti-abuse.md +36 -0
- package/docs/adr/0048-works-in-progress-ia-split.md +32 -0
- package/docs/adr/0049-split-parallel-safety-contract.md +46 -0
- package/docs/adr/0050-device-flow-admission-invite-gated-by-default.md +43 -0
- package/docs/adr/0051-full-session-transcript-corpus.md +57 -0
- package/docs/adr/0052-sandbox-for-everyone-game-only-preview.md +70 -0
- package/docs/adr/0053-scoped-dev-box-session.md +55 -0
- package/docs/adr/0054-session-token-reward-cost-plus.md +63 -0
- package/docs/adr/0055-server-mediated-branch-publish.md +47 -0
- package/docs/adr/0056-prod-deploy-script-mirror-and-healthcheck-retry.md +62 -0
- package/docs/adr/0057-container-cost-ledger.md +28 -0
- package/docs/adr/0057-discord-archon-approval-channels.md +64 -0
- package/docs/adr/0058-automatic-gate-surface-gatekeeper.md +64 -0
- package/docs/adr/0059-single-approval-remove-devbox-approval-gate.md +37 -0
- package/docs/adr/0060-gds-retrieval-layer.md +97 -0
- package/docs/adr/0061-context-layer-decomposition.md +61 -0
- package/docs/adr/0062-medusa-instance-model-decoupling.md +107 -0
- package/docs/adr/0063-generated-repo-map-symbol-skeleton.md +44 -0
- package/docs/adr/0064-rename-medusa-to-cloud-bongos.md +49 -0
- package/docs/adr/0065-agpl-nonprofit-ai-first-governance.md +69 -0
- package/docs/adr/0066-generated-file-map-sections.md +51 -0
- package/docs/adr/0067-session-start-fast-forward-pull.md +43 -0
- package/docs/adr/0068-shared-art-key-for-newcomers.md +38 -0
- package/docs/adr/0069-hall-live-channel-sse-decouple.md +35 -0
- package/docs/adr/0070-deterministic-session-card-delivery.md +44 -0
- package/docs/adr/0071-box-confirm-before-destroyed-and-drift-reconcile.md +59 -0
- package/docs/adr/0072-bongos-app-mac-signed-first-windows-deferred.md +35 -0
- package/docs/adr/0072-dev-box-code-staleness-visibility.md +39 -0
- package/docs/adr/0073-builder-needs-signal-and-byok-gemini-key.md +64 -0
- package/docs/adr/0073-secrets-scan-exclude-uri-detector.md +37 -0
- package/docs/adr/0074-memory-map-stays-light.md +32 -0
- package/docs/adr/0075-per-system-cost-attribution.md +37 -0
- package/docs/adr/0076-in-session-deterministic-compaction.md +58 -0
- package/docs/adr/0077-content-addressed-llm-cache.md +32 -0
- package/docs/adr/0078-deterministic-first-cron.md +48 -0
- package/docs/adr/0079-value-gated-autonomous-engagement.md +39 -0
- package/docs/adr/0080-llm-cache-api-transport-and-trust-model.md +46 -0
- package/docs/adr/0081-tool-agnostic-design-layer.md +62 -0
- package/docs/adr/0082-productized-key-storage-provisioning.md +32 -0
- package/docs/adr/0082-server-side-merge-conflict-auto-resolution.md +55 -0
- package/docs/adr/0083-modular-architecture-strangler-build-plan.md +143 -0
- package/docs/adr/0084-auto-derived-per-task-rank-floor.md +86 -0
- package/docs/adr/0085-remove-default-per-builder-spend-cap.md +39 -0
- package/docs/adr/0086-goal-scoped-work-hierarchy.md +123 -0
- package/docs/adr/0087-bongos-app-architecture-and-handoff-contract.md +49 -0
- package/docs/adr/0087-compete-on-governance-not-tooling-cursor.md +65 -0
- package/docs/adr/0088-consistent-character-generative-animation.md +169 -0
- package/docs/adr/0089-modular-multi-model-adversarial-grader.md +179 -0
- package/docs/adr/0090-metic-task-authoring.md +73 -0
- package/docs/adr/0091-bounding-the-kernel-and-db-carve.md +106 -0
- package/docs/adr/0092-hosting-module-and-on-prem-target.md +117 -0
- package/docs/adr/0093-tranche-2-core-carve-sequence.md +72 -0
- package/docs/adr/0094-repo-atlas-self-drawing-codebase-map.md +49 -0
- package/docs/adr/0095-borrowed-memory-and-retrieval-concepts.md +65 -0
- package/docs/adr/0095-cross-agent-context-management.md +58 -0
- package/docs/adr/0096-require-reward-before-workable.md +209 -0
- package/docs/adr/0097-one-active-claim-per-session-and-worktree-binding.md +46 -0
- package/docs/adr/0097-retroactive-reward-backfill.md +124 -0
- package/docs/adr/0098-public-mirror-publish-manifest.md +92 -0
- package/docs/adr/0099-delayed-redacted-mirror-export.md +55 -0
- package/docs/adr/0100-two-repo-instance-model.md +60 -0
- package/docs/adr/0101-goal-hierarchy-phase-5-judge-membership-reward.md +90 -0
- package/docs/adr/0102-finish-bounding-the-kernel.md +36 -0
- package/docs/adr/0103-core-first-extraction-cloud-bongos-trunk.md +70 -0
- package/docs/adr/0103-gdsv4-bongos-consolidation.md +28 -0
- package/docs/adr/0104-trust-gds-api-channel-in-auto-mode.md +42 -0
- package/docs/adr/0105-instance-seed-migrations-out-of-core.md +47 -0
- package/docs/adr/0106-goal-owner-manager-authority.md +84 -0
- package/docs/adr/0107-module-upstreaming-contribution-to-core-catalog.md +83 -0
- package/docs/adr/0108-instance-composition-configurable-root.md +87 -0
- package/docs/adr/0109-self-describing-openapi-and-hosted-docs.md +44 -0
- package/docs/adr/0110-untrack-whole-file-generated-nav-docs.md +49 -0
- package/docs/adr/0111-instance-hosting-provisioning-module.md +135 -0
- package/docs/adr/0112-private-goals-invitations-join-requests.md +72 -0
- package/docs/adr/0113-sandbox-studio-descope-superseded-by-0044-0052.md +41 -0
- package/docs/adr/0114-instance-docs-discovery-contract.md +32 -0
- package/docs/adr/0115-scheduled-routines-portability.md +31 -0
- package/docs/adr/0116-api-error-envelope-and-code-taxonomy.md +62 -0
- package/docs/adr/0117-api-versioning-and-deprecation-policy.md +50 -0
- package/docs/adr/0118-api-contract-source-of-truth-code-first.md +47 -0
- package/docs/adr/0119-api-pagination-contract.md +34 -0
- package/docs/adr/0120-pay-on-land-and-builder-owned-rebase-gate.md +108 -0
- package/docs/adr/0121-greenfield-vs-brownfield-onboarding-adopt-existing-repo.md +97 -0
- package/docs/adr/0122-onboarding-diagram-renders-deploy-rendered-off-git.md +43 -0
- package/docs/adr/0123-box-idle-sweep-autosave-before-destroy.md +36 -0
- package/docs/adr/0124-typed-api-response-bodies.md +37 -0
- package/docs/adr/0125-control-plane-scaffolds-standalone-instance-repo.md +36 -0
- package/docs/adr/0126-dedicated-cloudbongos-control-plane-droplet.md +30 -0
- package/docs/adr/0127-cross-box-fleet-observability.md +64 -0
- package/docs/adr/0128-provisioning-runner-privilege-and-db-auth-model.md +46 -0
- package/docs/adr/0129-cloudbongos-control-plane-pull-deploy.md +34 -0
- package/docs/adr/0130-provision-remote-exec-over-ssh.md +61 -0
- package/docs/adr/0131-rank-scoped-skill-visibility.md +47 -0
- package/docs/adr/0132-cohost-fleet-control-plane-migration.md +54 -0
- package/docs/adr/0133-github-app-manifest-onboarding-signin.md +42 -0
- package/docs/adr/0134-private-first-npm-distribution.md +38 -0
- package/docs/adr/README.md +208 -0
- package/docs/api/openapi.json +13720 -0
- package/docs/api-reference.md +437 -0
- package/docs/architecture.md +244 -0
- package/docs/branding-contract.md +66 -0
- package/docs/branding-fill-prompt.md +25 -0
- package/docs/canonical-permissions.md +241 -0
- package/docs/design/container-exterior-tiles.md +49 -0
- package/docs/design/container-exterior.md +81 -0
- package/docs/design/container-interior.md +77 -0
- package/docs/design/modular-architecture/00-research-report.md +107 -0
- package/docs/design/modular-architecture/01-architecture.md +125 -0
- package/docs/design/modular-architecture/02-module-map.md +116 -0
- package/docs/design/modular-architecture/03-builder-flows.md +104 -0
- package/docs/design/modular-architecture/04-module-lifecycle.md +62 -0
- package/docs/design/modular-architecture/README.md +27 -0
- package/docs/design/vanilla-hall-ui-redesign-scope.md +284 -0
- package/docs/design/world-map-scroll.md +41 -0
- package/docs/design-contract.md +320 -0
- package/docs/file-map.md +418 -0
- package/docs/handoff-template.md +92 -0
- package/docs/modules-contract.md +293 -0
- package/docs/onboarding/browser-terminal-guide.md +73 -0
- package/docs/onboarding/diagrams/01-task-lifecycle.mmd +28 -0
- package/docs/onboarding/diagrams/02-rank-ladder.mmd +54 -0
- package/docs/onboarding/diagrams/03-drachmae-karma.mmd +37 -0
- package/docs/onboarding/diagrams/04-architecture.mmd +51 -0
- package/docs/onboarding/diagrams/05-versioning.mmd +29 -0
- package/docs/onboarding/diagrams/README.md +94 -0
- package/docs/onboarding/diagrams/assertions.json +170 -0
- package/docs/onboarding/diagrams/puppeteer-config.json +1 -0
- package/docs/onboarding/diagrams/render-config.json +9 -0
- package/docs/onboarding/drachmae-and-karma.md +178 -0
- package/docs/onboarding/primer.md +202 -0
- package/docs/project-context.template.md +67 -0
- package/docs/recipes/README.md +35 -0
- package/docs/recipes/audit-replay.md +100 -0
- package/docs/recipes/bongos-cli-release.md +66 -0
- package/docs/recipes/builder-box-lifecycle.md +152 -0
- package/docs/recipes/claude-design-loop.md +143 -0
- package/docs/recipes/claude-gemini-bongos-doors.md +155 -0
- package/docs/recipes/cloudbongos-staging-gate.md +139 -0
- package/docs/recipes/cloudbongos-standup.md +111 -0
- package/docs/recipes/devbox-app-release.md +93 -0
- package/docs/recipes/devbox-app-windows-test.md +128 -0
- package/docs/recipes/failed-ship-recovery-proof.md +102 -0
- package/docs/recipes/figma-design-loop.md +129 -0
- package/docs/recipes/gds-db-backup.md +255 -0
- package/docs/recipes/instance-deploy.md +37 -0
- package/docs/recipes/managed-settings-remote-control.md +416 -0
- package/docs/recipes/memory-backup.md +71 -0
- package/docs/recipes/memory-sync-conflicts.md +98 -0
- package/docs/recipes/multi-builder-merge.md +78 -0
- package/docs/recipes/ops-gotchas.md +212 -0
- package/docs/recipes/overnight-builder.md +53 -0
- package/docs/recipes/packaging-the-core.md +49 -0
- package/docs/recipes/parallel-load-results-2026-05-30.md +63 -0
- package/docs/recipes/parallel-load-test.md +32 -0
- package/docs/recipes/pixel-art-pipeline.md +411 -0
- package/docs/recipes/private-npm-distribution.md +79 -0
- package/docs/recipes/search-index-ingestion.md +67 -0
- package/docs/recipes/self-host.md +60 -0
- package/docs/recipes/ship-and-regrade.md +72 -0
- package/docs/recipes/staging-data.md +50 -0
- package/docs/recipes/staging-environment.md +215 -0
- package/docs/recipes/upgrading-the-core.md +58 -0
- package/docs/research/cursor-competitive-analysis.md +255 -0
- package/docs/research/llm-model-agnostic-and-cheaper-grader.md +227 -0
- package/migrations/003_pms.sql +284 -0
- package/migrations/004_pms_cost_idempotency.sql +13 -0
- package/migrations/005_pms_smoke_filter.sql +44 -0
- package/migrations/006_pms_v2.sql +378 -0
- package/migrations/007_pms_v2_hierarchy_trigger.sql +59 -0
- package/migrations/008_pms_v2_migration_allocator.sql +27 -0
- package/migrations/009_pms_v2_blockers_table.sql +68 -0
- package/migrations/010_uptime.sql +29 -0
- package/migrations/011_backfill_v2_v3_done_when.sql +20 -0
- package/migrations/012_pms_v2_task_lifecycle_states.sql +82 -0
- package/migrations/013_claim_locking.sql +22 -0
- package/migrations/014_pms_task_discipline.sql +86 -0
- package/migrations/015_pms_estimation_calibration.sql +140 -0
- package/migrations/016_pms_task_grades.sql +60 -0
- package/migrations/017_version_progress_exclude_abandoned.sql +49 -0
- package/migrations/019_rename_pms_v3_to_gds_v3.sql +65 -0
- package/migrations/020_task_dependencies.sql +99 -0
- package/migrations/021_v3_renumber_and_deps.sql +224 -0
- package/migrations/022_v3_reconcile_dep_gated_status.sql +41 -0
- package/migrations/023_pms_rank.sql +30 -0
- package/migrations/025_builder_exit_status.sql +15 -0
- package/migrations/027_builders_preferred_disciplines.sql +46 -0
- package/migrations/028_tasks_parallel_safe.sql +71 -0
- package/migrations/029_rank_three_live.sql +32 -0
- package/migrations/030_vulnerability_reports.sql +61 -0
- package/migrations/031_reward_simplification.sql +57 -0
- package/migrations/032_repo_health_snapshots.sql +56 -0
- package/migrations/033_audit_log.sql +64 -0
- package/migrations/034_lifecycle_breakdown_leaf_only.sql +62 -0
- package/migrations/035_auth_token_hygiene.sql +66 -0
- package/migrations/037_builder_skill_model_prefs.sql +44 -0
- package/migrations/038_task_override_requests.sql +51 -0
- package/migrations/039_newcomer_friendly_column.sql +124 -0
- package/migrations/040_builder_karma.sql +58 -0
- package/migrations/041_kind_multipliers_and_idea_bonus.sql +42 -0
- package/migrations/042_criterion_proposal_workflow.sql +78 -0
- package/migrations/043_builder_onboarding_observability.sql +66 -0
- package/migrations/044_tasks_requires_rank.sql +97 -0
- package/migrations/045_builder_onboarding_state.sql +147 -0
- package/migrations/046_cost_log_builder_attribution.sql +42 -0
- package/migrations/054_builder_memory.sql +108 -0
- package/migrations/055_task_criteria.sql +90 -0
- package/migrations/058_peer_votes.sql +41 -0
- package/migrations/059_onboarding_pick_disciplines.sql +59 -0
- package/migrations/060_access_requests.sql +46 -0
- package/migrations/061_backfill_override_ship_attribution.sql +29 -0
- package/migrations/062_session_records.sql +34 -0
- package/migrations/063_session_records_tool_errors_idx.sql +11 -0
- package/migrations/064_grade_attempts.sql +18 -0
- package/migrations/065_bfg_principal.sql +58 -0
- package/migrations/066_live_notify_triggers.sql +69 -0
- package/migrations/067_builder_boxes.sql +117 -0
- package/migrations/067_discord_bot_foundation.sql +69 -0
- package/migrations/068_thetes_requires_rank.sql +27 -0
- package/migrations/069_builder_ssh_keys.sql +66 -0
- package/migrations/070_box_intents.sql +101 -0
- package/migrations/071_box_first_provision_approval.sql +46 -0
- package/migrations/072_onboarding_ship_three_remove_primer.sql +80 -0
- package/migrations/073_box_terminal_access.sql +46 -0
- package/migrations/075_builder_sound_prefs.sql +28 -0
- package/migrations/078_box_claude_active.sql +22 -0
- package/migrations/079_box_first_connected_at.sql +20 -0
- package/migrations/081_tasks_needs_migration.sql +34 -0
- package/migrations/084_tasks_security_sensitive.sql +24 -0
- package/migrations/085_security_engagement_docs.sql +34 -0
- package/migrations/086_rename_disciplines.sql +125 -0
- package/migrations/088_builders_anthropic_link.sql +28 -0
- package/migrations/089_builders_monthly_budget.sql +19 -0
- package/migrations/090_box_scoped_sessions.sql +38 -0
- package/migrations/091_session_token_reward.sql +44 -0
- package/migrations/093_tasks_sandbox_review.sql +22 -0
- package/migrations/102_remove_box_first_provision_approval.sql +58 -0
- package/migrations/103_search_chunks.sql +90 -0
- package/migrations/104_builder_box_blocked.sql +34 -0
- package/migrations/105_box_host_keys.sql +35 -0
- package/migrations/111_medusa_customer0_framing.sql +35 -0
- package/migrations/112_drop_track_check.sql +25 -0
- package/migrations/113_merge_lease.sql +16 -0
- package/migrations/114_cloudbongos_rename_live_strings.sql +32 -0
- package/migrations/118_currency_label_decoupling.sql +23 -0
- package/migrations/119_builder_behavior_prefs.sql +31 -0
- package/migrations/121_box_code_version.sql +37 -0
- package/migrations/122_builder_gemini_key.sql +30 -0
- package/migrations/123_cost_log_tiers.sql +33 -0
- package/migrations/124_cost_baseline.sql +45 -0
- package/migrations/125_llm_cache.sql +54 -0
- package/migrations/126_autonomy_runs.sql +33 -0
- package/migrations/143_cost_calibration.sql +63 -0
- package/migrations/145_backfill_task_requires_rank.sql +84 -0
- package/migrations/160_goal_tier.sql +88 -0
- package/migrations/163_polymorphic_dependencies.sql +187 -0
- package/migrations/164_event_sound_prefs.sql +20 -0
- package/migrations/165_task_module_key.sql +15 -0
- package/migrations/171_claims_published_head_sha.sql +24 -0
- package/migrations/174_close_orphaned_claims_on_terminal_tasks.sql +30 -0
- package/migrations/175_task_grades_diff_hash.sql +9 -0
- package/migrations/176_promotion_respects_open_blockers.sql +58 -0
- package/migrations/176_ui_discipline.sql +40 -0
- package/migrations/177_require_reward_before_workable.sql +76 -0
- package/migrations/178_reward_gate_auto_assign_revert_autopromote.sql +61 -0
- package/migrations/179_search_chunk_usefulness.sql +33 -0
- package/migrations/180_one_active_claim_per_session.sql +54 -0
- package/migrations/181_cost_log_skill_name.sql +33 -0
- package/migrations/184_claim_release_requested.sql +25 -0
- package/migrations/185_module_upstreaming_goal_wiring.sql +59 -0
- package/migrations/187_goal_sort_order.sql +30 -0
- package/migrations/187_tasks_kind_check_add_verify.sql +21 -0
- package/migrations/README.md +88 -0
- package/migrations/core_188_goal_visibility_and_membership_requests.sql +71 -0
- package/migrations/core_189_core_upgrades_ledger.sql +37 -0
- package/migrations/core_189_credit_log_task_id_index.sql +19 -0
- package/migrations/core_190_rebuild_claimable_task_views.sql +71 -0
- package/migrations/instance/018_pms_v3_planning_seed.sql +131 -0
- package/migrations/instance/080_gds_v4_planning_seed.sql +75 -0
- package/migrations/instance/110_medusa_planning_seed.sql +70 -0
- package/migrations/instance/120_bongos_v1_planning_seed.sql +69 -0
- package/migrations/instance/144_bongos_v1_module_system_criterion.sql +26 -0
- package/migrations/instance/159_bongos_v1_goal_hierarchy_criterion.sql +29 -0
- package/migrations/instance/172_v2_world_planning_seed.sql +163 -0
- package/migrations/instance/173_bongos_v1_c7_core_modularized.sql +33 -0
- package/migrations/instance/182_gdsv4_bongos_consolidation.sql +132 -0
- package/migrations/instance/183_gdsv4_carryover_themed_goals.sql +116 -0
- package/migrations/instance/186_bongos_v1_governance_planning_seed.sql +69 -0
- package/modules/autonomy/CLAUDE.md +49 -0
- package/modules/autonomy/db.js +50 -0
- package/modules/autonomy/module.json +13 -0
- package/modules/autonomy/pollers/routine-timers.js +146 -0
- package/modules/autonomy/routes/autonomy.js +37 -0
- package/modules/builder-settings/CLAUDE.md +58 -0
- package/modules/builder-settings/builder-needs.js +115 -0
- package/modules/builder-settings/db.js +168 -0
- package/modules/builder-settings/display-name.js +84 -0
- package/modules/builder-settings/event-sound-prefs.js +169 -0
- package/modules/builder-settings/interaction-prefs.js +201 -0
- package/modules/builder-settings/model-alloc-prefs.js +147 -0
- package/modules/builder-settings/module.json +10 -0
- package/modules/builder-settings/render-prefs.js +103 -0
- package/modules/builder-settings/routes/settings.js +417 -0
- package/modules/builder-settings/settings.js +52 -0
- package/modules/builder-settings/skill-prefs.js +196 -0
- package/modules/builder-settings/sound-prefs.js +178 -0
- package/modules/builder-settings/wandering-prefs.js +282 -0
- package/modules/dev-box/CLAUDE.md +38 -0
- package/modules/dev-box/box-access.js +275 -0
- package/modules/dev-box/box-credential.js +94 -0
- package/modules/dev-box/box-onboard.js +486 -0
- package/modules/dev-box/boxes.js +842 -0
- package/modules/dev-box/db.js +39 -0
- package/modules/dev-box/module.json +14 -0
- package/modules/dev-box/routes/box.js +977 -0
- package/modules/discord/CLAUDE.md +50 -0
- package/modules/discord/auth.js +54 -0
- package/modules/discord/bug-attachments.js +210 -0
- package/modules/discord/db.js +96 -0
- package/modules/discord/discord-approvals.js +145 -0
- package/modules/discord/discord-audit.js +29 -0
- package/modules/discord/discord-bot.js +545 -0
- package/modules/discord/discord-bugs.js +257 -0
- package/modules/discord/discord-channels.js +412 -0
- package/modules/discord/discord-inbound.js +147 -0
- package/modules/discord/discord-message-buffer.js +54 -0
- package/modules/discord/discord-reaction.js +186 -0
- package/modules/discord/discord-role-sync.js +318 -0
- package/modules/discord/module.json +14 -0
- package/modules/discord/pollers/discord-bot.js +19 -0
- package/modules/discord/routes/bug-attachments.js +44 -0
- package/modules/discord/routes/discord.js +102 -0
- package/modules/discord/ship-broadcast.js +78 -0
- package/modules/discord/webhook.js +74 -0
- package/modules/economy/CLAUDE.md +48 -0
- package/modules/economy/achievements.js +594 -0
- package/modules/economy/cost-classify.js +331 -0
- package/modules/economy/cost-summary-shape.js +90 -0
- package/modules/economy/cost.js +438 -0
- package/modules/economy/credits.js +430 -0
- package/modules/economy/migrations/economy_001_fix_gds_shipper_description.sql +91 -0
- package/modules/economy/module.json +10 -0
- package/modules/economy/reward.js +61 -0
- package/modules/economy/routes/cost.js +97 -0
- package/modules/economy/routes/leaderboard.js +26 -0
- package/modules/economy/routes/reward.js +42 -0
- package/modules/economy/streak.js +285 -0
- package/modules/grading/CLAUDE.md +42 -0
- package/modules/grading/db.js +39 -0
- package/modules/grading/grader-rubric.json +151 -0
- package/modules/grading/grader-workers/efficiency.js +213 -0
- package/modules/grading/grader-workers/extract-json.js +80 -0
- package/modules/grading/grader-workers/fence.js +100 -0
- package/modules/grading/grader-workers/hacker.js +239 -0
- package/modules/grading/grader-workers/index.js +183 -0
- package/modules/grading/grader-workers/narc.js +207 -0
- package/modules/grading/grader-workers/quality.js +198 -0
- package/modules/grading/grader-workers/rubric.js +20 -0
- package/modules/grading/grader-workers/worker-prompt.js +89 -0
- package/modules/grading/grader-workers/worker-verdict.js +50 -0
- package/modules/grading/grader.js +1790 -0
- package/modules/grading/module.json +12 -0
- package/modules/grading/routes/grade.js +51 -0
- package/modules/hall-ui/CLAUDE.md +61 -0
- package/modules/hall-ui/module.json +14 -0
- package/modules/hall-ui/public/atlas.html +180 -0
- package/modules/hall-ui/public/atlas.js +336 -0
- package/modules/hall-ui/public/box-panel.js +423 -0
- package/modules/hall-ui/public/brand-apply.js +117 -0
- package/modules/hall-ui/public/builders.js +3028 -0
- package/modules/hall-ui/public/chime.wav +0 -0
- package/modules/hall-ui/public/copy-on-click.js +174 -0
- package/modules/hall-ui/public/cursors/arrow.png +0 -0
- package/modules/hall-ui/public/cursors/hand-pointer.png +0 -0
- package/modules/hall-ui/public/cursors/magnifier-out.png +0 -0
- package/modules/hall-ui/public/cursors/magnifier.png +0 -0
- package/modules/hall-ui/public/diagram-viewer.css +125 -0
- package/modules/hall-ui/public/diagram-viewer.js +330 -0
- package/modules/hall-ui/public/diagrams.html +113 -0
- package/modules/hall-ui/public/dom-utils.js +212 -0
- package/modules/hall-ui/public/drachmae.html +68 -0
- package/modules/hall-ui/public/drachmae.js +136 -0
- package/modules/hall-ui/public/gate.html +143 -0
- package/modules/hall-ui/public/gate.js +228 -0
- package/modules/hall-ui/public/goals-page.js +1297 -0
- package/modules/hall-ui/public/goals.html +376 -0
- package/modules/hall-ui/public/goals.js +119 -0
- package/modules/hall-ui/public/hall-widgets.js +189 -0
- package/modules/hall-ui/public/harbor.html +167 -0
- package/modules/hall-ui/public/harbor.js +335 -0
- package/modules/hall-ui/public/index.html +116 -0
- package/modules/hall-ui/public/instances-panel.js +172 -0
- package/modules/hall-ui/public/md-reader.js +234 -0
- package/modules/hall-ui/public/modules.html +119 -0
- package/modules/hall-ui/public/modules.js +154 -0
- package/modules/hall-ui/public/new-project-wizard.js +186 -0
- package/modules/hall-ui/public/not-ready.html +48 -0
- package/modules/hall-ui/public/pair.html +119 -0
- package/modules/hall-ui/public/pair.js +132 -0
- package/modules/hall-ui/public/primer.css +404 -0
- package/modules/hall-ui/public/primer.html +85 -0
- package/modules/hall-ui/public/primer.js +641 -0
- package/modules/hall-ui/public/profile.html +85 -0
- package/modules/hall-ui/public/profile.js +236 -0
- package/modules/hall-ui/public/ranks.html +69 -0
- package/modules/hall-ui/public/ranks.js +206 -0
- package/modules/hall-ui/public/roadmap.html +209 -0
- package/modules/hall-ui/public/roadmap.js +375 -0
- package/modules/hall-ui/public/sessions.html +92 -0
- package/modules/hall-ui/public/sessions.js +222 -0
- package/modules/hall-ui/public/settings.html +640 -0
- package/modules/hall-ui/public/settings.js +1219 -0
- package/modules/hall-ui/public/shell.js +495 -0
- package/modules/hall-ui/public/style.css +1748 -0
- package/modules/hall-ui/public/task-detail.js +253 -0
- package/modules/hall-ui/public/task.html +83 -0
- package/modules/hall-ui/public/task.js +326 -0
- package/modules/hall-ui/public/watch.html +333 -0
- package/modules/hall-ui/public/watch.js +859 -0
- package/modules/hall-ui/public/work.html +469 -0
- package/modules/hall-ui/public/work.js +1292 -0
- package/modules/ideas/CLAUDE.md +37 -0
- package/modules/ideas/blockers.js +100 -0
- package/modules/ideas/inbox.js +459 -0
- package/modules/ideas/module.json +10 -0
- package/modules/ideas/routes/blockers.js +120 -0
- package/modules/ideas/routes/inbox.js +230 -0
- package/modules/lifecycle/CLAUDE.md +63 -0
- package/modules/lifecycle/conflict-resolve.js +436 -0
- package/modules/lifecycle/db.js +4970 -0
- package/modules/lifecycle/done-when.js +355 -0
- package/modules/lifecycle/github-push.js +969 -0
- package/modules/lifecycle/goal-conflicts.js +133 -0
- package/modules/lifecycle/hierarchy.js +104 -0
- package/modules/lifecycle/lifecycle.js +58 -0
- package/modules/lifecycle/merge-lock.js +261 -0
- package/modules/lifecycle/migrations/lifecycle_001_goal_first_leads.sql +28 -0
- package/modules/lifecycle/migrations/lifecycle_002_backfill_orphan_task_goals.sql +36 -0
- package/modules/lifecycle/module.json +13 -0
- package/modules/lifecycle/pollers/publish-reconciler.js +20 -0
- package/modules/lifecycle/publish-reconciler.js +418 -0
- package/modules/lifecycle/routes/analytics.js +63 -0
- package/modules/lifecycle/routes/claims.js +506 -0
- package/modules/lifecycle/routes/dependencies.js +82 -0
- package/modules/lifecycle/routes/done-when.js +136 -0
- package/modules/lifecycle/routes/gate-approvals.js +197 -0
- package/modules/lifecycle/routes/goals.js +1419 -0
- package/modules/lifecycle/routes/lifecycle.js +43 -0
- package/modules/lifecycle/routes/tasks.js +1703 -0
- package/modules/lifecycle/routes/versions.js +128 -0
- package/modules/lifecycle/ship-card.js +505 -0
- package/modules/lifecycle/ship-preflight.js +225 -0
- package/modules/lifecycle/task-classifier.js +512 -0
- package/modules/lifecycle/version-close.js +106 -0
- package/modules/memory/CLAUDE.md +40 -0
- package/modules/memory/learnings.js +275 -0
- package/modules/memory/memory.js +572 -0
- package/modules/memory/module.json +12 -0
- package/modules/memory/routes/learnings.js +90 -0
- package/modules/memory/routes/memory.js +916 -0
- package/modules/memory/routes/search.js +188 -0
- package/modules/memory/search-chunker.js +252 -0
- package/modules/memory/search.js +320 -0
- package/modules/onboarding/CLAUDE.md +55 -0
- package/modules/onboarding/approval-broadcast.js +59 -0
- package/modules/onboarding/db.js +54 -0
- package/modules/onboarding/module.json +10 -0
- package/modules/onboarding/newcomer-restock.js +212 -0
- package/modules/onboarding/onboarding-state.js +532 -0
- package/modules/onboarding/onboarding.js +508 -0
- package/modules/onboarding/port.js +63 -0
- package/modules/onboarding/routes/access-requests.js +208 -0
- package/modules/onboarding/routes/onboarding.js +54 -0
- package/modules/security/CLAUDE.md +44 -0
- package/modules/security/module.json +10 -0
- package/modules/security/routes/reports.js +251 -0
- package/modules/security/secret-scrub.js +201 -0
- package/modules/security/security.js +294 -0
- package/modules/sessions/CLAUDE.md +39 -0
- package/modules/sessions/bfg.js +357 -0
- package/modules/sessions/db.js +326 -0
- package/modules/sessions/module.json +10 -0
- package/modules/sessions/pulse.js +149 -0
- package/modules/sessions/routes/sessions.js +331 -0
- package/modules/status-ui/CLAUDE.md +47 -0
- package/modules/status-ui/module.json +14 -0
- package/modules/status-ui/public/README.md +29 -0
- package/modules/status-ui/public/cursors/arrow.png +0 -0
- package/modules/status-ui/public/cursors/hand-pointer.png +0 -0
- package/modules/status-ui/public/index.html +363 -0
- package/modules/status-ui/public/snapshots/.gitkeep +0 -0
- package/modules/status-ui/public/status.js +1375 -0
- package/modules/status-ui/public/style.css +1342 -0
- package/package-lock.json +975 -0
- package/package.json +28 -0
- package/public-docs/index.html +35 -0
- package/public-docs/redoc.standalone.js +1838 -0
- package/public-docs/redoc.standalone.js.LICENSE.txt +102 -0
- package/public-landing/buddha.png +0 -0
- package/public-landing/create.html +868 -0
- package/public-landing/index.html +168 -0
- package/scripts/bongos-mcp.js +28 -0
- package/scripts/cron/style_guide_audit.sh +134 -0
- package/scripts/discord/README.md +52 -0
- package/scripts/discord/lib.js +80 -0
- package/scripts/discord/post.js +51 -0
- package/scripts/gds/CLAUDE.md +144 -0
- package/scripts/gds/abandon.js +58 -0
- package/scripts/gds/adopt-detect.js +123 -0
- package/scripts/gds/adopt-import.js +111 -0
- package/scripts/gds/adopt-preflight.js +121 -0
- package/scripts/gds/api.js +78 -0
- package/scripts/gds/architect-audit.js +288 -0
- package/scripts/gds/art-stage.js +152 -0
- package/scripts/gds/audit-authorship.sh +243 -0
- package/scripts/gds/audit-deps.js +121 -0
- package/scripts/gds/audit-exports.js +128 -0
- package/scripts/gds/audit-replay.sh +161 -0
- package/scripts/gds/audit-ships.js +251 -0
- package/scripts/gds/autonomy-gate.js +135 -0
- package/scripts/gds/backfill-cost.js +165 -0
- package/scripts/gds/backfill-sessions.js +351 -0
- package/scripts/gds/backfill-task-rewards.js +408 -0
- package/scripts/gds/backup.js +94 -0
- package/scripts/gds/bfg-principal-token.js +65 -0
- package/scripts/gds/box-auth-check.js +160 -0
- package/scripts/gds/box-connect-lib.js +453 -0
- package/scripts/gds/box.js +1258 -0
- package/scripts/gds/build-bongos.js +94 -0
- package/scripts/gds/capture.js +123 -0
- package/scripts/gds/cf-tunnel.js +419 -0
- package/scripts/gds/ci-grade.js +82 -0
- package/scripts/gds/claim-recall.js +112 -0
- package/scripts/gds/claim.js +333 -0
- package/scripts/gds/classify-discipline.js +153 -0
- package/scripts/gds/claude-materialize.js +176 -0
- package/scripts/gds/cleanup-orphans.js +74 -0
- package/scripts/gds/cli-lib.js +518 -0
- package/scripts/gds/code.js +101 -0
- package/scripts/gds/codemod-rename-src-gds.js +145 -0
- package/scripts/gds/conductor-dispatch.js +426 -0
- package/scripts/gds/context-pack.js +228 -0
- package/scripts/gds/coreB-carve-proof.sh +716 -0
- package/scripts/gds/cost.js +47 -0
- package/scripts/gds/db-backup-nightly.sh +160 -0
- package/scripts/gds/db-backup-offsite.sh +152 -0
- package/scripts/gds/demote.js +40 -0
- package/scripts/gds/design-sync.js +62 -0
- package/scripts/gds/diagnose-achievements.js +118 -0
- package/scripts/gds/diagram-facts.js +319 -0
- package/scripts/gds/discipline-modes.json +25 -0
- package/scripts/gds/discord-channels.js +66 -0
- package/scripts/gds/do-api.js +176 -0
- package/scripts/gds/docs-entropy.js +403 -0
- package/scripts/gds/doctor.js +389 -0
- package/scripts/gds/feedback-latest.js +94 -0
- package/scripts/gds/fetch-art-key.js +106 -0
- package/scripts/gds/fetch-sound-prefs.js +88 -0
- package/scripts/gds/figma-design-sync.js +61 -0
- package/scripts/gds/fitness.js +1446 -0
- package/scripts/gds/gate-review.js +322 -0
- package/scripts/gds/gating.js +325 -0
- package/scripts/gds/gds-db-backup.service +24 -0
- package/scripts/gds/gds-db-backup.timer +20 -0
- package/scripts/gds/gds-db-offsite.service +29 -0
- package/scripts/gds/gds-db-offsite.timer +18 -0
- package/scripts/gds/gen-api-client.js +508 -0
- package/scripts/gds/gen-api-docs.js +1037 -0
- package/scripts/gds/gen-atlas.js +366 -0
- package/scripts/gds/gen-diagrams.js +608 -0
- package/scripts/gds/gen-file-map.js +196 -0
- package/scripts/gds/gen-repo-map.js +519 -0
- package/scripts/gds/gen-session-index.js +210 -0
- package/scripts/gds/git-merge-regen.js +147 -0
- package/scripts/gds/grade-smoke.js +205 -0
- package/scripts/gds/hooks/pre-push.js +169 -0
- package/scripts/gds/http-api-client.js +88 -0
- package/scripts/gds/init.js +903 -0
- package/scripts/gds/install-git-hooks.js +114 -0
- package/scripts/gds/key-card.js +213 -0
- package/scripts/gds/key-status.js +126 -0
- package/scripts/gds/land-watch.js +168 -0
- package/scripts/gds/learning-capture.js +145 -0
- package/scripts/gds/lib.sh +44 -0
- package/scripts/gds/linkify-refs.js +473 -0
- package/scripts/gds/local-preview-lib.js +159 -0
- package/scripts/gds/local-preview.js +95 -0
- package/scripts/gds/login.js +225 -0
- package/scripts/gds/main-audit.js +279 -0
- package/scripts/gds/me.js +88 -0
- package/scripts/gds/memory-map.js +174 -0
- package/scripts/gds/merge-lock.js +71 -0
- package/scripts/gds/migration-namespace.js +200 -0
- package/scripts/gds/mirror-lineage-check.js +319 -0
- package/scripts/gds/mirror-redact.js +305 -0
- package/scripts/gds/module.js +482 -0
- package/scripts/gds/newcomer-floor.config.json +13 -0
- package/scripts/gds/newcomer-floor.js +415 -0
- package/scripts/gds/newcomer-floor.templates.json +86 -0
- package/scripts/gds/newcomer-floor.test.js +235 -0
- package/scripts/gds/next-number.js +163 -0
- package/scripts/gds/oauth-secret.js +197 -0
- package/scripts/gds/onboard.js +217 -0
- package/scripts/gds/onboarding-analyze.js +226 -0
- package/scripts/gds/onboarding-config.js +178 -0
- package/scripts/gds/onboarding-ship.js +92 -0
- package/scripts/gds/package-core.js +684 -0
- package/scripts/gds/paste-token.js +131 -0
- package/scripts/gds/portability-smoke-art.sh +85 -0
- package/scripts/gds/portability-smoke-memory.sh +147 -0
- package/scripts/gds/provision.js +1324 -0
- package/scripts/gds/publish-manifest.js +307 -0
- package/scripts/gds/pulse.js +309 -0
- package/scripts/gds/push-main.js +45 -0
- package/scripts/gds/read-session-export.js +359 -0
- package/scripts/gds/reauth.js +149 -0
- package/scripts/gds/recall.js +135 -0
- package/scripts/gds/release.js +71 -0
- package/scripts/gds/render-ideas.js +173 -0
- package/scripts/gds/repo-metrics.js +363 -0
- package/scripts/gds/resolve-skill-model.js +57 -0
- package/scripts/gds/run-routine.js +197 -0
- package/scripts/gds/run-unit-tests.js +178 -0
- package/scripts/gds/sandbox-stage.js +653 -0
- package/scripts/gds/search-ingest-db.js +209 -0
- package/scripts/gds/search-ingest-md.js +225 -0
- package/scripts/gds/security-baseline-check.sh +180 -0
- package/scripts/gds/seed-adopt-tasks.js +75 -0
- package/scripts/gds/seed-api-contract-goal-tasks.js +141 -0
- package/scripts/gds/seed-bongos-app-tasks.js +294 -0
- package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +81 -0
- package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +100 -0
- package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +307 -0
- package/scripts/gds/seed-bongos-module-system-tasks.js +346 -0
- package/scripts/gds/seed-bongos-tasks.js +214 -0
- package/scripts/gds/seed-gds-v4-tasks.js +624 -0
- package/scripts/gds/seed-governance-tasks.js +340 -0
- package/scripts/gds/seed-medusa-tasks.js +440 -0
- package/scripts/gds/seed-module-upstreaming.js +219 -0
- package/scripts/gds/seed-productization-tasks.js +235 -0
- package/scripts/gds/seed-provisioning-tasks.js +83 -0
- package/scripts/gds/seed-staging.sh +104 -0
- package/scripts/gds/seed-v2-world-tasks.js +283 -0
- package/scripts/gds/seed-v3-tasks.js +1981 -0
- package/scripts/gds/session-cost.js +393 -0
- package/scripts/gds/session-digest.js +179 -0
- package/scripts/gds/session-eval.js +576 -0
- package/scripts/gds/session.js +404 -0
- package/scripts/gds/setup.js +504 -0
- package/scripts/gds/shell.js +100 -0
- package/scripts/gds/ship.js +3618 -0
- package/scripts/gds/smoke-batch-claim.sh +213 -0
- package/scripts/gds/smoke-batch-release.sh +296 -0
- package/scripts/gds/smoke-box.sh +150 -0
- package/scripts/gds/smoke-claim-consistency.sh +212 -0
- package/scripts/gds/smoke-dependencies.sh +84 -0
- package/scripts/gds/smoke-gds.js +125 -0
- package/scripts/gds/smoke-write.sh +168 -0
- package/scripts/gds/start.js +782 -0
- package/scripts/gds/status.js +365 -0
- package/scripts/gds/triage.js +366 -0
- package/scripts/gds/upgrade.js +421 -0
- package/scripts/gds/validate-design.js +254 -0
- package/scripts/gds/version-close.js +549 -0
- package/scripts/migrate.sh +183 -0
- package/scripts/migrate_cost_ledger.sh +178 -0
- package/scripts/public-mirror-export.js +291 -0
- package/scripts/render-diagrams.sh +88 -0
- package/scripts/security/dep-audit.js +276 -0
- package/scripts/setup-builder.js +274 -0
- package/scripts/setup-builder.sh +28 -0
- package/scripts/snapshots/backfill-history.mjs +292 -0
- package/scripts/snapshots/maybe-render-on-deploy.sh +66 -0
- package/scripts/snapshots/render-pre-art-eras.mjs +329 -0
- package/scripts/snapshots/render-world.mjs +322 -0
- package/scripts/status-mirror-sync.js +192 -0
- package/scripts/status-probe.mjs +185 -0
- package/server.js +212 -0
- package/src/asset-version.js +71 -0
- package/src/bongos/CLAUDE.md +64 -0
- package/src/bongos/api-errors.js +281 -0
- package/src/bongos/api-path-404.js +67 -0
- package/src/bongos/api-prefix.js +38 -0
- package/src/bongos/app-pair.js +172 -0
- package/src/bongos/auth.js +979 -0
- package/src/bongos/cascade-dispatch.js +123 -0
- package/src/bongos/db-kernel.js +252 -0
- package/src/bongos/db.js +911 -0
- package/src/bongos/goal-scope-check.js +120 -0
- package/src/bongos/hierarchy-config.js +189 -0
- package/src/bongos/live-channel.js +145 -0
- package/src/bongos/llm-cache.js +260 -0
- package/src/bongos/llm-pricing.js +220 -0
- package/src/bongos/metrics.js +286 -0
- package/src/bongos/middleware/audit.js +274 -0
- package/src/bongos/middleware/error-envelope.js +93 -0
- package/src/bongos/middleware/rate-limit.js +195 -0
- package/src/bongos/module-scope-map.js +271 -0
- package/src/bongos/optimizer.js +166 -0
- package/src/bongos/path-match.js +47 -0
- package/src/bongos/permission-path-check.js +248 -0
- package/src/bongos/pool.js +55 -0
- package/src/bongos/repo-info.js +91 -0
- package/src/bongos/route-rank-check.js +420 -0
- package/src/bongos/routes/CLAUDE.md +43 -0
- package/src/bongos/routes/_helpers.js +369 -0
- package/src/bongos/routes/audit-log.js +59 -0
- package/src/bongos/routes/auth.js +755 -0
- package/src/bongos/routes/backup.js +104 -0
- package/src/bongos/routes/builders.js +526 -0
- package/src/bongos/routes/healthz.js +16 -0
- package/src/bongos/routes/instance.js +129 -0
- package/src/bongos/routes/live.js +125 -0
- package/src/bongos/routes/llm-cache.js +119 -0
- package/src/bongos/routes/me.js +380 -0
- package/src/bongos/routes/modules.js +131 -0
- package/src/bongos/routes/optimizer.js +54 -0
- package/src/bongos/routes/public.js +476 -0
- package/src/bongos/routes/security.js +207 -0
- package/src/bongos/routes.js +166 -0
- package/src/bongos/secret-box.js +177 -0
- package/src/bongos/sensitive-surfaces.js +30 -0
- package/src/bongos/serve-internal.js +889 -0
- package/src/bongos/uptime-poller.js +90 -0
- package/src/bongos-downloads.js +70 -0
- package/src/branding.js +182 -0
- package/src/build-info.js +77 -0
- package/src/devbox-downloads.js +67 -0
- package/src/instance-config.js +200 -0
- package/src/module-api.js +366 -0
- package/src/module-loader/loader.js +268 -0
- package/src/module-loader/manifest-schema.js +140 -0
- package/src/module-loader/provenance.js +28 -0
- package/src/module-loader/semver.js +100 -0
- package/src/module-seams.js +291 -0
- package/src/modules.js +254 -0
- package/src/platform-server.js +135 -0
- package/src/ui/adapters/claude-design/index.js +333 -0
- package/src/ui/adapters/figma/index.js +328 -0
- package/tests/abandon_task.mjs +138 -0
- package/tests/achievements_reconcile.mjs +167 -0
- package/tests/adopt_detect.mjs +141 -0
- package/tests/adopt_import.mjs +132 -0
- package/tests/adopt_preflight.mjs +105 -0
- package/tests/anti_grid.mjs +89 -0
- package/tests/api_client.mjs +231 -0
- package/tests/api_docs.mjs +283 -0
- package/tests/api_error_envelope_buildcheck.mjs +56 -0
- package/tests/api_error_envelope_middleware.mjs +99 -0
- package/tests/api_error_registry.mjs +108 -0
- package/tests/api_pagination_contract.mjs +51 -0
- package/tests/api_path_404.mjs +96 -0
- package/tests/app_pair.mjs +168 -0
- package/tests/architect.mjs +140 -0
- package/tests/art_key.mjs +121 -0
- package/tests/art_stage.mjs +121 -0
- package/tests/asset_version.mjs +94 -0
- package/tests/atlas.mjs +69 -0
- package/tests/audit_deps.mjs +74 -0
- package/tests/audit_middleware.mjs +385 -0
- package/tests/auth_admission_gate.mjs +164 -0
- package/tests/auth_anthropic_identity.mjs +95 -0
- package/tests/auth_duplicate_cookie.mjs +56 -0
- package/tests/auth_error_brand.mjs +77 -0
- package/tests/auth_flow_slice1.mjs +223 -0
- package/tests/auth_inactive_builder.mjs +94 -0
- package/tests/auth_page_gate.mjs +92 -0
- package/tests/auth_session_ttl.mjs +155 -0
- package/tests/autonomous_fit_protected_paths.mjs +115 -0
- package/tests/autonomy_gate.mjs +85 -0
- package/tests/autotile_variants.mjs +256 -0
- package/tests/autotile_xverify.mjs +133 -0
- package/tests/backfill_sessions.mjs +101 -0
- package/tests/backfill_task_rewards.mjs +152 -0
- package/tests/backup_cli.mjs +104 -0
- package/tests/bfg.mjs +327 -0
- package/tests/bfg_write.mjs +423 -0
- package/tests/bongos_box_connect.mjs +89 -0
- package/tests/bongos_dispatch.mjs +74 -0
- package/tests/bongos_downloads.mjs +118 -0
- package/tests/bongos_login.mjs +34 -0
- package/tests/box_access.mjs +186 -0
- package/tests/box_auth_check.mjs +114 -0
- package/tests/box_code_staleness.mjs +116 -0
- package/tests/box_connect_e2e.mjs +196 -0
- package/tests/box_cost.mjs +70 -0
- package/tests/box_dns_repoint.mjs +151 -0
- package/tests/box_host_keys.mjs +102 -0
- package/tests/box_onboard.mjs +317 -0
- package/tests/box_scope_session.mjs +115 -0
- package/tests/box_ship_permissions.mjs +71 -0
- package/tests/box_terminal_ssrf.mjs +90 -0
- package/tests/boxes.mjs +1255 -0
- package/tests/branding.mjs +88 -0
- package/tests/bug_attachments.mjs +189 -0
- package/tests/build_info.mjs +88 -0
- package/tests/builder_needs.mjs +99 -0
- package/tests/cap_newcomer_tasks.mjs +114 -0
- package/tests/cascade-dispatch.mjs +95 -0
- package/tests/cf_tunnel.mjs +459 -0
- package/tests/claim_recall.mjs +150 -0
- package/tests/claims_bind_session.mjs +47 -0
- package/tests/claude_materialize.mjs +148 -0
- package/tests/cli_box_scope.mjs +52 -0
- package/tests/cli_lib_formatters.mjs +87 -0
- package/tests/cli_token_reissue.mjs +147 -0
- package/tests/client_bundle_route.mjs +47 -0
- package/tests/cloud_bongos_pack.mjs +85 -0
- package/tests/conductor.mjs +496 -0
- package/tests/confirm_attribution.mjs +156 -0
- package/tests/conflict_resolve.mjs +462 -0
- package/tests/context_pack.mjs +240 -0
- package/tests/cost.mjs +94 -0
- package/tests/cost_audit.mjs +122 -0
- package/tests/cost_budget_status.mjs +78 -0
- package/tests/cost_reconcile.mjs +102 -0
- package/tests/cost_summary_shape.mjs +94 -0
- package/tests/credit_grant.mjs +376 -0
- package/tests/criterion_progress.mjs +220 -0
- package/tests/criterion_proposal.mjs +109 -0
- package/tests/criterion_ref_parse.mjs +53 -0
- package/tests/currency_label.mjs +119 -0
- package/tests/day_cycle.mjs +197 -0
- package/tests/dependencies_migration.mjs +77 -0
- package/tests/dependencies_polymorphic.mjs +212 -0
- package/tests/deploy_instance.mjs +78 -0
- package/tests/devbox_downloads.mjs +122 -0
- package/tests/diff_derived_signals.mjs +115 -0
- package/tests/discord_approvals.mjs +174 -0
- package/tests/discord_autojoin.mjs +158 -0
- package/tests/discord_bot.mjs +94 -0
- package/tests/discord_bugs.mjs +297 -0
- package/tests/discord_channels.mjs +337 -0
- package/tests/discord_foundation.mjs +76 -0
- package/tests/discord_inbound.mjs +190 -0
- package/tests/discord_message_buffer.mjs +87 -0
- package/tests/discord_oauth.mjs +55 -0
- package/tests/discord_reaction.mjs +170 -0
- package/tests/discord_role_sync.mjs +151 -0
- package/tests/display_name.mjs +123 -0
- package/tests/dns_preflight.mjs +74 -0
- package/tests/event_sound_prefs.mjs +194 -0
- package/tests/eviction_policy.mjs +279 -0
- package/tests/figma_adapter.mjs +199 -0
- package/tests/file_map.mjs +91 -0
- package/tests/first_admin_bootstrap.mjs +40 -0
- package/tests/fitness.mjs +435 -0
- package/tests/fitness_two_root.mjs +104 -0
- package/tests/fixtures/session-506-digest.json +34 -0
- package/tests/gate_approvals.mjs +451 -0
- package/tests/gate_review.mjs +152 -0
- package/tests/git_merge_regen.mjs +151 -0
- package/tests/github_push_ancestry.mjs +119 -0
- package/tests/github_push_land_proof.mjs +127 -0
- package/tests/github_push_merge_driver.mjs +175 -0
- package/tests/goal_abuse_matrix.mjs +187 -0
- package/tests/goal_achievement.mjs +146 -0
- package/tests/goal_conflicts.mjs +305 -0
- package/tests/goal_dependencies_read.mjs +73 -0
- package/tests/goal_member_roles.mjs +420 -0
- package/tests/goal_membership_requests.mjs +332 -0
- package/tests/goal_routes.mjs +203 -0
- package/tests/goal_scope_check.mjs +167 -0
- package/tests/goal_tier.mjs +312 -0
- package/tests/goal_wall_proof.mjs +112 -0
- package/tests/grade_attempts.mjs +73 -0
- package/tests/grade_attribution.mjs +117 -0
- package/tests/grade_diff_hash.mjs +191 -0
- package/tests/grade_server_authoritative.mjs +305 -0
- package/tests/grade_unavailable_display.mjs +66 -0
- package/tests/grader.mjs +1960 -0
- package/tests/grader_bypass.mjs +57 -0
- package/tests/grader_panel.mjs +252 -0
- package/tests/grader_prompt_fencing.mjs +192 -0
- package/tests/helpers.mjs +52 -0
- package/tests/hierarchy-config.mjs +81 -0
- package/tests/init.mjs +463 -0
- package/tests/instance_config.mjs +76 -0
- package/tests/instance_manifest.mjs +110 -0
- package/tests/interaction_prefs.mjs +72 -0
- package/tests/key-card.mjs +110 -0
- package/tests/key-status.mjs +45 -0
- package/tests/land_watch.mjs +115 -0
- package/tests/lifecycle-card.mjs +145 -0
- package/tests/lifecycle_breakdown_view.mjs +236 -0
- package/tests/linkify_refs.mjs +264 -0
- package/tests/live_channel.mjs +128 -0
- package/tests/live_sse.mjs +122 -0
- package/tests/llm-cache-route.mjs +110 -0
- package/tests/llm-cache.mjs +140 -0
- package/tests/llm-pricing.mjs +152 -0
- package/tests/local_preview.mjs +136 -0
- package/tests/main_audit.mjs +137 -0
- package/tests/memory_isolation.mjs +431 -0
- package/tests/memory_map.mjs +107 -0
- package/tests/memory_pull.mjs +429 -0
- package/tests/merge_lease.mjs +100 -0
- package/tests/merge_lock.mjs +312 -0
- package/tests/metrics.mjs +147 -0
- package/tests/migration_allocation.mjs +146 -0
- package/tests/migration_namespace.mjs +185 -0
- package/tests/migrations_fresh_replay_guard.mjs +38 -0
- package/tests/mirror_lineage_fulltree.mjs +45 -0
- package/tests/mirror_lineage_proof.mjs +72 -0
- package/tests/mirror_redact.mjs +193 -0
- package/tests/model_alloc_prefs.mjs +63 -0
- package/tests/module-scope-map.mjs +88 -0
- package/tests/module_api.mjs +110 -0
- package/tests/module_cli.mjs +292 -0
- package/tests/module_contributions.mjs +148 -0
- package/tests/module_loader.mjs +286 -0
- package/tests/module_manifest.mjs +194 -0
- package/tests/module_owned_tests.mjs +105 -0
- package/tests/module_provenance.mjs +34 -0
- package/tests/module_route_rank.mjs +147 -0
- package/tests/module_seams.mjs +68 -0
- package/tests/modules.mjs +156 -0
- package/tests/modules_route.mjs +38 -0
- package/tests/newcomer_floor.mjs +17 -0
- package/tests/newcomer_restock.mjs +80 -0
- package/tests/next_number.mjs +154 -0
- package/tests/oauth_secret.mjs +60 -0
- package/tests/onboard.mjs +70 -0
- package/tests/onboarding_gate.mjs +267 -0
- package/tests/onboarding_observability.mjs +344 -0
- package/tests/onboarding_route_signals.mjs +175 -0
- package/tests/onboarding_state.mjs +346 -0
- package/tests/one_active_claim_per_session.mjs +111 -0
- package/tests/orphaned_claim_ship.mjs +135 -0
- package/tests/override_attribution.mjs +142 -0
- package/tests/override_request_ownership.mjs +235 -0
- package/tests/package_core.mjs +435 -0
- package/tests/parallel-load.mjs +402 -0
- package/tests/path_match.mjs +62 -0
- package/tests/permission_path.mjs +151 -0
- package/tests/platform_boot.mjs +167 -0
- package/tests/pre_compact.mjs +60 -0
- package/tests/preview_server.mjs +127 -0
- package/tests/profile_route.mjs +197 -0
- package/tests/provision.mjs +805 -0
- package/tests/provisioning_github_app_routes.mjs +98 -0
- package/tests/public_mirror_export.mjs +124 -0
- package/tests/public_task_resolver.mjs +112 -0
- package/tests/publish_branch_route.mjs +422 -0
- package/tests/publish_manifest.mjs +184 -0
- package/tests/publish_reconciler.mjs +728 -0
- package/tests/rank_gate.mjs +463 -0
- package/tests/rate_limit_public.mjs +217 -0
- package/tests/read_session_export.mjs +89 -0
- package/tests/recall_cli.mjs +82 -0
- package/tests/recall_hints.mjs +119 -0
- package/tests/recent_shipped_window.mjs +80 -0
- package/tests/regrade_eligibility.mjs +202 -0
- package/tests/render_prefs.mjs +122 -0
- package/tests/repo_map.mjs +92 -0
- package/tests/reward_gate.mjs +284 -0
- package/tests/route_rank_check.mjs +243 -0
- package/tests/route_validation.mjs +490 -0
- package/tests/routine_timers.mjs +72 -0
- package/tests/rubric_fixtures.mjs +140 -0
- package/tests/run_routine.mjs +69 -0
- package/tests/sandbox_stage.mjs +582 -0
- package/tests/scrubber_corpus.mjs +257 -0
- package/tests/search_chunker.mjs +209 -0
- package/tests/search_ingest.mjs +96 -0
- package/tests/search_ingest_db.mjs +88 -0
- package/tests/search_isolation.mjs +204 -0
- package/tests/search_route.mjs +95 -0
- package/tests/secret_box.mjs +189 -0
- package/tests/security_docs.mjs +186 -0
- package/tests/security_route.mjs +108 -0
- package/tests/served_paths_shipped.mjs +118 -0
- package/tests/session-cards.mjs +142 -0
- package/tests/session_506_regression.mjs +69 -0
- package/tests/session_caps.mjs +238 -0
- package/tests/session_cost.mjs +133 -0
- package/tests/session_digest.mjs +73 -0
- package/tests/session_eval.mjs +386 -0
- package/tests/session_index.mjs +105 -0
- package/tests/session_records.mjs +369 -0
- package/tests/session_search.mjs +78 -0
- package/tests/session_start_freshness.mjs +123 -0
- package/tests/setup_smoke.mjs +154 -0
- package/tests/ship_autolinkify.mjs +60 -0
- package/tests/ship_automerge_injection.mjs +174 -0
- package/tests/ship_broadcast_routing.mjs +125 -0
- package/tests/ship_broadcast_server.mjs +175 -0
- package/tests/ship_card.mjs +280 -0
- package/tests/ship_ci_deploy.mjs +374 -0
- package/tests/ship_preflight.mjs +368 -0
- package/tests/ship_premerge.mjs +75 -0
- package/tests/ship_resume.mjs +129 -0
- package/tests/ship_upload_skip.mjs +89 -0
- package/tests/ship_zero_commit.mjs +60 -0
- package/tests/single_host_hall.mjs +98 -0
- package/tests/skill_prefs.mjs +150 -0
- package/tests/smoke_preflight.mjs +66 -0
- package/tests/snapshot_picker.mjs +233 -0
- package/tests/sound_prefs.mjs +198 -0
- package/tests/sprite_facing.mjs +35 -0
- package/tests/status-probe.mjs +89 -0
- package/tests/status_backfill.mjs +94 -0
- package/tests/stop_refcheck.mjs +127 -0
- package/tests/streak.mjs +175 -0
- package/tests/subdomain_auth.mjs +58 -0
- package/tests/task_classifier_vocab.mjs +41 -0
- package/tests/task_create_idempotency.mjs +96 -0
- package/tests/task_goal_link.mjs +93 -0
- package/tests/task_ownership_gate.mjs +125 -0
- package/tests/terrain_picker.mjs +298 -0
- package/tests/touches_overlap.mjs +75 -0
- package/tests/triage_development.mjs +140 -0
- package/tests/turn_in_place.mjs +280 -0
- package/tests/upgrade.mjs +357 -0
- package/tests/verify_task_guard.mjs +64 -0
- package/tests/version_close.mjs +76 -0
- package/tests/versions_route.mjs +93 -0
- package/tests/walkability.mjs +188 -0
- package/tests/wandering_prefs.mjs +176 -0
- package/tests/worktree_disambiguation.mjs +105 -0
- package/tests/worktree_guard.mjs +90 -0
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
// scripts/gds/upgrade.js — the `bongos upgrade` update-consumption channel (ADR 0100 §2, task 1690).
|
|
4
|
+
//
|
|
5
|
+
// Turns the former stub (which only ran a module-vs-core compatibility PRE-CHECK) into the real
|
|
6
|
+
// channel a two-repo consumer uses to pull the Cloud Bongos core from version N to N+1:
|
|
7
|
+
//
|
|
8
|
+
// pre-flight clean git tree + module-compat vs the TARGET core version
|
|
9
|
+
// → bump pin vendor the new core .tgz, rewrite the package.json `file:` dependency
|
|
10
|
+
// → npm install node_modules/@cloudbongos/core becomes the new version
|
|
11
|
+
// → migrate `npm run migrate` → the core's migrate.sh applies additive `core_*` migrations
|
|
12
|
+
// → materialize refresh .claude/ skills+settings+hooks from the new core (claude-materialize / W3)
|
|
13
|
+
// → restart restart the instance's service so the new core is live
|
|
14
|
+
// → verify installed package version == target (+ optional /healthz + ledger row)
|
|
15
|
+
//
|
|
16
|
+
// SCOPE (ADR 0100 §2, reshaped by ADR 0103 §4): the SMALLEST channel the FIRST real consumer needs
|
|
17
|
+
// on its first core bump — driven by that consumer, not designed up front. That consumer is
|
|
18
|
+
// emersonian-circles (task 1917): a greenfield npm-dependency instance that pins the core as
|
|
19
|
+
// "@cloudbongos/core": "file:vendor/cloudbongos-core-<ver>.tgz"
|
|
20
|
+
// with `start`/`migrate` npm scripts and a materialized .claude/. Every step below maps to something
|
|
21
|
+
// that consumer actually has. A published-registry source, rollback, and multi-consumer shapes are
|
|
22
|
+
// deliberately OUT — they are follow-ups a second consumer's needs will define.
|
|
23
|
+
//
|
|
24
|
+
// Runs from the consumer instance root (default) or `--instance <dir>`. This script ships IN the core
|
|
25
|
+
// package, so once a consumer is on core vN+1 its own `bongos upgrade` is this code. The FIRST bump
|
|
26
|
+
// (before vN+1 is installed) is driven by running THIS file out of the new version's staged tree
|
|
27
|
+
// against `--instance <consumer>` — see docs/recipes for the bootstrap note.
|
|
28
|
+
|
|
29
|
+
const fs = require('node:fs');
|
|
30
|
+
const path = require('node:path');
|
|
31
|
+
const { spawnSync } = require('node:child_process');
|
|
32
|
+
const { arg, hasFlag } = require('./cli-lib');
|
|
33
|
+
|
|
34
|
+
const CORE_PKG = '@cloudbongos/core';
|
|
35
|
+
const ARTIFACT = 'cloudbongos-core';
|
|
36
|
+
|
|
37
|
+
// ---- pure helpers (no I/O side effects beyond the injected fs) --------------
|
|
38
|
+
|
|
39
|
+
// The pin a consumer carries is the vendored-tarball version in its `file:` dependency — there is no
|
|
40
|
+
// separate pin file for this consumer shape. Extract the version from either the dep string or the
|
|
41
|
+
// installed package.
|
|
42
|
+
function versionFromTgzPath(p) {
|
|
43
|
+
const m = String(p || '').match(new RegExp(`${ARTIFACT}-(\\d+\\.\\d+\\.\\d+[^/]*)\\.tgz$`));
|
|
44
|
+
return m ? m[1] : null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function readJson(file, fsImpl = fs) {
|
|
48
|
+
try { return JSON.parse(fsImpl.readFileSync(file, 'utf8')); } catch { return null; }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// The version currently installed under node_modules — the authoritative "from".
|
|
52
|
+
function readInstalledCoreVersion(instanceDir, fsImpl = fs) {
|
|
53
|
+
const pkg = readJson(path.join(instanceDir, 'node_modules', CORE_PKG, 'package.json'), fsImpl);
|
|
54
|
+
return pkg && pkg.version ? pkg.version : null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// The version the consumer's package.json currently pins (from the `file:` tarball path).
|
|
58
|
+
function readPinnedCoreVersion(instanceDir, fsImpl = fs) {
|
|
59
|
+
const pkg = readJson(path.join(instanceDir, 'package.json'), fsImpl);
|
|
60
|
+
const dep = pkg && ((pkg.dependencies || {})[CORE_PKG] || (pkg.devDependencies || {})[CORE_PKG]);
|
|
61
|
+
return versionFromTgzPath(dep);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Rewrite the consumer package.json to pin `file:<vendorRel>`. Returns the previous dep string.
|
|
65
|
+
function writePin(instanceDir, vendorRel, fsImpl = fs) {
|
|
66
|
+
const pkgPath = path.join(instanceDir, 'package.json');
|
|
67
|
+
const pkg = readJson(pkgPath, fsImpl);
|
|
68
|
+
if (!pkg) throw new Error(`no readable package.json at ${pkgPath}`);
|
|
69
|
+
pkg.dependencies = pkg.dependencies || {};
|
|
70
|
+
const prev = pkg.dependencies[CORE_PKG];
|
|
71
|
+
pkg.dependencies[CORE_PKG] = `file:${vendorRel}`;
|
|
72
|
+
fsImpl.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
73
|
+
return prev;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ---- steps (each injectable for tests) --------------------------------------
|
|
77
|
+
|
|
78
|
+
function gitTreeClean(instanceDir, run = spawnSync) {
|
|
79
|
+
const r = run('git', ['status', '--porcelain'], { cwd: instanceDir, encoding: 'utf8' });
|
|
80
|
+
if (!r || r.error || r.status !== 0) return { ok: false, reason: 'git status failed (not a git repo?)' };
|
|
81
|
+
const dirty = (r.stdout || '').trim();
|
|
82
|
+
return { ok: dirty === '', dirty };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Copy the source .tgz (+ its side-car manifest, if present) into the consumer's vendor/ dir under the
|
|
86
|
+
// canonical name. Returns the vendor-relative tarball path to pin.
|
|
87
|
+
function vendorTarball({ instanceDir, fromTgz, targetVersion }, fsImpl = fs) {
|
|
88
|
+
const vendorDir = path.join(instanceDir, 'vendor');
|
|
89
|
+
fsImpl.mkdirSync(vendorDir, { recursive: true });
|
|
90
|
+
const destName = `${ARTIFACT}-${targetVersion}.tgz`;
|
|
91
|
+
const destAbs = path.join(vendorDir, destName);
|
|
92
|
+
fsImpl.copyFileSync(fromTgz, destAbs);
|
|
93
|
+
const fromManifest = fromTgz.replace(/\.tgz$/, '.manifest.json');
|
|
94
|
+
if (fsImpl.existsSync(fromManifest)) {
|
|
95
|
+
fsImpl.copyFileSync(fromManifest, path.join(vendorDir, `${ARTIFACT}-${targetVersion}.manifest.json`));
|
|
96
|
+
}
|
|
97
|
+
return path.join('vendor', destName);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Lightweight module-compat pre-check reusing module.js against the TARGET core version. Best-effort:
|
|
101
|
+
// a vanilla consumer has no modules/ (trivially OK); any failure downgrades to a warning, never blocks
|
|
102
|
+
// the MVP bump. Returns { ok, blocking:[], note }.
|
|
103
|
+
function preflightModules({ instanceDir, targetVersion }, deps = {}) {
|
|
104
|
+
const modulesDir = path.join(instanceDir, 'modules');
|
|
105
|
+
if (!fs.existsSync(modulesDir)) return { ok: true, blocking: [], note: 'no modules/ — nothing to pre-check' };
|
|
106
|
+
try {
|
|
107
|
+
const mod = deps.moduleLib || require('./module');
|
|
108
|
+
const data = mod.gatherUpgrade({ modulesDir, core: targetVersion });
|
|
109
|
+
const verdict = mod.evaluateUpgrade(data);
|
|
110
|
+
return { ok: verdict.ok, blocking: verdict.blocking || [], note: verdict.ok ? 'all enabled modules satisfy the target' : 'incompatible enabled module(s)' };
|
|
111
|
+
} catch (e) {
|
|
112
|
+
return { ok: true, blocking: [], note: `module pre-check skipped (${e.message})` };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function npmInstall(instanceDir, run = spawnSync) {
|
|
117
|
+
// `npm install` (NOT `npm ci`): the pin just changed, so the lockfile must be regenerated from the
|
|
118
|
+
// new tarball; `npm ci` would refuse on the package.json↔lock divergence.
|
|
119
|
+
const r = run('npm', ['install', '--no-audit', '--no-fund'], { cwd: instanceDir, stdio: 'inherit' });
|
|
120
|
+
return !r || r.error ? { ok: false, reason: r && r.error ? r.error.message : 'spawn failed' } : { ok: r.status === 0, code: r.status };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function runMigrate(instanceDir, run = spawnSync) {
|
|
124
|
+
const r = run('npm', ['run', 'migrate'], { cwd: instanceDir, stdio: 'inherit' });
|
|
125
|
+
return !r || r.error ? { ok: false, reason: r && r.error ? r.error.message : 'spawn failed' } : { ok: r.status === 0, code: r.status };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Regenerate the per-instance API artifacts (OpenAPI spec + api-reference + typed
|
|
129
|
+
// client) from the NEW core's routes — the claude-materialize sibling (task 2051).
|
|
130
|
+
// WHY: the routes + generators ship WITH core, but the generated spec/docs/client are
|
|
131
|
+
// EXCLUDED from the package (per-instance artifacts), so a bump changes the served API
|
|
132
|
+
// while the instance's committed spec/client lag until the next ship's fitness gate.
|
|
133
|
+
// This closes that gap on upgrade. We SPAWN the new core's generators (a fresh child
|
|
134
|
+
// captures its output root from the env below) with <FALLBACK_PREFIX>_INSTANCE_ROOT set
|
|
135
|
+
// so resolveDocsRoot() writes INTO the instance repo, not node_modules. docs first — the
|
|
136
|
+
// client reads the spec it produces. Best-effort: a hiccup warns, never fails the bump
|
|
137
|
+
// (fitness `gen-api-docs --check` + the api_client test backstop it on the next ship).
|
|
138
|
+
// Runs AFTER npm install so the generators come from the NEW core.
|
|
139
|
+
function regenerateApiArtifacts({ instanceDir, coreRoot }, run = spawnSync, fsImpl = fs) {
|
|
140
|
+
const env = { ...process.env, CLOUDBONGOS_INSTANCE_ROOT: instanceDir };
|
|
141
|
+
const ran = [];
|
|
142
|
+
for (const gen of ['gen-api-docs.js', 'gen-api-client.js']) {
|
|
143
|
+
const script = path.join(coreRoot, 'scripts', 'gds', gen);
|
|
144
|
+
if (!fsImpl.existsSync(script)) return { ok: false, ran, reason: `${gen} not found in core (${coreRoot})` };
|
|
145
|
+
const r = run(process.execPath, [script], { cwd: instanceDir, env, stdio: 'inherit' });
|
|
146
|
+
if (!r || r.error || r.status !== 0) {
|
|
147
|
+
return { ok: false, ran, reason: r && r.error ? r.error.message : `${gen} exited ${r && r.status}` };
|
|
148
|
+
}
|
|
149
|
+
ran.push(gen);
|
|
150
|
+
}
|
|
151
|
+
return { ok: true, ran };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function restartService({ service, restartCmd }, run = spawnSync) {
|
|
155
|
+
if (restartCmd) {
|
|
156
|
+
const parts = restartCmd.split(/\s+/);
|
|
157
|
+
const r = run(parts[0], parts.slice(1), { stdio: 'inherit' });
|
|
158
|
+
return { ok: !!r && !r.error && r.status === 0, code: r && r.status };
|
|
159
|
+
}
|
|
160
|
+
if (service) {
|
|
161
|
+
const r = run('systemctl', ['restart', service], { stdio: 'inherit' });
|
|
162
|
+
return { ok: !!r && !r.error && r.status === 0, code: r && r.status };
|
|
163
|
+
}
|
|
164
|
+
return { ok: null, skipped: true };
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const LEDGER_INSERT_COLS = 'INSERT INTO core_upgrades (from_version, to_version, source_commit, note)';
|
|
168
|
+
|
|
169
|
+
// Best-effort append to the core_upgrades ledger (migration core_189). Resolves the DB the same two
|
|
170
|
+
// ways a consumer might connect:
|
|
171
|
+
// • DATABASE_URL — a connection string (managed / hosted shape): via the pg driver.
|
|
172
|
+
// • PGDATABASE — a bare db name over the unix socket + peer auth (the self-host shape): by
|
|
173
|
+
// delegating to `psql -d "$PGDATABASE"`, EXACTLY as migrate.sh does. We shell out rather than
|
|
174
|
+
// reuse pg here because pg defaults host to localhost/TCP, so `new Pool({database})` would miss
|
|
175
|
+
// the socket + peer auth a provisioned instance relies on (systemd sets only PGDATABASE — task
|
|
176
|
+
// 1976 found the URL-only path silently skipped on emersonian, the very shape it must serve).
|
|
177
|
+
// Skips silently only when NEITHER is present (a local rehearsal with no DB pointed at) — the bump's
|
|
178
|
+
// verification never depends on the ledger. An attempted-but-failed insert returns skipped:false so
|
|
179
|
+
// the caller can surface it (the manual-INSERT footgun from 1976), never lose it.
|
|
180
|
+
async function recordLedger({ fromVersion, toVersion, sourceCommit, note }, deps = {}) {
|
|
181
|
+
const url = deps.databaseUrl !== undefined ? deps.databaseUrl : process.env.DATABASE_URL;
|
|
182
|
+
const database = deps.pgDatabase !== undefined ? deps.pgDatabase : process.env.PGDATABASE;
|
|
183
|
+
if (!url && !database) return { ok: false, skipped: true, reason: 'no DATABASE_URL or PGDATABASE' };
|
|
184
|
+
|
|
185
|
+
// DATABASE_URL path: the pg driver with a bound-parameter query (no psql client needed).
|
|
186
|
+
if (url) {
|
|
187
|
+
let Pool;
|
|
188
|
+
try { ({ Pool } = deps.pg || require('pg')); } catch { return { ok: false, skipped: true, reason: 'pg not resolvable' }; }
|
|
189
|
+
const pool = new Pool({ connectionString: url });
|
|
190
|
+
try {
|
|
191
|
+
await pool.query(
|
|
192
|
+
`${LEDGER_INSERT_COLS} VALUES ($1,$2,$3,$4)`,
|
|
193
|
+
[fromVersion || null, toVersion, sourceCommit || null, note || null]
|
|
194
|
+
);
|
|
195
|
+
return { ok: true };
|
|
196
|
+
} catch (e) {
|
|
197
|
+
return { ok: false, skipped: false, reason: e.message };
|
|
198
|
+
} finally {
|
|
199
|
+
try { await pool.end(); } catch { /* ignore */ }
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// PGDATABASE path: `psql -d <db>` lets libpq resolve the socket + peer auth (same as migrate.sh).
|
|
204
|
+
// Values pass as separate argv `--set`s (no shell → no shell injection) and reach the SQL as psql
|
|
205
|
+
// :'var' literals, which psql quotes/escapes safely (no SQL injection). NULLIF maps an absent value
|
|
206
|
+
// to NULL, matching the `x || null` of the pg path. The SQL is fed on STDIN, not `-c`: `-c` requires
|
|
207
|
+
// pure server-parseable SQL and does NOT run :'var' interpolation, so a `-c` INSERT would send the
|
|
208
|
+
// literal `:'from_version'` and syntax-error — psql only interpolates variables in script/stdin
|
|
209
|
+
// mode. ON_ERROR_STOP=1 guarantees a non-zero exit on any SQL error.
|
|
210
|
+
const run = deps.run || spawnSync;
|
|
211
|
+
const sql = `${LEDGER_INSERT_COLS}\n VALUES (NULLIF(:'from_version',''), :'to_version', NULLIF(:'source_commit',''), NULLIF(:'note',''));\n`;
|
|
212
|
+
const r = run('psql', [
|
|
213
|
+
'-d', database,
|
|
214
|
+
'-v', 'ON_ERROR_STOP=1',
|
|
215
|
+
'-q', '--no-psqlrc',
|
|
216
|
+
'--set', `from_version=${fromVersion || ''}`,
|
|
217
|
+
'--set', `to_version=${toVersion || ''}`,
|
|
218
|
+
'--set', `source_commit=${sourceCommit || ''}`,
|
|
219
|
+
'--set', `note=${note || ''}`,
|
|
220
|
+
], { encoding: 'utf8', input: sql });
|
|
221
|
+
if (!r || r.error) {
|
|
222
|
+
const enoent = !!(r && r.error && r.error.code === 'ENOENT');
|
|
223
|
+
return { ok: false, skipped: enoent, reason: enoent ? 'psql not found' : (r && r.error ? r.error.message : 'psql spawn failed') };
|
|
224
|
+
}
|
|
225
|
+
if (r.status !== 0) return { ok: false, skipped: false, reason: (r.stderr || '').trim() || `psql exit ${r.status}` };
|
|
226
|
+
return { ok: true };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Poll a health URL until it returns 2xx or the time budget (~30s) elapses. After `systemctl restart`
|
|
230
|
+
// the service needs a moment to bind its port, so a single immediate GET races the restart and
|
|
231
|
+
// spuriously reports `fetch failed` (task 1976 — it bound ~1s later on the emersonian 1.15→1.16 bump).
|
|
232
|
+
// Connection-refused fails fast, so the early retries are cheap; the backoff caps at 2s.
|
|
233
|
+
async function pollHealth(healthUrl, deps = {}) {
|
|
234
|
+
const fetchImpl = deps.fetch || fetch;
|
|
235
|
+
const sleep = deps.sleep || ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
236
|
+
const now = deps.now || Date.now;
|
|
237
|
+
const budgetMs = deps.healthBudgetMs != null ? deps.healthBudgetMs : 30_000;
|
|
238
|
+
const deadline = now() + budgetMs;
|
|
239
|
+
let attempt = 0;
|
|
240
|
+
let last = { ok: false, error: 'not attempted' };
|
|
241
|
+
for (;;) {
|
|
242
|
+
attempt++;
|
|
243
|
+
try {
|
|
244
|
+
const res = await fetchImpl(healthUrl, { signal: AbortSignal.timeout(5_000) });
|
|
245
|
+
if (res.ok) return { ok: true, status: res.status, attempts: attempt };
|
|
246
|
+
last = { ok: false, status: res.status };
|
|
247
|
+
} catch (e) {
|
|
248
|
+
last = { ok: false, error: e.message };
|
|
249
|
+
}
|
|
250
|
+
if (now() >= deadline) return { ...last, attempts: attempt, timedOut: true };
|
|
251
|
+
await sleep(Math.min(2_000, 500 * attempt));
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// ---- orchestration ----------------------------------------------------------
|
|
256
|
+
|
|
257
|
+
async function runUpgrade(opts, deps = {}) {
|
|
258
|
+
const log = deps.log || console.log;
|
|
259
|
+
const err = deps.err || console.error;
|
|
260
|
+
const run = deps.run || spawnSync;
|
|
261
|
+
const fsImpl = deps.fs || fs;
|
|
262
|
+
const materialize = deps.materialize || require('./claude-materialize').materializeClaude;
|
|
263
|
+
|
|
264
|
+
const instanceDir = path.resolve(opts.instance || process.cwd());
|
|
265
|
+
const targetVersion = opts.to;
|
|
266
|
+
const dryRun = !!opts.dryRun;
|
|
267
|
+
if (!targetVersion) return { ok: false, error: 'missing --to <version> (the target core version)' };
|
|
268
|
+
|
|
269
|
+
const fromVersion = readInstalledCoreVersion(instanceDir, fsImpl) || readPinnedCoreVersion(instanceDir, fsImpl);
|
|
270
|
+
log(`bongos upgrade — ${CORE_PKG}: ${fromVersion || '(none)'} → ${targetVersion}`);
|
|
271
|
+
log(` instance: ${instanceDir}${dryRun ? ' [DRY RUN — no changes]' : ''}`);
|
|
272
|
+
if (fromVersion === targetVersion && !opts.force) {
|
|
273
|
+
return { ok: false, error: `already on ${targetVersion} (pass --force to re-run the steps anyway)`, fromVersion };
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// 1. pre-flight: clean tree (so the pin change is reviewable + revertable) + module compatibility.
|
|
277
|
+
if (!opts.force) {
|
|
278
|
+
const tree = gitTreeClean(instanceDir, run);
|
|
279
|
+
if (!tree.ok) return { ok: false, error: `working tree not clean — commit/stash first, or pass --force.\n${tree.dirty || tree.reason || ''}` };
|
|
280
|
+
}
|
|
281
|
+
const mods = preflightModules({ instanceDir, targetVersion }, deps);
|
|
282
|
+
log(` ✓ pre-flight: ${mods.note}`);
|
|
283
|
+
if (!mods.ok) return { ok: false, error: `module pre-check failed: ${mods.blocking.map((b) => b.key).join(', ')} incompatible with core ${targetVersion}` };
|
|
284
|
+
|
|
285
|
+
// 2. bump the pin (vendor the tarball + rewrite the file: dep).
|
|
286
|
+
let vendorRel = opts.pinPath || (opts.from ? null : path.join('vendor', `${ARTIFACT}-${targetVersion}.tgz`));
|
|
287
|
+
if (opts.from) {
|
|
288
|
+
if (!fsImpl.existsSync(opts.from)) return { ok: false, error: `--from tarball not found: ${opts.from}` };
|
|
289
|
+
if (dryRun) { log(` [dry-run] would vendor ${opts.from} → vendor/${ARTIFACT}-${targetVersion}.tgz`); vendorRel = path.join('vendor', `${ARTIFACT}-${targetVersion}.tgz`); }
|
|
290
|
+
else vendorRel = vendorTarball({ instanceDir, fromTgz: path.resolve(opts.from), targetVersion }, fsImpl);
|
|
291
|
+
}
|
|
292
|
+
if (!fsImpl.existsSync(path.join(instanceDir, vendorRel)) && !dryRun) {
|
|
293
|
+
return { ok: false, error: `no core tarball at ${vendorRel} — pass --from <path-to-.tgz> to vendor it` };
|
|
294
|
+
}
|
|
295
|
+
const prevPin = dryRun ? null : writePin(instanceDir, vendorRel, fsImpl);
|
|
296
|
+
log(` ${dryRun ? '[dry-run] would pin' : '✓ pinned'} ${CORE_PKG} → file:${vendorRel}${prevPin ? ` (was ${prevPin})` : ''}`);
|
|
297
|
+
|
|
298
|
+
if (dryRun) { log(' [dry-run] would: npm install → npm run migrate → materialize .claude → regen API docs+client → restart → verify'); return { ok: true, dryRun: true, fromVersion, toVersion: targetVersion }; }
|
|
299
|
+
|
|
300
|
+
// 3. npm install.
|
|
301
|
+
const inst = npmInstall(instanceDir, run);
|
|
302
|
+
if (!inst.ok) return { ok: false, error: `npm install failed (${inst.reason || 'exit ' + inst.code})`, fromVersion };
|
|
303
|
+
log(' ✓ npm install');
|
|
304
|
+
|
|
305
|
+
// 4. migrate (additive core_* migrations).
|
|
306
|
+
if (!opts.skipMigrate) {
|
|
307
|
+
const mig = runMigrate(instanceDir, run);
|
|
308
|
+
if (!mig.ok) return { ok: false, error: `migrate failed (${mig.reason || 'exit ' + mig.code})`, fromVersion };
|
|
309
|
+
log(' ✓ migrate');
|
|
310
|
+
} else log(' • migrate skipped (--skip-migrate)');
|
|
311
|
+
|
|
312
|
+
// 5. materialize .claude/ from the freshly-installed core.
|
|
313
|
+
if (!opts.skipMaterialize) {
|
|
314
|
+
const coreRoot = path.join(instanceDir, 'node_modules', CORE_PKG);
|
|
315
|
+
const sum = materialize({ coreRoot, instanceDir, log: (m) => log(m) });
|
|
316
|
+
log(` ✓ materialized .claude/ (${sum.skills} skill file(s)${sum.settings ? ', settings.json' : ''}${sum.hooks ? `, ${sum.hooks} hook(s)` : ''})`);
|
|
317
|
+
} else log(' • materialize skipped (--skip-materialize)');
|
|
318
|
+
|
|
319
|
+
// 5b. regenerate the per-instance API artifacts (OpenAPI spec + typed client) from the
|
|
320
|
+
// new core's routes — the claude-materialize sibling (task 2051). Best-effort: a regen
|
|
321
|
+
// hiccup is a warning, not a failed bump (the next ship's fitness gate refreshes them).
|
|
322
|
+
if (!opts.skipRegenDocs) {
|
|
323
|
+
const coreRoot = path.join(instanceDir, 'node_modules', CORE_PKG);
|
|
324
|
+
const regen = (deps.regenerateApiArtifacts || regenerateApiArtifacts)({ instanceDir, coreRoot }, run);
|
|
325
|
+
if (regen.ok) log(` ✓ regenerated API docs + typed client from core ${targetVersion}`);
|
|
326
|
+
else err(` ! API-artifact regen incomplete (${regen.reason}) — ran ${regen.ran.join(', ') || 'nothing'}; the next ship's fitness gate refreshes them.`);
|
|
327
|
+
} else log(' • API-artifact regen skipped (--skip-regen-docs)');
|
|
328
|
+
|
|
329
|
+
// 6. restart.
|
|
330
|
+
const rs = restartService({ service: opts.service, restartCmd: opts.restartCmd }, run);
|
|
331
|
+
if (rs.skipped) log(` • restart: no --service/--restart-cmd — restart the instance service to load core ${targetVersion}.`);
|
|
332
|
+
else if (!rs.ok) err(` ! restart command failed (exit ${rs.code}) — restart the service manually.`);
|
|
333
|
+
else log(` ✓ restarted ${opts.service || 'service'}`);
|
|
334
|
+
|
|
335
|
+
// 7. verify: installed version == target, optional /healthz, ledger row.
|
|
336
|
+
const installed = readInstalledCoreVersion(instanceDir, fsImpl);
|
|
337
|
+
const versionOk = installed === targetVersion;
|
|
338
|
+
log(` ${versionOk ? '✓' : '!'} installed core version: ${installed || '(unknown)'}${versionOk ? '' : ` (expected ${targetVersion})`}`);
|
|
339
|
+
|
|
340
|
+
let healthOk = null;
|
|
341
|
+
if (opts.healthUrl) {
|
|
342
|
+
const h = await pollHealth(opts.healthUrl, deps);
|
|
343
|
+
healthOk = h.ok;
|
|
344
|
+
if (h.ok) log(` ✓ health ${opts.healthUrl} → ${h.status}${h.attempts > 1 ? ` (ready after ${h.attempts} tries)` : ''}`);
|
|
345
|
+
else err(` ! health ${opts.healthUrl} not ready after ${h.attempts} tr${h.attempts === 1 ? 'y' : 'ies'}: ${h.error || 'status ' + h.status}`);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const ledger = await recordLedger({ fromVersion, toVersion: targetVersion, sourceCommit: opts.sourceCommit, note: opts.note }, deps);
|
|
349
|
+
if (ledger.ok) log(' ✓ recorded in core_upgrades ledger');
|
|
350
|
+
else if (ledger.skipped) log(` • ledger skipped (${ledger.reason})`);
|
|
351
|
+
else err(` ! ledger insert failed (${ledger.reason}) — record it manually`);
|
|
352
|
+
|
|
353
|
+
const ok = versionOk && healthOk !== false;
|
|
354
|
+
log(ok ? `\n✓ upgrade complete — core ${fromVersion || '(none)'} → ${targetVersion}` : `\n! upgrade finished with warnings — review above.`);
|
|
355
|
+
return { ok, fromVersion, toVersion: targetVersion, versionOk, healthOk, ledger: ledger.ok };
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function parseArgs(argv) {
|
|
359
|
+
return {
|
|
360
|
+
to: arg('--to', argv),
|
|
361
|
+
from: arg('--from', argv),
|
|
362
|
+
instance: arg('--instance', argv),
|
|
363
|
+
service: arg('--service', argv),
|
|
364
|
+
restartCmd: arg('--restart-cmd', argv),
|
|
365
|
+
healthUrl: arg('--health-url', argv),
|
|
366
|
+
sourceCommit: arg('--source-commit', argv),
|
|
367
|
+
note: arg('--note', argv),
|
|
368
|
+
pinPath: arg('--pin-path', argv),
|
|
369
|
+
dryRun: hasFlag('--dry-run', argv),
|
|
370
|
+
force: hasFlag('--force', argv),
|
|
371
|
+
skipMigrate: hasFlag('--skip-migrate', argv),
|
|
372
|
+
skipMaterialize: hasFlag('--skip-materialize', argv),
|
|
373
|
+
skipRegenDocs: hasFlag('--skip-regen-docs', argv),
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
async function main(argv = process.argv.slice(2)) {
|
|
378
|
+
if (hasFlag('--help', argv) || argv[0] === 'help') {
|
|
379
|
+
process.stdout.write([
|
|
380
|
+
'bongos upgrade — pull the Cloud Bongos core to a new version and apply it.',
|
|
381
|
+
'',
|
|
382
|
+
'Usage:',
|
|
383
|
+
' bongos upgrade module-compat pre-check against the installed core (exit 1 on mismatch)',
|
|
384
|
+
' bongos upgrade --to <version> [opts] pull + apply a new core version (the real channel)',
|
|
385
|
+
'',
|
|
386
|
+
' --to <version> target core version — presence switches from pre-check to a real bump',
|
|
387
|
+
' --from <tgz> source tarball to vendor into vendor/ (else it must already be there)',
|
|
388
|
+
' --instance <dir> consumer instance root (default: cwd)',
|
|
389
|
+
' --service <unit> systemd unit to restart after applying',
|
|
390
|
+
' --restart-cmd <cmd> explicit restart command (overrides --service)',
|
|
391
|
+
' --health-url <url> poll after restart (~30s) until 2xx; still-failing is a warning',
|
|
392
|
+
' --skip-migrate do not run `npm run migrate`',
|
|
393
|
+
' --skip-materialize do not refresh .claude/',
|
|
394
|
+
' --skip-regen-docs do not regenerate the OpenAPI spec + typed client from the new core',
|
|
395
|
+
' --dry-run show the plan; change nothing',
|
|
396
|
+
' --force skip the clean-tree + same-version guards',
|
|
397
|
+
'',
|
|
398
|
+
'Full bump: pre-flight → bump pin → npm install → migrate → materialize .claude → regen API docs+client → restart → verify.',
|
|
399
|
+
].join('\n') + '\n');
|
|
400
|
+
return 0;
|
|
401
|
+
}
|
|
402
|
+
// Backward-compatible: bare `bongos upgrade` (no --to) is the documented module-compatibility
|
|
403
|
+
// PRE-CHECK — unchanged behavior, delegated to the module CLI. A --to switches to the real channel.
|
|
404
|
+
if (!arg('--to', argv)) {
|
|
405
|
+
return require('./module').cmdUpgrade(argv);
|
|
406
|
+
}
|
|
407
|
+
const res = await runUpgrade(parseArgs(argv));
|
|
408
|
+
if (!res.ok) { process.stderr.write(`\n✖ ${res.error || 'upgrade failed'}\n`); return 1; }
|
|
409
|
+
return 0;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
module.exports = {
|
|
413
|
+
runUpgrade, parseArgs, main,
|
|
414
|
+
versionFromTgzPath, readInstalledCoreVersion, readPinnedCoreVersion, writePin,
|
|
415
|
+
vendorTarball, gitTreeClean, preflightModules, npmInstall, runMigrate, regenerateApiArtifacts, restartService, recordLedger, pollHealth,
|
|
416
|
+
CORE_PKG, ARTIFACT,
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
if (require.main === module) {
|
|
420
|
+
main().then((code) => process.exit(code)).catch((e) => { process.stderr.write(`✖ ${e.message}\n`); process.exit(1); });
|
|
421
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
// validate-design.js — minimal validator for the neutral design contract (task 1377).
|
|
4
|
+
// See docs/design-contract.md §6 for the full spec.
|
|
5
|
+
//
|
|
6
|
+
// Usage:
|
|
7
|
+
// node scripts/gds/validate-design.js # exits 0 on pass, 1 on failure
|
|
8
|
+
// node scripts/gds/validate-design.js --json # machine-readable { ok, errors, warnings }
|
|
9
|
+
// node scripts/gds/validate-design.js --strict # treat warnings as errors
|
|
10
|
+
|
|
11
|
+
const fs = require('node:fs');
|
|
12
|
+
const path = require('node:path');
|
|
13
|
+
|
|
14
|
+
const REPO_ROOT = path.resolve(__dirname, '..', '..');
|
|
15
|
+
const ARGS = new Set(process.argv.slice(2));
|
|
16
|
+
const JSON_MODE = ARGS.has('--json');
|
|
17
|
+
const STRICT = ARGS.has('--strict');
|
|
18
|
+
|
|
19
|
+
const NEUTRAL_TOKENS = path.join(REPO_ROOT, 'config', 'design-tokens.neutral.json');
|
|
20
|
+
const INSTANCE_TOKENS = path.join(REPO_ROOT, 'config', 'design-tokens.json');
|
|
21
|
+
const TOKENS_SCHEMA = path.join(REPO_ROOT, 'config', 'design-tokens.schema.json');
|
|
22
|
+
const DESIGN_SOURCES = path.join(REPO_ROOT, 'config', 'design-sources.json');
|
|
23
|
+
const UI_SRC = path.join(REPO_ROOT, 'src', 'ui');
|
|
24
|
+
const UI_ASSETS = path.join(REPO_ROOT, 'assets', 'ui');
|
|
25
|
+
const ADAPTERS_DIR = path.join(REPO_ROOT, 'src', 'ui', 'adapters');
|
|
26
|
+
|
|
27
|
+
const TOOL_ENUM = new Set(['claude-design', 'figma', 'hand', 'asset']);
|
|
28
|
+
const REQUIRED_COLORS = ['bg', 'bgCard', 'ink', 'accent'];
|
|
29
|
+
const REQUIRED_FONTS = ['display', 'body'];
|
|
30
|
+
|
|
31
|
+
const errors = [];
|
|
32
|
+
const warnings = [];
|
|
33
|
+
|
|
34
|
+
function err(msg) { errors.push(msg); }
|
|
35
|
+
function warn(msg) { warnings.push(msg); }
|
|
36
|
+
|
|
37
|
+
// ── helpers ──────────────────────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
function readJson(filePath, label) {
|
|
40
|
+
try {
|
|
41
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
42
|
+
} catch (e) {
|
|
43
|
+
err(`${label}: cannot read/parse — ${e.message}`);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function deepMerge(base, override) {
|
|
49
|
+
if (!override) return base;
|
|
50
|
+
const out = { ...base };
|
|
51
|
+
for (const [k, v] of Object.entries(override)) {
|
|
52
|
+
if (v && typeof v === 'object' && !Array.isArray(v) && typeof out[k] === 'object') {
|
|
53
|
+
out[k] = deepMerge(out[k], v);
|
|
54
|
+
} else {
|
|
55
|
+
out[k] = v;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function isUri(s) {
|
|
62
|
+
try { new URL(s); return true; } catch { return false; }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function dirExists(p) {
|
|
66
|
+
try { return fs.statSync(p).isDirectory(); } catch { return false; }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function fileExists(p) {
|
|
70
|
+
try { return fs.statSync(p).isFile(); } catch { return false; }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function listDirs(p) {
|
|
74
|
+
if (!dirExists(p)) return [];
|
|
75
|
+
return fs.readdirSync(p, { withFileTypes: true })
|
|
76
|
+
.filter(e => e.isDirectory())
|
|
77
|
+
.map(e => e.name);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ── Check 1: neutral tokens file exists + parses ─────────────────────────────
|
|
81
|
+
|
|
82
|
+
const schema = readJson(TOKENS_SCHEMA, 'config/design-tokens.schema.json');
|
|
83
|
+
const neutral = readJson(NEUTRAL_TOKENS, 'config/design-tokens.neutral.json');
|
|
84
|
+
|
|
85
|
+
if (!neutral) {
|
|
86
|
+
err('config/design-tokens.neutral.json is missing — this is the required baseline');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ── Check 2: instance tokens file, if present, parses ────────────────────────
|
|
90
|
+
|
|
91
|
+
let instance = null;
|
|
92
|
+
if (fileExists(INSTANCE_TOKENS)) {
|
|
93
|
+
instance = readJson(INSTANCE_TOKENS, 'config/design-tokens.json');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ── Check 3: merged tokens satisfy required fields ───────────────────────────
|
|
97
|
+
|
|
98
|
+
const merged = neutral ? deepMerge(neutral, instance) : null;
|
|
99
|
+
|
|
100
|
+
if (merged) {
|
|
101
|
+
if (!merged.colors || typeof merged.colors !== 'object') {
|
|
102
|
+
err('merged tokens: "colors" group is missing');
|
|
103
|
+
} else {
|
|
104
|
+
for (const key of REQUIRED_COLORS) {
|
|
105
|
+
if (!merged.colors[key]) err(`merged tokens: colors.${key} is required but missing`);
|
|
106
|
+
else if (typeof merged.colors[key] !== 'string') err(`merged tokens: colors.${key} must be a string`);
|
|
107
|
+
}
|
|
108
|
+
for (const [key, val] of Object.entries(merged.colors)) {
|
|
109
|
+
if (typeof val !== 'string') err(`merged tokens: colors.${key} must be a string`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (!merged.fonts || typeof merged.fonts !== 'object') {
|
|
114
|
+
err('merged tokens: "fonts" group is missing');
|
|
115
|
+
} else {
|
|
116
|
+
for (const key of REQUIRED_FONTS) {
|
|
117
|
+
if (!merged.fonts[key]) err(`merged tokens: fonts.${key} is required but missing`);
|
|
118
|
+
else if (typeof merged.fonts[key] !== 'string') err(`merged tokens: fonts.${key} must be a string`);
|
|
119
|
+
}
|
|
120
|
+
if (merged.fonts.links !== undefined) {
|
|
121
|
+
if (!Array.isArray(merged.fonts.links)) {
|
|
122
|
+
err('merged tokens: fonts.links must be an array');
|
|
123
|
+
} else {
|
|
124
|
+
for (const link of merged.fonts.links) {
|
|
125
|
+
if (typeof link !== 'string' || !isUri(link)) {
|
|
126
|
+
err(`merged tokens: fonts.links entry is not a valid URI: ${link}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Optional groups: check value types if present
|
|
134
|
+
if (merged.scale) {
|
|
135
|
+
for (const [k, v] of Object.entries(merged.scale)) {
|
|
136
|
+
if (typeof v !== 'string') err(`merged tokens: scale.${k} must be a string`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (merged.radius) {
|
|
140
|
+
for (const [k, v] of Object.entries(merged.radius)) {
|
|
141
|
+
if (typeof v !== 'string') err(`merged tokens: radius.${k} must be a string`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (merged.motion) {
|
|
145
|
+
for (const [k, v] of Object.entries(merged.motion)) {
|
|
146
|
+
if (typeof v !== 'string') err(`merged tokens: motion.${k} must be a string`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ── Check 4: design-sources.json is valid + entries have required fields ─────
|
|
152
|
+
|
|
153
|
+
let sources = null;
|
|
154
|
+
if (fileExists(DESIGN_SOURCES)) {
|
|
155
|
+
sources = readJson(DESIGN_SOURCES, 'config/design-sources.json');
|
|
156
|
+
if (sources) {
|
|
157
|
+
if (!sources.surfaces || typeof sources.surfaces !== 'object') {
|
|
158
|
+
err('config/design-sources.json: "surfaces" key must be an object');
|
|
159
|
+
} else {
|
|
160
|
+
for (const [surfaceId, entry] of Object.entries(sources.surfaces)) {
|
|
161
|
+
if (!entry || typeof entry !== 'object') {
|
|
162
|
+
err(`design-sources: surface "${surfaceId}" entry must be an object`);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (!entry.tool) {
|
|
166
|
+
err(`design-sources: surface "${surfaceId}" is missing "tool" field`);
|
|
167
|
+
} else if (!TOOL_ENUM.has(entry.tool)) {
|
|
168
|
+
err(`design-sources: surface "${surfaceId}" tool "${entry.tool}" is not in allowed enum (${[...TOOL_ENUM].join(', ')})`);
|
|
169
|
+
}
|
|
170
|
+
if (entry.sourceUrl !== undefined) {
|
|
171
|
+
if (typeof entry.sourceUrl !== 'string' || !isUri(entry.sourceUrl)) {
|
|
172
|
+
err(`design-sources: surface "${surfaceId}" sourceUrl is not a valid URI`);
|
|
173
|
+
}
|
|
174
|
+
} else if (entry.tool && !['hand', 'asset'].includes(entry.tool)) {
|
|
175
|
+
warn(`design-sources: surface "${surfaceId}" tool "${entry.tool}" has no sourceUrl`);
|
|
176
|
+
}
|
|
177
|
+
if (entry.lastSyncedAt !== undefined) {
|
|
178
|
+
if (typeof entry.lastSyncedAt !== 'string' || isNaN(Date.parse(entry.lastSyncedAt))) {
|
|
179
|
+
err(`design-sources: surface "${surfaceId}" lastSyncedAt is not a valid ISO 8601 date`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
} else {
|
|
186
|
+
warn('config/design-sources.json not found — this is optional until adapters are in use');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ── Check 5: design-sources surface ids match directories (if dirs exist) ─────
|
|
190
|
+
|
|
191
|
+
const hasUiSrc = dirExists(UI_SRC);
|
|
192
|
+
const hasUiAssets = dirExists(UI_ASSETS);
|
|
193
|
+
|
|
194
|
+
if (sources && sources.surfaces) {
|
|
195
|
+
const uiSrcDirs = hasUiSrc ? new Set(listDirs(UI_SRC).filter(n => n !== 'adapters')) : new Set();
|
|
196
|
+
const uiAssetsDirs = hasUiAssets ? new Set(listDirs(UI_ASSETS)) : new Set();
|
|
197
|
+
|
|
198
|
+
for (const surfaceId of Object.keys(sources.surfaces)) {
|
|
199
|
+
const inSrc = uiSrcDirs.has(surfaceId);
|
|
200
|
+
const inAssets = uiAssetsDirs.has(surfaceId);
|
|
201
|
+
if (!inSrc && !inAssets && (hasUiSrc || hasUiAssets)) {
|
|
202
|
+
warn(`design-sources: surface "${surfaceId}" has no matching directory in src/ui/ or assets/ui/`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// ── Check 6: adapter directories have valid index.js ─────────────────────────
|
|
208
|
+
|
|
209
|
+
if (dirExists(ADAPTERS_DIR)) {
|
|
210
|
+
for (const adapterName of listDirs(ADAPTERS_DIR)) {
|
|
211
|
+
const indexPath = path.join(ADAPTERS_DIR, adapterName, 'index.js');
|
|
212
|
+
if (!fileExists(indexPath)) {
|
|
213
|
+
err(`adapter "${adapterName}": missing index.js at src/ui/adapters/${adapterName}/index.js`);
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
let mod;
|
|
217
|
+
try {
|
|
218
|
+
mod = require(indexPath);
|
|
219
|
+
} catch (e) {
|
|
220
|
+
err(`adapter "${adapterName}": index.js threw on require — ${e.message}`);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (typeof mod.id !== 'string' || !mod.id) {
|
|
224
|
+
err(`adapter "${adapterName}": index.js must export a non-empty string "id"`);
|
|
225
|
+
} else if (mod.id !== adapterName) {
|
|
226
|
+
warn(`adapter "${adapterName}": exported id "${mod.id}" does not match directory name`);
|
|
227
|
+
}
|
|
228
|
+
if (typeof mod.import !== 'function') {
|
|
229
|
+
err(`adapter "${adapterName}": index.js must export an "import" function`);
|
|
230
|
+
}
|
|
231
|
+
if (typeof mod.export !== 'function') {
|
|
232
|
+
err(`adapter "${adapterName}": index.js must export an "export" function`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// ── Report ────────────────────────────────────────────────────────────────────
|
|
238
|
+
|
|
239
|
+
const effectiveErrors = STRICT ? [...errors, ...warnings] : errors;
|
|
240
|
+
const ok = effectiveErrors.length === 0;
|
|
241
|
+
|
|
242
|
+
if (JSON_MODE) {
|
|
243
|
+
process.stdout.write(JSON.stringify({ ok, errors, warnings }, null, 2) + '\n');
|
|
244
|
+
} else {
|
|
245
|
+
const label = ok ? '✓ design contract valid' : '✗ design contract invalid';
|
|
246
|
+
process.stdout.write(`${label}\n`);
|
|
247
|
+
for (const e of errors) process.stdout.write(` ERROR ${e}\n`);
|
|
248
|
+
for (const w of warnings) process.stdout.write(` WARNING ${w}\n`);
|
|
249
|
+
if (ok && !STRICT && warnings.length) {
|
|
250
|
+
process.stdout.write(` (${warnings.length} warning(s); use --strict to fail on warnings)\n`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
process.exit(ok ? 0 : 1);
|