Files
wehub-resource-sync 426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:43:05 +08:00

200 lines
6.3 KiB
JavaScript

/**
* Test registry for the console: the discovered run-all-tests task plan,
* joined with the guarded live-suite manifest and the connection catalog.
*
* Nothing here re-derives what committed sources of truth already know. The
* task list is `run-all-tests.mjs --plan=json --all` verbatim; live gating is
* `GUARDED_REAL_LIVE_SUITES` + `computeRealLiveAccounting` from
* packages/scripts/lib/real-live-suites.mjs (the same accounting the
* post-merge lane prints); connection ownership comes from connections.mjs.
* The join key is the repo-relative directory: a guarded suite belongs to the
* plan task whose `relativeDir` prefixes its path.
*/
import { spawnSync } from "node:child_process";
import path from "node:path";
import { fileURLToPath } from "node:url";
import {
computeRealLiveAccounting,
GUARDED_REAL_LIVE_SUITES,
} from "../../lib/real-live-suites.mjs";
import {
CONNECTIONS,
connectionStatus,
OPT_IN_GATES,
varOwnership,
} from "./connections.mjs";
const here = path.dirname(fileURLToPath(import.meta.url));
export const REPO_ROOT = path.resolve(here, "..", "..", "..", "..");
let cachedPlan = null;
/** Discover the full task plan (cached per process; ~1s cold). */
export function discoverPlan({ force = false } = {}) {
if (cachedPlan && !force) return cachedPlan;
const result = spawnSync(
process.execPath,
[
path.join(REPO_ROOT, "packages/scripts/run-all-tests.mjs"),
"--plan=json",
"--all",
],
{ cwd: REPO_ROOT, encoding: "utf8", maxBuffer: 64 * 1024 * 1024 },
);
if (result.status !== 0) {
throw new Error(
`plan discovery failed (exit ${result.status}): ${result.stderr?.slice(0, 2000)}`,
);
}
cachedPlan = JSON.parse(result.stdout);
return cachedPlan;
}
/**
* Effective env for gating decisions: ambient process env, overlaid with the
* operator's saved credentials and opt-in toggles. Saved values win so the
* console UI always reflects what a console-launched run would actually use.
*/
export function effectiveEnv(savedEnv, optInToggles = {}) {
const env = { ...process.env, ...savedEnv };
for (const [gate, on] of Object.entries(optInToggles)) {
if (on) env[gate] = "1";
else delete env[gate];
}
return env;
}
function suiteStatusIndex(env) {
const accounting = computeRealLiveAccounting(env);
const byFile = new Map();
for (const s of accounting.armed)
byFile.set(s.file, { state: "armed", notes: s.notes });
for (const s of accounting.probed)
byFile.set(s.file, { state: "probe", probe: s.probe });
for (const s of accounting.optIn)
byFile.set(s.file, { state: "opt-in", gate: s.gate });
for (const s of accounting.missingCreds)
byFile.set(s.file, { state: "missing-creds", missing: s.missing });
for (const s of accounting.blocked)
byFile.set(s.file, { state: "blocked", reason: s.reason });
return byFile;
}
/** Which connections own each missing var (for "configure X to enable"). */
function missingToConnections(missing, owners) {
const ids = new Set();
for (const key of missing ?? []) {
for (const id of owners.get(key) ?? []) ids.add(id);
}
return [...ids];
}
/**
* Build the full console state: tasks annotated with their guarded live
* suites, connection statuses, and the opt-in gate toggles.
*/
export function buildRegistry({
savedCredentials = {},
optInToggles = {},
history = {},
}) {
const plan = discoverPlan();
const owners = varOwnership();
const savedEnv = {};
for (const values of Object.values(savedCredentials)) {
Object.assign(savedEnv, values);
}
const env = effectiveEnv(savedEnv, optInToggles);
const suiteIndex = suiteStatusIndex(env);
// Attach each guarded suite to the deepest plan task dir that contains it.
const tasksByDir = [...plan.tasks].sort(
(a, b) => b.relativeDir.length - a.relativeDir.length,
);
const suitesByTaskLabel = new Map();
const orphanSuites = [];
for (const entry of GUARDED_REAL_LIVE_SUITES) {
const status = suiteIndex.get(entry.file) ?? { state: "unknown" };
const owner = tasksByDir.find((t) =>
entry.file.startsWith(`${t.relativeDir}/`),
);
const annotated = {
file: entry.file,
...status,
requires: entry.requires ?? [],
anyOf: entry.anyOf ?? [],
optIn: entry.optIn,
connections: missingToConnections(
status.state === "missing-creds"
? status.missing
: [...(entry.requires ?? []), ...(entry.anyOf ?? []).flat()],
owners,
),
};
if (owner) {
const list = suitesByTaskLabel.get(owner.label) ?? [];
list.push(annotated);
suitesByTaskLabel.set(owner.label, list);
} else {
orphanSuites.push(annotated);
}
}
const tasks = plan.tasks.map((task) => ({
...task,
liveSuites: suitesByTaskLabel.get(task.label) ?? [],
last: history[task.label] ?? null,
}));
const connections = CONNECTIONS.map((connection) => {
const saved = savedCredentials[connection.id] ?? {};
const { configured, missing } = connectionStatus(connection, saved);
// Count what this connection unlocks so the UI can rank setup impact.
const unlocks = GUARDED_REAL_LIVE_SUITES.filter((entry) => {
const needed = [...(entry.requires ?? []), ...(entry.anyOf ?? []).flat()];
return needed.some((key) => connection.fields.some((f) => f.key === key));
}).length;
return {
id: connection.id,
label: connection.label,
category: connection.category,
kind: connection.kind,
obtain: connection.obtain,
oauth: connection.oauth ?? null,
fields: connection.fields.map((f) => ({
...f,
// Never ship raw secrets to the browser — presence + suffix only.
set: Boolean((saved[f.key] ?? process.env[f.key] ?? "").trim()),
hint: maskValue(saved[f.key] ?? process.env[f.key] ?? ""),
})),
configured,
missing,
unlocks,
};
});
return {
summary: plan.summary,
tasks,
orphanSuites,
connections,
optInGates: OPT_IN_GATES.map((gate) => ({
...gate,
on:
Boolean(optInToggles[gate.key]) ||
(process.env[gate.key] ?? "") === "1",
})),
cloudStep: plan.cloudStep,
};
}
function maskValue(value) {
const trimmed = (value ?? "").trim();
if (!trimmed) return "";
if (trimmed.length <= 8) return "•••";
return `…${trimmed.slice(-4)}`;
}