@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,423 @@
|
|
|
1
|
+
// public-builders/box-panel.js — the shared dev-box management panel.
|
|
2
|
+
//
|
|
3
|
+
// One self-serve control surface for a builder's OWN hosted dev box: request
|
|
4
|
+
// (provision), open the in-browser terminal, see connection details, and close
|
|
5
|
+
// the box. It is driven by LIVE SERVER STATE (GET /box/me + GET /box/terminal),
|
|
6
|
+
// repainted on every mount and kept fresh by a single self-rescheduling poll
|
|
7
|
+
// while anything is in flight (provisioning / waking / closing / tunnel warming
|
|
8
|
+
// up). The poll stops once the box settles.
|
|
9
|
+
//
|
|
10
|
+
// It is used in two places (#807 / ADR 0040 — moving box mgmt into Settings):
|
|
11
|
+
// * the #777 onboarding welcome panel, in browser-only mode → showSsh:false
|
|
12
|
+
// (online terminal only — a newcomer never sees raw SSH details);
|
|
13
|
+
// * the Settings page → showSsh:true (both the online terminal AND the SSH
|
|
14
|
+
// IP + command, so a builder can drive their box however they like).
|
|
15
|
+
//
|
|
16
|
+
// Behaviour is identical in both; the ONLY difference is whether the SSH rows
|
|
17
|
+
// are shown. The terminal credential is a secret returned only to the box's own
|
|
18
|
+
// builder by GET /box/terminal — shown to that builder, never logged.
|
|
19
|
+
//
|
|
20
|
+
// Usage:
|
|
21
|
+
// const panel = OTBBoxPanel.create({ api: '/api/bongos', showSsh: true, toast });
|
|
22
|
+
// panel.mount(containerEl); // injects markup, wires clicks, paints state
|
|
23
|
+
// panel.refresh(); // repaint from server (e.g. on un-minimise)
|
|
24
|
+
// panel.stop(); // stop polling (e.g. on dismiss / minimise)
|
|
25
|
+
//
|
|
26
|
+
// The container element should carry the `.setup__box` class for styling. mount
|
|
27
|
+
// is re-entrant: calling it again (e.g. after the host re-renders its DOM)
|
|
28
|
+
// re-binds to the new element and cancels any prior poll.
|
|
29
|
+
|
|
30
|
+
(function () {
|
|
31
|
+
'use strict';
|
|
32
|
+
|
|
33
|
+
// escapeHtml now comes from the shared window.OTB toolkit (dom-utils.js,
|
|
34
|
+
// loaded first on every page that mounts this panel). q / getJSON / postJSON
|
|
35
|
+
// and the injected toast stay local — they carry per-panel behaviour.
|
|
36
|
+
const { escapeHtml } = window.OTB;
|
|
37
|
+
|
|
38
|
+
// ttyd's HTTP-basic username is the fixed `otb` user (box-terminal.service:
|
|
39
|
+
// --credential "otb:<pass>"); the password is the long hex `credential`.
|
|
40
|
+
const TERMINAL_USER = 'otb';
|
|
41
|
+
|
|
42
|
+
// Terminal URL with the basic-auth userinfo embedded, so "Open online
|
|
43
|
+
// environment" lands signed-in (browsers honor user:pass@host for top-level
|
|
44
|
+
// navigation; ttyd auth is plain HTTP basic). The credential is already
|
|
45
|
+
// displayed in plaintext on this panel, so the href adds no new exposure.
|
|
46
|
+
function terminalAuthUrl(term) {
|
|
47
|
+
if (!term || !term.url) return null;
|
|
48
|
+
if (!term.credential) return term.url;
|
|
49
|
+
try {
|
|
50
|
+
const u = new URL(term.url);
|
|
51
|
+
u.username = TERMINAL_USER;
|
|
52
|
+
u.password = term.credential;
|
|
53
|
+
return u.toString();
|
|
54
|
+
} catch (_) {
|
|
55
|
+
return term.url;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function create(opts) {
|
|
60
|
+
opts = opts || {};
|
|
61
|
+
const API = opts.api || '/api/bongos';
|
|
62
|
+
// Generated typed client (task 1996 / R09), served as window.BongosClient by
|
|
63
|
+
// /lib/bongos-client.js. baseUrl:'' passes the full same-origin paths this file
|
|
64
|
+
// builds through unchanged; result-mode ({ status, ok, data }) preserves control flow 1:1.
|
|
65
|
+
const api = window.BongosClient.createClient({ baseUrl: '', credentials: 'same-origin', throwOnError: false });
|
|
66
|
+
const showSsh = !!opts.showSsh;
|
|
67
|
+
const toast = typeof opts.toast === 'function' ? opts.toast : function () {};
|
|
68
|
+
|
|
69
|
+
let root = null; // the mounted container element
|
|
70
|
+
let pollTimer = null; // self-rescheduling refresh timer
|
|
71
|
+
let termWindow = null; // handle to the opened terminal tab (to close it)
|
|
72
|
+
let bound = false; // whether we've attached our click listener
|
|
73
|
+
|
|
74
|
+
const AUTH_REDIRECT = 'redirecting to auth';
|
|
75
|
+
|
|
76
|
+
async function getJSON(path) {
|
|
77
|
+
const res = await api.request('GET', path);
|
|
78
|
+
if (res.status === 401) { window.location.assign(`${API}/auth/web/start`); throw new Error(AUTH_REDIRECT); }
|
|
79
|
+
if (!res.ok) throw new Error(`${path} → ${res.status}`);
|
|
80
|
+
return res.data;
|
|
81
|
+
}
|
|
82
|
+
async function postJSON(path) {
|
|
83
|
+
const res = await api.request('POST', path);
|
|
84
|
+
if (res.status === 401) { window.location.assign(`${API}/auth/web/start`); throw new Error(AUTH_REDIRECT); }
|
|
85
|
+
if (!res.ok) {
|
|
86
|
+
let detail = `${path} → ${res.status}`;
|
|
87
|
+
try { const j = res.data; detail = j.message || j.detail || j.error || detail; } catch (_) { /* keep default */ }
|
|
88
|
+
const err = new Error(detail); err.status = res.status; throw err;
|
|
89
|
+
}
|
|
90
|
+
return res.data;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ---- DOM helpers (scoped to `root`) ------------------------------------
|
|
94
|
+
const q = (sel) => (root ? root.querySelector(sel) : null);
|
|
95
|
+
// NOTE: the `.setup__box-out` (display:flex) and `.setup__btn` (display:
|
|
96
|
+
// inline-block) rules out-specify the UA `[hidden]{display:none}` rule, so
|
|
97
|
+
// toggling the `hidden` attribute alone leaves an empty bordered stub / a
|
|
98
|
+
// stale "Request dev box" button visible. Drive `display` directly to hide.
|
|
99
|
+
function setOut(html) { const out = q('[data-box-out]'); if (out) { out.hidden = false; out.style.display = ''; out.innerHTML = html; } }
|
|
100
|
+
function hideOut() { const out = q('[data-box-out]'); if (out) { out.hidden = true; out.style.display = 'none'; out.innerHTML = ''; } }
|
|
101
|
+
function setRequestBtn(visible, label) {
|
|
102
|
+
const btn = q('[data-box-request]');
|
|
103
|
+
if (!btn) return;
|
|
104
|
+
btn.hidden = !visible;
|
|
105
|
+
btn.style.display = visible ? '' : 'none';
|
|
106
|
+
if (visible) { btn.disabled = false; btn.textContent = label || 'Request dev box'; }
|
|
107
|
+
}
|
|
108
|
+
function enableOpenBtn(url) {
|
|
109
|
+
const openBtn = q('[data-box-open]');
|
|
110
|
+
if (!openBtn) return;
|
|
111
|
+
if (url) {
|
|
112
|
+
openBtn.setAttribute('href', url);
|
|
113
|
+
openBtn.setAttribute('target', '_blank');
|
|
114
|
+
openBtn.setAttribute('rel', 'noopener noreferrer');
|
|
115
|
+
openBtn.removeAttribute('aria-disabled');
|
|
116
|
+
} else {
|
|
117
|
+
openBtn.removeAttribute('href');
|
|
118
|
+
openBtn.removeAttribute('target');
|
|
119
|
+
openBtn.removeAttribute('rel');
|
|
120
|
+
openBtn.setAttribute('aria-disabled', 'true');
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function stopPoll() { if (pollTimer) { clearTimeout(pollTimer); pollTimer = null; } }
|
|
125
|
+
function schedulePoll(ms) { stopPoll(); pollTimer = setTimeout(() => { refresh(); }, ms || 5000); }
|
|
126
|
+
|
|
127
|
+
function closeTermWindow() {
|
|
128
|
+
if (termWindow && !termWindow.closed) {
|
|
129
|
+
try { termWindow.close(); } catch (_) { /* cross-origin or already gone */ }
|
|
130
|
+
}
|
|
131
|
+
termWindow = null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// One credential/detail row. The value itself is click-to-copy (values are
|
|
135
|
+
// long) — no separate button.
|
|
136
|
+
function credRow(label, value) {
|
|
137
|
+
return `<div class="setup__cred-row">
|
|
138
|
+
<span class="setup__cred-k">${escapeHtml(label)}</span>
|
|
139
|
+
<code class="setup__cred-v setup__copy" data-copy="${escapeHtml(value)}" tabindex="0" role="button" title="Click to copy ${escapeHtml(label.toLowerCase())}" aria-label="Copy ${escapeHtml(label.toLowerCase())}">${escapeHtml(value)}</code>
|
|
140
|
+
</div>`;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// The default Close-box control. Clicking it ARMS a confirm step
|
|
144
|
+
// (armCloseConfirm) instead of closing immediately — task 1459: a fresh box
|
|
145
|
+
// gets a NEW SSH identity, so a newcomer who hits "Host denied" on reconnect
|
|
146
|
+
// tends to reflexively close + reopen again, which only rotates the identity
|
|
147
|
+
// once more and digs the hole deeper. The confirm names the real cure.
|
|
148
|
+
function closeSectionHtml() {
|
|
149
|
+
return '<button type="button" class="setup__btn setup__btn--danger" data-box-close>Close box</button>'
|
|
150
|
+
+ '<span class="setup__box-close-hint">Stops and deletes your box. Provision a fresh one anytime.</span>';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// The armed confirm: the warning + a real Close + a Keep. The Desktop/"Host
|
|
154
|
+
// denied" line is phrased conditionally so browser-terminal-only builders
|
|
155
|
+
// (who never touch SSH host keys) naturally skip it.
|
|
156
|
+
function closeConfirmHtml() {
|
|
157
|
+
// .setup__box-close is a flex row; flex-basis:100% puts the warning on its
|
|
158
|
+
// own line so the two buttons wrap neatly beneath it.
|
|
159
|
+
return '<p class="setup__box-close-hint" style="flex-basis:100%;margin:0">Closing deletes this box. The fresh one you open next has a '
|
|
160
|
+
+ '<strong>new identity</strong> — so if Claude Desktop then says <strong>“Host denied”</strong> '
|
|
161
|
+
+ 'or asks for a password, fully quit and reopen Desktop (it re-pins your box automatically) or press '
|
|
162
|
+
+ '<strong>Repair</strong>. Closing and reopening again will <em>not</em> help — it only changes the identity once more.</p>'
|
|
163
|
+
+ '<button type="button" class="setup__btn setup__btn--danger" data-box-close-confirm>Close box</button> '
|
|
164
|
+
+ '<button type="button" class="setup__btn" data-box-close-cancel>Keep box</button>';
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Swap the Close-box control between its default and armed states in place.
|
|
168
|
+
// Both operate on the enclosing .setup__box-close container, so a stray
|
|
169
|
+
// server repaint (which re-renders the default) just resets to "not armed".
|
|
170
|
+
function armCloseConfirm(btn) {
|
|
171
|
+
const wrap = btn.closest('.setup__box-close');
|
|
172
|
+
if (wrap) wrap.innerHTML = closeConfirmHtml();
|
|
173
|
+
}
|
|
174
|
+
function disarmCloseConfirm(btn) {
|
|
175
|
+
const wrap = btn.closest('.setup__box-close');
|
|
176
|
+
if (wrap) wrap.innerHTML = closeSectionHtml();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Render the active-box panel. SSH rows (IP + connect command) only appear
|
|
180
|
+
// when showSsh is true AND the box has an IP — the onboarding panel hides
|
|
181
|
+
// them so a newcomer sees only the online terminal. The terminal rows show
|
|
182
|
+
// whenever the tunnel has published a URL. All users get a Close button.
|
|
183
|
+
function renderBoxActive(box, term, cost) {
|
|
184
|
+
const parts = ['<p class="setup__box-msg setup__box-msg--ok">Your dev box is ready.</p>'];
|
|
185
|
+
|
|
186
|
+
// idea 332 / task 1316 (ADR 0072): flag a box running old code. A box too
|
|
187
|
+
// old to self-update can't be fixed in place — only a rebuild (Close box →
|
|
188
|
+
// provision fresh) brings it onto current code. Points at the Close button
|
|
189
|
+
// below. The server decides `stale` (boxes.computeCodeStaleness).
|
|
190
|
+
if (box.code && box.code.stale) {
|
|
191
|
+
parts.push(
|
|
192
|
+
'<p class="setup__box-msg setup__box-msg--warn">⚠ This box is running <strong>old code</strong>, '
|
|
193
|
+
+ 'which can break art generation and reconnecting. It can\'t update itself — '
|
|
194
|
+
+ 'use <strong>Close box</strong> below, then provision a fresh one to bring it current.</p>'
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (showSsh && box.ip) {
|
|
199
|
+
parts.push(credRow('IP', box.ip));
|
|
200
|
+
parts.push(credRow('SSH', `ssh root@${box.ip}`));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (term && term.url) {
|
|
204
|
+
if (showSsh && box.ip) parts.push('<hr class="setup__divider">');
|
|
205
|
+
parts.push(credRow('Terminal', term.url));
|
|
206
|
+
if (term.credential) {
|
|
207
|
+
parts.push(credRow('Username', TERMINAL_USER));
|
|
208
|
+
parts.push(credRow('Password', term.credential));
|
|
209
|
+
}
|
|
210
|
+
// #893: closing the terminal tab no longer kills the session (it runs in
|
|
211
|
+
// tmux on the box), and never shut the box down. Say both, so a builder
|
|
212
|
+
// neither fears losing work nor leaves the box billing thinking it's off.
|
|
213
|
+
parts.push('<p class="setup__box-close-hint">Closing the terminal tab keeps your session running — reopen to resume right where you left off. To shut the box down, use <strong>Close box</strong> below or type <code>close-box</code> in the terminal.</p>');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// #602: the builder's own running container-cost total. Tracked, not
|
|
217
|
+
// charged in the early stage (mirrors "shipped work isn't paid in real money
|
|
218
|
+
// yet") — say so plainly so the number doesn't read as a bill.
|
|
219
|
+
if (cost && Number(cost.total_usd) > 0) {
|
|
220
|
+
const f = (n) => `$${(Number(n) || 0).toFixed(2)}`;
|
|
221
|
+
parts.push('<hr class="setup__divider">');
|
|
222
|
+
parts.push(`<p class="setup__box-cost"><strong>What your box would cost:</strong> ${f(cost.total_usd)} so far `
|
|
223
|
+
+ `<span class="setup__box-cost-detail">(spin-up ${f(cost.spinup_usd)} · compute ${f(cost.compute_usd)} · storage ${f(cost.storage_usd)})</span><br>`
|
|
224
|
+
+ '<span class="setup__box-close-hint">Tracked for transparency — not charged in the early stage.</span></p>');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
parts.push(`<div class="setup__box-close">${closeSectionHtml()}</div>`);
|
|
228
|
+
|
|
229
|
+
return parts.join('\n');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Paint from live server state. Idempotent + safe to call repeatedly. Never
|
|
233
|
+
// throws into the caller. Stops polling once the element is gone.
|
|
234
|
+
async function refresh() {
|
|
235
|
+
if (!root || !document.body.contains(root)) { stopPoll(); return; }
|
|
236
|
+
|
|
237
|
+
let me;
|
|
238
|
+
try { me = await getJSON(`${API}/box/me`); }
|
|
239
|
+
catch (err) { if (err && err.message === AUTH_REDIRECT) return; stopPoll(); return; }
|
|
240
|
+
const box = (me && me.box) || {};
|
|
241
|
+
const intent = me && me.open_intent;
|
|
242
|
+
const state = box.state || 'none';
|
|
243
|
+
|
|
244
|
+
// A close is in flight: the box stays 'active' for up to a minute while
|
|
245
|
+
// the control-plane runner deprovisions it, so this MUST be checked
|
|
246
|
+
// BEFORE the active branch — otherwise every poll repaints the full active
|
|
247
|
+
// panel and wipes the "Closing…" feedback. Close the terminal tab now.
|
|
248
|
+
if (intent && intent.action === 'deprovision') {
|
|
249
|
+
closeTermWindow();
|
|
250
|
+
setRequestBtn(false);
|
|
251
|
+
enableOpenBtn(null);
|
|
252
|
+
setOut('<p class="setup__box-msg">Closing your box… (a few seconds)</p>');
|
|
253
|
+
schedulePoll(4000);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (state === 'active') {
|
|
258
|
+
let term = null;
|
|
259
|
+
try { term = await getJSON(`${API}/box/terminal`); }
|
|
260
|
+
catch (err) { if (err && err.message === AUTH_REDIRECT) return; }
|
|
261
|
+
|
|
262
|
+
setRequestBtn(false);
|
|
263
|
+
enableOpenBtn(terminalAuthUrl(term));
|
|
264
|
+
|
|
265
|
+
if (term && term.url) {
|
|
266
|
+
setOut(renderBoxActive(box, term, me && me.cost));
|
|
267
|
+
stopPoll();
|
|
268
|
+
} else if (term && term.warming_up) {
|
|
269
|
+
setOut('<p class="setup__box-msg">Your box is up — waiting for the terminal to come online (a few seconds after boot)…</p>');
|
|
270
|
+
schedulePoll(5000);
|
|
271
|
+
} else {
|
|
272
|
+
// SSH path (or tunnel not yet published). With SSH shown, surface the
|
|
273
|
+
// details now; either way keep polling so the terminal URL appears
|
|
274
|
+
// when it publishes.
|
|
275
|
+
setOut(renderBoxActive(box, null, me && me.cost));
|
|
276
|
+
if (!box.ip) schedulePoll(5000);
|
|
277
|
+
else if (!showSsh) schedulePoll(5000); // online-only: still awaiting terminal
|
|
278
|
+
else stopPoll();
|
|
279
|
+
}
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (intent || state === 'provisioning' || state === 'waking') {
|
|
283
|
+
setRequestBtn(false);
|
|
284
|
+
enableOpenBtn(null);
|
|
285
|
+
setOut('<p class="setup__box-msg">Setting up your box… (about a minute)</p>');
|
|
286
|
+
schedulePoll(5000);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
// No open intent and not active/provisioning/waking. Two cases:
|
|
290
|
+
// • destroyed → the builder HAD a box that is now gone — they closed it, or
|
|
291
|
+
// it was auto-stopped after ~10 min idle, which tears down the tunnel + its
|
|
292
|
+
// DNS. Opening the old terminal/sandbox URL then fails with a raw browser
|
|
293
|
+
// "can't find the server" error and no explanation (idea #295). Don't leave
|
|
294
|
+
// them staring at a bare button: say what happened + offer to turn it back on.
|
|
295
|
+
// • none → never had a box (first run). Keep the clean first-run button.
|
|
296
|
+
closeTermWindow();
|
|
297
|
+
stopPoll();
|
|
298
|
+
enableOpenBtn(null);
|
|
299
|
+
if (state === 'destroyed') {
|
|
300
|
+
setRequestBtn(true, 'Turn box back on');
|
|
301
|
+
setOut('<p class="setup__box-msg">Your dev box is stopped — turn it back on below.</p>'
|
|
302
|
+
+ '<p class="setup__box-close-hint">Boxes auto-stop after about 10 minutes idle to save cost '
|
|
303
|
+
+ '(or when you close one). A stopped box has no terminal or live-preview URL, so an old '
|
|
304
|
+
+ 'link will fail to load. Turning it back on takes about a minute. '
|
|
305
|
+
+ '<strong>Anything not committed or shipped on the old box is gone</strong> — commit early next time.</p>'
|
|
306
|
+
+ '<p class="setup__box-close-hint">The box you turn on has a <strong>new identity</strong>. If Claude '
|
|
307
|
+
+ 'Desktop says <strong>“Host denied”</strong> or asks for a password when reconnecting, fully quit '
|
|
308
|
+
+ 'and reopen Desktop (it re-pins your box automatically) or press <strong>Repair</strong> — do not keep turning '
|
|
309
|
+
+ 'the box off and on, which only changes the identity again.</p>');
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
setRequestBtn(true, 'Request dev box');
|
|
313
|
+
hideOut();
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Request the box (provision), then let refresh paint from server state.
|
|
317
|
+
async function requestBox() {
|
|
318
|
+
const btn = q('[data-box-request]');
|
|
319
|
+
if (btn) { btn.disabled = true; btn.textContent = 'Setting up…'; }
|
|
320
|
+
try {
|
|
321
|
+
await postJSON(`${API}/box/ensure`);
|
|
322
|
+
} catch (err) {
|
|
323
|
+
if (err && err.message === AUTH_REDIRECT) return;
|
|
324
|
+
if (btn) { btn.disabled = false; btn.textContent = 'Request dev box'; }
|
|
325
|
+
setOut(`<p class="setup__box-msg setup__box-msg--err">${escapeHtml(err.message || 'Could not set up your box just now.')} You can also ask in Discord #support.</p>`);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
refresh();
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Enqueue a deprovision intent, then poll until the box is destroyed. Paints
|
|
332
|
+
// "Closing…" and closes the terminal tab IMMEDIATELY so the action feels
|
|
333
|
+
// instant — the box stays active for up to a minute while it tears down.
|
|
334
|
+
async function closeBox() {
|
|
335
|
+
stopPoll();
|
|
336
|
+
closeTermWindow();
|
|
337
|
+
setOut('<p class="setup__box-msg">Closing your box… (a few seconds)</p>');
|
|
338
|
+
enableOpenBtn(null);
|
|
339
|
+
setRequestBtn(false);
|
|
340
|
+
try {
|
|
341
|
+
await postJSON(`${API}/box/close`);
|
|
342
|
+
} catch (err) {
|
|
343
|
+
if (err && err.message === AUTH_REDIRECT) return;
|
|
344
|
+
setOut(`<p class="setup__box-msg setup__box-msg--err">${escapeHtml(err.message || 'Could not close your box just now.')} You can also ask in Discord #support.</p>`);
|
|
345
|
+
schedulePoll(1000);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
refresh();
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function onClick(e) {
|
|
352
|
+
if (e.target.closest('[data-box-request]')) { requestBox(); return; }
|
|
353
|
+
// Close box is a two-step confirm: first click arms (shows the reconnect
|
|
354
|
+
// warning), then Close box / Keep box. Check the armed buttons before the
|
|
355
|
+
// bare [data-box-close] so the arming click can't also fire a close.
|
|
356
|
+
if (e.target.closest('[data-box-close-confirm]')) { closeBox(); return; }
|
|
357
|
+
if (e.target.closest('[data-box-close-cancel]')) { disarmCloseConfirm(e.target.closest('[data-box-close-cancel]')); return; }
|
|
358
|
+
if (e.target.closest('[data-box-close]')) { armCloseConfirm(e.target.closest('[data-box-close]')); return; }
|
|
359
|
+
// Open the in-browser terminal via window.open (NOT a plain target=_blank
|
|
360
|
+
// nav) so we hold a handle and can close the tab when the box is torn
|
|
361
|
+
// down. The named target reuses the same tab on re-click.
|
|
362
|
+
const openBtnEl = e.target.closest('[data-box-open]');
|
|
363
|
+
if (openBtnEl) {
|
|
364
|
+
const url = openBtnEl.getAttribute('href');
|
|
365
|
+
if (url && openBtnEl.getAttribute('aria-disabled') !== 'true') {
|
|
366
|
+
e.preventDefault();
|
|
367
|
+
termWindow = window.open(url, 'otb-box-terminal');
|
|
368
|
+
if (termWindow) { try { termWindow.opener = null; } catch (_) {} }
|
|
369
|
+
}
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const copyEl = e.target.closest('.setup__copy[data-copy]');
|
|
373
|
+
if (copyEl) {
|
|
374
|
+
const text = copyEl.getAttribute('data-copy') || '';
|
|
375
|
+
const done = () => {
|
|
376
|
+
copyEl.classList.add('setup__copy--copied');
|
|
377
|
+
setTimeout(() => { copyEl.classList.remove('setup__copy--copied'); }, 1200);
|
|
378
|
+
};
|
|
379
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
380
|
+
navigator.clipboard.writeText(text).then(done).catch(() => toast('Could not copy — select and copy by hand.'));
|
|
381
|
+
} else {
|
|
382
|
+
toast('Copy not supported here — select the value and copy by hand.');
|
|
383
|
+
}
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const MARKUP = `
|
|
389
|
+
<div class="setup__box-btns">
|
|
390
|
+
<button type="button" class="setup__btn setup__btn--box" data-box-request>Request dev box</button>
|
|
391
|
+
<a class="setup__btn setup__btn--open" data-box-open aria-disabled="true">Open online environment</a>
|
|
392
|
+
</div>
|
|
393
|
+
<div class="setup__box-out" data-box-out hidden></div>`;
|
|
394
|
+
|
|
395
|
+
function mount(el) {
|
|
396
|
+
stopPoll();
|
|
397
|
+
root = el || null;
|
|
398
|
+
if (!root) return;
|
|
399
|
+
root.innerHTML = MARKUP;
|
|
400
|
+
// The element is freshly re-created by the host on each render, so a new
|
|
401
|
+
// listener per mount does not stack on a live node. Guard anyway.
|
|
402
|
+
if (!root._otbBoxBound) {
|
|
403
|
+
root.addEventListener('click', onClick);
|
|
404
|
+
// Keyboard activation for the click-to-copy values (role="button").
|
|
405
|
+
root.addEventListener('keydown', (e) => {
|
|
406
|
+
if ((e.key === 'Enter' || e.key === ' ') && e.target.closest('.setup__copy[data-copy]')) {
|
|
407
|
+
e.preventDefault();
|
|
408
|
+
onClick(e);
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
root._otbBoxBound = true;
|
|
412
|
+
}
|
|
413
|
+
bound = true;
|
|
414
|
+
refresh();
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function stop() { stopPoll(); }
|
|
418
|
+
|
|
419
|
+
return { mount, refresh, stop };
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
window.OTBBoxPanel = { create };
|
|
423
|
+
})();
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// brand-apply.js — apply the instance branding pack to the hall's static markup
|
|
2
|
+
// (R56 task 1195, ADR 0062 §3). The pack is injected synchronously as
|
|
3
|
+
// window.__BRANDING__ by the server (src/bongos/serve-internal.js); this fills the
|
|
4
|
+
// markup that can't read it inline.
|
|
5
|
+
//
|
|
6
|
+
// R56 handles the configurable CURRENCY LABEL: any element carrying
|
|
7
|
+
// `data-currency-label` has its text replaced with branding.currency.label.
|
|
8
|
+
// <span data-currency-label>drachmae</span> → the label, lowercase
|
|
9
|
+
// <span data-currency-label="caps">Drachmae</span> → the label, Capitalized
|
|
10
|
+
// For a label embedded in a phrase (e.g. an <option>), use a template carrying
|
|
11
|
+
// {label} (lowercase) / {Label} (Capitalized) placeholders:
|
|
12
|
+
// <option data-currency-tmpl="highest {label}">highest drachmae</option>
|
|
13
|
+
// The element's existing text is the no-JS / pre-load fallback. For OTB the
|
|
14
|
+
// configured label IS "drachmae", so nothing visibly changes; a differently
|
|
15
|
+
// branded instance sees its own unit. R57 (task 1196) extends window.__BRANDING__
|
|
16
|
+
// to the full pack and this file grows to apply identity/theme/copy too.
|
|
17
|
+
(function () {
|
|
18
|
+
'use strict';
|
|
19
|
+
var brand = (typeof window !== 'undefined' && window.__BRANDING__) || null;
|
|
20
|
+
|
|
21
|
+
function capitalize(s) {
|
|
22
|
+
return s ? s.charAt(0).toUpperCase() + s.slice(1) : s;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function applyCurrencyLabels(root) {
|
|
26
|
+
if (!brand || !brand.currency || !brand.currency.label) return;
|
|
27
|
+
var label = brand.currency.label;
|
|
28
|
+
var Label = capitalize(label);
|
|
29
|
+
var scope = root || document;
|
|
30
|
+
var nodes = scope.querySelectorAll('[data-currency-label]');
|
|
31
|
+
for (var i = 0; i < nodes.length; i++) {
|
|
32
|
+
nodes[i].textContent = nodes[i].getAttribute('data-currency-label') === 'caps' ? Label : label;
|
|
33
|
+
}
|
|
34
|
+
var tmpls = scope.querySelectorAll('[data-currency-tmpl]');
|
|
35
|
+
for (var j = 0; j < tmpls.length; j++) {
|
|
36
|
+
tmpls[j].textContent = tmpls[j].getAttribute('data-currency-tmpl')
|
|
37
|
+
.replace(/\{label\}/g, label).replace(/\{Label\}/g, Label);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// BV1.R75 (ADR 0062 §4): drive the hall index page's chrome — <title>, <h1>, and
|
|
42
|
+
// meta description — from the branding pack so the reskin reaches the browser tab,
|
|
43
|
+
// not just the page body. copy.hallName is the hall's name ("Builders' Hall");
|
|
44
|
+
// identity.productName / worldName is the instance ("Off the Boats" / "Amazonprimea").
|
|
45
|
+
// The static markup is the no-JS / pre-load fallback. SCOPED to the hall index via
|
|
46
|
+
// the #hall-h1 marker: the other hall pages (sessions/watch/work) carry their own
|
|
47
|
+
// page-specific titles + headings and must keep them — gating on #hall-h1 leaves
|
|
48
|
+
// them untouched. Re-skinning those pages' chrome is its own (future) carve.
|
|
49
|
+
function applyPageChrome() {
|
|
50
|
+
if (!brand) return;
|
|
51
|
+
var h1 = document.getElementById('hall-h1');
|
|
52
|
+
if (!h1) return; // not the hall index — leave this page's chrome alone
|
|
53
|
+
var hallName = (brand.copy && brand.copy.hallName) || '';
|
|
54
|
+
var product = (brand.identity && (brand.identity.productName || brand.identity.worldName)) || '';
|
|
55
|
+
if (hallName) {
|
|
56
|
+
// Tab title: "<Hall> — <Product>" when both are known, else whichever exists.
|
|
57
|
+
document.title = product ? hallName + ' — ' + product : hallName;
|
|
58
|
+
h1.textContent = hallName;
|
|
59
|
+
}
|
|
60
|
+
if (product) {
|
|
61
|
+
var desc = document.querySelector('meta[name="description"]');
|
|
62
|
+
if (desc) {
|
|
63
|
+
desc.setAttribute('content',
|
|
64
|
+
'The builder hub for ' + product + '. Standing, achievements, and work waiting to be claimed.');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Expose a tiny accessor so JS-rendered strings can read the label without
|
|
70
|
+
// re-reading window.__BRANDING__ everywhere (and so a future test can stub it).
|
|
71
|
+
function currencyLabel(opts) {
|
|
72
|
+
var label = (brand && brand.currency && brand.currency.label) || 'credits';
|
|
73
|
+
return opts && opts.caps ? capitalize(label) : label;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// task 1957 — a task's drachmae is an ESTIMATE (credits_reward, assigned at
|
|
77
|
+
// creation) until the task SETTLES. Credits only land at 'confirmed' and
|
|
78
|
+
// persist through 'shipped'; from that point the real payout is credits_awarded
|
|
79
|
+
// (the ledger sum the task API surfaces). These helpers centralize the
|
|
80
|
+
// "estimate vs actual" decision so every task surface renders it identically:
|
|
81
|
+
// unsettled → the estimate with a "<Currency> Est." label; settled → the actual
|
|
82
|
+
// ledger payout with a plain "<Currency>" label.
|
|
83
|
+
function taskSettled(task) {
|
|
84
|
+
var s = task && task.status;
|
|
85
|
+
return s === 'confirmed' || s === 'shipped';
|
|
86
|
+
}
|
|
87
|
+
function taskCreditValue(task) {
|
|
88
|
+
if (!task) return null;
|
|
89
|
+
if (taskSettled(task)) {
|
|
90
|
+
var awarded = Number(task.credits_awarded);
|
|
91
|
+
// Settled with a real ledger payout → show it. If a settled task has no
|
|
92
|
+
// ledger record (0 — legacy pre-ledger tasks, or reward-exempt), fall back
|
|
93
|
+
// to the estimate rather than showing a misleading "0".
|
|
94
|
+
if (isFinite(awarded) && awarded > 0) return awarded;
|
|
95
|
+
}
|
|
96
|
+
return task.credits_reward;
|
|
97
|
+
}
|
|
98
|
+
function taskCreditLabel(task, opts) {
|
|
99
|
+
var base = currencyLabel(opts);
|
|
100
|
+
return taskSettled(task) ? base : base + ' Est.';
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
window.OTBBranding = {
|
|
104
|
+
currencyLabel: currencyLabel,
|
|
105
|
+
taskSettled: taskSettled,
|
|
106
|
+
taskCreditValue: taskCreditValue,
|
|
107
|
+
taskCreditLabel: taskCreditLabel,
|
|
108
|
+
applyCurrencyLabels: applyCurrencyLabels,
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
if (document.readyState === 'loading') {
|
|
112
|
+
document.addEventListener('DOMContentLoaded', function () { applyCurrencyLabels(document); applyPageChrome(); });
|
|
113
|
+
} else {
|
|
114
|
+
applyCurrencyLabels(document);
|
|
115
|
+
applyPageChrome();
|
|
116
|
+
}
|
|
117
|
+
})();
|