Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 11 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ jobs:
# exact gap let a stale env-reference block an unrelated MCP npm release, since the release
# workflow was the only place this check ever ran. Gated on `ui` too, same reason as its sibling:
# the generated UI-side file lives under apps/loopover-ui/**. Also gated on `engine`:
# DEFAULT_SOURCE_ROOTS in generate-env-reference.mjs explicitly includes
# DEFAULT_SOURCE_ROOTS in generate-env-reference.ts explicitly includes
# packages/loopover-engine/src/miner (the coding-agent driver's env vars live there, not under
# packages/loopover-miner itself), so an engine-only PR touching that directory used to skip this
# check entirely.
Expand Down Expand Up @@ -499,6 +499,16 @@ jobs:
- name: Engine package check
if: ${{ github.event_name == 'push' || needs.changes.outputs.backend == 'true' || needs.changes.outputs.engine == 'true' || needs.changes.outputs.ui == 'true' }}
run: npm run test:engine-pack
# Moved ahead of Typecheck (was originally positioned much later, alongside "Miner package check"):
# benchmark.ts and cross-repo-evaluation.ts (packages/loopover-miner/scripts/, real .ts since #9527's
# port) import from this package's OWN ../dist/lib/*.js, so Typecheck cannot resolve them until this
# has run -- the identical class of gap the contract/engine build-order comments above already
# describe, just for the miner package's own dist rather than a workspace dependency's. Trigger
# condition matches Typecheck's exactly (not just miner/engine) for the same reason those two match:
# any trigger that typechecks must also have built what typechecking reads.
- name: Build miner CLI
if: ${{ github.event_name == 'push' || needs.changes.outputs.backend == 'true' || needs.changes.outputs.engine == 'true' || needs.changes.outputs.mcp == 'true' || needs.changes.outputs.miner == 'true' }}
run: npx turbo run build:tsc build:verify --filter=@loopover/miner
# .tsbuildinfo mutates every run (tsc's own incremental state), unlike node_modules above which is
# immutable per lockfile -- so this needs the run_id-suffixed-key + restore-keys-prefix pattern (always
# creates a new cache entry to save into, restore falls back to the most recent matching prefix) rather
Expand Down Expand Up @@ -567,25 +577,6 @@ jobs:
- name: MCP package check
if: ${{ github.event_name == 'push' || needs.changes.outputs.mcp == 'true' || needs.changes.outputs.engine == 'true' }}
run: npm run test:mcp-pack
# Same "ships .ts only, this build is for the published npm tarball + the pack-check below, not for
# tests" story as MCP's own "Build MCP" step above. Invokes turbo.json's @loopover/miner#build:tsc
# (real caching win since the 2026-07-24 dist/ migration -- previously cache: false, historically to
# avoid a cache restore stomping this package's hand-written .js files while the #7290 migration was
# still in-flight; #7317 closed that out, and the dist/ split removed the original in-place-emit
# hazard entirely, so caching was finally enabled) and @loopover/miner#build:verify (real caching
# win: skips re-`node --check`-ing all bin/lib files when neither changed) DIRECTLY as their own task names,
# deliberately NOT via the aggregate `@loopover/miner#build` task (which exists for standalone/local
# `npm run build` callers) -- that aggregate's own script is `npm run build:tsc && npm run
# build:verify`, i.e. it re-invokes both of these exact scripts a second time even when turbo already
# ran them as cached prerequisite tasks (declaring a task as a dependsOn prerequisite doesn't replace
# a parent task's own script body). Calling the aggregate here would silently double both the tsc
# compile and the syntax check on every run, negating the caching win this comment describes --
# confirmed by reproducing the double execution locally before switching to this direct form. This
# also finally activates the build:tsc/build:verify split from Phase 0, which no ci.yml step
# exercised until now.
- name: Build miner CLI
if: ${{ github.event_name == 'push' || needs.changes.outputs.miner == 'true' || needs.changes.outputs.engine == 'true' }}
run: npx turbo run build:tsc build:verify --filter=@loopover/miner
# loopover-miner depends on @loopover/engine for real too (same relationship as loopover-mcp above
# -- packages/loopover-miner/package.json lists it as a dependency), so this and "Build miner CLI"
# above now also trigger on an engine-only PR, matching "Build MCP"/"MCP package check"'s existing
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-selfhost.yml
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ jobs:
attempts=5
delay_secs=10
for attempt in $(seq 1 "$attempts"); do
if node review-enrichment/scripts/validate-posthog-release.mjs; then
if node --experimental-strip-types review-enrichment/scripts/validate-posthog-release.ts; then
exit 0
fi
if [ "$attempt" -lt "$attempts" ]; then
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion apps/loopover-ui/src/lib/ams-env-reference.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated by scripts/generate-env-reference.mjs (npm run miner:env-reference). Do not edit manually.
// Generated by scripts/generate-env-reference.ts (npm run miner:env-reference). Do not edit manually.
export type MinerEnvReferenceRow = {
name: string;
firstReference: string;
Expand Down
2 changes: 1 addition & 1 deletion apps/loopover-ui/src/lib/rees-analyzers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated by review-enrichment/scripts/generate-analyzer-metadata.mjs.
// Generated by review-enrichment/scripts/generate-analyzer-metadata.ts.
// Do not edit by hand; update review-enrichment analyzer descriptors instead.

export type ReesProfileName = "fast" | "balanced" | "deep";
Expand Down
2 changes: 1 addition & 1 deletion control-plane/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"cf:dev": "wrangler dev",
"cf:deploy": "wrangler deploy",
"cf:typecheck": "tsc -p tsconfig.worker.json --noEmit",
"cf:typegen": "node scripts/gen-cf-typegen.mjs"
"cf:typegen": "node --experimental-strip-types scripts/gen-cf-typegen.ts"
},
"dependencies": {
"@cloudflare/containers": "^0.3.7",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// Regenerates worker-configuration.d.ts from wrangler.jsonc and strips trailing whitespace -- wrangler's
// raw `wrangler types` output has trailing whitespace on several lines, which fails this repo's own
// `git diff --check` whitespace gate the moment it's committed (mirrors
// packages/discovery-index/scripts/gen-cf-typegen.mjs, found the hard way on that package's own #7167/#4250
// PR). Simpler than the root repo's scripts/gen-cf-typegen.mjs: this package's Env has no `vars`-derived
// packages/discovery-index/scripts/gen-cf-typegen.ts, found the hard way on that package's own #7167/#4250
// PR). Simpler than the root repo's scripts/gen-cf-typegen.ts: this package's Env has no `vars`-derived
// Pick<Cloudflare.Env, ...> union to reformat (only a KV binding + ambient-declared secrets), so only the
// whitespace-stripping half of that script's job applies here.
import { execFileSync } from "node:child_process";
Expand Down
2 changes: 1 addition & 1 deletion control-plane/src/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// driver-factory.ts) into the plain, already-tested Hono app (http-app.ts). Adds NO route logic of its own.
//
// Not unit-tested: exercised only by real Cloudflare Workers/KV/Containers infrastructure, matching
// packages/discovery-index/src/worker.ts's own identical exclusion (see scripts/control-plane-coverage.mjs).
// packages/discovery-index/src/worker.ts's own identical exclusion (see scripts/control-plane-coverage.ts).
import { Container } from "@cloudflare/containers";
import { wakeDueAmsTenants } from "./ams-wake.js";
import { createTenantProvisioningDriver } from "./driver-factory.js";
Expand Down
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
"selfhost:postgres:migrate": "tsx scripts/migrate-selfhost-sqlite-to-postgres.ts",
"selfhost:env-reference": "node --experimental-strip-types scripts/gen-selfhost-env-reference.ts",
"selfhost:env-reference:check": "node --experimental-strip-types scripts/gen-selfhost-env-reference.ts --check",
"miner:env-reference": "tsx packages/loopover-miner/scripts/generate-env-reference.mjs",
"miner:env-reference:check": "tsx packages/loopover-miner/scripts/generate-env-reference.mjs --check",
"benchmark:miner": "node packages/loopover-miner/scripts/benchmark.mjs",
"cross-repo-eval:miner": "node packages/loopover-miner/scripts/cross-repo-evaluation.mjs",
"loadtest:iterate-loop": "npm run build --workspace @loopover/engine && node packages/loopover-engine/scripts/load-test-iterate-loop.mjs",
"miner:env-reference": "tsx packages/loopover-miner/scripts/generate-env-reference.ts",
"miner:env-reference:check": "tsx packages/loopover-miner/scripts/generate-env-reference.ts --check",
"benchmark:miner": "node --experimental-strip-types packages/loopover-miner/scripts/benchmark.ts",
"cross-repo-eval:miner": "node --experimental-strip-types packages/loopover-miner/scripts/cross-repo-evaluation.ts",
"loadtest:iterate-loop": "npm run build --workspace @loopover/engine && node --experimental-strip-types packages/loopover-engine/scripts/load-test-iterate-loop.ts",
"loadtest:worker": "node --experimental-strip-types scripts/load-test-worker.ts",
"command-reference": "node --experimental-strip-types scripts/gen-command-reference.ts",
"command-reference:check": "node --experimental-strip-types scripts/gen-command-reference.ts --check",
Expand All @@ -47,7 +47,7 @@
"rees:coverage": "node --experimental-strip-types scripts/rees-coverage.ts",
"control-plane:install": "npm ci --prefix control-plane --prefer-offline --no-audit --no-fund",
"control-plane:test": "npm run control-plane:install && npm --prefix control-plane test",
"control-plane:coverage": "node scripts/control-plane-coverage.mjs",
"control-plane:coverage": "node --experimental-strip-types scripts/control-plane-coverage.ts",
"engine:coverage": "node --experimental-strip-types scripts/engine-coverage.ts",
"db:migrations:check": "tsx scripts/check-migrations.ts",
"db:schema-drift:check": "tsx scripts/check-schema-drift.ts",
Expand All @@ -69,6 +69,7 @@
"ui:version-audit:sync": "node --experimental-strip-types scripts/check-ui-mcp-version-copy.ts --write",
"docs:drift-check": "node --experimental-strip-types scripts/check-docs-drift.ts",
"coverage-boltons:check": "node --experimental-strip-types scripts/check-coverage-bolt-on-filenames.ts",
"validate:no-hand-written-js": "node --experimental-strip-types scripts/validate-no-hand-written-js.ts",
"import-specifiers:check": "node --experimental-strip-types scripts/check-import-specifiers.ts",
"dead-source-files:check": "node --experimental-strip-types scripts/check-dead-source-files.ts",
"replay-runner-manifest": "tsx scripts/replay-runner-image-manifest.ts",
Expand Down Expand Up @@ -115,7 +116,7 @@
"test:smoke:browser:install": "playwright install chromium",
"test:smoke:browser": "node --experimental-strip-types scripts/smoke-ui-browser.ts",
"pretest:ci": "npm run check-node-version",
"test:ci": "git diff --check && npm run actionlint && npm run lint:composite-actions && npm run db:migrations:check && npm run db:schema-drift:check && npm run selfhost:env-reference:check && npm run miner:env-reference:check && npm run selfhost:validate-observability && npm run cf-typegen:check && npm run build --workspace @loopover/engine && npm run build --workspace @loopover/discovery-index && npm run build:mcp && npm run build:miner && npm run build --workspace @loopover/ui-kit && npm run typecheck && npm run test:coverage && npm run test:engine-parity && npm run test:live-gate-parity && npm run test:driver-parity && npm run test --workspace @loopover/engine && npm run test:workers && npm run test:mcp-pack && npm run test:miner-pack && npm run test:engine-pack && npm run test:ui-kit-pack && npm run test:miner-deployment-docs-audit && npm run rees:test && npm run ui:openapi:check && npm run ui:openapi:settings-parity && npm run ui:version-audit && npm run docs:drift-check && npm run coverage-boltons:check && npm run import-specifiers:check && npm run dead-source-files:check && npm run replay-runner-manifest:check && npm run coco-dev-versions:check && npm run branding-drift:check && npm run manifest:drift-check && npm run engine-parity:drift-check && npm run engines-nvmrc:check && npm run release-manifest:sync:check && npm run command-reference:check && npm run ui:lint && npm run ui:typecheck && npm run ui:test && npm run ui:build",
"test:ci": "git diff --check && npm run actionlint && npm run lint:composite-actions && npm run db:migrations:check && npm run db:schema-drift:check && npm run selfhost:env-reference:check && npm run miner:env-reference:check && npm run selfhost:validate-observability && npm run cf-typegen:check && npm run build --workspace @loopover/engine && npm run build --workspace @loopover/discovery-index && npm run build:mcp && npm run build:miner && npm run build --workspace @loopover/ui-kit && npm run typecheck && npm run test:coverage && npm run test:engine-parity && npm run test:live-gate-parity && npm run test:driver-parity && npm run test --workspace @loopover/engine && npm run test:workers && npm run test:mcp-pack && npm run test:miner-pack && npm run test:engine-pack && npm run test:ui-kit-pack && npm run test:miner-deployment-docs-audit && npm run rees:test && npm run ui:openapi:check && npm run ui:openapi:settings-parity && npm run ui:version-audit && npm run docs:drift-check && npm run coverage-boltons:check && npm run import-specifiers:check && npm run dead-source-files:check && npm run validate:no-hand-written-js && npm run replay-runner-manifest:check && npm run coco-dev-versions:check && npm run branding-drift:check && npm run manifest:drift-check && npm run engine-parity:drift-check && npm run engines-nvmrc:check && npm run release-manifest:sync:check && npm run command-reference:check && npm run ui:lint && npm run ui:typecheck && npm run ui:test && npm run ui:build",
"test:release": "npm run test:ci && npm run changelog:check",
"test:release:mcp": "npm run test:ci",
"test:watch": "vitest",
Expand Down
2 changes: 1 addition & 1 deletion packages/discovery-index/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Soft-claim design note: the shipped client payload never carries caller identity

Runtime errors (route handler failures, unhandled rejections/exceptions) report into PostHog. See `src/posthog.ts` for the full redaction rules (secret-named fields and GitHub-token-shaped values are always filtered before anything leaves the process) and `OPERATIONS.md`'s Monitoring section for how this fits alongside `/metrics`. This surface previously reported into the shared `metagraphed` Sentry project (`jsonbored` org) that this repo's other infra/operational pieces flow into -- a genuine cross-project entanglement -- until #8289 replaced it outright.

Source maps and release tracking are handled by `src/upload-sourcemaps.ts`, which runs as the **first step of the container's runtime `CMD`** (not at Docker build time — `POSTHOG_CLI_API_KEY` is a runtime-only secret, never baked into an image layer): it injects PostHog chunk ids, uploads the exact post-injection source maps, then verifies at least one symbol set exists for the release via `scripts/validate-posthog-release.mjs` (queries PostHog's `error_tracking/symbol_sets` API — PostHog's release model has no equivalent of Sentry's commits/deploys/finalize lifecycle, so this is a narrower check by design), before deleting the `.map` files it just uploaded and starting `server.ts`. Any step failing is non-fatal to the boot unless `DISCOVERY_INDEX_POSTHOG_UPLOAD_STRICT=true` is set. `posthog-cli sourcemap inject`/`upload` run with an explicit `--release-version` (not the CLI's own git-metadata auto-detection — the Docker build stage never copies `.git` into the image).
Source maps and release tracking are handled by `src/upload-sourcemaps.ts`, which runs as the **first step of the container's runtime `CMD`** (not at Docker build time — `POSTHOG_CLI_API_KEY` is a runtime-only secret, never baked into an image layer): it injects PostHog chunk ids, uploads the exact post-injection source maps, then verifies at least one symbol set exists for the release via `scripts/validate-posthog-release.ts` (queries PostHog's `error_tracking/symbol_sets` API — PostHog's release model has no equivalent of Sentry's commits/deploys/finalize lifecycle, so this is a narrower check by design), before deleting the `.map` files it just uploaded and starting `server.ts`. Any step failing is non-fatal to the boot unless `DISCOVERY_INDEX_POSTHOG_UPLOAD_STRICT=true` is set. `posthog-cli sourcemap inject`/`upload` run with an explicit `--release-version` (not the CLI's own git-metadata auto-detection — the Docker build stage never copies `.git` into the image).

## Deployment

Expand Down
4 changes: 2 additions & 2 deletions packages/discovery-index/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
},
"scripts": {
"build": "tsc -p tsconfig.json",
"validate:sourcemaps": "node scripts/validate-sourcemaps.mjs",
"validate:sourcemaps": "node --experimental-strip-types scripts/validate-sourcemaps.ts",
"start": "node dist/server.js",
"dev": "node --experimental-strip-types --watch src/server.ts",
"cf:dev": "wrangler dev",
"cf:deploy": "wrangler deploy",
"cf:typecheck": "tsc -p tsconfig.worker.json --noEmit",
"cf:typegen": "node scripts/gen-cf-typegen.mjs"
"cf:typegen": "node --experimental-strip-types scripts/gen-cf-typegen.ts"
},
"dependencies": {
"@cloudflare/containers": "^0.3.7",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Regenerates worker-configuration.d.ts from wrangler.jsonc and strips trailing whitespace -- wrangler's
// raw `wrangler types` output has trailing whitespace on several lines, which fails this repo's own
// `git diff --check` whitespace gate the moment it's committed (found the hard way on #7167/#4250's PR).
// Simpler than the root repo's scripts/gen-cf-typegen.mjs: this package's Env has no `vars`-derived
// Simpler than the root repo's scripts/gen-cf-typegen.ts: this package's Env has no `vars`-derived
// Pick<Cloudflare.Env, ...> union to reformat (only Durable Object bindings + ambient-declared secrets),
// so only the whitespace-stripping half of that script's job applies here.
import { execFileSync } from "node:child_process";
Expand Down
Loading
Loading