@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,145 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Capture a learning — durable storage in the GDS DB (Phase 2b: the DB is
|
|
3
|
+
// now the only canonical home for short-form learnings; long-form recipes
|
|
4
|
+
// live under docs/recipes/).
|
|
5
|
+
//
|
|
6
|
+
// Usage:
|
|
7
|
+
// node scripts/gds/learning-capture.js \
|
|
8
|
+
// --tags "caddy,cloudflare" \
|
|
9
|
+
// --title "Origin cert needs *.amazonprimea.com SAN" \
|
|
10
|
+
// --body-file path/to/body.md
|
|
11
|
+
//
|
|
12
|
+
// Body source (in priority order): --body-file PATH > --body "text" > stdin.
|
|
13
|
+
// Related files: --files "infra/Caddyfile,..." > auto-detected `git diff --name-only HEAD`.
|
|
14
|
+
// Idempotency: --source / --source-ref pair acts as soft-key (server skips on duplicate).
|
|
15
|
+
|
|
16
|
+
const fs = require('node:fs');
|
|
17
|
+
const fsp = require('node:fs/promises');
|
|
18
|
+
const path = require('node:path');
|
|
19
|
+
const { execSync } = require('node:child_process');
|
|
20
|
+
|
|
21
|
+
const { cliClient, requireSession, arg } = require('./cli-lib');
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
function csv(v) {
|
|
25
|
+
if (!v) return [];
|
|
26
|
+
return String(v).split(',').map((s) => s.trim()).filter(Boolean);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function readStdin() {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
if (process.stdin.isTTY) return resolve('');
|
|
32
|
+
let data = '';
|
|
33
|
+
process.stdin.setEncoding('utf8');
|
|
34
|
+
process.stdin.on('data', (chunk) => (data += chunk));
|
|
35
|
+
process.stdin.on('end', () => resolve(data));
|
|
36
|
+
process.stdin.on('error', reject);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function autoDetectFiles() {
|
|
41
|
+
try {
|
|
42
|
+
const out = execSync('git diff --name-only HEAD', {
|
|
43
|
+
encoding: 'utf8',
|
|
44
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
45
|
+
});
|
|
46
|
+
return out.split('\n').map((s) => s.trim()).filter(Boolean);
|
|
47
|
+
} catch (_) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
(async () => {
|
|
54
|
+
await requireSession();
|
|
55
|
+
const args = process.argv.slice(2);
|
|
56
|
+
|
|
57
|
+
const title = arg('--title', args);
|
|
58
|
+
const tags = csv(arg('--tags', args));
|
|
59
|
+
const bodyFile = arg('--body-file', args);
|
|
60
|
+
const bodyInline = arg('--body', args);
|
|
61
|
+
const filesArg = arg('--files', args);
|
|
62
|
+
const source = arg('--source', args);
|
|
63
|
+
const sourceRef = arg('--source-ref', args);
|
|
64
|
+
const taskIdStr = arg('--task-id', args);
|
|
65
|
+
const taskId = taskIdStr ? Number(taskIdStr) : null;
|
|
66
|
+
const dryRun = args.includes('--dry-run');
|
|
67
|
+
|
|
68
|
+
if (!title || tags.length === 0) {
|
|
69
|
+
console.error('usage: node scripts/gds/learning-capture.js --tags "a,b" --title "..." (--body-file PATH | --body "..." | stdin) [--files "f,g"] [--source manual] [--source-ref id] [--task-id N] [--dry-run]');
|
|
70
|
+
process.exit(2);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let body;
|
|
74
|
+
if (bodyFile) {
|
|
75
|
+
try {
|
|
76
|
+
body = await fsp.readFile(bodyFile, 'utf8');
|
|
77
|
+
} catch (err) {
|
|
78
|
+
console.error(`failed to read --body-file ${bodyFile}: ${err.message}`);
|
|
79
|
+
process.exit(2);
|
|
80
|
+
}
|
|
81
|
+
} else if (bodyInline) {
|
|
82
|
+
body = bodyInline;
|
|
83
|
+
} else {
|
|
84
|
+
body = await readStdin();
|
|
85
|
+
}
|
|
86
|
+
if (!body || !body.trim()) {
|
|
87
|
+
console.error('body is empty (provide via --body-file PATH, --body "...", or piped stdin)');
|
|
88
|
+
process.exit(2);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const relatedFiles = filesArg ? csv(filesArg) : autoDetectFiles();
|
|
92
|
+
|
|
93
|
+
// Find current builder login so the file footer says who captured.
|
|
94
|
+
let capturedByLogin = null;
|
|
95
|
+
try {
|
|
96
|
+
const api = await cliClient();
|
|
97
|
+
const me = await api.me.getMe();
|
|
98
|
+
if (me.ok) capturedByLogin = me.data?.builder?.github_login ?? null;
|
|
99
|
+
} catch (_) {}
|
|
100
|
+
|
|
101
|
+
if (dryRun) {
|
|
102
|
+
console.log('=== DRY RUN ===');
|
|
103
|
+
console.log('POST /api/gds/learnings:');
|
|
104
|
+
console.log(JSON.stringify({
|
|
105
|
+
title, body_md: body, tags, related_files: relatedFiles, source, source_ref: sourceRef, task_id: taskId,
|
|
106
|
+
}, null, 2));
|
|
107
|
+
process.exit(0);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const api = await cliClient();
|
|
111
|
+
const r = await api.learnings.postLearnings({
|
|
112
|
+
body: {
|
|
113
|
+
title,
|
|
114
|
+
body_md: body,
|
|
115
|
+
tags,
|
|
116
|
+
related_files: relatedFiles,
|
|
117
|
+
source,
|
|
118
|
+
source_ref: sourceRef,
|
|
119
|
+
task_id: taskId,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
if (r.status === 200 && r.data?.skipped) {
|
|
124
|
+
console.log(`Skipped: duplicate (source=${source}, source_ref=${sourceRef}) already captured.`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (r.status !== 201) {
|
|
128
|
+
console.error(`capture failed (${r.status}):`, r.data);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const { learning } = r.data;
|
|
133
|
+
console.log(`Captured learning #${learning.id}: ${learning.title}`);
|
|
134
|
+
console.log(`Tags: ${learning.tags.join(', ')}`);
|
|
135
|
+
if (learning.related_files?.length) {
|
|
136
|
+
console.log(`Related files: ${learning.related_files.join(', ')}`);
|
|
137
|
+
}
|
|
138
|
+
console.log('Stored in GDS DB. Query with: node scripts/gds/learning-list.js (TBD) or GET /api/gds/learnings');
|
|
139
|
+
// Phase 2b — the per-tag markdown append was removed. The DB is now the
|
|
140
|
+
// canonical store for short-form learnings; long-form operational recipes
|
|
141
|
+
// live separately under docs/recipes/.
|
|
142
|
+
})().catch((err) => {
|
|
143
|
+
console.error('fatal:', err);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scripts/gds/lib.sh — shared helpers for the GDS shell smoke scripts.
|
|
3
|
+
# SOURCED, never executed: source "$(dirname "$0")/lib.sh"
|
|
4
|
+
#
|
|
5
|
+
# Holds ONLY the pieces that were byte-identical across smoke-batch-claim.sh,
|
|
6
|
+
# smoke-claim-consistency.sh, and smoke-write.sh: the GDS API base-URL default
|
|
7
|
+
# (a literal that had drifted) and the CLI session-token resolution.
|
|
8
|
+
#
|
|
9
|
+
# Deliberately NOT here:
|
|
10
|
+
# - the per-script curl `call()` wrapper — the two contracts differ in
|
|
11
|
+
# load-bearing ways (smoke-batch-claim echoes "PAYLOAD\nCODE" and never exits
|
|
12
|
+
# non-zero so its caller can read CODE/PAYLOAD; smoke-write/-consistency echo
|
|
13
|
+
# the payload and `return 1` on a non-2xx so `set -e` aborts). Merging them
|
|
14
|
+
# would break one or the other, so each script keeps its own.
|
|
15
|
+
# - smoke-dependencies.sh / portability-smoke-memory.sh, whose token + base-URL
|
|
16
|
+
# handling intentionally differs (macOS-only path / env-first token / no PMS
|
|
17
|
+
# fallback / skip-on-missing) — left as-is to preserve that drift.
|
|
18
|
+
|
|
19
|
+
# The GDS API host. One home for the default that had drifted across the smoke
|
|
20
|
+
# scripts; still overridable via GDS_API_BASE / (legacy) PMS_API_BASE.
|
|
21
|
+
gds_api_base() {
|
|
22
|
+
printf '%s' "${GDS_API_BASE:-${PMS_API_BASE:-https://amazonprimea.com}}"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
# Resolve the CLI session token: prefer ~/.config/otb/gds-session.json, fall back
|
|
26
|
+
# to the legacy pms-session.json. Echoes the token on success. On a missing file
|
|
27
|
+
# or empty token it prints a FAIL line to stderr and returns 2 — callers run
|
|
28
|
+
# TOKEN="$(gds_resolve_token)" || exit $?
|
|
29
|
+
# so the failure propagates out of the command substitution.
|
|
30
|
+
gds_resolve_token() {
|
|
31
|
+
local sf="${HOME}/.config/otb/gds-session.json"
|
|
32
|
+
[[ -f "$sf" ]] || sf="${HOME}/.config/otb/pms-session.json"
|
|
33
|
+
if [[ ! -f "$sf" ]]; then
|
|
34
|
+
echo "FAIL: no session at $sf. Run setup first." >&2
|
|
35
|
+
return 2
|
|
36
|
+
fi
|
|
37
|
+
local tok
|
|
38
|
+
tok=$(python3 -c "import json; print(json.load(open('$sf'))['token'])")
|
|
39
|
+
if [[ -z "$tok" ]]; then
|
|
40
|
+
echo "FAIL: no token in $sf" >&2
|
|
41
|
+
return 2
|
|
42
|
+
fi
|
|
43
|
+
printf '%s' "$tok"
|
|
44
|
+
}
|
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// linkify-refs.js — rewrite bare "#NNN" GDS references in docs into explicit
|
|
3
|
+
// markdown links to the Builders' Hall deep-link resolver, so they STOP
|
|
4
|
+
// colliding with GitHub's built-in PR/issue autolinker when the docs are read
|
|
5
|
+
// on github.com.
|
|
6
|
+
//
|
|
7
|
+
// THE PROBLEM. Our docs reference GDS ids as bare "#NNN". GitHub, viewing
|
|
8
|
+
// markdown in the repo, auto-links every "#NNN" to PR/issue #NNN — a SEPARATE
|
|
9
|
+
// number space from our task/idea/blocker ids. Early on task#≈PR# so it
|
|
10
|
+
// coincidentally worked; they've since diverged, so "#170" now lands on an
|
|
11
|
+
// unrelated PR (or a dead number). An explicit markdown link —
|
|
12
|
+
// [#170](https://…/#/task/170) — suppresses GitHub's autolinker AND points at
|
|
13
|
+
// the right record.
|
|
14
|
+
//
|
|
15
|
+
// THREE RESOLVABLE KINDS (#629). The hall resolves /#/task/N, /#/idea/N and
|
|
16
|
+
// /#/blocker/N (DEEPLINK_RE in public-builders/builders.js), so this linkifier
|
|
17
|
+
// classifies a ref by its surrounding noun and links it to the matching
|
|
18
|
+
// resolver. A ref whose id is NOT in the matching public id set, and any other
|
|
19
|
+
// entity that has no resolver (session/migration/report/learning/builder/…),
|
|
20
|
+
// is NEUTRALIZED instead — wrapped in a code span (`#N`) that GitHub never
|
|
21
|
+
// autolinks — so it can't 404 yet also can't mis-link.
|
|
22
|
+
//
|
|
23
|
+
// THE RISK. A WRONG rewrite (pointing a number at the wrong thing) just
|
|
24
|
+
// recreates the complaint. So the classifier is deliberately conservative —
|
|
25
|
+
// it links a "#NNN" ONLY when ALL of these hold:
|
|
26
|
+
// • NNN is a real id of the classified kind (fetched live from the public
|
|
27
|
+
// /api/gds/public/ref-ids allow-list; PR-only numbers are therefore never
|
|
28
|
+
// touched, and an idea id is never linked as a task).
|
|
29
|
+
// • It is a bare reference — NOT a markdown heading anchor like
|
|
30
|
+
// `](#12-session-update-protocol)` (digits followed by `-`/word chars), and
|
|
31
|
+
// NOT already link text `[#170]` or a link target `](#170)`.
|
|
32
|
+
// • It is not inside an inline code span or a fenced code block (with the one
|
|
33
|
+
// exception of upgrading a prior `#N` idea/blocker NEUTRALIZATION — see
|
|
34
|
+
// upgradeLineCodeSpans).
|
|
35
|
+
// Anything ambiguous is left bare/neutralized — a missed link is strictly safer
|
|
36
|
+
// than a wrong one.
|
|
37
|
+
//
|
|
38
|
+
// USAGE
|
|
39
|
+
// node scripts/gds/linkify-refs.js # dry-run on the default index docs
|
|
40
|
+
// node scripts/gds/linkify-refs.js --apply # write the changes
|
|
41
|
+
// node scripts/gds/linkify-refs.js --check # CI gate: non-zero exit if any bare/upgradeable ref remains
|
|
42
|
+
// node scripts/gds/linkify-refs.js --apply docs/x.md CLAUDE.md # explicit file set
|
|
43
|
+
// node scripts/gds/linkify-refs.js --ids 1,2,3 ... # offline: supply the task-id set
|
|
44
|
+
//
|
|
45
|
+
// The core linkifyText() is a pure function (exported) so it can be unit-tested
|
|
46
|
+
// without the API or the filesystem (see tests/linkify_refs.mjs).
|
|
47
|
+
|
|
48
|
+
const fs = require('node:fs');
|
|
49
|
+
const path = require('node:path');
|
|
50
|
+
|
|
51
|
+
const RESOLVER_BASE = 'https://amazonprimea.com/builders#/task/';
|
|
52
|
+
const RESOLVER_BASE_IDEA = 'https://amazonprimea.com/builders#/idea/';
|
|
53
|
+
const RESOLVER_BASE_BLOCKER = 'https://amazonprimea.com/builders#/blocker/';
|
|
54
|
+
// API_BASE comes from cli-lib (the single source). Safe for this token-free CI
|
|
55
|
+
// gate: cli-lib does no eager session read or network at module scope.
|
|
56
|
+
const { API_BASE } = require('./cli-lib');
|
|
57
|
+
|
|
58
|
+
// Every hand-authored markdown file that a reader sees rendered on github.com:
|
|
59
|
+
// the root CLAUDE.md/README.md plus all of docs/** (session-logs included). A
|
|
60
|
+
// "GENERATED FILE" marker means the bare refs reappear on the next regen, so
|
|
61
|
+
// the generator — not its output — is where those get fixed; skip them here.
|
|
62
|
+
function discoverDocs() {
|
|
63
|
+
const out = [];
|
|
64
|
+
const walk = (rel) => {
|
|
65
|
+
const abs = path.resolve(process.cwd(), rel);
|
|
66
|
+
if (!fs.existsSync(abs)) return;
|
|
67
|
+
if (fs.statSync(abs).isDirectory()) {
|
|
68
|
+
for (const name of fs.readdirSync(abs).sort()) walk(path.join(rel, name));
|
|
69
|
+
} else if (rel.endsWith('.md')) {
|
|
70
|
+
out.push(rel);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
for (const root of ['CLAUDE.md', 'README.md', 'docs']) walk(root);
|
|
74
|
+
return out.filter((rel) =>
|
|
75
|
+
!/GENERATED FILE/i.test(fs.readFileSync(path.resolve(process.cwd(), rel), 'utf8').slice(0, 200))
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// "#NNN" preceded by an IDEA / BLOCKER noun → that kind's resolver (#629). These
|
|
80
|
+
// are checked before the generic ENTITY_RE so an idea/blocker ref links rather
|
|
81
|
+
// than merely neutralizing.
|
|
82
|
+
const IDEA_CTX_RE = /\b(idea_inbox|ideas?)[`'")\s(:]*$/i;
|
|
83
|
+
const BLOCKER_CTX_RE = /\b(blockers?)[`'")\s(:]*$/i;
|
|
84
|
+
// "#NNN" preceded by one of these nouns denotes a DIFFERENT entity that shares
|
|
85
|
+
// the integer space with tasks but has NO resolver (a session ordinal, a
|
|
86
|
+
// migration number, a security-report id, a learning, a builder, …). Those must
|
|
87
|
+
// never be rewritten to a resolver URL — a wrong link is the exact bug we're
|
|
88
|
+
// fixing. But leaving them BARE is also a bug: GitHub autolinks any bare "#NNN"
|
|
89
|
+
// to its own PR/issue space, which 404s. So these are NEUTRALIZED — wrapped in a
|
|
90
|
+
// code span (`#170`) GitHub never autolinks. ("task"/"tasks" is deliberately
|
|
91
|
+
// NOT here: those ARE refs we want to linkify; idea/blocker are handled above.)
|
|
92
|
+
// The trailing class tolerates a closing backtick / quote / opening paren /
|
|
93
|
+
// colon so "`security_reports` (#2)" still classifies.
|
|
94
|
+
const ENTITY_RE = /\b(idea_inbox|ideas?|blockers?|sessions?|migrations?|criteri(?:on|a)|(?:security[_ ]?)?reports?|learnings?|builders?|claims?|intents?|findings?|achievements?)[`'")\s(:]*$/i;
|
|
95
|
+
// "#NNN" preceded by a GitHub-namespace noun (a PR ref) genuinely lives in
|
|
96
|
+
// GitHub's number space — a bare "#NNN" there autolinks CORRECTLY, so it is
|
|
97
|
+
// the one class we leave completely alone.
|
|
98
|
+
const GITHUB_NS_RE = /\b(pull requests?|pull|prs?)[`'")\s(:]*$/i;
|
|
99
|
+
// Pure list glue between two refs ("#1, #2" / "#1 and #2" / "#2–#11") — lets a
|
|
100
|
+
// classification carry across a list or range so "blockers #1, #2" and
|
|
101
|
+
// "reports #2–#11" treat BOTH ends the same way.
|
|
102
|
+
const LIST_GLUE_RE = /^[\s,–—-]*(?:and|&|\+|or|to|through)?[\s,–—-]*$/i;
|
|
103
|
+
|
|
104
|
+
const escapeRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
105
|
+
// An existing markdown link of the exact TASK form this script writes:
|
|
106
|
+
// [#N](task-resolver/N). Used only to undo PAST task-resolver mis-links of
|
|
107
|
+
// entity/idea/blocker refs; the idea/blocker resolver links are left alone.
|
|
108
|
+
const RESOLVER_LINK_RE = new RegExp(`\\[#(\\d{1,5})\\]\\(${escapeRe(RESOLVER_BASE)}(\\d{1,5})\\)`, 'g');
|
|
109
|
+
|
|
110
|
+
// Classify a ref by its left context (+ list-glue carry). Returns one of
|
|
111
|
+
// 'github' | 'idea' | 'blocker' | 'entity' | null (null = candidate task ref).
|
|
112
|
+
function classifyKind(left, carried, prevKind) {
|
|
113
|
+
if (GITHUB_NS_RE.test(left)) return 'github';
|
|
114
|
+
if (IDEA_CTX_RE.test(left)) return 'idea';
|
|
115
|
+
if (BLOCKER_CTX_RE.test(left)) return 'blocker';
|
|
116
|
+
if (ENTITY_RE.test(left)) return 'entity';
|
|
117
|
+
if (carried) return prevKind;
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Accept a bare Set (legacy: task ids only) or {tasks, ideas, blockers}.
|
|
122
|
+
function normalizeIdSets(ids) {
|
|
123
|
+
const toSet = (v) => (v instanceof Set ? v : new Set((v || []).map(Number).filter(Number.isInteger)));
|
|
124
|
+
if (ids instanceof Set) return { tasks: ids, ideas: new Set(), blockers: new Set() };
|
|
125
|
+
return { tasks: toSet(ids && ids.tasks), ideas: toSet(ids && ids.ideas), blockers: toSet(ids && ids.blockers) };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Undo PAST mis-linkifications: an entity/idea/blocker-context ref that an
|
|
129
|
+
// earlier, less careful run rewrote into a TASK link ("learning [#53](task/53)"
|
|
130
|
+
// — wrong target). Such links become neutral code spans (Phase 2 then upgrades
|
|
131
|
+
// idea/blocker ones to their proper resolver); a GitHub-namespace one (a PR ref
|
|
132
|
+
// wrongly sent to the task resolver) goes back to bare so GitHub's own
|
|
133
|
+
// autolinker works again. Same accumulating left-context + list-glue carry as
|
|
134
|
+
// linkifySegment so ranges ("reports [#2](u)–[#11](u)") unwrap on both ends.
|
|
135
|
+
function unlinkEntitySegment(segment, leftContext, stats) {
|
|
136
|
+
let out = '';
|
|
137
|
+
let last = 0;
|
|
138
|
+
let prevEnd = 0;
|
|
139
|
+
let hadPrev = false;
|
|
140
|
+
let prevKind = null; // 'entity' | 'idea' | 'blocker' | 'github' | null
|
|
141
|
+
let m;
|
|
142
|
+
RESOLVER_LINK_RE.lastIndex = 0;
|
|
143
|
+
while ((m = RESOLVER_LINK_RE.exec(segment)) !== null) {
|
|
144
|
+
if (m[1] !== m[2]) continue; // text/target number mismatch — not ours
|
|
145
|
+
const num = m[1];
|
|
146
|
+
const start = m.index;
|
|
147
|
+
const left = leftContext + out + segment.slice(last, start);
|
|
148
|
+
const gap = segment.slice(prevEnd, start);
|
|
149
|
+
const carried = hadPrev && prevKind && LIST_GLUE_RE.test(gap);
|
|
150
|
+
const kind = classifyKind(left, carried, prevKind);
|
|
151
|
+
|
|
152
|
+
prevEnd = start + m[0].length;
|
|
153
|
+
hadPrev = true;
|
|
154
|
+
prevKind = kind;
|
|
155
|
+
if (!kind) continue; // a genuine task link — leave it
|
|
156
|
+
|
|
157
|
+
out += segment.slice(last, start);
|
|
158
|
+
out += kind === 'github' ? `#${num}` : `\`#${num}\``;
|
|
159
|
+
last = prevEnd;
|
|
160
|
+
stats.unlinked = (stats.unlinked || 0) + 1;
|
|
161
|
+
}
|
|
162
|
+
out += segment.slice(last);
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Replace bare "#NNN" refs in a single non-code text segment. `leftContext` is
|
|
167
|
+
// everything already emitted on this line (for left-context tests). `ids` is
|
|
168
|
+
// {tasks, ideas, blockers} Sets. Returns the transformed segment; mutates `stats`.
|
|
169
|
+
function linkifySegment(segment, ids, leftContext, stats) {
|
|
170
|
+
let out = '';
|
|
171
|
+
const re = /#(\d{1,5})/g;
|
|
172
|
+
let m;
|
|
173
|
+
let last = 0;
|
|
174
|
+
let prevEnd = 0; // index in `segment` just past the previous match
|
|
175
|
+
let hadPrev = false;
|
|
176
|
+
let prevKind = null; // carries across list glue
|
|
177
|
+
// Index ranges covered by the TEXT of a markdown link `[text](url)`. A "#NNN"
|
|
178
|
+
// inside link text is already part of a link; rewriting it nests one link
|
|
179
|
+
// inside another (`[task [#415](resolver)](url)`). prevChar==='[' only caught
|
|
180
|
+
// "#" right after the bracket — this catches it anywhere in the text.
|
|
181
|
+
const linkRanges = [];
|
|
182
|
+
{ const lre = /\[([^\]]*)\]\([^)]*\)/g; let lm;
|
|
183
|
+
while ((lm = lre.exec(segment)) !== null) linkRanges.push([lm.index + 1, lm.index + 1 + lm[1].length]); }
|
|
184
|
+
while ((m = re.exec(segment)) !== null) {
|
|
185
|
+
const num = m[1];
|
|
186
|
+
const start = m.index;
|
|
187
|
+
const matchEnd = start + m[0].length;
|
|
188
|
+
const endChar = segment[matchEnd]; // char immediately after the digits
|
|
189
|
+
// Left context = the line so far + this segment up to the match.
|
|
190
|
+
const left = leftContext + segment.slice(0, start);
|
|
191
|
+
const prevChar = left.length ? left[left.length - 1] : '';
|
|
192
|
+
const gap = segment.slice(prevEnd, start);
|
|
193
|
+
|
|
194
|
+
// Classification = directly preceded by an entity / idea / blocker / GitHub
|
|
195
|
+
// noun, OR inherited across a pure list-glue gap.
|
|
196
|
+
const carried = hadPrev && prevKind && LIST_GLUE_RE.test(gap);
|
|
197
|
+
const kind = classifyKind(left, carried, prevKind);
|
|
198
|
+
|
|
199
|
+
// Positional skips first — these positions must never be rewritten in ANY
|
|
200
|
+
// direction (anchors, existing link text/targets).
|
|
201
|
+
let skipReason = null;
|
|
202
|
+
if (prevChar === '`' && endChar === '`') {
|
|
203
|
+
// Already a neutralized code-span ref (`#170`) — Phase 2 owns upgrading
|
|
204
|
+
// those; never wrap one again here.
|
|
205
|
+
skipReason = 'already-neutralized';
|
|
206
|
+
} else if (endChar === '-' || /[A-Za-z0-9_]/.test(endChar || '')) {
|
|
207
|
+
// `#12-session-update-protocol` (heading anchor) or `#170abc` — not a bare ref.
|
|
208
|
+
skipReason = 'anchor-or-slug';
|
|
209
|
+
} else if (prevChar === '[') {
|
|
210
|
+
// Already link text: `[#170](...)`.
|
|
211
|
+
skipReason = 'already-link-text';
|
|
212
|
+
} else if (linkRanges.some(([s, e]) => start >= s && start < e)) {
|
|
213
|
+
// Inside link text mid-string: `[task #170](url)` — would nest links.
|
|
214
|
+
skipReason = 'in-link-text';
|
|
215
|
+
} else if (/\]\($/.test(left)) {
|
|
216
|
+
// Link target: `](#170)`.
|
|
217
|
+
skipReason = 'link-target';
|
|
218
|
+
} else if (kind === 'github') {
|
|
219
|
+
// "PR #475" — genuinely GitHub's number space; the bare autolink is CORRECT.
|
|
220
|
+
skipReason = 'github-namespace';
|
|
221
|
+
} else if (!kind && !ids.tasks.has(Number(num))) {
|
|
222
|
+
// No context and not a known task id — too ambiguous to touch (a bare PR
|
|
223
|
+
// ref, a future task, a numeric color). Left bare.
|
|
224
|
+
skipReason = 'not-a-task';
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Advance list state for the NEXT match regardless of this one's outcome.
|
|
228
|
+
prevEnd = matchEnd;
|
|
229
|
+
hadPrev = true;
|
|
230
|
+
prevKind = kind;
|
|
231
|
+
|
|
232
|
+
if (skipReason) {
|
|
233
|
+
stats.skipped[skipReason] = (stats.skipped[skipReason] || 0) + 1;
|
|
234
|
+
continue; // leave the match untouched; regex keeps scanning after it
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
out += segment.slice(last, start);
|
|
238
|
+
if (kind === 'idea' || kind === 'blocker') {
|
|
239
|
+
// An idea/blocker ref: link to that resolver when the id is real, else
|
|
240
|
+
// neutralize (a stale/typo'd id bare would still autolink to a GitHub 404).
|
|
241
|
+
const set = kind === 'idea' ? ids.ideas : ids.blockers;
|
|
242
|
+
if (set.has(Number(num))) {
|
|
243
|
+
const base = kind === 'idea' ? RESOLVER_BASE_IDEA : RESOLVER_BASE_BLOCKER;
|
|
244
|
+
out += `[#${num}](${base}${num})`;
|
|
245
|
+
stats[kind === 'idea' ? 'linkified_idea' : 'linkified_blocker'] =
|
|
246
|
+
(stats[kind === 'idea' ? 'linkified_idea' : 'linkified_blocker'] || 0) + 1;
|
|
247
|
+
} else {
|
|
248
|
+
out += `\`#${num}\``;
|
|
249
|
+
stats.neutralized = (stats.neutralized || 0) + 1;
|
|
250
|
+
}
|
|
251
|
+
} else if (kind === 'entity') {
|
|
252
|
+
// A different entity's id with no resolver — neutralize.
|
|
253
|
+
out += `\`#${num}\``;
|
|
254
|
+
stats.neutralized = (stats.neutralized || 0) + 1;
|
|
255
|
+
} else {
|
|
256
|
+
// A task ref (validated above).
|
|
257
|
+
out += `[#${num}](${RESOLVER_BASE}${num})`;
|
|
258
|
+
stats.linkified += 1;
|
|
259
|
+
}
|
|
260
|
+
last = matchEnd;
|
|
261
|
+
}
|
|
262
|
+
out += segment.slice(last);
|
|
263
|
+
return out;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Phase 2 (#629): upgrade a PRIOR idea/blocker NEUTRALIZATION (`#N`, emitted by
|
|
267
|
+
// an earlier run before those resolvers existed) into a proper resolver link.
|
|
268
|
+
// Operates on the rejoined line and matches ONLY the exact lone `#N` code-span
|
|
269
|
+
// token, gated on (a) idea/blocker left-context (with list-glue carry) AND (b)
|
|
270
|
+
// the id being in the matching public id set — so a legitimate code span like
|
|
271
|
+
// "the `#197` marker" (no entity noun) and an other-entity neutralization
|
|
272
|
+
// ("learning `#53`") are left untouched. Idempotent: once upgraded to a link
|
|
273
|
+
// the `#N` code span is gone, so a second pass is a no-op.
|
|
274
|
+
function upgradeLineCodeSpans(line, ids, stats) {
|
|
275
|
+
let out = '';
|
|
276
|
+
let last = 0;
|
|
277
|
+
let prevEnd = 0;
|
|
278
|
+
let hadPrev = false;
|
|
279
|
+
let prevKind = null; // only 'idea' | 'blocker' carry here
|
|
280
|
+
const re = /`#(\d{1,5})`/g;
|
|
281
|
+
let m;
|
|
282
|
+
while ((m = re.exec(line)) !== null) {
|
|
283
|
+
const num = m[1];
|
|
284
|
+
const start = m.index;
|
|
285
|
+
const matchEnd = start + m[0].length;
|
|
286
|
+
const left = line.slice(0, start);
|
|
287
|
+
const gap = line.slice(prevEnd, start);
|
|
288
|
+
const carried = hadPrev && prevKind && LIST_GLUE_RE.test(gap);
|
|
289
|
+
let kind = null;
|
|
290
|
+
if (IDEA_CTX_RE.test(left)) kind = 'idea';
|
|
291
|
+
else if (BLOCKER_CTX_RE.test(left)) kind = 'blocker';
|
|
292
|
+
else if (carried) kind = prevKind;
|
|
293
|
+
|
|
294
|
+
prevEnd = matchEnd;
|
|
295
|
+
hadPrev = true;
|
|
296
|
+
prevKind = kind === 'idea' || kind === 'blocker' ? kind : null;
|
|
297
|
+
|
|
298
|
+
if (kind === 'idea' || kind === 'blocker') {
|
|
299
|
+
const set = kind === 'idea' ? ids.ideas : ids.blockers;
|
|
300
|
+
if (set.has(Number(num))) {
|
|
301
|
+
out += line.slice(last, start);
|
|
302
|
+
const base = kind === 'idea' ? RESOLVER_BASE_IDEA : RESOLVER_BASE_BLOCKER;
|
|
303
|
+
out += `[#${num}](${base}${num})`;
|
|
304
|
+
last = matchEnd;
|
|
305
|
+
stats.upgraded = (stats.upgraded || 0) + 1;
|
|
306
|
+
}
|
|
307
|
+
// valid-set miss → leave the code span as-is (correctly still neutralized)
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
out += line.slice(last);
|
|
311
|
+
return out;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Pure: rewrite all eligible "#NNN" refs in `text`. `ids` is a Set of task ids
|
|
315
|
+
// (legacy) or {tasks, ideas, blockers}. Skips fenced code blocks and inline code
|
|
316
|
+
// spans (except the Phase-2 idea/blocker neutralization upgrade).
|
|
317
|
+
function linkifyText(text, ids, stats) {
|
|
318
|
+
ids = normalizeIdSets(ids);
|
|
319
|
+
stats = stats || { linkified: 0, skipped: {} };
|
|
320
|
+
if (!stats.skipped) stats.skipped = {};
|
|
321
|
+
const lines = text.split('\n');
|
|
322
|
+
let inFence = false;
|
|
323
|
+
const result = lines.map((line) => {
|
|
324
|
+
const fenceToggle = /^\s*(```|~~~)/.test(line);
|
|
325
|
+
if (fenceToggle) {
|
|
326
|
+
inFence = !inFence;
|
|
327
|
+
return line; // the fence line itself is never transformed
|
|
328
|
+
}
|
|
329
|
+
if (inFence) return line;
|
|
330
|
+
// Phase 1. Split on inline code spans (single backtick). Even indices are
|
|
331
|
+
// outside code, odd indices are inside — only transform the outside segments.
|
|
332
|
+
const parts = line.split('`');
|
|
333
|
+
let leftContext = '';
|
|
334
|
+
for (let k = 0; k < parts.length; k++) {
|
|
335
|
+
if (k % 2 === 1) {
|
|
336
|
+
leftContext += '`' + parts[k]; // odd index = inside a code span; never transformed
|
|
337
|
+
} else {
|
|
338
|
+
// First undo past mis-linkifications (entity refs wrongly sent to the
|
|
339
|
+
// task resolver), then classify what's left.
|
|
340
|
+
const unlinked = unlinkEntitySegment(parts[k], leftContext, stats);
|
|
341
|
+
const transformed = linkifySegment(unlinked, ids, leftContext, stats);
|
|
342
|
+
leftContext += transformed;
|
|
343
|
+
parts[k] = transformed;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// Phase 2. Upgrade pre-existing idea/blocker `#N` neutralizations to links.
|
|
347
|
+
return upgradeLineCodeSpans(parts.join('`'), ids, stats);
|
|
348
|
+
});
|
|
349
|
+
return { text: result.join('\n'), stats };
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// ---- CLI ----------------------------------------------------------------
|
|
353
|
+
|
|
354
|
+
// Token-free: the public id allow-list, so this script (and the CI gate) work
|
|
355
|
+
// with no builder session. Override the host with GDS_API_BASE for local dev.
|
|
356
|
+
async function fetchRefIds() {
|
|
357
|
+
const res = await fetch(`${API_BASE}/api/gds/public/ref-ids`);
|
|
358
|
+
if (!res.ok) throw new Error(`/public/ref-ids fetch failed (HTTP ${res.status})`);
|
|
359
|
+
const data = await res.json();
|
|
360
|
+
const toSet = (a) => new Set((a || []).map(Number).filter(Number.isInteger));
|
|
361
|
+
const tasks = toSet(data.tasks);
|
|
362
|
+
if (!tasks.size) throw new Error('no task ids returned from /public/ref-ids');
|
|
363
|
+
return { tasks, ideas: toSet(data.ideas), blockers: toSet(data.blockers) };
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function unifiedish(file, before, after) {
|
|
367
|
+
// Print only the lines that changed, with a little context — enough for a
|
|
368
|
+
// human to eyeball without drowning in a full-file diff.
|
|
369
|
+
const a = before.split('\n');
|
|
370
|
+
const b = after.split('\n');
|
|
371
|
+
const out = [];
|
|
372
|
+
for (let i = 0; i < a.length; i++) {
|
|
373
|
+
if (a[i] !== b[i]) {
|
|
374
|
+
out.push(` ${file}:${i + 1}`);
|
|
375
|
+
out.push(` - ${a[i]}`);
|
|
376
|
+
out.push(` + ${b[i]}`);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return out.join('\n');
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
async function main() {
|
|
383
|
+
const args = process.argv.slice(2);
|
|
384
|
+
const apply = args.includes('--apply');
|
|
385
|
+
const check = args.includes('--check'); // CI gate: report + non-zero exit, no writes
|
|
386
|
+
const idsArgIdx = args.indexOf('--ids');
|
|
387
|
+
let ids;
|
|
388
|
+
const files = args.filter((a, i) => !a.startsWith('--') && !(idsArgIdx >= 0 && i === idsArgIdx + 1));
|
|
389
|
+
const targets = files.length ? files : discoverDocs();
|
|
390
|
+
|
|
391
|
+
if (idsArgIdx >= 0) {
|
|
392
|
+
const tasks = new Set(String(args[idsArgIdx + 1] || '').split(',').map((s) => Number(s.trim())).filter(Number.isInteger));
|
|
393
|
+
ids = { tasks, ideas: new Set(), blockers: new Set() };
|
|
394
|
+
} else {
|
|
395
|
+
try {
|
|
396
|
+
ids = await fetchRefIds();
|
|
397
|
+
} catch (err) {
|
|
398
|
+
// Fail OPEN on infra in --check: a network blip or a not-yet-deployed
|
|
399
|
+
// endpoint must never red-X an unrelated build. Real bare refs still get
|
|
400
|
+
// caught on the next run once the id list is reachable.
|
|
401
|
+
if (check) {
|
|
402
|
+
console.warn(`⚠ skipping check — id allow-list unavailable (${err.message}).`);
|
|
403
|
+
process.exit(0);
|
|
404
|
+
}
|
|
405
|
+
throw err;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
const mode = check ? 'check (CI gate — non-zero exit if any bare/upgradeable ref remains)'
|
|
409
|
+
: apply ? 'apply (writing changes)'
|
|
410
|
+
: 'dry-run (no files written; pass --apply to write)';
|
|
411
|
+
console.log(`Linkify refs → task/idea/blocker resolvers (${ids.tasks.size} task · ${ids.ideas.size} idea · ${ids.blockers.size} blocker ids · ${targets.length} docs)`);
|
|
412
|
+
console.log(`MODE: ${mode}\n`);
|
|
413
|
+
|
|
414
|
+
const totals = { linkified: 0, linkified_idea: 0, linkified_blocker: 0, neutralized: 0, unlinked: 0, upgraded: 0, skipped: {} };
|
|
415
|
+
const offenders = [];
|
|
416
|
+
for (const rel of targets) {
|
|
417
|
+
const abs = path.resolve(process.cwd(), rel);
|
|
418
|
+
if (!fs.existsSync(abs)) {
|
|
419
|
+
console.log(` (skip — not found: ${rel})`);
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
const before = fs.readFileSync(abs, 'utf8');
|
|
423
|
+
const { text: after, stats } = linkifyText(before, ids);
|
|
424
|
+
totals.linkified += stats.linkified;
|
|
425
|
+
totals.linkified_idea += stats.linkified_idea || 0;
|
|
426
|
+
totals.linkified_blocker += stats.linkified_blocker || 0;
|
|
427
|
+
totals.neutralized += stats.neutralized || 0;
|
|
428
|
+
totals.unlinked += stats.unlinked || 0;
|
|
429
|
+
totals.upgraded += stats.upgraded || 0;
|
|
430
|
+
for (const [k, v] of Object.entries(stats.skipped)) totals.skipped[k] = (totals.skipped[k] || 0) + v;
|
|
431
|
+
if (after !== before) {
|
|
432
|
+
const changed = (stats.linkified || 0) + (stats.linkified_idea || 0) + (stats.linkified_blocker || 0) + (stats.upgraded || 0) + (stats.neutralized || 0) + (stats.unlinked || 0);
|
|
433
|
+
offenders.push({ rel, count: changed });
|
|
434
|
+
if (!check) {
|
|
435
|
+
console.log(`■ ${rel} — ${changed} change(s)`);
|
|
436
|
+
console.log(unifiedish(rel, before, after));
|
|
437
|
+
console.log('');
|
|
438
|
+
}
|
|
439
|
+
if (apply) fs.writeFileSync(abs, after);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
console.log('— summary —');
|
|
444
|
+
console.log(` docs needing rewrites: ${offenders.length}`);
|
|
445
|
+
console.log(` task refs ${apply ? 'linkified' : 'pending'}: ${totals.linkified}`);
|
|
446
|
+
console.log(` idea refs ${apply ? 'linkified' : 'pending'}: ${totals.linkified_idea}`);
|
|
447
|
+
console.log(` blocker refs ${apply ? 'linkified' : 'pending'}: ${totals.linkified_blocker}`);
|
|
448
|
+
console.log(` prior idea/blocker neutralizations ${apply ? 'upgraded' : 'to upgrade'}: ${totals.upgraded}`);
|
|
449
|
+
console.log(` entity refs ${apply ? 'neutralized' : 'to neutralize'} (code-spanned): ${totals.neutralized}`);
|
|
450
|
+
console.log(` past mis-links ${apply ? 'unwrapped' : 'to unwrap'}: ${totals.unlinked}`);
|
|
451
|
+
console.log(` skipped: ${JSON.stringify(totals.skipped)}`);
|
|
452
|
+
|
|
453
|
+
if (check && offenders.length) {
|
|
454
|
+
console.error(`\n✖ ${offenders.length} doc(s) still have a bare/upgradeable "#NNN" that mis-renders on github.com:`);
|
|
455
|
+
for (const o of offenders) console.error(` - ${o.rel} (${o.count})`);
|
|
456
|
+
console.error('\n Fix locally: node scripts/gds/linkify-refs.js --apply');
|
|
457
|
+
process.exit(1);
|
|
458
|
+
}
|
|
459
|
+
if (!apply && !check && offenders.length) console.log('\n Re-run with --apply to write these changes.');
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
if (require.main === module) {
|
|
463
|
+
main().catch((e) => {
|
|
464
|
+
console.error('ERR', e.message);
|
|
465
|
+
process.exit(1);
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
module.exports = {
|
|
470
|
+
linkifyText, linkifySegment, unlinkEntitySegment, upgradeLineCodeSpans,
|
|
471
|
+
classifyKind, normalizeIdSets, discoverDocs,
|
|
472
|
+
RESOLVER_BASE, RESOLVER_BASE_IDEA, RESOLVER_BASE_BLOCKER,
|
|
473
|
+
};
|