@bongos/core 1.18.3 → 1.18.18
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 +1575 -285
- package/.claude/skills/builder-box/SKILL.md +6 -0
- package/.claude/skills/builder-sequence/SKILL.md +97 -0
- package/.claude/skills/builder-ship/SKILL.md +8 -2
- package/.claude/skills/builder-start/SKILL.md +11 -0
- package/.claude/skills/builder-sync/SKILL.md +41 -0
- package/.claude/skills/fix-task/SKILL.md +64 -0
- package/.claude/skills/goal-create/SKILL.md +158 -0
- package/.claude/skills/goal-review/SKILL.md +3 -1
- package/.claude/skills/idea-triage/SKILL.md +14 -8
- package/.claude/skills/merge-mode/SKILL.md +2 -2
- package/.claude/skills/new-project/SKILL.md +1 -0
- package/.claude/skills/planning-session/SKILL.md +45 -18
- package/.env.local.example +4 -3
- package/README.md +4 -2
- package/bin/bongos.js +1 -0
- package/clients/bongos-client/README.md +2 -2
- package/clients/bongos-client/bongos-client.global.js +82 -18
- package/clients/bongos-client/index.cjs +82 -18
- package/clients/bongos-client/index.d.ts +131 -29
- package/clients/bongos-client/index.mjs +82 -18
- package/config/branding.neutral.json +6 -1
- package/config/governance.neutral.json +21 -0
- package/docs/adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md +24 -0
- package/docs/adr/0090-metic-task-authoring.md +1 -1
- package/docs/adr/0144-devbox-rehome-onto-cloudbongos-plane.md +41 -0
- package/docs/adr/0144-federated-single-logout-backchannel.md +42 -0
- package/docs/adr/0145-devbox-app-branding-driven-module.md +44 -0
- package/docs/adr/0145-free-hosted-project-tier-isolation-and-domain-separation.md +62 -0
- package/docs/adr/0146-configurable-reward-mode-cost-plus-only.md +53 -0
- package/docs/adr/0147-standalone-live-docs-regen.md +39 -0
- package/docs/adr/0148-task-scoped-box-source-access.md +48 -0
- package/docs/adr/0149-bongos-dev-local-launcher.md +57 -0
- package/docs/adr/0150-box-first-boot-bringup-vendored-instances.md +68 -0
- package/docs/adr/0151-governance-permissions-as-atom-ranks-as-roles.md +229 -0
- package/docs/adr/0152-landing-gate-served-by-the-core-app.md +92 -0
- package/docs/adr/0152-metic-task-abandonment.md +67 -0
- package/docs/adr/0153-sequential-chain-runner.md +51 -0
- package/docs/adr/0154-goal-owner-criterion-authoring.md +86 -0
- package/docs/adr/README.md +10 -0
- package/docs/api/openapi.json +843 -17
- package/docs/api-reference.md +23 -10
- package/docs/architecture.md +4 -2
- package/docs/branding-contract.md +3 -1
- package/docs/canonical-permissions.md +21 -8
- package/docs/file-map.md +8 -0
- package/docs/onboarding/diagrams/01-task-lifecycle.mmd +2 -2
- package/docs/onboarding/diagrams/02-rank-ladder.mmd +3 -1
- package/docs/onboarding/diagrams/05-versioning.mmd +1 -3
- package/docs/onboarding/diagrams/assertions.json +4 -7
- package/docs/onboarding/drachmae-and-karma.md +3 -3
- package/docs/onboarding/primer.md +17 -16
- package/docs/onboarding/slash-commands.md +124 -0
- package/docs/recipes/builder-box-lifecycle.md +23 -0
- package/docs/recipes/devbox-app-release.md +14 -4
- package/docs/recipes/instance-first-run.md +16 -0
- package/docs/recipes/local-dev.md +81 -0
- package/docs/recipes/ops-gotchas.md +19 -1
- package/docs/recipes/overnight-builder.md +1 -1
- package/docs/recipes/parallel-goal-waves.md +174 -0
- package/docs/recipes/ship-and-regrade.md +2 -2
- package/docs/recipes/standalone-live-docs.md +48 -0
- package/docs/recipes/work-on-a-task-from-your-dev-box.md +108 -0
- package/migrations/003_pms.sql +6 -7
- package/migrations/006_pms_v2.sql +3 -31
- package/migrations/core_193_task_needs_rebase.sql +28 -0
- package/migrations/core_194_confirmed_backlog_clawback.sql +63 -0
- package/migrations/core_195_idea_triage_provenance.sql +57 -0
- package/migrations/core_196_session_reward_topup.sql +69 -0
- package/modules/autonomy/pollers/routine-timers.js +9 -8
- package/modules/builder-settings/wandering-prefs.js +61 -18
- package/modules/dev-box/app/README.md +73 -0
- package/modules/dev-box/app/assets/tray/mac-alertTemplate.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-alertTemplate@2x.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-busyTemplate.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-busyTemplate@2x.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-offTemplate.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-offTemplate@2x.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-onTemplate.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-onTemplate@2x.png +0 -0
- package/modules/dev-box/app/assets/tray/win-alert.png +0 -0
- package/modules/dev-box/app/assets/tray/win-busy.png +0 -0
- package/modules/dev-box/app/assets/tray/win-off.png +0 -0
- package/modules/dev-box/app/assets/tray/win-on.png +0 -0
- package/modules/dev-box/app/build-resources/dmg-background.png +0 -0
- package/modules/dev-box/app/build-resources/dmg-background@2x.png +0 -0
- package/modules/dev-box/app/build-resources/icon.png +0 -0
- package/modules/dev-box/app/electron-builder.tmpl.yml +95 -0
- package/modules/dev-box/app/electron-builder.yml +95 -0
- package/modules/dev-box/app/package-lock.json +5291 -0
- package/modules/dev-box/app/package.json +30 -0
- package/modules/dev-box/app/renderer/app.js +319 -0
- package/modules/dev-box/app/renderer/index.html +45 -0
- package/modules/dev-box/app/renderer/styles.css +246 -0
- package/modules/dev-box/app/renderer/theme.generated.css +16 -0
- package/modules/dev-box/app/scripts/apply-dmg-backdrop.sh +82 -0
- package/modules/dev-box/app/scripts/dmgbuild-settings.py +39 -0
- package/modules/dev-box/app/scripts/gen-brand.js +138 -0
- package/modules/dev-box/app/scripts/gen-dmg-backdrop.py +323 -0
- package/modules/dev-box/app/scripts/gen-icons.js +286 -0
- package/modules/dev-box/app/scripts/vendor-client.js +23 -0
- package/modules/dev-box/app/src/box-controller.js +287 -0
- package/modules/dev-box/app/src/brand.generated.json +13 -0
- package/modules/dev-box/app/src/brand.js +16 -0
- package/modules/dev-box/app/src/config.js +19 -0
- package/modules/dev-box/app/src/gds-client.js +90 -0
- package/modules/dev-box/app/src/main.js +610 -0
- package/modules/dev-box/app/src/pairing.js +57 -0
- package/modules/dev-box/app/src/preload.js +29 -0
- package/modules/dev-box/app/src/session-store.js +58 -0
- package/modules/dev-box/app/src/ssh-setup.js +569 -0
- package/modules/dev-box/app/src/task-picker.js +70 -0
- package/modules/dev-box/app/src/tray.js +99 -0
- package/modules/dev-box/app/src/updater.js +55 -0
- package/modules/dev-box/app/src/vendor/bongos-client.cjs +698 -0
- package/modules/dev-box/app/test/unit.mjs +526 -0
- package/modules/dev-box/box-access.js +121 -4
- package/modules/dev-box/boxes.js +20 -0
- package/modules/dev-box/module.json +1 -1
- package/modules/dev-box/routes/box.js +87 -3
- package/modules/economy/credits.js +116 -25
- package/modules/economy/reward.js +8 -0
- package/modules/economy/streak.js +2 -1
- package/modules/governance/CLAUDE.md +15 -0
- package/modules/governance/catalog.js +419 -0
- package/modules/governance/config.js +174 -0
- package/modules/governance/db.js +125 -0
- package/modules/governance/migrations/governance_001_tables.sql +81 -0
- package/modules/governance/migrations/governance_002_seed_and_backfill.sql +103 -0
- package/modules/governance/migrations/governance_003_task_abandon_metic.sql +28 -0
- package/modules/governance/migrations/governance_004_criterion_create.sql +39 -0
- package/modules/governance/migrations/governance_005_resync_builder_rank_roles.sql +56 -0
- package/modules/governance/module.json +10 -0
- package/modules/governance/protected-surfaces.js +88 -0
- package/modules/governance/protected-surfaces.json +80 -0
- package/modules/governance/rank-roles.js +83 -0
- package/modules/governance/resolver.js +221 -0
- package/modules/governance/routes/governance.js +89 -0
- package/modules/governance/routes/role-sync.js +49 -0
- package/modules/governance/session-scopes.js +127 -0
- package/modules/governance/session-scopes.json +38 -0
- package/modules/hall-ui/public/atlas.css +117 -0
- package/modules/hall-ui/public/atlas.html +3 -114
- package/modules/hall-ui/public/brand-apply.js +34 -6
- package/modules/hall-ui/public/builders.js +187 -219
- package/modules/hall-ui/public/diagrams.html +2 -0
- package/modules/hall-ui/public/dom-utils.js +27 -0
- package/modules/hall-ui/public/drachmae.html +2 -0
- package/modules/hall-ui/public/drachmae.js +54 -1
- package/modules/hall-ui/public/gate.css +98 -0
- package/modules/hall-ui/public/gate.html +3 -95
- package/modules/hall-ui/public/goal-inbox.js +4 -1
- package/modules/hall-ui/public/goals-page.js +626 -114
- package/modules/hall-ui/public/goals.css +79 -1
- package/modules/hall-ui/public/goals.html +38 -11
- package/modules/hall-ui/public/hall-widgets.js +62 -52
- package/modules/hall-ui/public/harbor.css +123 -0
- package/modules/hall-ui/public/harbor.html +3 -120
- package/modules/hall-ui/public/index.html +11 -4
- package/modules/hall-ui/public/instances-panel.js +4 -1
- package/modules/hall-ui/public/modules.css +63 -0
- package/modules/hall-ui/public/modules.html +3 -60
- package/modules/hall-ui/public/new-project-wizard.js +7 -3
- package/modules/hall-ui/public/not-ready.html +2 -0
- package/modules/hall-ui/public/pair.css +73 -0
- package/modules/hall-ui/public/pair.html +3 -70
- package/modules/hall-ui/public/palette.js +302 -0
- package/modules/hall-ui/public/primer.css +13 -0
- package/modules/hall-ui/public/primer.html +2 -0
- package/modules/hall-ui/public/profile.html +2 -0
- package/modules/hall-ui/public/ranks.html +2 -0
- package/modules/hall-ui/public/roadmap.css +179 -0
- package/modules/hall-ui/public/roadmap.html +9 -172
- package/modules/hall-ui/public/roadmap.js +329 -316
- package/modules/hall-ui/public/sessions.css +16 -0
- package/modules/hall-ui/public/sessions.html +3 -13
- package/modules/hall-ui/public/settings.html +2 -0
- package/modules/hall-ui/public/settings.js +4 -4
- package/modules/hall-ui/public/shell.js +143 -18
- package/modules/hall-ui/public/style.css +231 -39
- package/modules/hall-ui/public/task-detail.js +347 -26
- package/modules/hall-ui/public/task.html +6 -1
- package/modules/hall-ui/public/watch.html +2 -0
- package/modules/hall-ui/public/work.html +8 -6
- package/modules/hall-ui/public/work.js +1 -1
- package/modules/ideas/inbox.js +61 -11
- package/modules/ideas/routes/inbox.js +23 -0
- package/modules/lifecycle/claim-eligibility.js +72 -0
- package/modules/lifecycle/db.js +519 -139
- package/modules/lifecycle/done-when.js +18 -3
- package/modules/lifecycle/github-push.js +19 -2
- package/modules/lifecycle/goal-advisory.js +114 -0
- package/modules/lifecycle/goal-authz.js +62 -0
- package/modules/lifecycle/lifecycle.js +9 -0
- package/modules/lifecycle/publish-reconciler.js +109 -6
- package/modules/lifecycle/routes/claims.js +68 -23
- package/modules/lifecycle/routes/done-when.js +110 -15
- package/modules/lifecycle/routes/goals.js +8 -38
- package/modules/lifecycle/routes/tasks.js +38 -6
- package/modules/lifecycle/ship-card.js +6 -0
- package/modules/onboarding/onboarding-state.js +1 -1
- package/modules/platform-identity/CLAUDE.md +15 -0
- package/modules/platform-identity/hub-device.js +147 -0
- package/modules/platform-identity/hub-keys.js +151 -0
- package/modules/platform-identity/migrations/platform_identity_001_tables.sql +114 -0
- package/modules/platform-identity/migrations/platform_identity_002_client_origin_index.sql +18 -0
- package/modules/platform-identity/migrations/platform_identity_003_project_memberships.sql +42 -0
- package/modules/platform-identity/migrations/platform_identity_004_projects.sql +44 -0
- package/modules/platform-identity/migrations/platform_identity_005_builder_activity.sql +42 -0
- package/modules/platform-identity/module.json +18 -0
- package/modules/platform-identity/platform-identity.js +531 -0
- package/modules/platform-identity/pollers/code-sweep.js +43 -0
- package/modules/platform-identity/routes/my-projects.js +140 -0
- package/modules/platform-identity/routes/projects.js +107 -0
- package/modules/platform-identity/routes/scouting.js +35 -0
- package/modules/platform-identity/routes/sso.js +402 -0
- package/modules/platform-identity/tests/platform-identity.mjs +388 -0
- package/modules/platform-identity/ui/.gitkeep +0 -0
- package/modules/security/routes/reports.js +10 -0
- package/modules/sessions/db.js +166 -21
- package/modules/sessions/module.json +1 -1
- package/modules/sessions/pollers/session-reward-reconcile.js +78 -0
- package/modules/sessions/routes/sessions.js +33 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/public-landing/assets/anim/idle/frame_00.webp +0 -0
- package/public-landing/assets/anim/idle/frame_01.webp +0 -0
- package/public-landing/assets/anim/idle/frame_02.webp +0 -0
- package/public-landing/assets/anim/idle/frame_03.webp +0 -0
- package/public-landing/assets/anim/idle/frame_04.webp +0 -0
- package/public-landing/assets/anim/idle/frame_05.webp +0 -0
- package/public-landing/assets/anim/idle/frame_06.webp +0 -0
- package/public-landing/assets/anim/idle/frame_07.webp +0 -0
- package/public-landing/assets/anim/idle/frame_08.webp +0 -0
- package/public-landing/assets/anim/idle/frame_09.webp +0 -0
- package/public-landing/assets/anim/idle/frame_10.webp +0 -0
- package/public-landing/assets/anim/idle/frame_11.webp +0 -0
- package/public-landing/assets/anim/idle/frame_12.webp +0 -0
- package/public-landing/assets/anim/idle/frame_13.webp +0 -0
- package/public-landing/assets/anim/idle/frame_14.webp +0 -0
- package/public-landing/assets/anim/idle/frame_15.webp +0 -0
- package/public-landing/assets/anim/idle/frame_16.webp +0 -0
- package/public-landing/assets/anim/idle/frame_17.webp +0 -0
- package/public-landing/assets/anim/idle/frame_18.webp +0 -0
- package/public-landing/assets/anim/idle/frame_19.webp +0 -0
- package/public-landing/assets/anim/idle/frame_20.webp +0 -0
- package/public-landing/assets/anim/idle/frame_21.webp +0 -0
- package/public-landing/assets/anim/idle/frame_22.webp +0 -0
- package/public-landing/assets/anim/idle/frame_23.webp +0 -0
- package/public-landing/assets/anim/idle/frame_24.webp +0 -0
- package/public-landing/assets/anim/idle/frame_25.webp +0 -0
- package/public-landing/assets/anim/idle/frame_26.webp +0 -0
- package/public-landing/assets/anim/idle/frame_27.webp +0 -0
- package/public-landing/assets/anim/idle/frame_28.webp +0 -0
- package/public-landing/assets/anim/idle/frame_29.webp +0 -0
- package/public-landing/assets/anim/idle/frame_30.webp +0 -0
- package/public-landing/assets/anim/idle/frame_31.webp +0 -0
- package/public-landing/assets/anim/idle/frame_32.webp +0 -0
- package/public-landing/assets/anim/idle/frame_33.webp +0 -0
- package/public-landing/assets/anim/idle/frame_34.webp +0 -0
- package/public-landing/assets/anim/idle/frame_35.webp +0 -0
- package/public-landing/assets/anim/idle/frame_36.webp +0 -0
- package/public-landing/assets/anim/idle/frame_37.webp +0 -0
- package/public-landing/assets/anim/idle/frame_38.webp +0 -0
- package/public-landing/assets/anim/idle/frame_39.webp +0 -0
- package/public-landing/assets/anim/idle/frame_40.webp +0 -0
- package/public-landing/assets/anim/idle/frame_41.webp +0 -0
- package/public-landing/assets/anim/idle/frame_42.webp +0 -0
- package/public-landing/assets/anim/idle/frame_43.webp +0 -0
- package/public-landing/create.html +51 -58
- package/public-landing/gate/README.md +137 -0
- package/public-landing/gate/dispmaps/bar.png +0 -0
- package/public-landing/gate/dispmaps/flat.png +0 -0
- package/public-landing/gate/dispmaps/key.png +0 -0
- package/public-landing/gate/index.html +587 -0
- package/public-landing/gate/previews/cloud-bongos.jpg +0 -0
- package/public-landing/gate/previews/off-the-boats.jpg +0 -0
- package/public-landing/gate/space.css +799 -0
- package/public-landing/gate/space.js +1826 -0
- package/public-landing/gate/sprites/enter.png +0 -0
- package/public-landing/gate/sprites/search.png +0 -0
- package/public-landing/gate/sprites/terminal-blank.png +0 -0
- package/public-landing/gate/sprites/tile.png +0 -0
- package/public-landing/world/assets/clouds/cloud-island-large.png +0 -0
- package/public-landing/world/assets/clouds/cloud-puff.png +0 -0
- package/public-landing/world/assets/creatures/creature-whale-cargo.png +0 -0
- package/public-landing/world/assets/creatures/creature-whale-glide.png +0 -0
- package/public-landing/world/assets/plates/plate-clouds-near.png +0 -0
- package/public-landing/world/assets/plates/scene-establishing.png +0 -0
- package/scripts/gds/abandon.js +6 -4
- package/scripts/gds/api.js +10 -5
- package/scripts/gds/api.ps1 +26 -0
- package/scripts/gds/api.sh +6 -0
- package/scripts/gds/audit-ships.js +7 -1
- package/scripts/gds/backfill-sessions.js +78 -18
- package/scripts/gds/backup.js +23 -1
- package/scripts/gds/box-connect-lib.js +124 -31
- package/scripts/gds/box-sync.js +66 -0
- package/scripts/gds/box.js +225 -53
- package/scripts/gds/cf-tunnel.js +145 -6
- package/scripts/gds/claim.js +34 -3
- package/scripts/gds/cli-lib.js +161 -27
- package/scripts/gds/code.js +6 -2
- package/scripts/gds/deploy-divergence.js +209 -0
- package/scripts/gds/dev-lib.js +309 -0
- package/scripts/gds/dev.js +322 -0
- package/scripts/gds/doctor.js +90 -61
- package/scripts/gds/fetch-art-key.js +1 -1
- package/scripts/gds/fetch-sound-prefs.js +2 -2
- package/scripts/gds/fitness.js +228 -12
- package/scripts/gds/gds-db-backup.service +16 -1
- package/scripts/gds/gds-db-offsite.service +9 -1
- package/scripts/gds/gen-api-client.js +1 -1
- package/scripts/gds/gen-api-docs.js +36 -14
- package/scripts/gds/gen-diagrams.js +45 -28
- package/scripts/gds/gen-file-map.js +2 -1
- package/scripts/gds/gen-freshness.js +32 -0
- package/scripts/gds/gen-repo-map.js +3 -2
- package/scripts/gds/gen-session-index.js +14 -5
- package/scripts/gds/hooks/pre-push.js +2 -2
- package/scripts/gds/init.js +60 -3
- package/scripts/gds/install-git-hooks.js +1 -1
- package/scripts/gds/key-card.js +15 -6
- package/scripts/gds/key-status.js +1 -1
- package/scripts/gds/linkify-refs.js +35 -9
- package/scripts/gds/login.js +16 -1
- package/scripts/gds/paste-token.js +7 -1
- package/scripts/gds/preflight.js +126 -0
- package/scripts/gds/provision.js +123 -12
- package/scripts/gds/publish-manifest.js +7 -1
- package/scripts/gds/reauth.js +7 -3
- package/scripts/gds/regen-instance-docs.js +47 -0
- package/scripts/gds/run-unit-tests.js +4 -2
- package/scripts/gds/seed-bongos-v1-seo-tasks.js +104 -0
- package/scripts/gds/seed-bv1-profiles-tasks.js +126 -0
- package/scripts/gds/sequence.js +425 -0
- package/scripts/gds/session-cost.js +10 -1
- package/scripts/gds/setup.js +31 -5
- package/scripts/gds/shell.js +5 -3
- package/scripts/gds/ship.js +319 -29
- package/scripts/gds/smoke-gds.js +139 -8
- package/scripts/gds/start.js +171 -22
- package/scripts/gds/status.js +1 -1
- package/scripts/gds/triage.js +10 -9
- package/scripts/gds/upgrade.js +124 -2
- package/scripts/status-mirror-sync.js +114 -84
- package/src/bongos/api-errors.js +1 -0
- package/src/bongos/auth.js +447 -102
- package/src/bongos/db-kernel.js +27 -0
- package/src/bongos/db.js +39 -0
- package/src/bongos/module-scope-map.js +27 -1
- package/src/bongos/permission-path-check.js +136 -102
- package/src/bongos/repo-info.js +47 -11
- package/src/bongos/route-rank-check.js +429 -46
- package/src/bongos/routes/_helpers.js +12 -1
- package/src/bongos/routes/auth.js +219 -2
- package/src/bongos/routes/backup.js +58 -2
- package/src/bongos/routes/me.js +35 -1
- package/src/bongos/serve-internal.js +84 -15
- package/src/branding.js +32 -0
- package/src/instance-config.js +30 -0
- package/src/module-api.js +112 -1
- package/src/platform-server.js +86 -9
- package/tests/abandon_task.mjs +59 -3
- package/tests/api_cli_flags.mjs +53 -0
- package/tests/auth_page_gate.mjs +13 -0
- package/tests/backfill_sessions.mjs +127 -1
- package/tests/backup_cli.mjs +54 -0
- package/tests/bongos_box_connect.mjs +77 -0
- package/tests/box_access.mjs +130 -1
- package/tests/box_credential.mjs +125 -0
- package/tests/box_host_keys.mjs +24 -0
- package/tests/box_infra_resolve.mjs +149 -0
- package/tests/box_scope_session.mjs +6 -2
- package/tests/box_sync.mjs +55 -0
- package/tests/box_task_scope.mjs +99 -0
- package/tests/branding.mjs +12 -0
- package/tests/cf_ruleset_preflight.mjs +142 -0
- package/tests/cf_tunnel.mjs +37 -0
- package/tests/claim_gate_rebase.mjs +98 -0
- package/tests/clawback_confirmed_backlog.mjs +103 -0
- package/tests/cli_lib_formatters.mjs +20 -0
- package/tests/confirm_attribution.mjs +30 -46
- package/tests/credit_grant.mjs +198 -10
- package/tests/criterion_authoring_gate.mjs +272 -0
- package/tests/criterion_progress.mjs +33 -1
- package/tests/dev_lib.mjs +253 -0
- package/tests/devbox_artifact_gate.mjs +75 -0
- package/tests/devbox_dmg_backdrop.mjs +137 -0
- package/tests/devbox_icons.mjs +304 -0
- package/tests/devbox_installer_brand.mjs +232 -0
- package/tests/devbox_key_register.mjs +234 -0
- package/tests/docs_openapi_route.mjs +110 -0
- package/tests/doctor_hooks.mjs +141 -0
- package/tests/extract_json.mjs +140 -0
- package/tests/fitness.mjs +89 -0
- package/tests/gen_freshness.mjs +96 -0
- package/tests/goal_advisory.mjs +251 -0
- package/tests/goal_criterion_confirm_ui.mjs +269 -0
- package/tests/goal_routes.mjs +59 -4
- package/tests/goal_tier.mjs +12 -3
- package/tests/governance_catalog.mjs +129 -0
- package/tests/governance_claim_eligibility.mjs +262 -0
- package/tests/governance_config.mjs +187 -0
- package/tests/governance_ownership_scope.mjs +410 -0
- package/tests/governance_page_gates.mjs +324 -0
- package/tests/governance_parity.mjs +336 -0
- package/tests/governance_principals.mjs +232 -0
- package/tests/governance_protected_surfaces.mjs +208 -0
- package/tests/governance_require_permission.mjs +223 -0
- package/tests/governance_resolver.mjs +84 -0
- package/tests/governance_role_sync.mjs +231 -0
- package/tests/governance_seed.mjs +127 -0
- package/tests/governance_session_scope.mjs +434 -0
- package/tests/governance_vanilla_boot.mjs +203 -0
- package/tests/grade_attribution.mjs +7 -7
- package/tests/hall_audit.mjs +223 -0
- package/tests/hall_nav.mjs +191 -0
- package/tests/hall_palette.mjs +206 -0
- package/tests/hall_signout.mjs +124 -0
- package/tests/hook_user_agents.mjs +10 -0
- package/tests/idea_triage.mjs +162 -0
- package/tests/idp_device_exchange.mjs +93 -0
- package/tests/init.mjs +51 -0
- package/tests/instance_config.mjs +65 -0
- package/tests/instance_mismatch_guard.mjs +23 -6
- package/tests/instance_release_config.mjs +104 -0
- package/tests/linkify_refs.mjs +15 -2
- package/tests/module_contributions.mjs +55 -0
- package/tests/module_loader.mjs +10 -5
- package/tests/module_scope_active_claims.mjs +94 -0
- package/tests/needs_rebase.mjs +92 -0
- package/tests/one_active_claim_per_session.mjs +76 -0
- package/tests/override_attribution.mjs +10 -8
- package/tests/override_request_ownership.mjs +8 -4
- package/tests/parse_cookie_decode.mjs +42 -0
- package/tests/pay_on_land.mjs +129 -0
- package/tests/platform_boot.mjs +100 -1
- package/tests/post_login_landing.mjs +42 -0
- package/tests/preflight_checks.mjs +72 -0
- package/tests/provision.mjs +132 -7
- package/tests/publish_branch_route.mjs +53 -0
- package/tests/publish_reconciler.mjs +187 -2
- package/tests/repo_info_binding.mjs +248 -0
- package/tests/reward_gate.mjs +11 -2
- package/tests/reward_mode_cost_plus_only.mjs +116 -0
- package/tests/reward_mode_surfacing.mjs +168 -0
- package/tests/route_permission_check.mjs +301 -0
- package/tests/route_rank_check.mjs +254 -12
- package/tests/route_validation.mjs +30 -0
- package/tests/sequence.mjs +267 -0
- package/tests/session_digest.mjs +44 -0
- package/tests/session_index.mjs +18 -6
- package/tests/session_records.mjs +39 -1
- package/tests/session_reward_on_land.mjs +381 -0
- package/tests/session_reward_reconcile.mjs +229 -0
- package/tests/ship_api_client_pathspec.mjs +100 -0
- package/tests/ship_base_flag.mjs +93 -0
- package/tests/ship_ci_deploy.mjs +80 -3
- package/tests/ship_upstream_deletion.mjs +57 -0
- package/tests/smoke_target.mjs +233 -0
- package/tests/start_env_guard.mjs +87 -0
- package/tests/start_rebase_warning.mjs +103 -0
- package/tests/status_mirror_sync.mjs +122 -0
- package/tests/stop_refcheck.mjs +19 -1
- package/tests/task_goal_link.mjs +15 -6
- package/tests/upgrade.mjs +139 -0
- package/tests/web_admission_status.mjs +162 -0
- package/tests/write_validation_gaps.mjs +110 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* sessions.css — Page-local styles for the Session log page.
|
|
2
|
+
Lifted verbatim out of the page's inline <style> block (task 1002176);
|
|
3
|
+
the ?v= cache-bust is stamped automatically from this file's content hash
|
|
4
|
+
at boot (src/asset-version.js). */
|
|
5
|
+
|
|
6
|
+
/* Page-local styles for the session log — small additions on top of the
|
|
7
|
+
shared .ledger / .stat-row components in style.css. */
|
|
8
|
+
.ledger-table-wrap { overflow-x: auto; margin-top: 6px; }
|
|
9
|
+
table.ledger th, table.ledger td { white-space: nowrap; }
|
|
10
|
+
.ledger td.warn { color: var(--danger); font-weight: 600; }
|
|
11
|
+
.ledger-sid {
|
|
12
|
+
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
|
13
|
+
font-size: 12.5px;
|
|
14
|
+
color: var(--info);
|
|
15
|
+
}
|
|
16
|
+
.ledger-rank { font-size: 12px; color: var(--ink-faint); }
|
|
@@ -10,19 +10,7 @@
|
|
|
10
10
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11
11
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
12
12
|
<link rel="stylesheet" href="/builders/style.css?v=2026-06-04-sessions">
|
|
13
|
-
<
|
|
14
|
-
/* Page-local styles for the session log — small additions on top of the
|
|
15
|
-
shared .ledger / .stat-row components in style.css. */
|
|
16
|
-
.ledger-table-wrap { overflow-x: auto; margin-top: 6px; }
|
|
17
|
-
table.ledger th, table.ledger td { white-space: nowrap; }
|
|
18
|
-
.ledger td.warn { color: var(--danger); font-weight: 600; }
|
|
19
|
-
.ledger-sid {
|
|
20
|
-
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
|
21
|
-
font-size: 12.5px;
|
|
22
|
-
color: var(--info);
|
|
23
|
-
}
|
|
24
|
-
.ledger-rank { font-size: 12px; color: var(--ink-faint); }
|
|
25
|
-
</style>
|
|
13
|
+
<link rel="stylesheet" href="/builders/sessions.css">
|
|
26
14
|
</head>
|
|
27
15
|
<body data-page="sessions" data-page-title="Sessions">
|
|
28
16
|
|
|
@@ -83,6 +71,8 @@
|
|
|
83
71
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
84
72
|
chrome exists before the page script runs. -->
|
|
85
73
|
<script src="/builders/shell.js?v=2026-07-02-shell1"></script>
|
|
74
|
+
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
75
|
+
<script src="/builders/palette.js" defer></script>
|
|
86
76
|
<!-- shared frontend toolkit (window.OTB) — loaded BEFORE sessions.js so it can pull from it. -->
|
|
87
77
|
<script src="/builders/dom-utils.js?v=2026-06-14-domutils"></script>
|
|
88
78
|
<script src="/builders/task-detail.js?v=2026-07-03-taskdetail"></script>
|
|
@@ -298,6 +298,8 @@
|
|
|
298
298
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
299
299
|
chrome exists before the page scripts run. -->
|
|
300
300
|
<script src="/builders/shell.js?v=2026-07-02-shell1"></script>
|
|
301
|
+
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
302
|
+
<script src="/builders/palette.js" defer></script>
|
|
301
303
|
<!-- shared frontend toolkit (window.OTB) — loaded before consuming IIFEs. -->
|
|
302
304
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
303
305
|
<!-- shared component kit (window.OTBKit) — section rail (task 2166). -->
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
? data.allowed_models
|
|
59
59
|
: ['opus', 'sonnet', 'haiku', 'script'];
|
|
60
60
|
if (rows.length === 0) {
|
|
61
|
-
body.innerHTML =
|
|
61
|
+
body.innerHTML = `<tr><td colspan="3">${window.OTBKit.emptyStateHtml('No skills registered.')}</td></tr>`;
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
64
|
body.innerHTML = rows.map((row) => {
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
if (!wrap) return;
|
|
140
140
|
const rows = Array.isArray(data?.effective) ? data.effective : [];
|
|
141
141
|
if (rows.length === 0) {
|
|
142
|
-
wrap.innerHTML = '
|
|
142
|
+
wrap.innerHTML = window.OTBKit.emptyStateHtml('No sounds registered.');
|
|
143
143
|
return;
|
|
144
144
|
}
|
|
145
145
|
wrap.innerHTML = rows.map((row) => {
|
|
@@ -284,7 +284,7 @@
|
|
|
284
284
|
if (!wrap) return;
|
|
285
285
|
const rows = Array.isArray(data?.effective) ? data.effective : [];
|
|
286
286
|
if (rows.length === 0) {
|
|
287
|
-
wrap.innerHTML = '
|
|
287
|
+
wrap.innerHTML = window.OTBKit.emptyStateHtml('No event sounds registered.');
|
|
288
288
|
return;
|
|
289
289
|
}
|
|
290
290
|
wrap.innerHTML = rows.map((row) => {
|
|
@@ -402,7 +402,7 @@
|
|
|
402
402
|
const eff = typeof data?.effective_level === 'number' ? data.effective_level : null;
|
|
403
403
|
const def = typeof data?.default_level === 'number' ? data.default_level : null;
|
|
404
404
|
if (levels.length === 0) {
|
|
405
|
-
wrap.innerHTML = '
|
|
405
|
+
wrap.innerHTML = window.OTBKit.emptyStateHtml('No levels registered.');
|
|
406
406
|
return;
|
|
407
407
|
}
|
|
408
408
|
wrap.innerHTML = levels.map((lv) => {
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
// (#app-sidebar / #app-topbar / #app-foot) every hall page carries;
|
|
14
14
|
// - rank-gate nav items COSMETICALLY (server-side page gates remain the real
|
|
15
15
|
// access control — serve-internal.js requireArchonPage etc.);
|
|
16
|
-
// - on the index (body[data-page="home"]) route the
|
|
17
|
-
// #standing, #achievements
|
|
18
|
-
// deep-link hashes belong to builders.js and are
|
|
16
|
+
// - on the index (body[data-page="home"]) route the three views (#home,
|
|
17
|
+
// #standing, #leaderboard) plus the #achievements alias into Standing. The
|
|
18
|
+
// `#/task|idea|blocker/N` deep-link hashes belong to builders.js and are
|
|
19
|
+
// deliberately ignored here;
|
|
19
20
|
// - expose window.OTBShell.applyAccess(...) so builders.js (index) or the
|
|
20
21
|
// shell's own /api/bongos/me probe (other pages) can settle gated nav state.
|
|
21
22
|
(function () {
|
|
@@ -29,7 +30,23 @@
|
|
|
29
30
|
var brand = window.__BRANDING__ || {};
|
|
30
31
|
var PAGE = (document.body && document.body.dataset.page) || '';
|
|
31
32
|
var IS_INDEX = PAGE === 'home';
|
|
32
|
-
var VIEWS = ['home', 'standing', '
|
|
33
|
+
var VIEWS = ['home', 'standing', 'leaderboard'];
|
|
34
|
+
// task 2174: #achievements retired as a view — the achievements grid folded
|
|
35
|
+
// into Standing's Achievements rail section; task 2175 then retired its nav
|
|
36
|
+
// entry. Old links (bookmarks, the stat tiles) keep working: the hash resolves
|
|
37
|
+
// to its host view and, after the view is shown, scrolls to the section anchor.
|
|
38
|
+
// task 2178: each Standing rail section is addressable too, so the jump palette
|
|
39
|
+
// (and any link) can land on one directly. Without an alias entry `#standing-work`
|
|
40
|
+
// is an unknown hash and route() deliberately leaves the current view alone —
|
|
41
|
+
// the section would never be reachable from another page. Keys mirror
|
|
42
|
+
// builders.js STANDING_GROUPS; tests/hall_palette.mjs holds them in step.
|
|
43
|
+
var VIEW_ALIASES = {
|
|
44
|
+
achievements: { view: 'standing', anchor: 'standing-achievements' },
|
|
45
|
+
'standing-work': { view: 'standing', anchor: 'standing-work' },
|
|
46
|
+
'standing-karma': { view: 'standing', anchor: 'standing-karma' },
|
|
47
|
+
'standing-progress': { view: 'standing', anchor: 'standing-progress' },
|
|
48
|
+
'standing-achievements': { view: 'standing', anchor: 'standing-achievements' },
|
|
49
|
+
};
|
|
33
50
|
// builders.js owns these hashes (deep-link overlay) — never route them.
|
|
34
51
|
var DEEPLINK_RE = /^#\/(task|idea|blocker)\/(\d+)$/;
|
|
35
52
|
|
|
@@ -60,7 +77,6 @@
|
|
|
60
77
|
profile: '<rect x="2.5" y="4" width="13" height="10" rx="1.5"/><circle cx="6.3" cy="8" r="1.6"/><path d="M4.1 12c.3-1.1 1.1-1.7 2.2-1.7s1.9.6 2.2 1.7"/><path d="M10.4 7.5h3M10.4 10.3h3"/>',
|
|
61
78
|
goals: '<circle cx="9" cy="9" r="6.5"/><circle cx="9" cy="9" r="3.5"/><circle cx="9" cy="9" r="0.8" fill="currentColor"/>',
|
|
62
79
|
roadmap: '<path d="M3 15.5V3.5l4 2 4-2 4 2v10l-4-2-4 2-4-2Z"/><path d="M7 3.5v10M11 5.5v10"/>',
|
|
63
|
-
achievements: '<circle cx="9" cy="7" r="4.5"/><path d="M6.2 10.8 5 15.5l4-2 4 2-1.2-4.7"/>',
|
|
64
80
|
leaderboard: '<path d="M3.5 15.5v-6M9 15.5V3.5m5.5 12v-9"/>',
|
|
65
81
|
docs: '<path d="M4 3.5h7l3 3v10H4v-13Z"/><path d="M11 3.5v3h3"/>',
|
|
66
82
|
settings: '<circle cx="9" cy="9" r="2.5"/><path d="M9 2.5v2m0 9v2M2.5 9h2m9 0h2M4.4 4.4l1.4 1.4m6.4 6.4 1.4 1.4m0-9.2-1.4 1.4M5.8 12.2l-1.4 1.4"/>',
|
|
@@ -81,16 +97,30 @@
|
|
|
81
97
|
// current (mirrors the old #hall-nav-work rule, task #833)
|
|
82
98
|
// archon — rank === 'archon'
|
|
83
99
|
// `view` marks an index view (hash-routed); `module` gates on window.__MODULES__.
|
|
100
|
+
// task 2175: grouped by AUDIENCE of the data, so the sidebar reads in coherent
|
|
101
|
+
// runs instead of one long list — the project (unlabeled), You, Community,
|
|
102
|
+
// Docs, Archon. A group's `gate` must match its most permissive item's, or the
|
|
103
|
+
// head renders over nothing.
|
|
84
104
|
var NAV = [
|
|
85
105
|
{ group: '', items: [
|
|
86
106
|
{ id: 'home', label: 'Home', icon: 'home', href: '/', view: 'home', gate: 'always' },
|
|
87
|
-
// task 1966: Work is visible to ANY signed-in builder (incl. newcomer Xenos).
|
|
88
|
-
// Claimability is controlled per-task, not by hiding the page — every row
|
|
89
|
-
// carries a rank tag and the server enforces requires_rank on the claim. This
|
|
90
|
-
// reverses task #833's newcomer hide (the 'work' gate below is now unused).
|
|
91
|
-
{ id: 'work', label: 'Work', icon: 'work', href: '/work', gate: 'signed' },
|
|
92
107
|
{ id: 'roadmap', label: 'Roadmap', icon: 'roadmap', href: '/roadmap', gate: 'member' },
|
|
93
108
|
{ id: 'goals', label: 'Goals', icon: 'goals', href: '/goals', gate: 'member' },
|
|
109
|
+
// task 1966: Tasks (the board formerly labelled "Work") is visible to ANY
|
|
110
|
+
// signed-in builder (incl. newcomer Xenos). Claimability is controlled
|
|
111
|
+
// per-task, not by hiding the page — every row carries a rank tag and the
|
|
112
|
+
// server enforces requires_rank on the claim. This reverses task #833's
|
|
113
|
+
// newcomer hide (the 'work' gate below is now unused).
|
|
114
|
+
// task 1002425: relabelled Work → Tasks and moved below Roadmap/Goals. The
|
|
115
|
+
// id ('work') and href ('/work') are deliberately UNCHANGED so deep links,
|
|
116
|
+
// active-nav detection (#nav-work), the 'work' gate case, and the server
|
|
117
|
+
// page-gate all keep working — only the visible label and order change.
|
|
118
|
+
{ id: 'work', label: 'Tasks', icon: 'work', href: '/work', gate: 'signed' },
|
|
119
|
+
] },
|
|
120
|
+
// Your own numbers. task 2174 folded Achievements into Standing and this task
|
|
121
|
+
// retires its nav entry; VIEW_ALIASES still routes #achievements here, so old
|
|
122
|
+
// bookmarks and the stat tiles keep landing on the section.
|
|
123
|
+
{ group: 'You', gate: 'signed', items: [
|
|
94
124
|
{ id: 'standing', label: 'Standing', icon: 'standing', href: '/#standing', view: 'standing', gate: 'signed' },
|
|
95
125
|
// task 1467: the viewable, shareable builder profile. The nav link points at
|
|
96
126
|
// the viewer's OWN profile (profile.js defaults to self when no ?id=). gate is
|
|
@@ -98,15 +128,24 @@
|
|
|
98
128
|
// /profile?id=N from the leaderboard); 'signed' just means "show this 'my
|
|
99
129
|
// profile' shortcut once you're signed in".
|
|
100
130
|
{ id: 'profile', label: 'Profile', icon: 'profile', href: '/profile', gate: 'signed' },
|
|
101
|
-
|
|
131
|
+
] },
|
|
132
|
+
{ group: 'Community', gate: 'member', items: [
|
|
102
133
|
{ id: 'leaderboard', label: 'Leaderboard', icon: 'leaderboard', href: '/#leaderboard', view: 'leaderboard', gate: 'member' },
|
|
103
134
|
] },
|
|
104
135
|
{ group: 'Docs', gate: 'signed', items: [
|
|
105
136
|
{ id: 'primer', label: 'Primer', icon: 'docs', href: '/primer', gate: 'member' },
|
|
137
|
+
{ id: 'ranks', label: 'Ranks', icon: 'docs', href: '/ranks', gate: 'signed' },
|
|
138
|
+
// task 2175: /drachmae had no nav entry at all — reachable only from prose
|
|
139
|
+
// links since task 2174 moved the bounty rate card onto it. It is reference
|
|
140
|
+
// material (the reward schedule + how karma differs), so it belongs in Docs,
|
|
141
|
+
// not on personal Standing. Labelled for the TOPIC rather than the instance's
|
|
142
|
+
// currency: the page covers karma too, which is not currency, and "Economy"
|
|
143
|
+
// stays right whatever `branding.currency.label` is set to. Page is public
|
|
144
|
+
// like /ranks — 'signed' is the same cosmetic "show it once you're in".
|
|
145
|
+
{ id: 'economy', label: 'Economy', icon: 'docs', href: '/drachmae', gate: 'signed' },
|
|
106
146
|
{ id: 'diagrams', label: 'Diagrams', icon: 'docs', href: '/diagrams', gate: 'member' },
|
|
107
147
|
{ id: 'atlas', label: 'Repo Atlas', icon: 'docs', href: '/atlas', gate: 'member' },
|
|
108
148
|
{ id: 'modules', label: 'Modules', icon: 'docs', href: '/modules', gate: 'member' },
|
|
109
|
-
{ id: 'ranks', label: 'Ranks', icon: 'docs', href: '/ranks', gate: 'signed' },
|
|
110
149
|
// The rendered OpenAPI reference lives on the APEX (/docs), not this builders
|
|
111
150
|
// subdomain — external so the rewrite shim doesn't turn it into /builders/docs.
|
|
112
151
|
{ id: 'apidocs', label: 'API docs', icon: 'docs', href: '/docs', gate: 'signed', external: true },
|
|
@@ -119,11 +158,13 @@
|
|
|
119
158
|
] },
|
|
120
159
|
];
|
|
121
160
|
|
|
122
|
-
// ---------- nav group collapse (labeled groups only
|
|
161
|
+
// ---------- nav group collapse (labeled groups only) ----------
|
|
123
162
|
// Mirrors the THEME_KEY localStorage pattern: per-group collapsed state,
|
|
124
163
|
// survives reloads and carries across every hall page (shell.js runs on all
|
|
125
164
|
// of them). Only labeled groups get a toggle — the unlabeled main group
|
|
126
|
-
// (Home/
|
|
165
|
+
// (Home/Roadmap/Goals/Tasks) is core nav and always stays expanded. Keys are
|
|
166
|
+
// the lowercased group label, so a regroup renames the key and a group reverts
|
|
167
|
+
// to expanded once — acceptable for a cosmetic preference.
|
|
127
168
|
var NAV_COLLAPSE_KEY = 'hall-nav-collapsed';
|
|
128
169
|
|
|
129
170
|
function collapsedGroups() {
|
|
@@ -152,6 +193,9 @@
|
|
|
152
193
|
// builders./status. subdomain). Derived from the current host so it's correct
|
|
153
194
|
// on any instance (amazonprimea.com, cloudbongos.com, localhost).
|
|
154
195
|
var APEX_ORIGIN = window.location.origin.replace('://builders.', '://').replace('://status.', '://');
|
|
196
|
+
// Instance product/world name for the "back to home" wayfinding link — same
|
|
197
|
+
// source renderFoot() uses, so the core carries no hardcoded identity.
|
|
198
|
+
var platformName = (brand.identity && (brand.identity.productName || brand.identity.worldName)) || 'projects';
|
|
155
199
|
var groups = NAV.map(function (g) {
|
|
156
200
|
var groupId = g.group ? g.group.toLowerCase() : '';
|
|
157
201
|
var collapsible = !!g.group;
|
|
@@ -189,6 +233,15 @@
|
|
|
189
233
|
'<span class="shell-user__meta"><span class="shell-user__name" id="shell-user-name"></span>' +
|
|
190
234
|
'<span class="shell-user__rank" id="shell-user-rank"></span></span>' +
|
|
191
235
|
'</a>' +
|
|
236
|
+
// Wayfinding back to the platform's public home (the orbs gate on
|
|
237
|
+
// cloudbongos), where a builder can browse the OTHER projects. Kept core-
|
|
238
|
+
// neutral: the label is the instance's product/world name (as renderFoot
|
|
239
|
+
// does) and the href is the derived apex origin — no instance identity
|
|
240
|
+
// hardcoded. Ungated (shown signed-in or out) — it's a way out, not a
|
|
241
|
+
// gated action. Sits by Sign out (bottom-left) per the owner's call.
|
|
242
|
+
'<a class="shell-home" id="shell-home" href="' + esc(APEX_ORIGIN + '/') + '" title="Back to ' + esc(platformName) + ' — browse projects">' +
|
|
243
|
+
'<svg class="nav-icon" viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.5 4 5.5 9l5 5"/><path d="M5.5 9H14"/></svg>' +
|
|
244
|
+
'<span class="nav-item__label">' + esc(platformName) + '</span></a>' +
|
|
192
245
|
'<a class="shell-signout" id="logout-link" href="/api/bongos/auth/logout" title="Sign out">' + icon('signout') + '<span class="nav-item__label">Sign out</span></a>' +
|
|
193
246
|
'</div>';
|
|
194
247
|
var nameEl = document.getElementById('brand-name');
|
|
@@ -206,6 +259,15 @@
|
|
|
206
259
|
'</button>' +
|
|
207
260
|
'<h2 class="topbar-title" id="topbar-title"></h2>' +
|
|
208
261
|
'<div class="topbar-side"><span class="topbar-note" id="welcome-line"></span>' +
|
|
262
|
+
// task 2178: the jump-palette slot. Rendered inert + hidden — palette.js
|
|
263
|
+
// reveals and wires it when the page loads it. A page without palette.js
|
|
264
|
+
// therefore shows no slot and runs no palette code (progressive
|
|
265
|
+
// enhancement): the shell never calls into it, so nothing can throw.
|
|
266
|
+
'<button class="topbar-jump" id="topbar-jump" type="button" hidden aria-label="Jump to a page or record">' +
|
|
267
|
+
'<svg viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><circle cx="8" cy="8" r="4.5"/><path d="M11.5 11.5 15 15"/></svg>' +
|
|
268
|
+
'<span class="topbar-jump__label">Jump to…</span>' +
|
|
269
|
+
'<kbd class="topbar-jump__kbd" id="topbar-jump-kbd"></kbd>' +
|
|
270
|
+
'</button>' +
|
|
209
271
|
'<button class="zoom-toggle" id="zoom-toggle" type="button" aria-label="Text size"></button>' +
|
|
210
272
|
'<button class="theme-toggle" id="theme-toggle" type="button" aria-label="Switch theme"></button></div>';
|
|
211
273
|
var t = document.getElementById('topbar-title');
|
|
@@ -358,10 +420,14 @@
|
|
|
358
420
|
|
|
359
421
|
var currentView = 'home';
|
|
360
422
|
|
|
423
|
+
// → { view, anchor } for a routable hash, else null. An aliased hash resolves
|
|
424
|
+
// to its host view plus the in-view anchor to scroll to once it is shown.
|
|
361
425
|
function viewFromHash(hash) {
|
|
362
426
|
if (!hash || DEEPLINK_RE.test(hash)) return null;
|
|
363
427
|
var name = hash.replace(/^#\/?/, '');
|
|
364
|
-
|
|
428
|
+
if (VIEWS.indexOf(name) !== -1) return { view: name, anchor: null };
|
|
429
|
+
var alias = VIEW_ALIASES[name];
|
|
430
|
+
return alias ? { view: alias.view, anchor: alias.anchor } : null;
|
|
365
431
|
}
|
|
366
432
|
|
|
367
433
|
function setView(name, opts) {
|
|
@@ -384,12 +450,30 @@
|
|
|
384
450
|
}
|
|
385
451
|
|
|
386
452
|
function route(opts) {
|
|
387
|
-
var
|
|
388
|
-
if (
|
|
389
|
-
|
|
453
|
+
var target = viewFromHash(window.location.hash);
|
|
454
|
+
if (target) {
|
|
455
|
+
// An aliased hash owns its scroll position, so suppress setView's
|
|
456
|
+
// scroll-to-top and land on the section instead.
|
|
457
|
+
setView(target.view, target.anchor ? { scroll: false } : opts);
|
|
458
|
+
if (target.anchor) scrollToAnchor(target.anchor);
|
|
459
|
+
} else if (!window.location.hash || window.location.hash === '#') {
|
|
460
|
+
setView('home', opts);
|
|
461
|
+
}
|
|
390
462
|
// unknown hashes (deep-links, legacy anchors) leave the current view alone.
|
|
391
463
|
}
|
|
392
464
|
|
|
465
|
+
// The anchor is stamped by builders.js when it mounts the hall widgets, which
|
|
466
|
+
// can land after the first route() call — retry on the next frame so a cold
|
|
467
|
+
// load of an aliased hash still arrives at the section.
|
|
468
|
+
function scrollToAnchor(id) {
|
|
469
|
+
var el = document.getElementById(id);
|
|
470
|
+
if (el) { el.scrollIntoView(); return; }
|
|
471
|
+
window.requestAnimationFrame(function () {
|
|
472
|
+
var late = document.getElementById(id);
|
|
473
|
+
if (late) late.scrollIntoView();
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
|
|
393
477
|
// ---------- drawer (≤768px) ----------
|
|
394
478
|
|
|
395
479
|
function openDrawer() {
|
|
@@ -407,6 +491,35 @@
|
|
|
407
491
|
if (btn) btn.setAttribute('aria-expanded', 'false');
|
|
408
492
|
}
|
|
409
493
|
|
|
494
|
+
// Sign out. The /api/bongos/auth/logout endpoint is POST + cookie-gated, so a
|
|
495
|
+
// plain-anchor GET navigation (what the sidebar/footer sign-out links do on
|
|
496
|
+
// their own) just 404s: the session is never revoked, the still-valid cookie
|
|
497
|
+
// signs the builder back in on the next page, and — because the POST handler
|
|
498
|
+
// is the ONLY place seams.emit('builder.logout') fires — the federated
|
|
499
|
+
// single-logout to the hub never happens either (ADR 0144 / task 1002238).
|
|
500
|
+
// shell.js draws the sign-out control on EVERY hall page, so this handler must
|
|
501
|
+
// live here, not only on the index (builders.js used to own it alone). Convert
|
|
502
|
+
// the click into the real POST, then bounce home.
|
|
503
|
+
function doLogout() {
|
|
504
|
+
var finish = function () {
|
|
505
|
+
// Mirror the SERVER logout (src/bongos/routes/auth.js): expire BOTH the
|
|
506
|
+
// current gds_session and the legacy pms_session, each in BOTH the
|
|
507
|
+
// host-only form and the apex-scoped Domain=.<apex> form (#726 — the
|
|
508
|
+
// session cookie is apex-scoped on production hosts so it crosses
|
|
509
|
+
// subdomains; a Max-Age=0 only matches the cookie whose Domain attribute
|
|
510
|
+
// it names, so the host-only expire alone leaves the apex cookie live).
|
|
511
|
+
var apex = location.hostname.split('.').slice(-2).join('.');
|
|
512
|
+
['gds_session', 'pms_session'].forEach(function (name) {
|
|
513
|
+
document.cookie = name + '=; Max-Age=0; path=/';
|
|
514
|
+
document.cookie = name + '=; Max-Age=0; path=/; Domain=.' + apex;
|
|
515
|
+
});
|
|
516
|
+
window.location.assign('/');
|
|
517
|
+
};
|
|
518
|
+
// Best-effort: whether the POST succeeds, fails, or the network drops, still
|
|
519
|
+
// clear the client cookies and bounce (finish runs on both settle paths).
|
|
520
|
+
api.request('POST', '/api/bongos/auth/logout').then(finish, finish);
|
|
521
|
+
}
|
|
522
|
+
|
|
410
523
|
function wire() {
|
|
411
524
|
var menu = document.getElementById('topbar-menu');
|
|
412
525
|
if (menu) menu.addEventListener('click', function () {
|
|
@@ -441,6 +554,18 @@
|
|
|
441
554
|
document.addEventListener('keydown', function (e) {
|
|
442
555
|
if (e.key === 'Escape') closeDrawer();
|
|
443
556
|
});
|
|
557
|
+
// Sign-out: delegated so it catches BOTH the sidebar (#logout-link) and the
|
|
558
|
+
// footer sign-out anchors on every page, plus any future one. Any anchor
|
|
559
|
+
// pointing at the logout endpoint is intercepted and turned into the real
|
|
560
|
+
// POST (see doLogout) instead of a dead GET navigation.
|
|
561
|
+
document.addEventListener('click', function (e) {
|
|
562
|
+
var a = e.target.closest && e.target.closest('a');
|
|
563
|
+
if (!a) return;
|
|
564
|
+
if (/\/auth\/logout\/?$/.test(a.getAttribute('href') || '')) {
|
|
565
|
+
e.preventDefault();
|
|
566
|
+
doLogout();
|
|
567
|
+
}
|
|
568
|
+
});
|
|
444
569
|
}
|
|
445
570
|
|
|
446
571
|
// Non-index pages: probe /api/bongos/me for cosmetic nav gating (the index's
|