mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 02:06:43 +00:00
chore(tooling): typecheck root test/** with a dedicated tsgo lane (#104475)
* chore(types): add declaration files for scripts/lib and scripts/e2e modules
* chore(types): add declaration files for top-level script modules (a-m)
* chore(types): add declaration files for top-level script modules (n-z)
* test: use a non-secret-shaped gateway token fixture
* test: type ci workflow guard helpers for the root test lane
* chore(tooling): typecheck root test/** with a dedicated tsgo lane
- test/tsconfig/tsconfig.test.root.json: root-test program (strict unused checks,
fixtures excluded; two Docker E2E clients that import built dist/** stay out,
same rationale as the scripts/e2e exclusion in tsconfig.scripts.json)
- tsgo:test:root wired into tsgo:test, check:test-types, scripts/check.mjs, and
the ci.yml test-types shard, mirroring the tsgo:scripts lane (#104348)
- changed-lane routing: test/**/*.ts (excluding fixtures) and the lane tsconfig
now trigger 'typecheck test root' in check:changed; previously test/ paths ran
lint only, so harness type errors surfaced first in CI (#104287 envDir case)
- burn down all 1071 latent type errors in the program: precise param/local
types across test/scripts, test/vitest, test/e2e, and transitive scripts/e2e
program members; 205 sibling .d.mts declaration files for imported .mjs
modules (committed separately); zero any, zero ts-expect-error
- resolve the pre-existing testing star-export ambiguity in
scripts/e2e/parallels/common.ts with an explicit re-export
Closes #104388
* chore(types): correct declaration fidelity per structured review
- re-derive 51 .d.mts files from implementation data flow instead of
initializers: fix a wrong never return (runTestProjectsDelegation returns
the child), add encoding-sensitive exec/spawn overloads (plain-gh), restore
the full release profile union, make parsed paths string | null, add missing
parseArgs fields via help/non-help unions, add a missing sibling declaration
(budget-number-args), drop 15 unused lint directives
- precise install-record/tuple typing removes the type-aware oxlint
regressions the first declarations caused in scripts/e2e implementations
- route .mts declaration edits under test/ to the testRoot lane and reference
the test-root project from tsconfig.projects.json so tsgo:all covers it
(closes both review findings against the lane wiring)
* chore(scripts): keep telegram runner dist typing structural for the boundary guard
* chore(types): declare runtime pack and gateway readiness exports added on main
* test: pin the importTargetPlan form of the plugin-contract plan import
The guard expectation still referenced the raw await import( form that
7ae5996bb3 (#103975) replaced with the importTargetPlan fallback helper;
the assertion fails on current main.
This commit is contained in:
@@ -1472,6 +1472,12 @@ jobs:
|
||||
echo "Current CI targets must provide the tsgo:scripts package script." >&2
|
||||
exit 1
|
||||
fi
|
||||
if pnpm run --silent 2>/dev/null | grep -q '^ tsgo:test:root$'; then
|
||||
pnpm tsgo:test:root
|
||||
elif [[ "$HISTORICAL_TARGET" != "true" ]]; then
|
||||
echo "Current CI targets must provide the tsgo:test:root package script." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported check task: $TASK" >&2
|
||||
|
||||
+2
-1
@@ -1963,9 +1963,10 @@
|
||||
"tsgo:prod": "pnpm tsgo:core && pnpm tsgo:extensions",
|
||||
"tsgo:profile": "node scripts/profile-tsgo.mjs",
|
||||
"tsgo:scripts": "node scripts/run-tsgo.mjs -p tsconfig.scripts.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/scripts.tsbuildinfo",
|
||||
"tsgo:test": "pnpm tsgo:core:test && pnpm tsgo:extensions:test",
|
||||
"tsgo:test": "pnpm tsgo:core:test && pnpm tsgo:extensions:test && pnpm tsgo:test:root",
|
||||
"tsgo:test:extensions": "pnpm tsgo:extensions:test",
|
||||
"tsgo:test:packages": "node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.test.packages.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/test-packages.tsbuildinfo",
|
||||
"tsgo:test:root": "node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.test.root.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/test-root.tsbuildinfo",
|
||||
"tsgo:test:src": "node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.test.src.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/test-src.tsbuildinfo",
|
||||
"tsgo:test:ui": "node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.test.ui.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/test-ui.tsbuildinfo",
|
||||
"tui": "node scripts/run-node.mjs tui",
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env node
|
||||
export function describeSeamKinds(relativePath: unknown, source: unknown): string[];
|
||||
export function determineSeamTestStatus(
|
||||
seamKinds: unknown,
|
||||
relatedTestMatches: unknown,
|
||||
): {
|
||||
status: string;
|
||||
reason: string;
|
||||
};
|
||||
export function main(argv?: string[]): Promise<void>;
|
||||
export const HELP_TEXT: "Usage: node scripts/audit-seams.mjs [--help]\n\nAudit repo seam inventory and emit JSON to stdout.\n\nSections:\n duplicatedSeamFamilies Plugin SDK seam families imported from multiple production files\n overlapFiles Production files that touch multiple seam families\n optionalClusterStaticLeaks Optional extension/plugin clusters referenced from the static graph\n missingPackages Workspace packages whose deps are not mirrored at the root\n seamTestInventory High-signal seam candidates with nearby-test gap signals,\n including cron orchestration seams for agent handoff,\n outbound/media delivery, heartbeat/followup handoff,\n and scheduler state crossings, plus subagent seams\n for spawn/session handoff, announce delivery,\n lifecycle registry, cleanup, and parent streaming\n\nNotes:\n - Output is JSON only.\n - For clean redirected JSON through package scripts, prefer:\n pnpm --silent audit:seams > seam-inventory.json\n";
|
||||
@@ -0,0 +1,24 @@
|
||||
export function parseArgs(argv: unknown): {
|
||||
maxWorkers?: unknown;
|
||||
cwd: string;
|
||||
mode: unknown;
|
||||
ref: unknown;
|
||||
rss: unknown;
|
||||
};
|
||||
export function parseMaxRssBytes(output: unknown): number | null;
|
||||
export function formatRss(valueBytes: unknown): string;
|
||||
export function resolveBenchRssResult({
|
||||
label,
|
||||
output,
|
||||
rss,
|
||||
status,
|
||||
}: {
|
||||
label: unknown;
|
||||
output: unknown;
|
||||
rss: unknown;
|
||||
status: unknown;
|
||||
}): {
|
||||
maxRssBytes: number | null;
|
||||
output: unknown;
|
||||
status: unknown;
|
||||
};
|
||||
@@ -0,0 +1,92 @@
|
||||
import type fs from "node:fs";
|
||||
|
||||
export type BuildCacheEntry =
|
||||
| string
|
||||
| {
|
||||
path: string;
|
||||
extensions?: string[];
|
||||
recursive?: boolean;
|
||||
};
|
||||
|
||||
export type BuildAllStep = {
|
||||
label: string;
|
||||
kind?: "node" | "pnpm";
|
||||
args?: string[];
|
||||
pnpmArgs?: string[];
|
||||
env?: NodeJS.ProcessEnv;
|
||||
windowsNodeOptions?: string;
|
||||
cache?: {
|
||||
env?: string[];
|
||||
inputs: BuildCacheEntry[];
|
||||
outputs: BuildCacheEntry[];
|
||||
restore?: "always";
|
||||
};
|
||||
};
|
||||
|
||||
export type BuildAllCacheState = {
|
||||
cacheable: boolean;
|
||||
fresh: boolean;
|
||||
restorable?: boolean;
|
||||
reason: string;
|
||||
signature?: string;
|
||||
outputRoot?: string;
|
||||
stampPath?: string;
|
||||
inputFiles?: number;
|
||||
outputFiles?: number;
|
||||
relativeOutputFiles?: string[];
|
||||
stampedOutputs?: string[];
|
||||
};
|
||||
|
||||
export const BUILD_ALL_STEPS: BuildAllStep[];
|
||||
export const BUILD_ALL_PROFILES: Record<string, string[]>;
|
||||
export const BUILD_ALL_PROFILE_STEP_ENV: Record<string, Record<string, NodeJS.ProcessEnv>>;
|
||||
|
||||
export function buildAllUsage(): string;
|
||||
export function parseBuildAllArgs(argv: string[]): { help: boolean; profile: string };
|
||||
export function resolveBuildAllSteps(profile?: string): BuildAllStep[];
|
||||
export function resolveBuildAllEnvironment(
|
||||
env?: NodeJS.ProcessEnv,
|
||||
now?: () => Date,
|
||||
readGitCommit?: () => string | null,
|
||||
): { [key: string]: string | undefined; OPENCLAW_BUILD_TIMESTAMP: string };
|
||||
export function resolveBuildAllStep(
|
||||
step: BuildAllStep,
|
||||
params?: {
|
||||
platform?: NodeJS.Platform;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
nodeExecPath?: string;
|
||||
npmExecPath?: string;
|
||||
comSpec?: string;
|
||||
},
|
||||
): {
|
||||
command: string;
|
||||
args: string[];
|
||||
options: {
|
||||
stdio: "inherit";
|
||||
env: NodeJS.ProcessEnv;
|
||||
shell?: boolean;
|
||||
windowsVerbatimArguments?: boolean;
|
||||
};
|
||||
};
|
||||
export function resolveBuildAllStepCacheState(
|
||||
step: BuildAllStep,
|
||||
params?: { rootDir?: string; fs?: typeof fs; env?: NodeJS.ProcessEnv },
|
||||
): BuildAllCacheState;
|
||||
export function writeBuildAllStepCacheStamp(
|
||||
step: BuildAllStep,
|
||||
cacheState: BuildAllCacheState,
|
||||
params?: { rootDir?: string; fs?: typeof fs },
|
||||
): void;
|
||||
export function resolveBuildAllStepCacheStampState(
|
||||
step: BuildAllStep,
|
||||
cacheState: BuildAllCacheState,
|
||||
params?: { rootDir?: string; fs?: typeof fs },
|
||||
): BuildAllCacheState;
|
||||
export function restoreBuildAllStepCacheOutputs(
|
||||
cacheState: BuildAllCacheState,
|
||||
params?: { rootDir?: string; fs?: typeof fs },
|
||||
): boolean;
|
||||
export function formatBuildAllDuration(durationMs: number): string;
|
||||
export function formatBuildAllTimingSummary(
|
||||
timings: Array<{ label: string; durationMs: number; status: string }>,
|
||||
): string;
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Creates the esbuild plugin that neutralizes Pierre diffs' browser side-effect import.
|
||||
*/
|
||||
export function createPierreDiffsSideEffectImportPlugin(): {
|
||||
name: string;
|
||||
setup(buildContext: unknown): void;
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Reads bundled plugin asset hook commands for a build or copy phase.
|
||||
*/
|
||||
export function readBundledPluginAssetHooks(options?: Record<string, unknown>): Promise<
|
||||
{
|
||||
aliases: string[];
|
||||
command: string;
|
||||
packageName: unknown;
|
||||
phase: unknown;
|
||||
pluginDir: string;
|
||||
pluginId: string;
|
||||
}[]
|
||||
>;
|
||||
/**
|
||||
* Runs bundled plugin asset hook commands for the selected phase/plugins.
|
||||
*/
|
||||
export function runBundledPluginAssetHooks(options?: Record<string, unknown>): Promise<void>;
|
||||
/**
|
||||
* Parses `--phase` and repeated `--plugin` flags for asset hook scripts.
|
||||
*/
|
||||
export function parseBundledPluginAssetArgs(argv: unknown): {
|
||||
phase: unknown;
|
||||
plugins: unknown[];
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
export type ChangedLane =
|
||||
| "core"
|
||||
| "coreTests"
|
||||
| "extensions"
|
||||
| "extensionTests"
|
||||
| "scripts"
|
||||
| "testRoot"
|
||||
| "apps"
|
||||
| "docs"
|
||||
| "tooling"
|
||||
| "liveDockerTooling"
|
||||
| "releaseMetadata"
|
||||
| "all";
|
||||
|
||||
export type ChangedLanes = Record<ChangedLane, boolean>;
|
||||
|
||||
export type ChangedLaneResult = {
|
||||
paths: string[];
|
||||
lanes: ChangedLanes;
|
||||
extensionImpactFromCore: boolean;
|
||||
docsOnly: boolean;
|
||||
reasons: string[];
|
||||
};
|
||||
|
||||
export type DetectChangedLanesOptions = {
|
||||
packageJsonChangeKind?: "liveDockerTooling" | "tooling" | null;
|
||||
};
|
||||
|
||||
export function normalizeChangedPath(inputPath: unknown): string;
|
||||
export function createEmptyChangedLanes(): ChangedLanes;
|
||||
export function isChangedLaneTestPath(changedPath: string): boolean;
|
||||
export function detectChangedLanes(
|
||||
changedPaths: string[],
|
||||
options?: DetectChangedLanesOptions,
|
||||
): ChangedLaneResult;
|
||||
export function detectChangedLanesForPaths(params: {
|
||||
paths: string[];
|
||||
base: string;
|
||||
head?: string;
|
||||
staged?: boolean;
|
||||
mergeHeadFirstParent?: boolean;
|
||||
}): ChangedLaneResult;
|
||||
export function listChangedPathsFromGit(params: {
|
||||
base: string;
|
||||
head?: string;
|
||||
includeWorktree?: boolean;
|
||||
cwd?: string;
|
||||
mergeHeadFirstParent?: boolean;
|
||||
}): string[];
|
||||
export function listStagedChangedPaths(cwd?: string): string[];
|
||||
export function isLiveDockerPackageScriptOnlyChange(before: string, after: string): boolean;
|
||||
export function isPackageScriptOnlyChange(before: string, after: string): boolean;
|
||||
|
||||
export const LIVE_DOCKER_AUTH_SHELL_TARGETS: string[];
|
||||
export const RELEASE_METADATA_PATHS: Set<string>;
|
||||
@@ -15,6 +15,8 @@ const EXTENSION_PATH_RE = /^extensions\/[^/]+(?:\/|$)/u;
|
||||
const CORE_PATH_RE = /^(?:src\/|ui\/|packages\/)/u;
|
||||
const SCRIPTS_TYPECHECK_PATH_RE =
|
||||
/^(?:scripts\/.*\.(?:[cm]?ts|[cm]?tsx)|tsconfig\.scripts\.json)$/u;
|
||||
const TEST_ROOT_TYPECHECK_PATH_RE =
|
||||
/^(?:test\/(?!fixtures\/).*\.(?:[cm]?ts|[cm]?tsx)|test\/tsconfig\/tsconfig\.test\.root\.json)$/u;
|
||||
const TOOLING_PATH_RE =
|
||||
/^(?:scripts\/|test\/vitest\/|\.github\/|\.vscode\/|config\/|deploy\/|git-hooks\/|Dockerfile\.sandbox(?:-(?:browser|common))?$|Makefile$|docker-setup\.sh$|setup-podman\.sh$|openclaw\.podman\.env$|skills\/pyproject\.toml$|vitest(?:\..+)?\.config\.ts$|tsconfig.*\.json$|\.dockerignore$|\.gitignore$|\.jscpd\.json$|\.npmignore$|\.pre-commit-config\.yaml$|\.swiftformat$|\.swiftlint\.yml$|\.oxlint.*|\.oxfmt.*)/u;
|
||||
const ROOT_GLOBAL_PATH_RE =
|
||||
@@ -56,7 +58,7 @@ export const RELEASE_METADATA_PATHS = new Set([
|
||||
"package.json",
|
||||
]);
|
||||
|
||||
/** @typedef {"core" | "coreTests" | "extensions" | "extensionTests" | "scripts" | "apps" | "docs" | "tooling" | "liveDockerTooling" | "releaseMetadata" | "all"} ChangedLane */
|
||||
/** @typedef {"core" | "coreTests" | "extensions" | "extensionTests" | "scripts" | "testRoot" | "apps" | "docs" | "tooling" | "liveDockerTooling" | "releaseMetadata" | "all"} ChangedLane */
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
@@ -88,6 +90,7 @@ export function createEmptyChangedLanes() {
|
||||
extensions: false,
|
||||
extensionTests: false,
|
||||
scripts: false,
|
||||
testRoot: false,
|
||||
apps: false,
|
||||
docs: false,
|
||||
tooling: false,
|
||||
@@ -145,6 +148,9 @@ export function detectChangedLanes(changedPaths, options = {}) {
|
||||
if (SCRIPTS_TYPECHECK_PATH_RE.test(changedPath)) {
|
||||
lanes.scripts = true;
|
||||
}
|
||||
if (TEST_ROOT_TYPECHECK_PATH_RE.test(changedPath)) {
|
||||
lanes.testRoot = true;
|
||||
}
|
||||
|
||||
if (DOCS_PATH_RE.test(changedPath)) {
|
||||
lanes.docs = true;
|
||||
@@ -299,12 +305,14 @@ export function listChangedPathsFromGit(params) {
|
||||
let rangePaths;
|
||||
let noMergeBase = false;
|
||||
try {
|
||||
// oxlint-disable-next-line typescript/no-base-to-string, typescript/restrict-template-expressions -- resolveMergeHeadDiffBase returns a git ref string when present.
|
||||
rangePaths = runGitNameOnlyDiff([`${base}...${head}`], cwd);
|
||||
} catch (error) {
|
||||
if (!isGitNoMergeBaseError(error)) {
|
||||
throw error;
|
||||
}
|
||||
noMergeBase = true;
|
||||
// oxlint-disable-next-line typescript/no-base-to-string, typescript/restrict-template-expressions -- resolveMergeHeadDiffBase returns a git ref string when present.
|
||||
rangePaths = runGitNameOnlyDiff([`${base}..${head}`], cwd);
|
||||
}
|
||||
if (params.includeWorktree === false) {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Collects architecture smell findings from the configured source roots.
|
||||
*/
|
||||
export function collectArchitectureSmells(): Promise<
|
||||
Array<{
|
||||
category: string;
|
||||
file: string;
|
||||
line: number;
|
||||
kind: string;
|
||||
specifier: string;
|
||||
reason: string;
|
||||
}>
|
||||
>;
|
||||
/**
|
||||
* Runs the architecture smell check and writes human/JSON output.
|
||||
*/
|
||||
export function main(argv: unknown, io: unknown): Promise<number>;
|
||||
@@ -0,0 +1,69 @@
|
||||
import type { ChangedLaneResult } from "./changed-lanes.mjs";
|
||||
|
||||
export type ChangedCheckCommand = {
|
||||
name: string;
|
||||
args: string[];
|
||||
bin?: string;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
};
|
||||
|
||||
export type ChangedCheckPlan = {
|
||||
commands: ChangedCheckCommand[];
|
||||
summary: string;
|
||||
};
|
||||
|
||||
export type ChangedCheckPlanOptions = {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
staged?: boolean;
|
||||
base?: string;
|
||||
head?: string;
|
||||
platform?: NodeJS.Platform;
|
||||
swiftlintAvailable?: boolean;
|
||||
};
|
||||
|
||||
export type TargetedLintOptions = {
|
||||
fileExists?: (path: string) => boolean;
|
||||
};
|
||||
|
||||
export type TargetedLintCommand = Required<
|
||||
Pick<ChangedCheckCommand, "name" | "bin" | "args" | "env">
|
||||
>;
|
||||
|
||||
export function createChangedCheckChildEnv(baseEnv?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
||||
export function shouldDelegateChangedCheckToCrabbox(
|
||||
argv?: string[],
|
||||
env?: NodeJS.ProcessEnv,
|
||||
): boolean;
|
||||
export function buildChangedCheckCrabboxArgs(argv?: string[], options?: { cwd?: string }): string[];
|
||||
export function shouldRunShrinkwrapGuard(paths: string[]): boolean;
|
||||
export function shouldRunPromptSnapshotCheck(paths: string[]): boolean;
|
||||
export function shouldRunPromptSnapshotOwnerTest(paths: string[]): boolean;
|
||||
export function shouldRunRuntimeSidecarBaselineCheck(paths: string[]): boolean;
|
||||
export function shouldRunCanvasA2uiNativeResourceCheck(paths: string[]): boolean;
|
||||
export function shouldRunAppcastOwnerTest(paths: string[]): boolean;
|
||||
export function shouldRunTestTempCreationReport(paths: string[]): boolean;
|
||||
export function createShrinkwrapGuardCommand(paths: string[]): ChangedCheckCommand | null;
|
||||
export function createChangedCheckPlan(
|
||||
result: ChangedLaneResult,
|
||||
options?: ChangedCheckPlanOptions,
|
||||
): ChangedCheckPlan;
|
||||
export function createTargetedCoreLintCommand(
|
||||
paths: string[],
|
||||
env?: NodeJS.ProcessEnv,
|
||||
options?: TargetedLintOptions,
|
||||
): TargetedLintCommand | null;
|
||||
export function createTargetedExtensionLintCommand(
|
||||
paths: string[],
|
||||
env?: NodeJS.ProcessEnv,
|
||||
options?: TargetedLintOptions,
|
||||
): TargetedLintCommand | null;
|
||||
export function createTargetedScriptLintCommand(
|
||||
paths: string[],
|
||||
env?: NodeJS.ProcessEnv,
|
||||
options?: TargetedLintOptions,
|
||||
): TargetedLintCommand | null;
|
||||
export function createPnpmManagedCommand<T extends ChangedCheckCommand>(
|
||||
command: T,
|
||||
env?: NodeJS.ProcessEnv,
|
||||
): T & { bin: string; env: NodeJS.ProcessEnv };
|
||||
export function cleanupCorepackPnpmShimDir(): void;
|
||||
@@ -394,6 +394,9 @@ export function createChangedCheckPlan(result, options = {}) {
|
||||
if (lanes.scripts) {
|
||||
addTypecheck("typecheck scripts", ["tsgo:scripts"]);
|
||||
}
|
||||
if (lanes.testRoot) {
|
||||
addTypecheck("typecheck test root", ["tsgo:test:root"]);
|
||||
}
|
||||
|
||||
if (lanes.core || lanes.coreTests) {
|
||||
const coreLintCommand = createTargetedCoreLintCommand(result.paths, baseEnv);
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Reports whether a handle is forbidden in changelog thanks text.
|
||||
*/
|
||||
export function isForbiddenChangelogThanksHandle(
|
||||
handle: unknown,
|
||||
options?: Record<string, unknown>,
|
||||
): boolean;
|
||||
/**
|
||||
* Reports whether a handle needs a separate human credit.
|
||||
*/
|
||||
export function requiresExplicitHumanChangelogThanks(handle: unknown): boolean;
|
||||
/**
|
||||
* Finds changelog lines that thank forbidden handles.
|
||||
*/
|
||||
export function findForbiddenChangelogThanks(content: unknown): unknown;
|
||||
/**
|
||||
* Runs the changelog attribution check.
|
||||
*/
|
||||
export function main(argv?: string[]): Promise<void>;
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Finds channel-specific references inside channel-agnostic protected sources.
|
||||
*/
|
||||
export function findChannelAgnosticBoundaryViolations(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
options?: Record<string, unknown>,
|
||||
): unknown[];
|
||||
/**
|
||||
* Finds reverse dependencies from channel core into plugin/runtime surfaces.
|
||||
*/
|
||||
export function findChannelCoreReverseDependencyViolations(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
): unknown[];
|
||||
/**
|
||||
* Finds user-facing channel names in ACP-owned text sources.
|
||||
*/
|
||||
export function findAcpUserFacingChannelNameViolations(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
): unknown[];
|
||||
/**
|
||||
* Finds raw system mark literals where shared constants should be used.
|
||||
*/
|
||||
export function findSystemMarkLiteralViolations(content: unknown, fileName?: string): unknown[];
|
||||
/**
|
||||
* Runs all channel-agnostic boundary checks.
|
||||
*/
|
||||
export function main(): Promise<void>;
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env node
|
||||
export namespace testing {
|
||||
export { cases };
|
||||
export { nodeImportSpecifierForPath };
|
||||
export { parseArgs };
|
||||
export { readPositiveIntEnv };
|
||||
export { readPositiveNumberEnv };
|
||||
export { repoRoot };
|
||||
export { resolveDefaultLimitsMb };
|
||||
export { runCase };
|
||||
export { runStartupMemoryCheck };
|
||||
}
|
||||
declare const cases: {
|
||||
id: string;
|
||||
label: string;
|
||||
args: string[];
|
||||
limitMb: unknown;
|
||||
}[];
|
||||
declare function nodeImportSpecifierForPath(filePath: unknown): string;
|
||||
declare function parseArgs(argv: unknown): {
|
||||
jsonPath: string;
|
||||
summaryPath: string;
|
||||
};
|
||||
declare function readPositiveIntEnv(
|
||||
name: unknown,
|
||||
fallback: unknown,
|
||||
env?: NodeJS.ProcessEnv,
|
||||
): unknown;
|
||||
declare function readPositiveNumberEnv(
|
||||
name: unknown,
|
||||
fallback: unknown,
|
||||
env?: NodeJS.ProcessEnv,
|
||||
): unknown;
|
||||
declare const repoRoot: string;
|
||||
declare function resolveDefaultLimitsMb(platform?: NodeJS.Platform): {
|
||||
help: number;
|
||||
pluginsList: number;
|
||||
statusJson: number;
|
||||
gatewayStatus: number;
|
||||
};
|
||||
declare function runCase(
|
||||
testCase: unknown,
|
||||
params?: Record<string, unknown>,
|
||||
): {
|
||||
id: unknown;
|
||||
label: unknown;
|
||||
command: string;
|
||||
limitMb: unknown;
|
||||
maxRssMb: number | null;
|
||||
status: string;
|
||||
exitCode: unknown;
|
||||
signal: unknown;
|
||||
error: string | null;
|
||||
};
|
||||
declare function runStartupMemoryCheck(
|
||||
argv?: string[],
|
||||
params?: Record<string, unknown>,
|
||||
): {
|
||||
skipped: boolean;
|
||||
results: {
|
||||
id: unknown;
|
||||
label: unknown;
|
||||
command: string;
|
||||
limitMb: unknown;
|
||||
maxRssMb: number | null;
|
||||
status: string;
|
||||
exitCode: unknown;
|
||||
signal: unknown;
|
||||
error: string | null;
|
||||
}[];
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env node
|
||||
export function collectDatabaseFirstLegacyStoreSourceFiles(
|
||||
sourceRoots: string[],
|
||||
): Promise<string[]>;
|
||||
/**
|
||||
* Finds database-first legacy-store violations in one TypeScript/JavaScript source file.
|
||||
*/
|
||||
export function collectDatabaseFirstLegacyStoreViolations(
|
||||
content: string,
|
||||
relativePath?: string,
|
||||
scanOptions?: Record<string, unknown>,
|
||||
): {
|
||||
kind: string;
|
||||
line: number;
|
||||
}[];
|
||||
/**
|
||||
* Runs the database-first legacy-store guard.
|
||||
*/
|
||||
export function main(): Promise<void>;
|
||||
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Parses compact knip output into unused file paths.
|
||||
*/
|
||||
export function parseKnipCompactUnusedFiles(output: unknown): unknown[];
|
||||
/**
|
||||
* Compares detected unused files against the checked-in allowlist.
|
||||
*/
|
||||
export function compareUnusedFilesToAllowlist(
|
||||
actualFiles: unknown,
|
||||
allowlistFiles: unknown,
|
||||
optionalAllowlistFiles?: unknown[],
|
||||
): {
|
||||
actual: unknown[];
|
||||
allowed: unknown[];
|
||||
unexpected: unknown[];
|
||||
stale: unknown[];
|
||||
duplicateAllowedCount: number;
|
||||
allowlistIsSorted: boolean;
|
||||
};
|
||||
/**
|
||||
* Runs knip and returns parsed unused-file results.
|
||||
*/
|
||||
export function runKnipUnusedFiles(params?: Record<string, unknown>): Promise<unknown>;
|
||||
/**
|
||||
* Checks detected unused files against the current allowlist.
|
||||
*/
|
||||
export function checkUnusedFiles(
|
||||
output: unknown,
|
||||
allowlistFiles?: string[],
|
||||
optionalAllowlistFiles?: string[],
|
||||
): {
|
||||
ok: boolean;
|
||||
comparison: {
|
||||
actual: unknown[];
|
||||
allowed: unknown[];
|
||||
unexpected: unknown[];
|
||||
stale: unknown[];
|
||||
duplicateAllowedCount: number;
|
||||
allowlistIsSorted: boolean;
|
||||
};
|
||||
message: string;
|
||||
};
|
||||
/**
|
||||
* Maximum buffered knip output retained for diagnostics.
|
||||
*/
|
||||
export const KNIP_MAX_BUFFER_BYTES: number;
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Collects dependency pin violations for the current workspace.
|
||||
*/
|
||||
export function collectDependencyPinViolations(cwd?: string): unknown[];
|
||||
/**
|
||||
* Runs the dependency pin check.
|
||||
*/
|
||||
export function main(): Promise<void>;
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env node
|
||||
export function parseArgs(argv: unknown): {
|
||||
base: string;
|
||||
head: string;
|
||||
};
|
||||
export type TermMatch = {
|
||||
file: string;
|
||||
line: number;
|
||||
kind: "title" | "link label";
|
||||
term: string;
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Parses docs MDX check arguments.
|
||||
*/
|
||||
export function parseArgs(argv: unknown): {
|
||||
roots: unknown[];
|
||||
jsonOut: string;
|
||||
maxErrors: number;
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Finds dynamic import advisories in a single source file.
|
||||
*/
|
||||
export function findDynamicImportAdvisories(content: unknown, fileName?: string): unknown[];
|
||||
/**
|
||||
* Runs the dynamic import advisory check.
|
||||
*/
|
||||
export function main(argv?: string[]): Promise<void>;
|
||||
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Resolves the compile worker count from CLI/env/default settings.
|
||||
*/
|
||||
export function resolveCompileConcurrency(
|
||||
env?: NodeJS.ProcessEnv,
|
||||
availableParallelism?: number,
|
||||
): number;
|
||||
/**
|
||||
* Appends child-process output while preserving only the diagnostic tail.
|
||||
*/
|
||||
export function appendBoundedStepOutput(
|
||||
buffer: unknown,
|
||||
chunk: unknown,
|
||||
maxChars?: number,
|
||||
): {
|
||||
text: string;
|
||||
truncatedChars: unknown;
|
||||
};
|
||||
/**
|
||||
* Formats the successful boundary compile summary.
|
||||
*/
|
||||
export function formatBoundaryCheckSuccessSummary(params?: Record<string, unknown>): string;
|
||||
/**
|
||||
* Formats skipped compile progress for fresh extension canaries.
|
||||
*/
|
||||
export function formatSkippedCompileProgress(params?: Record<string, unknown>): string;
|
||||
/**
|
||||
* Formats slow extension compile diagnostics.
|
||||
*/
|
||||
export function formatSlowCompileSummary(params?: Record<string, unknown>): string;
|
||||
/**
|
||||
* Formats a failed boundary-check child process step.
|
||||
*/
|
||||
export function formatStepFailure(label: unknown, params?: Record<string, unknown>): string;
|
||||
/**
|
||||
* Checks whether an extension boundary compile canary is still fresh.
|
||||
*/
|
||||
export function isBoundaryCompileFresh(
|
||||
extensionId: unknown,
|
||||
params?: Record<string, unknown>,
|
||||
): boolean;
|
||||
/**
|
||||
* Runs one node-based boundary check step with timeout and output capture.
|
||||
*/
|
||||
export function runNodeStepAsync(
|
||||
label: unknown,
|
||||
args: unknown,
|
||||
timeoutMs: unknown,
|
||||
params?: Record<string, unknown>,
|
||||
): Promise<unknown>;
|
||||
/**
|
||||
* Runs boundary check steps with bounded concurrency.
|
||||
*/
|
||||
export function runNodeStepsWithConcurrency(steps: unknown, concurrency: unknown): Promise<void>;
|
||||
/**
|
||||
* Resolves canary artifact paths for an extension boundary compile.
|
||||
*/
|
||||
export function resolveCanaryArtifactPaths(
|
||||
extensionId: unknown,
|
||||
rootDir?: string,
|
||||
): {
|
||||
extensionRoot: string;
|
||||
canaryPath: string;
|
||||
tsconfigPath: string;
|
||||
};
|
||||
/**
|
||||
* Removes canary artifacts for multiple extensions.
|
||||
*/
|
||||
export function cleanupCanaryArtifactsForExtensions(extensionIds: unknown, rootDir?: string): void;
|
||||
/**
|
||||
* Installs signal/exit cleanup for extension canary artifacts.
|
||||
*/
|
||||
export function installCanaryArtifactCleanup(
|
||||
extensionIds: unknown,
|
||||
params?: Record<string, unknown>,
|
||||
): () => void;
|
||||
/**
|
||||
* Resolves the local lock path for extension boundary checks.
|
||||
*/
|
||||
export function resolveBoundaryCheckLockPath(rootDir?: string): string;
|
||||
/**
|
||||
* Acquires the single-process lock for extension boundary checks.
|
||||
*/
|
||||
export function acquireBoundaryCheckLock(params?: Record<string, unknown>): () => void;
|
||||
/**
|
||||
* Runs the extension package TypeScript boundary check.
|
||||
*/
|
||||
export function main(argv?: string[]): Promise<void>;
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Reads the checked-in expected boundary inventory.
|
||||
*/
|
||||
export function readExpectedInventory(mode: unknown): Promise<unknown>;
|
||||
/**
|
||||
* Diffs expected and actual boundary inventory entries.
|
||||
*/
|
||||
export function diffInventory(
|
||||
expected: unknown,
|
||||
actual: unknown,
|
||||
): {
|
||||
missing: unknown;
|
||||
unexpected: unknown;
|
||||
};
|
||||
/**
|
||||
* Entrypoint wrapper for the extension plugin SDK boundary check.
|
||||
*/
|
||||
export function main(argv: unknown, io: unknown): Promise<1 | 0>;
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Finds local wildcard re-export lines in a barrel source string.
|
||||
*/
|
||||
export function findLocalWildcardReexports(source: unknown): unknown;
|
||||
/**
|
||||
* Runs the extension wildcard re-export guard.
|
||||
*/
|
||||
export function main(argv?: string[], io?: NodeJS.Process): Promise<0 | 1>;
|
||||
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env node
|
||||
export namespace testing {
|
||||
export { hasPrivateQaDist };
|
||||
export { parseArgs };
|
||||
export { readStartupReport };
|
||||
export { runGatewayCpuScenarios };
|
||||
export { validateStartupReport };
|
||||
}
|
||||
declare function hasPrivateQaDist(repoRoot: unknown, fsImpl?: typeof fs): boolean;
|
||||
declare function parseArgs(argv: string[]): {
|
||||
outputDir: string;
|
||||
startupCases: string[];
|
||||
qaScenarios: string[];
|
||||
runs: number;
|
||||
warmup: number;
|
||||
skipStartup: boolean;
|
||||
skipQa: boolean;
|
||||
cpuCoreWarn: number;
|
||||
hotWallWarnMs: number;
|
||||
};
|
||||
declare function readStartupReport(startupOutput: unknown):
|
||||
| {
|
||||
diagnosticFailure: string;
|
||||
diagnosticDetail: string;
|
||||
report: null;
|
||||
}
|
||||
| {
|
||||
diagnosticFailure: null;
|
||||
diagnosticDetail: null;
|
||||
report: unknown;
|
||||
};
|
||||
declare function runGatewayCpuScenarios(
|
||||
options: unknown,
|
||||
params?: Record<string, unknown>,
|
||||
): Promise<{
|
||||
exitCode: number;
|
||||
summary: {
|
||||
options: {
|
||||
startupCases: unknown;
|
||||
qaScenarios: unknown;
|
||||
runs: unknown;
|
||||
warmup: unknown;
|
||||
cpuCoreWarn: unknown;
|
||||
hotWallWarnMs: unknown;
|
||||
qaStateDir: string | null;
|
||||
};
|
||||
steps: {
|
||||
error?: unknown;
|
||||
name: unknown;
|
||||
status: unknown;
|
||||
signal: unknown;
|
||||
}[];
|
||||
observations: (
|
||||
| {
|
||||
kind: string;
|
||||
id: unknown;
|
||||
cpuCoreRatioMax: number;
|
||||
wallMsMax: number;
|
||||
cpuCoreRatio?: undefined;
|
||||
wallMs?: undefined;
|
||||
}
|
||||
| {
|
||||
kind: string;
|
||||
id: string;
|
||||
cpuCoreRatio: number;
|
||||
wallMs: number;
|
||||
cpuCoreRatioMax?: undefined;
|
||||
wallMsMax?: undefined;
|
||||
}
|
||||
)[];
|
||||
qaSummaryFailure?: string | undefined;
|
||||
qaSummaryFailureDetail?: string | null | undefined;
|
||||
startupReportFailure?: string | undefined;
|
||||
startupReportFailureDetail?: string | null | undefined;
|
||||
generatedAt: string;
|
||||
outputDir: unknown;
|
||||
startupOutput: string | null;
|
||||
qaSummary: string | null;
|
||||
};
|
||||
}>;
|
||||
declare function validateStartupReport(
|
||||
report: unknown,
|
||||
):
|
||||
| "startup report must be a JSON Record<string, unknown>"
|
||||
| "startup report missing results array"
|
||||
| "startup report has no measured results"
|
||||
| null;
|
||||
import fs from "node:fs";
|
||||
@@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Appends watch output while preserving only the diagnostic tail.
|
||||
*/
|
||||
export function appendBoundedWatchLog(
|
||||
current: unknown,
|
||||
chunk: unknown,
|
||||
maxChars?: number,
|
||||
): {
|
||||
text: string;
|
||||
truncated: boolean;
|
||||
};
|
||||
/**
|
||||
* Updates bounded watch-build detection state from new output.
|
||||
*/
|
||||
export function updateWatchBuildDetection(
|
||||
state: unknown,
|
||||
chunk: unknown,
|
||||
): {
|
||||
buffer: string;
|
||||
triggered: unknown;
|
||||
reason: unknown;
|
||||
};
|
||||
/**
|
||||
* Parses a safe non-negative integer CLI value.
|
||||
*/
|
||||
export function readNonNegativeInteger(value: unknown, label: unknown): number;
|
||||
/**
|
||||
* Parses gateway watch regression CLI arguments.
|
||||
*/
|
||||
export function parseArgs(argv: unknown): {
|
||||
outputDir: string;
|
||||
windowMs: number;
|
||||
readyTimeoutMs: number;
|
||||
readySettleMs: number;
|
||||
sigkillGraceMs: number;
|
||||
sigkillExitGraceMs: number;
|
||||
cpuWarnMs: number;
|
||||
cpuFailMs: number;
|
||||
distRuntimeFileGrowthMax: number;
|
||||
distRuntimeByteGrowthMax: number;
|
||||
keepLogs: boolean;
|
||||
skipBuild: boolean;
|
||||
};
|
||||
/**
|
||||
* Reports whether gateway watch output contains a ready marker.
|
||||
*/
|
||||
export function hasGatewayReadyLog(text: unknown): boolean;
|
||||
export function resolveTimedWatchShell(deps?: Record<string, unknown>): string;
|
||||
export function buildTimedWatchCommand(
|
||||
pidFilePath: unknown,
|
||||
timeFilePath: unknown,
|
||||
isolatedHomeDir: unknown,
|
||||
port: unknown,
|
||||
deps?: Record<string, unknown>,
|
||||
):
|
||||
| {
|
||||
command: string;
|
||||
args: unknown[];
|
||||
env: {
|
||||
OPENCLAW_DISABLE_BONJOUR: string;
|
||||
OPENCLAW_SKIP_ACPX_RUNTIME: string;
|
||||
OPENCLAW_SKIP_ACPX_RUNTIME_PROBE: string;
|
||||
OPENCLAW_SKIP_BROWSER_CONTROL_SERVER: string;
|
||||
OPENCLAW_SKIP_CANVAS_HOST: string;
|
||||
OPENCLAW_SKIP_CHANNELS: string;
|
||||
OPENCLAW_SKIP_CRON: string;
|
||||
OPENCLAW_SKIP_GMAIL_WATCHER: string;
|
||||
OPENCLAW_RUNTIME_POSTBUILD_STATIC_ASSETS: string;
|
||||
OPENCLAW_TEST_MINIMAL_GATEWAY: string;
|
||||
NODE_ENV: string;
|
||||
OPENCLAW_WATCH_PID_FILE: unknown;
|
||||
HOME: unknown;
|
||||
OPENCLAW_HOME: unknown;
|
||||
OPENCLAW_CONFIG_PATH: string;
|
||||
OPENCLAW_STATE_DIR: string;
|
||||
PATH: string;
|
||||
XDG_CONFIG_HOME: string;
|
||||
};
|
||||
}
|
||||
| {
|
||||
command: unknown;
|
||||
args: string[];
|
||||
env: {
|
||||
OPENCLAW_DISABLE_BONJOUR: string;
|
||||
OPENCLAW_SKIP_ACPX_RUNTIME: string;
|
||||
OPENCLAW_SKIP_ACPX_RUNTIME_PROBE: string;
|
||||
OPENCLAW_SKIP_BROWSER_CONTROL_SERVER: string;
|
||||
OPENCLAW_SKIP_CANVAS_HOST: string;
|
||||
OPENCLAW_SKIP_CHANNELS: string;
|
||||
OPENCLAW_SKIP_CRON: string;
|
||||
OPENCLAW_SKIP_GMAIL_WATCHER: string;
|
||||
OPENCLAW_RUNTIME_POSTBUILD_STATIC_ASSETS: string;
|
||||
OPENCLAW_TEST_MINIMAL_GATEWAY: string;
|
||||
NODE_ENV: string;
|
||||
OPENCLAW_WATCH_PID_FILE: unknown;
|
||||
HOME: unknown;
|
||||
OPENCLAW_HOME: unknown;
|
||||
OPENCLAW_CONFIG_PATH: string;
|
||||
OPENCLAW_STATE_DIR: string;
|
||||
PATH: string;
|
||||
XDG_CONFIG_HOME: string;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Runs a bounded gateway watch process and captures timing/log artifacts.
|
||||
*/
|
||||
export function runTimedWatch(
|
||||
options: unknown,
|
||||
outputDir: unknown,
|
||||
deps?: Record<string, unknown>,
|
||||
): Promise<{
|
||||
exit: unknown;
|
||||
spawnError: unknown;
|
||||
timingFileMissing: boolean;
|
||||
timing: unknown;
|
||||
readyBeforeWindow: boolean;
|
||||
exitedBeforeReady: boolean;
|
||||
exitedBeforeStop: boolean;
|
||||
idleCpuMs: number | null;
|
||||
stdoutPath: string;
|
||||
stderrPath: string;
|
||||
timeFilePath: string;
|
||||
watchTriggeredBuild: boolean;
|
||||
watchBuildReason: string | null;
|
||||
}>;
|
||||
/**
|
||||
* Stops the timed watch child process with TERM/KILL fallback.
|
||||
*/
|
||||
export function stopTimedWatchChild(
|
||||
child: unknown,
|
||||
watchPid: unknown,
|
||||
options: unknown,
|
||||
deps?: Record<string, unknown>,
|
||||
): Promise<unknown>;
|
||||
/**
|
||||
* Reports whether restored CI artifacts need fresh build stamps.
|
||||
*/
|
||||
export function shouldRefreshBuildStampForRestoredArtifacts(params: unknown): boolean;
|
||||
/**
|
||||
* Writes build and runtime-postbuild stamps for the current artifact set.
|
||||
*/
|
||||
export function writeBuildAndRuntimePostBuildStamps(params?: Record<string, unknown>): void;
|
||||
/**
|
||||
* Collects pass/fail findings for the bounded gateway watch regression run.
|
||||
*/
|
||||
export function collectGatewayWatchFindings(params: unknown): {
|
||||
failures: string[];
|
||||
warnings: string[];
|
||||
};
|
||||
export function shouldReportDuplicateDistRuntimeRegression(failures: unknown): unknown;
|
||||
/**
|
||||
* Maximum retained stdout/stderr text for gateway watch diagnostics.
|
||||
*/
|
||||
export const WATCH_LOG_CAPTURE_MAX_CHARS: number;
|
||||
export const WATCH_LOG_FAILURE_TAIL_CHARS: 12000;
|
||||
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Parses a safe non-negative integer option.
|
||||
*/
|
||||
export function readNumber(value: unknown, label: unknown): number;
|
||||
/**
|
||||
* Parses a safe positive integer option.
|
||||
*/
|
||||
export function readPositiveNumber(value: unknown, label: unknown): number;
|
||||
/**
|
||||
* Parses memory FD repro CLI arguments and environment fallbacks.
|
||||
*/
|
||||
export function parseArgs(argv: string[]): {
|
||||
fileCount: number;
|
||||
mode: "fixed" | "leak" | "report";
|
||||
maxWorkspaceRegFds: number;
|
||||
minLeakedFds: number;
|
||||
invokeTimeoutMs: number;
|
||||
sampleDelayMs: number;
|
||||
settleDelayMs: number;
|
||||
outputDir: string;
|
||||
keep: boolean;
|
||||
allowNonDarwin: boolean;
|
||||
};
|
||||
/**
|
||||
* Writes isolated OpenClaw config for the synthetic memory workspace.
|
||||
*/
|
||||
export function writeConfig({
|
||||
homeDir,
|
||||
workspaceDir,
|
||||
port,
|
||||
token,
|
||||
}: {
|
||||
homeDir: unknown;
|
||||
workspaceDir: unknown;
|
||||
port: unknown;
|
||||
token: unknown;
|
||||
}): string;
|
||||
/**
|
||||
* Updates bounded gateway-ready output state from a stdout/stderr chunk.
|
||||
*/
|
||||
export function updateGatewayReadyOutputState(
|
||||
state: unknown,
|
||||
chunk: unknown,
|
||||
maxChars?: number,
|
||||
): {
|
||||
tail: string;
|
||||
readySeen: boolean;
|
||||
};
|
||||
/**
|
||||
* Reports whether a spawned child has already exited.
|
||||
*/
|
||||
export function hasChildExited(child: unknown): boolean;
|
||||
/**
|
||||
* Waits until gateway output and listener state both indicate readiness.
|
||||
*/
|
||||
export function waitForGatewayReady({
|
||||
child,
|
||||
port,
|
||||
logPath,
|
||||
timeoutMs,
|
||||
}: {
|
||||
child: unknown;
|
||||
port: unknown;
|
||||
logPath: unknown;
|
||||
timeoutMs: unknown;
|
||||
}): Promise<void>;
|
||||
/**
|
||||
* Stops the gateway child using the default process/runtime hooks.
|
||||
*/
|
||||
export function stopGateway({ child, port }: { child: unknown; port: unknown }): Promise<void>;
|
||||
/**
|
||||
* Stops the gateway child and unknown remaining listener process.
|
||||
*/
|
||||
export function stopGatewayWithRuntime({
|
||||
child,
|
||||
childExitPollIntervalMs,
|
||||
childExitPolls,
|
||||
port,
|
||||
findGatewayPidFn,
|
||||
killProcess,
|
||||
listenerSettleDelayMs,
|
||||
}: {
|
||||
child: unknown;
|
||||
childExitPollIntervalMs?: number | undefined;
|
||||
childExitPolls?: number | undefined;
|
||||
port: unknown;
|
||||
findGatewayPidFn: unknown;
|
||||
killProcess: unknown;
|
||||
listenerSettleDelayMs?: number | undefined;
|
||||
}): Promise<void>;
|
||||
/**
|
||||
* Classifies the memory_search HTTP response into success/error details.
|
||||
*/
|
||||
export function classifyMemorySearchInvokeResponse({
|
||||
httpOk,
|
||||
status,
|
||||
bodyText,
|
||||
}: {
|
||||
httpOk: unknown;
|
||||
status: unknown;
|
||||
bodyText: unknown;
|
||||
}):
|
||||
| {
|
||||
ok: boolean;
|
||||
httpOk: unknown;
|
||||
status: unknown;
|
||||
gatewayOk: boolean | undefined;
|
||||
error: string;
|
||||
}
|
||||
| {
|
||||
ok: boolean;
|
||||
httpOk: unknown;
|
||||
status: unknown;
|
||||
error: string;
|
||||
gatewayOk?: undefined;
|
||||
}
|
||||
| {
|
||||
error?: string | undefined;
|
||||
toolError?: string | undefined;
|
||||
ok: boolean;
|
||||
httpOk: unknown;
|
||||
status: unknown;
|
||||
gatewayOk: boolean | undefined;
|
||||
resultCount: unknown;
|
||||
toolDisabled: boolean;
|
||||
toolUnavailable: boolean;
|
||||
};
|
||||
export function invokeMemorySearch({
|
||||
port,
|
||||
token,
|
||||
timeoutMs,
|
||||
}: {
|
||||
port: unknown;
|
||||
token: unknown;
|
||||
timeoutMs: unknown;
|
||||
}): Promise<
|
||||
| {
|
||||
durationMs: number;
|
||||
bodyPreview: string;
|
||||
ok: boolean;
|
||||
httpOk: unknown;
|
||||
status: unknown;
|
||||
gatewayOk: boolean | undefined;
|
||||
error: string;
|
||||
aborted?: undefined;
|
||||
}
|
||||
| {
|
||||
durationMs: number;
|
||||
bodyPreview: string;
|
||||
ok: boolean;
|
||||
httpOk: unknown;
|
||||
status: unknown;
|
||||
error: string;
|
||||
gatewayOk?: undefined;
|
||||
aborted?: undefined;
|
||||
}
|
||||
| {
|
||||
durationMs: number;
|
||||
bodyPreview: string;
|
||||
error?: string | undefined;
|
||||
toolError?: string | undefined;
|
||||
ok: boolean;
|
||||
httpOk: unknown;
|
||||
status: unknown;
|
||||
gatewayOk: boolean | undefined;
|
||||
resultCount: unknown;
|
||||
toolDisabled: boolean;
|
||||
toolUnavailable: boolean;
|
||||
aborted?: undefined;
|
||||
}
|
||||
| {
|
||||
ok: boolean;
|
||||
aborted: boolean;
|
||||
durationMs: number;
|
||||
error: string;
|
||||
}
|
||||
>;
|
||||
/**
|
||||
* Maximum gateway-ready output tail retained while waiting for startup.
|
||||
*/
|
||||
export const GATEWAY_READY_OUTPUT_MAX_CHARS: number;
|
||||
/**
|
||||
* Maximum bytes read from the memory_search HTTP response.
|
||||
*/
|
||||
export const MEMORY_SEARCH_RESPONSE_MAX_BYTES: number;
|
||||
/**
|
||||
* Probe query expected to hit the synthetic top-level memory file.
|
||||
*/
|
||||
export const MEMORY_SEARCH_PROBE_QUERY: "Top-level memory file";
|
||||
export { readBoundedResponseText };
|
||||
import { readBoundedResponseText } from "./lib/bounded-response.mjs";
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Returns one-based line numbers containing merge conflict markers.
|
||||
*/
|
||||
export function findConflictMarkerLines(content: unknown): unknown[];
|
||||
/**
|
||||
* Lists tracked files in the repository.
|
||||
*/
|
||||
export function listTrackedFiles(cwd?: string): string[];
|
||||
/**
|
||||
* Scans files for merge conflict markers, skipping binary content.
|
||||
*/
|
||||
export function findConflictMarkersInFiles(
|
||||
filePaths: unknown,
|
||||
readFile?: typeof fs.readFileSync,
|
||||
): {
|
||||
filePath: unknown;
|
||||
lines: unknown[];
|
||||
}[];
|
||||
/**
|
||||
* Finds merge conflict markers in tracked repository files.
|
||||
*/
|
||||
export function findConflictMarkersInTrackedFiles(cwd?: string): {
|
||||
filePath: unknown;
|
||||
lines: unknown[];
|
||||
}[];
|
||||
/**
|
||||
* Runs the merge conflict marker check.
|
||||
*/
|
||||
export function main(): Promise<void>;
|
||||
import fs from "node:fs";
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Finds `os.tmpdir()` or imported `tmpdir()` call lines in source.
|
||||
*/
|
||||
export function findMessagingTmpdirCallLines(content: unknown, fileName?: string): unknown[];
|
||||
/**
|
||||
* Runs the messaging tmpdir guard.
|
||||
*/
|
||||
export function main(): Promise<void>;
|
||||
/**
|
||||
* Source roots scanned for unsafe messaging tmpdir usage.
|
||||
*/
|
||||
export const messagingTmpdirGuardSourceRoots: string[];
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Finds raw `window.open(...)` or `globalThis.open(...)` call lines.
|
||||
*/
|
||||
export function findRawWindowOpenLines(content: unknown, fileName?: string): unknown[];
|
||||
/**
|
||||
* Runs the raw window.open guard.
|
||||
*/
|
||||
export function main(): Promise<void>;
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Collects disallowed package patch declarations and patch files.
|
||||
*/
|
||||
export function collectPackagePatchViolations(cwd?: string): unknown[];
|
||||
/**
|
||||
* Runs the package patch guard.
|
||||
*/
|
||||
export function main(): Promise<void>;
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Diffs expected and actual plugin-extension boundary inventory entries.
|
||||
*/
|
||||
export function diffInventory(
|
||||
expected: unknown,
|
||||
actual: unknown,
|
||||
): {
|
||||
missing: unknown;
|
||||
unexpected: unknown;
|
||||
};
|
||||
/**
|
||||
* Entrypoint wrapper for the plugin-extension import boundary check.
|
||||
*/
|
||||
export function main(argv: unknown, io: unknown): Promise<1 | 0>;
|
||||
/**
|
||||
* Cached inventory of src/plugins imports that cross into bundled extensions.
|
||||
*/
|
||||
export const collectPluginExtensionImportBoundaryInventory: () => Promise<
|
||||
Array<{
|
||||
file: string;
|
||||
line: number;
|
||||
kind: string;
|
||||
specifier: string;
|
||||
reason: string;
|
||||
}>
|
||||
>;
|
||||
/**
|
||||
* Cached expected plugin-extension import inventory baseline.
|
||||
*/
|
||||
export const readExpectedInventory: () => Promise<
|
||||
Array<{
|
||||
file: string;
|
||||
line: number;
|
||||
kind: string;
|
||||
specifier: string;
|
||||
reason: string;
|
||||
}>
|
||||
>;
|
||||
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Parses plugin gateway gauntlet CLI arguments and env defaults.
|
||||
*/
|
||||
export function parseArgs(argv: string[]): {
|
||||
repoRoot: string;
|
||||
outputDir: string;
|
||||
pluginIds: string[];
|
||||
shardTotal: number;
|
||||
shardIndex: number;
|
||||
limit: number | undefined;
|
||||
skipPrebuild: boolean;
|
||||
skipLifecycle: boolean;
|
||||
skipQa: boolean;
|
||||
qaBaseline: boolean;
|
||||
skipSlashHelp: boolean;
|
||||
qaScenarios: string[];
|
||||
qaPluginChunkSize: number;
|
||||
cpuCoreWarn: number;
|
||||
hotWallWarnMs: number;
|
||||
maxRssWarnMb: number;
|
||||
wallAnomalyMultiplier: number;
|
||||
rssAnomalyMultiplier: number;
|
||||
qaCpuRegressionMultiplier: number;
|
||||
qaWallRegressionMultiplier: number;
|
||||
commandTimeoutMs: number;
|
||||
buildTimeoutMs: number;
|
||||
qaTimeoutMs: number;
|
||||
allowEmpty: boolean;
|
||||
failOnObservation: boolean;
|
||||
keepRunRoot: boolean;
|
||||
};
|
||||
export function buildObservationGuardFailures(observations: unknown, enabled?: boolean): unknown;
|
||||
/**
|
||||
* Builds the command that prepares QA runtime artifacts before gauntlet probes.
|
||||
*/
|
||||
export function createGauntletPrebuildCommand(repoRoot: unknown): {
|
||||
command: string;
|
||||
args: string[];
|
||||
};
|
||||
/**
|
||||
* Converts an output path to a repo-relative path, rejecting paths outside the repo.
|
||||
*/
|
||||
export function toRepoRelativePath(repoRoot: unknown, absolutePath: unknown): string;
|
||||
/**
|
||||
* Parses `/usr/bin/time` output into wall, CPU, and RSS metrics.
|
||||
*/
|
||||
export function parseTimedMetrics(
|
||||
stderr: unknown,
|
||||
wallMs: unknown,
|
||||
mode: unknown,
|
||||
): {
|
||||
wallMs: unknown;
|
||||
cpuMs: number | null;
|
||||
cpuCoreRatio: number | null;
|
||||
maxRssMb: number | null;
|
||||
};
|
||||
/**
|
||||
* Runs a measured command through the live process implementation.
|
||||
*/
|
||||
export type GauntletMeasuredRow = {
|
||||
diagnosticFailure?: string;
|
||||
logPath: string | null;
|
||||
logWriteError?: string;
|
||||
spawnError?: { code?: string };
|
||||
status: number;
|
||||
timedOut: boolean;
|
||||
wallMs: number;
|
||||
};
|
||||
export type GauntletMeasuredCommandParams = {
|
||||
[key: string]: unknown;
|
||||
args: string[];
|
||||
command: string;
|
||||
consoleOutputMaxBytes?: number;
|
||||
cwd: string;
|
||||
env: NodeJS.ProcessEnv;
|
||||
label: string;
|
||||
logDir: string;
|
||||
maxBufferBytes?: number;
|
||||
phase: string;
|
||||
timeoutKillGraceMs?: number;
|
||||
timeoutMs: number;
|
||||
timeMode?: string;
|
||||
};
|
||||
export function runMeasuredCommand(
|
||||
params: GauntletMeasuredCommandParams,
|
||||
): Promise<GauntletMeasuredRow>;
|
||||
/**
|
||||
* Runs one command with optional timing wrapper, bounded output, and log capture.
|
||||
*/
|
||||
export function runMeasuredCommandLive(
|
||||
params: GauntletMeasuredCommandParams,
|
||||
): Promise<GauntletMeasuredRow>;
|
||||
/**
|
||||
* Reports whether gauntlet result rows contain work beyond the prebuild step.
|
||||
*/
|
||||
export function hasGauntletWorkRows(rows: unknown): unknown;
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env node
|
||||
export function parseArgs(argv: unknown):
|
||||
| {
|
||||
help: true;
|
||||
packageDirs: string[];
|
||||
}
|
||||
| {
|
||||
packageDirs: string[];
|
||||
help?: undefined;
|
||||
};
|
||||
/**
|
||||
* Builds publishable plugin npm runtimes and verifies declared outputs exist.
|
||||
*/
|
||||
export function checkPluginNpmRuntimeBuilds(params?: Record<string, unknown>): Promise<
|
||||
{
|
||||
pluginDir: string;
|
||||
status: string;
|
||||
entryCount: number;
|
||||
copiedStaticAssets: string[];
|
||||
}[]
|
||||
>;
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Finds wildcard plugin SDK re-export lines in an extension API barrel.
|
||||
*/
|
||||
export function findPluginSdkWildcardReexports(source: unknown): unknown;
|
||||
/**
|
||||
* Runs the plugin SDK wildcard re-export guard.
|
||||
*/
|
||||
export function main(argv?: string[], io?: NodeJS.Process): Promise<0 | 1>;
|
||||
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Extracts the gateway event name list from server-methods-list.ts source.
|
||||
* Bare identifiers in the array (e.g. GATEWAY_EVENT_UPDATE_AVAILABLE) are
|
||||
* resolved against constantsSource (src/gateway/events.ts).
|
||||
*/
|
||||
export function extractGatewayEventNames(listSource: unknown, constantsSource: unknown): string[];
|
||||
/**
|
||||
* Extracts qualified static string constants declared at Swift type scope.
|
||||
* Type qualification avoids resolving unrelated constants that share a short
|
||||
* member name elsewhere in the app.
|
||||
*/
|
||||
export function extractSwiftStaticStringConstants(source: unknown): Map<unknown, unknown>;
|
||||
/** Extracts Swift gateway-event case labels, including qualified constants. */
|
||||
export function extractSwiftHandledEvents(
|
||||
source: unknown,
|
||||
constants?: Map<unknown, unknown>,
|
||||
): Set<unknown>;
|
||||
/**
|
||||
* Extracts event names a Kotlin source handles: string-literal case labels of
|
||||
* `when (event)` blocks plus `event == "..."` comparisons, both scoped to
|
||||
* `fun handle*Event(...)` bodies. Scoping matters: bare `event == "..."`
|
||||
* literals also appear in predicate helpers that are not called from the
|
||||
* dispatch path (e.g. gatewayEventInvalidatesNodesDevices in NodeRuntime.kt),
|
||||
* and counting those would silently mark events as covered. Swift extraction
|
||||
* stays tree-wide because Swift consumption always reads `.event` off a
|
||||
* received EventFrame, which does not have that false-positive shape.
|
||||
*/
|
||||
export function extractKotlinHandledEvents(source: unknown): Set<unknown>;
|
||||
/**
|
||||
* Compares a client's handled events against the gateway catalog and its
|
||||
* allowlist. Returns human-readable error strings. Client-only names (e.g. the
|
||||
* client-synthesized "seqGap" pseudo-event) are intentionally ignored; this
|
||||
* check only guards the server->client direction.
|
||||
*/
|
||||
export function compareEventCoverage(params: unknown): string[];
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env node
|
||||
export function parseArgs(argv: string[]): {
|
||||
staged: boolean;
|
||||
base: string;
|
||||
head: string;
|
||||
paths: string[];
|
||||
};
|
||||
export function main(argv?: string[]): void;
|
||||
@@ -0,0 +1,14 @@
|
||||
export type RuntimeSidecarLoaderViolation = {
|
||||
line: number;
|
||||
specifier: string;
|
||||
sourcePath: string;
|
||||
reason: string;
|
||||
};
|
||||
export function collectTsdownEntrySources(
|
||||
config: Array<{ entry?: Record<string, string> }>,
|
||||
): Set<string>;
|
||||
export function findRuntimeSidecarLoaderViolations(
|
||||
content: string,
|
||||
importerPath: string,
|
||||
explicitEntrySources: Set<string>,
|
||||
): RuntimeSidecarLoaderViolation[];
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Entrypoint for the SDK-package extension import boundary checker.
|
||||
*/
|
||||
export const main: (argv: unknown, io: unknown) => Promise<1 | 0>;
|
||||
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env node
|
||||
export function collectSessionStoreRuntimeFileBackedCompatExports(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
): Map<unknown, unknown>;
|
||||
export function findSessionStoreRuntimeFileBackedCompatExportViolations(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
): {
|
||||
line: unknown;
|
||||
reason: string;
|
||||
}[];
|
||||
export function findSessionAccessorBoundaryViolations(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
): unknown[];
|
||||
export function findEmbeddedAgentSessionTargetViolations(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
): unknown[];
|
||||
export function findSessionAccessorWriteBoundaryViolations(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
): unknown[];
|
||||
export function findTranscriptWriterBoundaryViolations(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
): unknown[];
|
||||
export function findGatewaySessionCreateLifecycleViolations(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
): unknown[];
|
||||
export function findSessionCompactManualTrimBoundaryViolations(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
): unknown[];
|
||||
export function findSessionLifecycleCleanupBoundaryViolations(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
): unknown[];
|
||||
export function findMemoryHostSessionCorpusBoundaryViolations(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
): unknown[];
|
||||
/** Ratchet compare: counts above baseline are regressions, below are improvements. */
|
||||
export function compareSessionAccessorDebt(
|
||||
currentCounts: unknown,
|
||||
baselineCounts: unknown,
|
||||
): {
|
||||
regressions: {
|
||||
concern: string;
|
||||
path: string;
|
||||
currentCount: unknown;
|
||||
baselineCount: unknown;
|
||||
}[];
|
||||
improvements: {
|
||||
concern: string;
|
||||
path: string;
|
||||
currentCount: unknown;
|
||||
baselineCount: unknown;
|
||||
}[];
|
||||
};
|
||||
export function formatSessionAccessorDebtImprovements(improvements: unknown): unknown[];
|
||||
export function main(): Promise<void>;
|
||||
export const allowedSessionStoreRuntimeFileBackedCompatExports: Set<string>;
|
||||
export const migratedSessionAccessorFiles: Set<string>;
|
||||
export const migratedBundledPluginSessionAccessorFiles: Set<string>;
|
||||
export const migratedEmbeddedAgentSessionTargetFiles: Set<string>;
|
||||
export const migratedSessionAccessorWriteFiles: Set<string>;
|
||||
export const migratedTranscriptWriterFiles: Set<string>;
|
||||
export const migratedSessionCompactManualTrimFiles: Set<string>;
|
||||
export const migratedSessionLifecycleCleanupFiles: Set<string>;
|
||||
export const migratedMemoryHostSessionCorpusFiles: Set<string>;
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
export function findSessionTranscriptReaderBoundaryViolations(
|
||||
content: unknown,
|
||||
fileName?: string,
|
||||
): unknown[];
|
||||
export function main(): Promise<void>;
|
||||
export const migratedSessionTranscriptReaderFiles: Set<string>;
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Entrypoint for the src extension import boundary checker.
|
||||
*/
|
||||
export const main: (argv: unknown, io: unknown) => Promise<1 | 0>;
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Collects test-helper extension import boundary inventory.
|
||||
*/
|
||||
export const collectTestHelperExtensionImportBoundaryInventory: () => Promise<unknown>;
|
||||
/**
|
||||
* Entrypoint for the test-helper extension import boundary checker.
|
||||
*/
|
||||
export const main: (argv: unknown, io: unknown) => Promise<1 | 0>;
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Collects web-fetch provider boundary violations in core source files.
|
||||
*/
|
||||
export function collectWebFetchProviderBoundaryViolations(): Promise<
|
||||
Array<{
|
||||
file: string;
|
||||
line: number;
|
||||
provider: string;
|
||||
reason: string;
|
||||
}>
|
||||
>;
|
||||
/**
|
||||
* Runs the web-fetch provider boundary check.
|
||||
*/
|
||||
export function main(argv: unknown, io: unknown): Promise<1 | 0>;
|
||||
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Collects web-search provider boundary inventory from core source files.
|
||||
*/
|
||||
export function collectWebSearchProviderBoundaryInventory(): Promise<
|
||||
Array<{
|
||||
file: string;
|
||||
line: number;
|
||||
provider: string;
|
||||
reason: string;
|
||||
}>
|
||||
>;
|
||||
/**
|
||||
* Reads the expected web-search provider boundary inventory baseline.
|
||||
*/
|
||||
export function readExpectedInventory(): Promise<
|
||||
Array<{
|
||||
file: string;
|
||||
line: number;
|
||||
provider: string;
|
||||
reason: string;
|
||||
}>
|
||||
>;
|
||||
/**
|
||||
* Diffs expected and actual web-search provider boundary inventory entries.
|
||||
*/
|
||||
export function diffInventory(
|
||||
expected: unknown,
|
||||
actual: unknown,
|
||||
): {
|
||||
missing: unknown;
|
||||
unexpected: unknown;
|
||||
};
|
||||
/**
|
||||
* Entrypoint wrapper for the web-search provider boundary check.
|
||||
*/
|
||||
export function main(argv: unknown, io: unknown): Promise<1 | 0>;
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Returns command usage text for the aggregate check runner.
|
||||
*/
|
||||
export function usage(): string;
|
||||
/**
|
||||
* Runs selected repository check lanes.
|
||||
*/
|
||||
export function main(argv?: string[]): Promise<void>;
|
||||
/**
|
||||
* Runs one managed check command and returns timing/status details.
|
||||
*/
|
||||
export function runCommand(
|
||||
command: unknown,
|
||||
runManagedCommandImpl?: (options: { args: string[]; bin: string }) => Promise<number>,
|
||||
): Promise<{
|
||||
name: unknown;
|
||||
durationMs: number;
|
||||
status: number;
|
||||
}>;
|
||||
@@ -119,6 +119,7 @@ export async function main(argv = process.argv.slice(2)) {
|
||||
: [
|
||||
{ name: "typecheck prod", args: ["tsgo:prod"] },
|
||||
{ name: "typecheck scripts", args: ["tsgo:scripts"] },
|
||||
{ name: "typecheck test root", args: ["tsgo:test:root"] },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env node
|
||||
export function isRetryableGhJsonErrorMessage(message: unknown): boolean;
|
||||
/**
|
||||
* Flattens paginated GitHub run job responses.
|
||||
*/
|
||||
export function collectRunJobsFromPages(
|
||||
pages: Array<{ jobs?: Array<Record<string, unknown>> }>,
|
||||
): Array<Record<string, unknown>>;
|
||||
/**
|
||||
* Summarizes longest jobs and total timing for a workflow run.
|
||||
*/
|
||||
export function summarizeRunTimings(
|
||||
run: unknown,
|
||||
limit?: number,
|
||||
): {
|
||||
byDuration: Array<{ name: string; durationSeconds: number }>;
|
||||
byQueue: Array<{ name: string; queueSeconds: number }>;
|
||||
conclusion: unknown;
|
||||
status: unknown;
|
||||
wallSeconds: number | null;
|
||||
badJobs: unknown;
|
||||
};
|
||||
/**
|
||||
* Summarizes pnpm store warmup overlap near run start.
|
||||
*/
|
||||
export function summarizePnpmStoreWarmupBarrier(
|
||||
run: unknown,
|
||||
windowSeconds?: number,
|
||||
): {
|
||||
activePostWarmupJobCount: unknown;
|
||||
firstPostWarmupStartDelaySeconds: number | null;
|
||||
postWarmupP95StartDelaySeconds: unknown;
|
||||
postWarmupStartedWithinWindow: unknown;
|
||||
preflightToWarmupCompleteSeconds: number | null;
|
||||
preflightToWarmupStartSeconds: number | null;
|
||||
warmupDurationSeconds: number | null;
|
||||
warmupResult: string;
|
||||
windowSeconds: number;
|
||||
} | null;
|
||||
/**
|
||||
* Selects the latest main push CI run, optionally matching a head SHA.
|
||||
*/
|
||||
export function selectLatestMainPushCiRun(
|
||||
runs: Array<Record<string, unknown>>,
|
||||
headSha?: string | null,
|
||||
): Record<string, unknown> | null;
|
||||
/**
|
||||
* Parses CI run timing CLI arguments.
|
||||
*/
|
||||
export function parseRunTimingArgs(args: unknown): {
|
||||
explicitRunId: unknown;
|
||||
limit: number;
|
||||
recentLimit: number | null;
|
||||
useLatestMain: boolean;
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Parses comma-separated PR numbers from CLI/env input.
|
||||
*/
|
||||
export function parsePrNumberList(value: unknown): number[];
|
||||
/**
|
||||
* Parses duplicate PR close workflow arguments.
|
||||
*/
|
||||
export function parseArgs(
|
||||
argv: string[],
|
||||
env?: NodeJS.ProcessEnv,
|
||||
):
|
||||
| {
|
||||
apply: boolean;
|
||||
duplicates: number[];
|
||||
help: true;
|
||||
labels: string[];
|
||||
landedPr?: number;
|
||||
repo: string;
|
||||
}
|
||||
| {
|
||||
apply: boolean;
|
||||
duplicates: number[];
|
||||
help?: undefined;
|
||||
labels: string[];
|
||||
landedPr: number;
|
||||
repo: string;
|
||||
};
|
||||
/**
|
||||
* Parses changed hunk ranges from unified diff text.
|
||||
*/
|
||||
export function parseUnifiedDiffRanges(diffText: unknown): Map<unknown, unknown>;
|
||||
/**
|
||||
* Builds the close/skip plan for duplicate PR candidates.
|
||||
*/
|
||||
export function buildDuplicateClosePlan({
|
||||
candidates,
|
||||
diffs,
|
||||
landed,
|
||||
repo,
|
||||
}: {
|
||||
candidates: unknown;
|
||||
diffs: unknown;
|
||||
landed: unknown;
|
||||
repo: unknown;
|
||||
}): Array<Record<string, unknown>>;
|
||||
/**
|
||||
* Applies labels/comments/closes for planned duplicate PR actions.
|
||||
*/
|
||||
export function applyClosePlan({
|
||||
labels,
|
||||
plan,
|
||||
repo,
|
||||
runGh,
|
||||
}: {
|
||||
labels?: string[] | undefined;
|
||||
plan: unknown;
|
||||
repo: unknown;
|
||||
runGh: unknown;
|
||||
}): void;
|
||||
/**
|
||||
* Runs the duplicate PR close workflow.
|
||||
*/
|
||||
export function runDuplicateCloseWorkflow(
|
||||
args: unknown,
|
||||
runGh?: (args: string[], options?: Record<string, unknown>) => string,
|
||||
): Array<Record<string, unknown>>;
|
||||
@@ -0,0 +1,3 @@
|
||||
export function canonicalProviderName(provider: unknown): unknown;
|
||||
export function parseProvidersFromHelp(text: unknown): unknown[];
|
||||
export function isProviderAdvertised(provider: unknown, advertisedProviders: unknown): unknown;
|
||||
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Creates a structured dependency diff report from base/head payloads.
|
||||
*/
|
||||
export function createDependencyChangesReport({
|
||||
basePayload,
|
||||
headPayload,
|
||||
dependencyFileChanges,
|
||||
baseLabel,
|
||||
headLabel,
|
||||
generatedAt,
|
||||
}: {
|
||||
basePayload: unknown;
|
||||
headPayload: unknown;
|
||||
dependencyFileChanges?:
|
||||
| Array<{ status: string; path: string; oldPath: string | null }>
|
||||
| undefined;
|
||||
baseLabel?: string | undefined;
|
||||
headLabel?: string | undefined;
|
||||
generatedAt?: string | undefined;
|
||||
}): {
|
||||
generatedAt: string;
|
||||
baseLabel: string;
|
||||
headLabel: string;
|
||||
summary: {
|
||||
basePackages: number;
|
||||
headPackages: number;
|
||||
addedPackages: number;
|
||||
removedPackages: number;
|
||||
changedPackages: number;
|
||||
dependencyFileChanges: number;
|
||||
};
|
||||
dependencyFileChanges: unknown[];
|
||||
addedPackages: {
|
||||
packageName: string;
|
||||
versions: unknown[];
|
||||
}[];
|
||||
removedPackages: {
|
||||
packageName: string;
|
||||
versions: unknown[];
|
||||
}[];
|
||||
changedPackages: {
|
||||
packageName: string;
|
||||
addedVersions: unknown[];
|
||||
removedVersions: unknown[];
|
||||
}[];
|
||||
};
|
||||
/**
|
||||
* Reports whether a path is a dependency-related file.
|
||||
*/
|
||||
export function isDependencyFile(filePath: unknown): boolean;
|
||||
/**
|
||||
* Returns git pathspecs used for dependency diff collection.
|
||||
*/
|
||||
export function dependencyDiffPathspecs(): string[];
|
||||
export function parseArgs(argv: string[]):
|
||||
| {
|
||||
rootDir: string;
|
||||
baseRef: string;
|
||||
baseLockfile: null;
|
||||
headLockfile: string;
|
||||
jsonPath: string | null;
|
||||
markdownPath: string | null;
|
||||
}
|
||||
| {
|
||||
rootDir: string;
|
||||
baseRef: null;
|
||||
baseLockfile: string;
|
||||
headLockfile: string;
|
||||
jsonPath: string | null;
|
||||
markdownPath: string | null;
|
||||
};
|
||||
/**
|
||||
* Runs the dependency changes report CLI.
|
||||
*/
|
||||
export function main(argv?: string[]): Promise<number>;
|
||||
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Extracts the package name from a pnpm lockfile package key.
|
||||
*/
|
||||
export function packageNameFromLockKey(lockKey: unknown): unknown;
|
||||
/**
|
||||
* Collects dependency ownership and transitive surface metadata.
|
||||
*/
|
||||
export function collectDependencyOwnershipSurfaceReport(params?: Record<string, unknown>): {
|
||||
schemaVersion: number;
|
||||
generatedAt: string;
|
||||
target: {
|
||||
packageName: unknown;
|
||||
packageVersion: unknown;
|
||||
gitBranch: string | null;
|
||||
gitCommit: string | null;
|
||||
lockfile: string;
|
||||
ownershipMetadata: string;
|
||||
};
|
||||
summary: {
|
||||
importerCount: number;
|
||||
lockfilePackageCount: number;
|
||||
rootDirectDependencyCount: number;
|
||||
rootClosurePackageCount: number;
|
||||
rootOwnershipRecordCount: number;
|
||||
buildRiskPackageCount: number;
|
||||
};
|
||||
ownershipGaps: string[];
|
||||
staleOwnershipRecords: string[];
|
||||
ownershipWarnings: {
|
||||
name: string;
|
||||
owner: unknown;
|
||||
sourceSections: unknown[];
|
||||
message: string;
|
||||
}[];
|
||||
buildRiskPackages: {
|
||||
name: unknown;
|
||||
lockKey: string;
|
||||
requiresBuild: boolean;
|
||||
hasBin: boolean;
|
||||
platformRestricted: boolean;
|
||||
}[];
|
||||
topRootDependencyCones: {
|
||||
name: string;
|
||||
specifier: unknown;
|
||||
section: string;
|
||||
resolved: string;
|
||||
owner: unknown;
|
||||
class: unknown;
|
||||
risk: unknown;
|
||||
sourceCategory: string | null;
|
||||
sourceSections: unknown[];
|
||||
sourceFileCount: number;
|
||||
closureSize: number;
|
||||
missingSnapshotKeys: unknown[];
|
||||
}[];
|
||||
rootDependencies: {
|
||||
name: string;
|
||||
specifier: unknown;
|
||||
section: string;
|
||||
resolved: string;
|
||||
owner: unknown;
|
||||
class: unknown;
|
||||
risk: unknown;
|
||||
sourceCategory: string | null;
|
||||
sourceSections: unknown[];
|
||||
sourceFileCount: number;
|
||||
closureSize: number;
|
||||
missingSnapshotKeys: unknown[];
|
||||
}[];
|
||||
importerClosures: {
|
||||
importer: string;
|
||||
directDependencyCount: number;
|
||||
closureSize: number;
|
||||
}[];
|
||||
};
|
||||
/**
|
||||
* Collects policy errors from a dependency ownership surface report.
|
||||
*/
|
||||
export function collectDependencyOwnershipSurfaceCheckErrors(report: unknown): unknown;
|
||||
/**
|
||||
* Renders a dependency ownership surface report as Markdown.
|
||||
*/
|
||||
export function renderDependencyOwnershipSurfaceMarkdownReport(report: unknown): string;
|
||||
export function parseArgs(argv: string[]): {
|
||||
asJson: boolean;
|
||||
check: boolean;
|
||||
jsonPath: string | null;
|
||||
markdownPath: string | null;
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Classifies npm advisory findings into report-only findings and hard blockers.
|
||||
*/
|
||||
export type VulnerabilityAdvisory = {
|
||||
id: string;
|
||||
severity: string;
|
||||
title: string;
|
||||
url: string;
|
||||
vulnerable_versions: string;
|
||||
};
|
||||
export type VulnerabilityFinding = VulnerabilityAdvisory & {
|
||||
malware: boolean;
|
||||
packageName: string;
|
||||
production: boolean;
|
||||
};
|
||||
export function classifyVulnerabilityFindings({
|
||||
allAdvisories,
|
||||
productionAdvisories,
|
||||
}: {
|
||||
allAdvisories: Record<string, VulnerabilityAdvisory[]>;
|
||||
productionAdvisories: Record<string, VulnerabilityAdvisory[]>;
|
||||
}): {
|
||||
blockers: VulnerabilityFinding[];
|
||||
findings: VulnerabilityFinding[];
|
||||
};
|
||||
/**
|
||||
* Runs the dependency vulnerability gate against pnpm-lock.yaml.
|
||||
*/
|
||||
export function runDependencyVulnerabilityGate({
|
||||
rootDir,
|
||||
fetchImpl,
|
||||
}?: {
|
||||
rootDir?: string | undefined;
|
||||
fetchImpl?: typeof fetch | undefined;
|
||||
}): Promise<{
|
||||
blockers: VulnerabilityFinding[];
|
||||
findings: VulnerabilityFinding[];
|
||||
generatedAt: string;
|
||||
policy: {
|
||||
blocks: string[];
|
||||
reports: string[];
|
||||
vulnerabilityExceptions: boolean;
|
||||
};
|
||||
graphs: {
|
||||
all: {
|
||||
packages: number;
|
||||
packageVersions: unknown;
|
||||
};
|
||||
production: {
|
||||
packages: number;
|
||||
packageVersions: unknown;
|
||||
};
|
||||
};
|
||||
}>;
|
||||
/**
|
||||
* Renders the dependency vulnerability gate report as Markdown.
|
||||
*/
|
||||
export function renderDependencyVulnerabilityGateMarkdownReport(report: unknown): string;
|
||||
export function main(argv?: string[]): Promise<1 | 0>;
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env node
|
||||
export function parseArgs(argv: unknown): {
|
||||
target: string;
|
||||
sourceRepo: string;
|
||||
sourceSha: string;
|
||||
clawhubRepo: string;
|
||||
clawhubSourceRepo: string;
|
||||
clawhubSourceSha: string;
|
||||
};
|
||||
/**
|
||||
* Resolves the local ClawHub repository path used for docs mirroring.
|
||||
*/
|
||||
export function resolveClawHubRepoPath(value?: string, options?: Record<string, unknown>): string;
|
||||
/**
|
||||
* Mirrors ClawHub docs into the target docs tree.
|
||||
*/
|
||||
export function syncClawHubDocsTree(
|
||||
targetDocsDir: unknown,
|
||||
options?: Record<string, unknown>,
|
||||
): {
|
||||
repository: unknown;
|
||||
sha: unknown;
|
||||
path: string;
|
||||
files: number;
|
||||
};
|
||||
@@ -162,7 +162,9 @@ async function runCronCleanupScenario(params: {
|
||||
gateway: GatewayRpcClient;
|
||||
pidPath: string;
|
||||
}): Promise<{ jobId: string; runId?: string; pid: number; status?: unknown }> {
|
||||
const { assert, waitFor } = await loadMcpChannelsHarness();
|
||||
const harness = await loadMcpChannelsHarness();
|
||||
const assert: McpChannelsHarness["assert"] = harness.assert;
|
||||
const { waitFor } = harness;
|
||||
const { gateway, pidPath } = params;
|
||||
const job = await gateway.request<CronJob>("cron.add", {
|
||||
name: "cron mcp cleanup docker e2e",
|
||||
@@ -245,7 +247,8 @@ async function runSubagentCleanupScenario(params: {
|
||||
pidsPath: string;
|
||||
exitPath: string;
|
||||
}): Promise<{ runId: string; exitedPids: number[]; pids: number[] }> {
|
||||
const { assert } = await loadMcpChannelsHarness();
|
||||
const harness = await loadMcpChannelsHarness();
|
||||
const assert: McpChannelsHarness["assert"] = harness.assert;
|
||||
const { gateway, pidPath, pidsPath, exitPath } = params;
|
||||
await resetProbeFiles({ pidPath, pidsPath, exitPath });
|
||||
|
||||
@@ -295,7 +298,9 @@ async function runSubagentCleanupScenario(params: {
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const { assert, connectGateway } = await loadMcpChannelsHarness();
|
||||
const harness = await loadMcpChannelsHarness();
|
||||
const assert: McpChannelsHarness["assert"] = harness.assert;
|
||||
const { connectGateway } = harness;
|
||||
const gatewayUrl = process.env.GW_URL?.trim();
|
||||
const gatewayToken = process.env.GW_TOKEN?.trim();
|
||||
const stateDir = process.env.OPENCLAW_STATE_DIR?.trim() || path.join(os.homedir(), ".openclaw");
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
export function shouldPrintHelp(argv: string[]): boolean;
|
||||
export function validateCliArgs(argv: string[]): void;
|
||||
export function readPositiveInt(raw: string | undefined, fallback: number, label?: string): number;
|
||||
export function readPositiveTimerMs(
|
||||
raw: string | undefined,
|
||||
fallback: number,
|
||||
label?: string,
|
||||
): number;
|
||||
export function resolveKitchenSinkRpcConfig(env?: NodeJS.ProcessEnv): {
|
||||
commandMaxRssMiB: number;
|
||||
commandTimeoutMs: number;
|
||||
fetchBodyMaxBytes: number;
|
||||
fetchTimeoutMs: number;
|
||||
installTimeoutMs: number;
|
||||
maxRssMiB: number;
|
||||
outputCaptureChars: number;
|
||||
readyTimeoutMs: number;
|
||||
rpcTimeoutMs: number;
|
||||
};
|
||||
export function resolveKitchenSinkRpcPort(
|
||||
env?: NodeJS.ProcessEnv,
|
||||
options?: { findAvailablePort?: () => Promise<number> },
|
||||
): Promise<number>;
|
||||
export function makeEnv(): {
|
||||
root: string;
|
||||
env: {
|
||||
HOME: string;
|
||||
USERPROFILE: string;
|
||||
OPENCLAW_HOME: string;
|
||||
OPENCLAW_STATE_DIR: string;
|
||||
OPENCLAW_CONFIG_PATH: string;
|
||||
OPENCLAW_NO_ONBOARD: string;
|
||||
OPENCLAW_SKIP_PROVIDERS: string;
|
||||
OPENCLAW_KITCHEN_SINK_PERSONALITY: string;
|
||||
};
|
||||
};
|
||||
export function cleanupKitchenSinkEnv(
|
||||
root: string,
|
||||
options?: {
|
||||
attempts?: number;
|
||||
delayMs?: number;
|
||||
throwOnFailure?: boolean;
|
||||
warn?: boolean;
|
||||
},
|
||||
): Promise<boolean>;
|
||||
export function appendBoundedOutput(
|
||||
buffer: { text: string; truncatedChars: number },
|
||||
chunk: string | Uint8Array,
|
||||
maxChars?: number,
|
||||
): {
|
||||
text: string;
|
||||
truncatedChars: number;
|
||||
};
|
||||
export function runCommand(
|
||||
command: string,
|
||||
args: string[],
|
||||
options?: Record<string, unknown>,
|
||||
): Promise<{
|
||||
stderr: string;
|
||||
stdout: string;
|
||||
stderrTruncatedChars: number;
|
||||
stdoutTruncatedChars: number;
|
||||
}>;
|
||||
export function signalProcessGroup(
|
||||
child: { pid?: number; kill(signal?: NodeJS.Signals): unknown },
|
||||
signal: NodeJS.Signals,
|
||||
{
|
||||
platform,
|
||||
runTaskkill,
|
||||
useProcessGroup,
|
||||
}?: {
|
||||
platform?: NodeJS.Platform | undefined;
|
||||
runTaskkill?:
|
||||
| ((
|
||||
command: string,
|
||||
args: string[],
|
||||
options: { stdio: "ignore" },
|
||||
) => { error?: Error; status: number | null })
|
||||
| undefined;
|
||||
useProcessGroup?: boolean | undefined;
|
||||
},
|
||||
): void;
|
||||
export function parseJsonOutput(stdout: string): Record<string, unknown>;
|
||||
export function parseGatewayCliRequestFailure(error: unknown):
|
||||
| (Error & {
|
||||
retryAfterMs?: number;
|
||||
retryable: boolean;
|
||||
details?: Record<string, unknown>;
|
||||
name: string;
|
||||
gatewayCode: string;
|
||||
})
|
||||
| null;
|
||||
export function unwrapRpcPayload(raw: unknown): Record<string, unknown>;
|
||||
export function createRpcCliRunOptions(
|
||||
method: string,
|
||||
options?: { env?: NodeJS.ProcessEnv; commandResourceOptions?: Record<string, unknown> },
|
||||
): Record<string, unknown> & { resourceLabel: string; timeoutMs: number };
|
||||
export function findDistCallGatewayModuleFiles(cwd?: string): string[];
|
||||
export function usesBuiltOpenClawEntry(
|
||||
runner: unknown,
|
||||
cwd?: string,
|
||||
env?: NodeJS.ProcessEnv,
|
||||
): boolean;
|
||||
export function fetchJson(
|
||||
url: unknown,
|
||||
options?: Record<string, unknown>,
|
||||
): Promise<{
|
||||
ok: unknown;
|
||||
status: unknown;
|
||||
body: unknown;
|
||||
}>;
|
||||
export function readBoundedResponseText(
|
||||
response: unknown,
|
||||
byteLimit: number,
|
||||
timeoutPromise?: Promise<never>,
|
||||
): Promise<string>;
|
||||
export function stopGateway(child: unknown, options?: Record<string, unknown>): Promise<void>;
|
||||
export function hasChildExited(child: unknown): boolean;
|
||||
export function signalGateway(
|
||||
child: unknown,
|
||||
signal: unknown,
|
||||
killProcess?: typeof defaultKillProcess,
|
||||
options?: Record<string, unknown>,
|
||||
): boolean;
|
||||
export function createGatewayReadyLogScanner(logPath: unknown, marker?: string): () => boolean;
|
||||
export function waitForGatewayReady(
|
||||
child: unknown,
|
||||
port: unknown,
|
||||
logPath: unknown,
|
||||
options?: Record<string, unknown>,
|
||||
): Promise<void>;
|
||||
export function extractPluginCommandNames(payload: unknown): unknown[];
|
||||
export function assertExpectedKitchenSinkToolEntries(
|
||||
entries: unknown,
|
||||
label: unknown,
|
||||
{
|
||||
requirePluginProvenance,
|
||||
}?: {
|
||||
requirePluginProvenance?: boolean | undefined;
|
||||
},
|
||||
): unknown;
|
||||
export function assertChannelAccountRunning(payload: unknown): unknown;
|
||||
export function extractTtsProviderIds(payload: unknown, surface: unknown): unknown[];
|
||||
export function assertTtsProviderCoverage(payload: unknown, surface: unknown): void;
|
||||
export function assertKitchenSinkSearchInvokeResult(payload: unknown): void;
|
||||
export function assertKitchenSinkTextInvokeResult(payload: unknown): void;
|
||||
export function assertKitchenSinkImageJobInvokeResult(payload: unknown): void;
|
||||
export function listKitchenSinkToolInvokeNames(): string[];
|
||||
export function listKitchenSinkReadOnlyRpcProbeNames(): string[];
|
||||
export function listKitchenSinkAuthorizationRpcProbeNames(): string[];
|
||||
export function assertOperatorRpcDenied(probe: unknown, call: unknown): Promise<void>;
|
||||
export function assertCreatedKitchenSinkSession(payload: unknown, expectedKey?: string): unknown;
|
||||
export function assertKitchenSinkUiDescriptors(
|
||||
payload: unknown,
|
||||
options?: Record<string, unknown>,
|
||||
): unknown;
|
||||
export function assertDiagnosticStabilityClean(payload: unknown): void;
|
||||
export function assertGatewayHealthPayload(payload: unknown): void;
|
||||
export function assertGatewayStatusPayload(payload: unknown): void;
|
||||
export function sampleProcess(
|
||||
pid: unknown,
|
||||
options?: Record<string, unknown>,
|
||||
): Promise<{
|
||||
aggregateRssMiB: number;
|
||||
rssMiB: number;
|
||||
cpuPercent: unknown;
|
||||
processId: unknown;
|
||||
} | null>;
|
||||
export function summarizeProcessSamples(samples: unknown): unknown;
|
||||
export function sampleWindowsProcessByPort(
|
||||
port: unknown,
|
||||
options?: Record<string, unknown>,
|
||||
): Promise<
|
||||
| {
|
||||
rssMiB: number;
|
||||
aggregateRssMiB: number;
|
||||
cpuPercent: null;
|
||||
cpuSeconds: number | null;
|
||||
processId: number;
|
||||
}
|
||||
| {
|
||||
rssMiB: number;
|
||||
cpuPercent: null;
|
||||
cpuSeconds: null;
|
||||
processId: number;
|
||||
}
|
||||
| null
|
||||
>;
|
||||
export function assertResourceCeiling(sample: unknown): void;
|
||||
export function assertCommandResourceCeiling(sample: unknown): void;
|
||||
export function findErrorLogFindings(logPath: string): Array<{ line: string; lineNumber: number }>;
|
||||
export function tailFile(file: string, maxBytes?: number): string;
|
||||
export function main(): Promise<void>;
|
||||
export const MAX_KITCHEN_SINK_TIMER_TIMEOUT_MS: 2147000000;
|
||||
declare function defaultKillProcess(pid: unknown, signal: unknown): true;
|
||||
@@ -0,0 +1,3 @@
|
||||
export function extractAgentReplyTexts(text: string): string[];
|
||||
export function assertAgentReplyContainsMarker(marker: string, outputPath: string): void;
|
||||
export function assertOpenAiRequestLogUsed(requestLogPath: string, label?: string): void;
|
||||
@@ -0,0 +1,6 @@
|
||||
export function readBoundedResponseText(
|
||||
response: unknown,
|
||||
label: unknown,
|
||||
byteLimit: unknown,
|
||||
timeoutPromise?: Promise<never>,
|
||||
): Promise<string>;
|
||||
@@ -0,0 +1,14 @@
|
||||
export function stateDir(): string;
|
||||
export function configPath(): string;
|
||||
export function managedNpmRoot(): string;
|
||||
export function realPathMaybe(filePath: string): string;
|
||||
export function assertPathInside(parentPath: string, childPath: string, label: string): void;
|
||||
import type { PluginInstallRecord } from "./plugin-index-sqlite.mjs";
|
||||
|
||||
export function readInstallRecords(
|
||||
fallbackRecords?: Record<string, PluginInstallRecord>,
|
||||
): Record<string, PluginInstallRecord>;
|
||||
export function npmProjectRootForInstalledPackage(installPath: string, packageName: string): string;
|
||||
export function findPackageJson(packageName: string, roots: string[]): string | undefined;
|
||||
export { readJson };
|
||||
import { readJson } from "./fixtures/common.mjs";
|
||||
@@ -0,0 +1,6 @@
|
||||
export function createJsonlRequestTailer(
|
||||
filePath: string,
|
||||
options?: { historyLimit?: number; maxReadBytes?: number; tailLineLimit?: number },
|
||||
): {
|
||||
read(): unknown[];
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
export function readPositiveIntEnv(
|
||||
name: unknown,
|
||||
fallback: unknown,
|
||||
env?: NodeJS.ProcessEnv,
|
||||
): number;
|
||||
export function readTcpPortEnv(name: unknown, fallback: unknown, env?: NodeJS.ProcessEnv): number;
|
||||
@@ -24,12 +24,12 @@ if (!codexRecord) {
|
||||
if (codexRecord.source !== "npm") {
|
||||
throw new Error(`expected npm codex install record, got ${codexRecord.source}`);
|
||||
}
|
||||
if (!String(codexRecord.spec || "").includes("@openclaw/codex")) {
|
||||
if (!codexRecord.spec?.includes("@openclaw/codex")) {
|
||||
throw new Error(`expected @openclaw/codex install spec, got ${codexRecord.spec}`);
|
||||
}
|
||||
|
||||
const npmRoot = managedNpmRoot();
|
||||
const installPath = String(codexRecord.installPath || "").replace(/^~(?=$|\/)/u, process.env.HOME);
|
||||
const installPath = (codexRecord.installPath || "").replace(/^~(?=$|\/)/u, process.env.HOME);
|
||||
if (!installPath) {
|
||||
throw new Error(`missing codex installPath: ${JSON.stringify(codexRecord)}`);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
export function createConfigReloadLogScanner(
|
||||
logPath: string,
|
||||
options?: { maxReadBytes?: number; tailLineLimit?: number },
|
||||
): {
|
||||
scan(): { reloadLines: string[]; restartLines: string[]; tailLines: string[] };
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
export type FixtureJson = Record<string, unknown> & {
|
||||
bin?: string | { codex?: string };
|
||||
name?: string;
|
||||
};
|
||||
|
||||
export function json(value: unknown): string;
|
||||
export function readJson(file: string): FixtureJson;
|
||||
export function write(file: string, contents: string | NodeJS.ArrayBufferView): void;
|
||||
export function writeJson(file: string, value: unknown): void;
|
||||
export function requireArg(value: string | undefined, name: string): string;
|
||||
export function assert(condition: unknown, message: string): asserts condition;
|
||||
@@ -0,0 +1,2 @@
|
||||
export function parseMockOpenAiPort(value: unknown, label?: string): number;
|
||||
export function applyMockOpenAiModelConfig(cfg: unknown, params: unknown): void;
|
||||
@@ -72,12 +72,14 @@ function assertAgentsDeleteResult([outputPath]) {
|
||||
const message = error instanceof Error ? error.message.split("\n").at(0) : String(error);
|
||||
throw new Error(`agents delete --json parse failed: ${message}`, { cause: error });
|
||||
}
|
||||
for (const [actual, expected, label] of [
|
||||
/** @type {Array<[unknown, unknown, string]>} */
|
||||
const comparisons = [
|
||||
[parsed.agentId, "ops", "agentId"],
|
||||
[parsed.workspace, process.env.SHARED_WORKSPACE, "workspace"],
|
||||
[parsed.workspaceRetained, true, "workspaceRetained"],
|
||||
[parsed.workspaceRetainedReason, "shared", "workspaceRetainedReason"],
|
||||
]) {
|
||||
];
|
||||
for (const [actual, expected, label] of comparisons) {
|
||||
assert(actual === expected, `${label} mismatch: ${JSON.stringify(actual)}`);
|
||||
}
|
||||
assert(
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export function resolveGatewaySuccessPayload(frame: unknown): unknown;
|
||||
@@ -0,0 +1,37 @@
|
||||
export type GatewayFrame = {
|
||||
error?: {
|
||||
code?: string;
|
||||
details?: Record<string, unknown>;
|
||||
message?: string;
|
||||
retryable?: boolean;
|
||||
};
|
||||
id?: string;
|
||||
ok?: boolean;
|
||||
payload?: Record<string, unknown>;
|
||||
type?: string;
|
||||
};
|
||||
export type GatewaySocket = { close(): void; send(payload: string): void };
|
||||
export function assertReadySuspensionResponse(
|
||||
response: Record<string, unknown>,
|
||||
now?: number,
|
||||
): Record<string, unknown>;
|
||||
export function assertGatewaySuspendingError(response: GatewayFrame): void;
|
||||
export function assertSuspendedProbes(
|
||||
health: Record<string, unknown>,
|
||||
readiness: Record<string, unknown>,
|
||||
): void;
|
||||
export function responseError(method: string, response: GatewayFrame): Error;
|
||||
export function runGatewayNetworkClient(
|
||||
options: { token: string; url: string; timeoutMs?: number },
|
||||
deps?: {
|
||||
delay?: (ms: number) => Promise<void>;
|
||||
onceFrame?: (
|
||||
ws: GatewaySocket,
|
||||
predicate: (message: GatewayFrame) => boolean,
|
||||
timeoutMs?: number,
|
||||
) => Promise<GatewayFrame>;
|
||||
openSocket?: (url: string, timeoutMs?: number) => Promise<GatewaySocket>;
|
||||
protocolVersion?: number;
|
||||
stdout?: (message: string) => void;
|
||||
},
|
||||
): Promise<void>;
|
||||
@@ -0,0 +1 @@
|
||||
export function readGatewayNetworkClientConnectTimeoutMs(env?: NodeJS.ProcessEnv): number;
|
||||
@@ -0,0 +1,5 @@
|
||||
export function onceFrame(
|
||||
ws: unknown,
|
||||
filter: (message: Record<string, unknown>) => boolean,
|
||||
timeoutMs?: number,
|
||||
): Promise<Record<string, unknown>>;
|
||||
@@ -0,0 +1,10 @@
|
||||
export function resolvePositiveInteger(value: unknown, fallback: number): number;
|
||||
export function createIncrementalLineReader(
|
||||
filePath: string,
|
||||
options?: { maxReadBytes?: number },
|
||||
): {
|
||||
readLines(): {
|
||||
lines: string[];
|
||||
reset: boolean;
|
||||
};
|
||||
};
|
||||
@@ -416,7 +416,7 @@ function pluginInstallPath() {
|
||||
if (record.source !== "npm" || record.artifactKind !== "npm-pack") {
|
||||
throw new Error(`expected npm-pack install record: ${JSON.stringify(record)}`);
|
||||
}
|
||||
return String(record.installPath || "").replace(/^~(?=$|\/)/u, process.env.HOME);
|
||||
return (record.installPath || "").replace(/^~(?=$|\/)/u, process.env.HOME);
|
||||
}
|
||||
|
||||
function writeFixture() {
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
export function readMockOpenAiHttpLimits(env?: NodeJS.ProcessEnv): {
|
||||
requestMaxBytes?: number;
|
||||
requestLogBodyMaxBytes?: number;
|
||||
};
|
||||
export function isRequestBodyTooLargeError(error: unknown): error is Error;
|
||||
export function readBody(
|
||||
req: unknown,
|
||||
limits?: {
|
||||
requestMaxBytes?: number;
|
||||
requestLogBodyMaxBytes?: number;
|
||||
},
|
||||
): Promise<string>;
|
||||
export function boundedRequestLogBody(
|
||||
value: unknown,
|
||||
bodyText: unknown,
|
||||
limits?: {
|
||||
requestMaxBytes?: number;
|
||||
requestLogBodyMaxBytes: number;
|
||||
},
|
||||
): unknown;
|
||||
export function writeRequestLogEntryOrFail(
|
||||
res: unknown,
|
||||
{
|
||||
requestLog,
|
||||
entry,
|
||||
label,
|
||||
required,
|
||||
}: {
|
||||
requestLog: unknown;
|
||||
entry: unknown;
|
||||
label?: string | undefined;
|
||||
required?: boolean | undefined;
|
||||
},
|
||||
): boolean;
|
||||
export function writeJson(res: unknown, status: unknown, body: unknown): void;
|
||||
export function writeSse(res: unknown, events: unknown): void;
|
||||
@@ -0,0 +1,2 @@
|
||||
export function readLogTail(file: unknown, maxBytes?: number): string;
|
||||
export function logTailContains(file: unknown, needle: unknown, maxBytes?: number): unknown;
|
||||
@@ -0,0 +1,16 @@
|
||||
export namespace testing {
|
||||
export { DEFAULT_GATEWAY_SCHEMA_ERROR };
|
||||
export { DEFAULT_RAW_SCHEMA_ERROR };
|
||||
export { SUCCESS_MARKER };
|
||||
export { extractSuccessReplyTexts };
|
||||
export { resolveGatewayPort };
|
||||
export { validateSuccessResult };
|
||||
export { validateRejectResult };
|
||||
}
|
||||
declare const DEFAULT_GATEWAY_SCHEMA_ERROR: "provider rejected the request schema or tool payload";
|
||||
declare const DEFAULT_RAW_SCHEMA_ERROR: "400 The following tools cannot be used with reasoning.effort 'minimal': web_search.";
|
||||
declare const SUCCESS_MARKER: "OPENCLAW_SCHEMA_E2E_OK";
|
||||
declare function extractSuccessReplyTexts(value: unknown): unknown[];
|
||||
declare function resolveGatewayPort(env?: NodeJS.ProcessEnv): number;
|
||||
declare function validateSuccessResult(result: unknown, marker?: string): void;
|
||||
declare function validateRejectResult(result: unknown, expectedRawSchemaError?: string): string;
|
||||
@@ -0,0 +1,13 @@
|
||||
export function probeHttpStatus({
|
||||
url,
|
||||
expectedRaw,
|
||||
timeoutMs,
|
||||
bearer,
|
||||
fetchImpl,
|
||||
}: {
|
||||
url: unknown;
|
||||
expectedRaw?: string | undefined;
|
||||
timeoutMs?: number | undefined;
|
||||
bearer?: string | undefined;
|
||||
fetchImpl?: typeof fetch | undefined;
|
||||
}): Promise<boolean>;
|
||||
@@ -0,0 +1,23 @@
|
||||
export type PluginInstallRecord = Record<string, unknown> & {
|
||||
artifactKind?: string;
|
||||
gitCommit?: string;
|
||||
installPath?: string;
|
||||
resolvedSpec?: string;
|
||||
resolvedVersion?: string;
|
||||
source?: string;
|
||||
sourcePath?: string;
|
||||
spec?: string;
|
||||
};
|
||||
|
||||
export function stateDir(): string;
|
||||
export function configPath(): string;
|
||||
export function readPluginInstallIndex(options?: Record<string, unknown>): unknown;
|
||||
export function readPluginInstallRecords(options?: {
|
||||
configPath?: string;
|
||||
fallbackRecords?: Record<string, PluginInstallRecord>;
|
||||
stateDir?: string;
|
||||
}): Record<string, PluginInstallRecord>;
|
||||
export function writePluginInstallIndexForE2E(
|
||||
index: unknown,
|
||||
options?: Record<string, unknown>,
|
||||
): void;
|
||||
@@ -0,0 +1,6 @@
|
||||
export function waitForClickClackSocket(params: {
|
||||
baseUrl: string;
|
||||
timeoutMs: number;
|
||||
pollIntervalMs?: number;
|
||||
}): Promise<void>;
|
||||
export function runReleaseUserJourneyAssertion(command: string, args?: string[]): Promise<void>;
|
||||
@@ -0,0 +1,8 @@
|
||||
export function tailText(text: string, maxBytes: number): string;
|
||||
export function readTextFileTail(file: string, maxBytes: number): string;
|
||||
export function readTextFileBounded(
|
||||
file: string,
|
||||
label: string,
|
||||
maxBytes: number,
|
||||
options?: { tailBytes?: number },
|
||||
): string;
|
||||
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env node
|
||||
export function isReleaseBefore(version: unknown, minimum: unknown): boolean;
|
||||
export function resolveUpgradeSurvivorOpenClawCommand(
|
||||
argv: unknown,
|
||||
params?: Record<string, unknown>,
|
||||
):
|
||||
| {
|
||||
command: unknown;
|
||||
args: string[];
|
||||
commandLabel: string;
|
||||
shell: boolean;
|
||||
windowsVerbatimArguments: boolean;
|
||||
}
|
||||
| {
|
||||
command: string;
|
||||
args: unknown;
|
||||
commandLabel: string;
|
||||
shell: boolean;
|
||||
windowsVerbatimArguments?: undefined;
|
||||
};
|
||||
export function runUpgradeSurvivorOpenClawStep(
|
||||
step: unknown,
|
||||
params?: Record<string, unknown>,
|
||||
): {
|
||||
id: unknown;
|
||||
intent: unknown;
|
||||
command: string;
|
||||
status: unknown;
|
||||
signal: unknown;
|
||||
ok: boolean;
|
||||
errorCode: string | undefined;
|
||||
errorMessage: string | undefined;
|
||||
stdout: string;
|
||||
stderr: string;
|
||||
};
|
||||
export const CONFIG_COMMAND_TIMEOUT_MS: 120000;
|
||||
export const CONFIG_COMMAND_MAX_BUFFER_BYTES: number;
|
||||
@@ -0,0 +1,5 @@
|
||||
export function waitForWebSocketOpen(
|
||||
ws: unknown,
|
||||
timeoutMs: unknown,
|
||||
message?: string,
|
||||
): Promise<unknown>;
|
||||
@@ -5,6 +5,7 @@ import { randomUUID } from "node:crypto";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import type { QaProviderMode } from "../../extensions/qa-lab/src/run-config.ts";
|
||||
|
||||
function parseBoolean(value: string | undefined) {
|
||||
const normalized = value?.trim().toLowerCase();
|
||||
@@ -132,7 +133,7 @@ async function main() {
|
||||
repoRoot,
|
||||
outputDir,
|
||||
sutOpenClawCommand,
|
||||
providerMode: process.env.OPENCLAW_NPM_TELEGRAM_PROVIDER_MODE,
|
||||
providerMode: process.env.OPENCLAW_NPM_TELEGRAM_PROVIDER_MODE as QaProviderMode | undefined,
|
||||
primaryModel: process.env.OPENCLAW_NPM_TELEGRAM_MODEL,
|
||||
alternateModel: process.env.OPENCLAW_NPM_TELEGRAM_ALT_MODEL,
|
||||
fastMode: parseBoolean(process.env.OPENCLAW_NPM_TELEGRAM_FAST),
|
||||
@@ -152,7 +153,13 @@ async function main() {
|
||||
|
||||
async function formatRunnerErrorMessage(error: unknown) {
|
||||
try {
|
||||
const { formatErrorMessage } = await import("../../dist/infra/errors.js");
|
||||
// Widen the specifier so the source-only test-root program does not try to
|
||||
// resolve dist (TS2307); the docker-e2e boundary guard requires importing
|
||||
// built dist here, so the cast stays structural instead of a src reference.
|
||||
const distErrorsPath = "../../dist/infra/errors.js" as string;
|
||||
const { formatErrorMessage } = (await import(distErrorsPath)) as {
|
||||
formatErrorMessage: (err: unknown) => string;
|
||||
};
|
||||
return formatErrorMessage(error);
|
||||
} catch {
|
||||
return error instanceof Error ? error.message : String(error);
|
||||
|
||||
@@ -6,6 +6,10 @@ export * from "./host-server.ts";
|
||||
export * from "./lane-runner.ts";
|
||||
export * from "./macos-users.ts";
|
||||
export * from "./package-artifact.ts";
|
||||
// host-server.ts and package-artifact.ts both export a module-private `testing` hook, which
|
||||
// star re-exports silently drop as ambiguous. Re-export one explicitly so the barrel
|
||||
// typechecks (TS2308); import either module's `testing` directly, never through this barrel.
|
||||
export { testing } from "./host-server.ts";
|
||||
export * from "./parallels-vm.ts";
|
||||
export * from "./plugin-isolation.ts";
|
||||
export * from "./provider-auth.ts";
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
// Host Server script supports OpenClaw repository automation.
|
||||
import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
|
||||
import { spawn, type ChildProcess } from "node:child_process";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { rm } from "node:fs/promises";
|
||||
import { createServer } from "node:http";
|
||||
import { createConnection } from "node:net";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
import type { Readable } from "node:stream";
|
||||
import { sleep as delay } from "../../lib/sleep.mjs";
|
||||
import { die, run, say, sh, warn } from "./host-command.ts";
|
||||
import type { HostServer, NpmRegistryPackage, NpmRegistryServer } from "./types.ts";
|
||||
|
||||
const HOST_SERVER_STDERR_LIMIT_BYTES = 64 * 1024;
|
||||
const HOST_SERVER_STDERR_DRAIN_MS = 5_000;
|
||||
type HostServerChild = ChildProcess & { stderr: Readable };
|
||||
|
||||
export function resolveHostIp(explicit = ""): string {
|
||||
if (explicit) {
|
||||
@@ -132,7 +134,7 @@ export async function startNpmRegistryServer(input: {
|
||||
}
|
||||
|
||||
async function stopHostServerChild(
|
||||
child: ChildProcessWithoutNullStreams,
|
||||
child: HostServerChild,
|
||||
terminateTimeoutMs = 2_000,
|
||||
killTimeoutMs = 1_500,
|
||||
): Promise<boolean> {
|
||||
@@ -147,10 +149,7 @@ async function stopHostServerChild(
|
||||
return await waitForChildExit(child, killTimeoutMs);
|
||||
}
|
||||
|
||||
async function waitForChildExit(
|
||||
child: ChildProcessWithoutNullStreams,
|
||||
timeoutMs: number,
|
||||
): Promise<boolean> {
|
||||
async function waitForChildExit(child: HostServerChild, timeoutMs: number): Promise<boolean> {
|
||||
if (hasHostServerChildExited(child)) {
|
||||
return true;
|
||||
}
|
||||
@@ -172,14 +171,11 @@ async function waitForChildExit(
|
||||
});
|
||||
}
|
||||
|
||||
function hasHostServerChildExited(child: ChildProcessWithoutNullStreams): boolean {
|
||||
function hasHostServerChildExited(child: HostServerChild): boolean {
|
||||
return child.exitCode != null || child.signalCode != null;
|
||||
}
|
||||
|
||||
async function waitForHostServer(
|
||||
child: ChildProcessWithoutNullStreams,
|
||||
port: number,
|
||||
): Promise<void> {
|
||||
async function waitForHostServer(child: HostServerChild, port: number): Promise<void> {
|
||||
let stderr = "";
|
||||
child.stderr.on("data", (chunk: Buffer) => {
|
||||
stderr = appendBoundedOutput(stderr, chunk, HOST_SERVER_STDERR_LIMIT_BYTES);
|
||||
@@ -218,7 +214,7 @@ function appendBoundedOutput(previous: string, chunk: Buffer, limitBytes: number
|
||||
return combined.subarray(combined.byteLength - limitBytes).toString("utf8");
|
||||
}
|
||||
|
||||
function formatHostServerExit(child: ChildProcessWithoutNullStreams): string {
|
||||
function formatHostServerExit(child: HostServerChild): string {
|
||||
return child.signalCode ? `signal ${child.signalCode}` : `exit ${child.exitCode ?? "unknown"}`;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ export function parseMacosDsclUserHomeLine(line: string): { user: string; home:
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
return { user: match[1], home: match[2] };
|
||||
return { user: match[1]!, home: match[2]! };
|
||||
}
|
||||
|
||||
export function isLikelyMacosDesktopHome(home: string | undefined): boolean {
|
||||
const normalized = home?.trim();
|
||||
return Boolean(normalized) && /(?:^|\/)Users\/[^/]+$/u.test(normalized);
|
||||
return normalized !== undefined && /(?:^|\/)Users\/[^/]+$/u.test(normalized);
|
||||
}
|
||||
|
||||
@@ -571,7 +571,7 @@ export class NpmUpdateSmoke {
|
||||
private tgzDir = "";
|
||||
private latestVersion = "";
|
||||
private packageSpec = "";
|
||||
private currentHead = "";
|
||||
currentHead = "";
|
||||
private currentHeadShort = "";
|
||||
private harnessCheckoutVersion = "";
|
||||
private harnessTargetFamily = "";
|
||||
|
||||
@@ -7,7 +7,7 @@ import { die, run } from "./host-command.ts";
|
||||
import type { Mode, Platform, Provider, ProviderAuth } from "./types.ts";
|
||||
|
||||
type ResolveLatestVersionDeps = {
|
||||
createTempDir?: typeof mkdtempSync;
|
||||
createTempDir?: (prefix: string) => string;
|
||||
removeDir?: typeof rmSync;
|
||||
runCommand?: typeof run;
|
||||
tempDir?: typeof tmpdir;
|
||||
|
||||
@@ -630,7 +630,11 @@ export function signalCommandTree(
|
||||
useProcessGroup = platform !== "win32",
|
||||
}: {
|
||||
platform?: NodeJS.Platform;
|
||||
runTaskkill?: typeof spawnSync;
|
||||
runTaskkill?: (
|
||||
command: string,
|
||||
args: readonly string[],
|
||||
options: { stdio: "ignore" },
|
||||
) => { error?: Error; status: number | null };
|
||||
useProcessGroup?: boolean;
|
||||
} = {},
|
||||
) {
|
||||
@@ -1206,10 +1210,11 @@ export async function startLocalSut(
|
||||
cwd: params.repoRoot,
|
||||
env: mockServerEnv({ ...params, requestLog }),
|
||||
});
|
||||
const runningMock = mock;
|
||||
await waitForOutputReady(
|
||||
mock.child,
|
||||
runningMock.child,
|
||||
/mock-openai listening/u,
|
||||
() => mock.output,
|
||||
() => runningMock.output,
|
||||
"mock-openai",
|
||||
10_000,
|
||||
);
|
||||
@@ -1219,23 +1224,24 @@ export async function startLocalSut(
|
||||
repoRoot: params.repoRoot,
|
||||
});
|
||||
gateway = spawnLoggedCommand(gatewaySpec.command, gatewaySpec.args, gatewaySpec.options);
|
||||
const runningGateway = gateway;
|
||||
await waitForOutputReady(
|
||||
gateway.child,
|
||||
runningGateway.child,
|
||||
/\[gateway\] ready/u,
|
||||
() => gateway.output,
|
||||
() => runningGateway.output,
|
||||
"gateway",
|
||||
60_000,
|
||||
);
|
||||
return {
|
||||
...config,
|
||||
drained,
|
||||
gateway: gateway.child,
|
||||
gateway: runningGateway.child,
|
||||
get gatewayLog() {
|
||||
return gateway.output;
|
||||
return runningGateway.output;
|
||||
},
|
||||
mock: mock.child,
|
||||
mock: runningMock.child,
|
||||
get mockLog() {
|
||||
return mock.output;
|
||||
return runningMock.output;
|
||||
},
|
||||
requestLog,
|
||||
};
|
||||
@@ -1327,10 +1333,10 @@ async function startLocalSutDaemon(params: {
|
||||
gatewayPid = spawnDaemon({
|
||||
args: gatewaySpec.args,
|
||||
command: gatewaySpec.command,
|
||||
cwd: gatewaySpec.options.cwd ?? params.repoRoot,
|
||||
cwd: (gatewaySpec.options.cwd ?? params.repoRoot) as string,
|
||||
env: gatewaySpec.options.env ?? gatewayEnvVars,
|
||||
logPath: gatewayLog,
|
||||
shell: gatewaySpec.options.shell,
|
||||
shell: gatewaySpec.options.shell as boolean | undefined,
|
||||
windowsVerbatimArguments: gatewaySpec.options.windowsVerbatimArguments,
|
||||
});
|
||||
if (!gatewayPid) {
|
||||
|
||||
@@ -5,6 +5,12 @@ import { resolveWindowsTaskkillPath } from "../lib/windows-taskkill.mjs";
|
||||
|
||||
export type JsonObject = Record<string, unknown>;
|
||||
|
||||
type RunTaskkill = (
|
||||
command: string,
|
||||
args: string[],
|
||||
options: { stdio: "ignore" },
|
||||
) => { error?: Error; status: number | null };
|
||||
|
||||
type FetchJsonParams = {
|
||||
fetchImpl?: (url: string, init: RequestInit) => Promise<Response>;
|
||||
init: RequestInit;
|
||||
@@ -256,7 +262,7 @@ export function signalChildProcessTree(
|
||||
useProcessGroup = platform !== "win32",
|
||||
}: {
|
||||
platform?: NodeJS.Platform;
|
||||
runTaskkill?: typeof spawnSync;
|
||||
runTaskkill?: RunTaskkill;
|
||||
useProcessGroup?: boolean;
|
||||
} = {},
|
||||
) {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Resolves the CLI startup build timeout from environment.
|
||||
*/
|
||||
export type StartupBuildParams = {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
nodeExecPath?: string;
|
||||
rootDir?: string;
|
||||
spawnSync?: (
|
||||
command: string,
|
||||
args: string[],
|
||||
options: Record<string, unknown>,
|
||||
) => { error?: Error; status?: number | null };
|
||||
stdio?: "inherit" | "pipe";
|
||||
};
|
||||
export function resolveCliStartupBuildTimeoutMs(env?: NodeJS.ProcessEnv): number;
|
||||
/**
|
||||
* Reports whether required CLI startup build outputs exist.
|
||||
*/
|
||||
export function hasCliStartupBuild(params?: StartupBuildParams): boolean;
|
||||
/**
|
||||
* Builds CLI startup assets when required outputs are missing.
|
||||
*/
|
||||
export function ensureCliStartupBuild(params?: StartupBuildParams): {
|
||||
built: boolean;
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Resolves the extension memory build timeout from environment.
|
||||
*/
|
||||
export type ExtensionMemoryBuildParams = {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
nodeExecPath?: string;
|
||||
requiredExtensionIds?: string[];
|
||||
rootDir?: string;
|
||||
spawnSync?: (
|
||||
command: string,
|
||||
args: string[],
|
||||
options: Record<string, unknown>,
|
||||
) => { error?: Error; status: number | null };
|
||||
stdio?: "inherit" | "pipe";
|
||||
};
|
||||
export function resolveExtensionMemoryBuildTimeoutMs(env?: NodeJS.ProcessEnv): number;
|
||||
/**
|
||||
* Reports whether built memory extension entries exist.
|
||||
*/
|
||||
export function hasBuiltExtensionMemoryEntries(params?: ExtensionMemoryBuildParams): boolean;
|
||||
/**
|
||||
* Builds memory extension entries when required outputs are missing.
|
||||
*/
|
||||
export function ensureExtensionMemoryBuild(params?: ExtensionMemoryBuildParams): {
|
||||
built: boolean;
|
||||
};
|
||||
@@ -1,29 +1,32 @@
|
||||
import type { spawnSync, SpawnSyncOptions } from "node:child_process";
|
||||
import type { existsSync } from "node:fs";
|
||||
import type { resolvePnpmRunner } from "./pnpm-runner.mjs";
|
||||
|
||||
type Getuid = typeof process.getuid;
|
||||
type SpawnSyncLike = (
|
||||
command: string,
|
||||
args: string[],
|
||||
options?: Record<string, unknown>,
|
||||
) => { error?: Error; status: number | null };
|
||||
type ChromiumInstallOptions = {
|
||||
comSpec?: string;
|
||||
cwd?: string;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
executablePath?: string;
|
||||
existsSync?: typeof existsSync;
|
||||
existsSync?: (path: string) => boolean;
|
||||
getuid?: Getuid;
|
||||
log?: (message: string) => void;
|
||||
platform?: NodeJS.Platform;
|
||||
spawnSync?: typeof spawnSync;
|
||||
stdio?: SpawnSyncOptions["stdio"];
|
||||
spawnSync?: SpawnSyncLike;
|
||||
stdio?: "ignore" | "inherit" | "pipe";
|
||||
};
|
||||
|
||||
export const systemChromiumExecutableCandidates: readonly string[];
|
||||
export function canRunChromiumExecutable(
|
||||
executablePath: string,
|
||||
spawnSync?: typeof spawnSync,
|
||||
spawnSync?: SpawnSyncLike,
|
||||
): boolean;
|
||||
export function resolveSystemChromiumExecutablePath(
|
||||
existsSync?: typeof existsSync,
|
||||
spawnSync?: typeof spawnSync,
|
||||
existsSync?: (path: string) => boolean,
|
||||
spawnSync?: SpawnSyncLike,
|
||||
): string;
|
||||
export function resolvePlaywrightInstallRunner(options?: {
|
||||
comSpec?: string;
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env node
|
||||
export function docsFiles(root?: string, deps?: Record<string, unknown>): string[];
|
||||
export function chunkFilesForCommand(
|
||||
files: unknown,
|
||||
prefixArgs: unknown,
|
||||
maxBytes?: number,
|
||||
): unknown[][];
|
||||
export function resolveOxfmtInvocation(
|
||||
args: unknown,
|
||||
params?: Record<string, unknown>,
|
||||
):
|
||||
| {
|
||||
command: string;
|
||||
args: string[];
|
||||
shell: boolean;
|
||||
windowsVerbatimArguments: boolean;
|
||||
}
|
||||
| {
|
||||
command: string;
|
||||
args: string[];
|
||||
shell: boolean;
|
||||
windowsVerbatimArguments?: undefined;
|
||||
}
|
||||
| {
|
||||
command: string;
|
||||
args: string[];
|
||||
shell: boolean;
|
||||
windowsVerbatimArguments?: undefined;
|
||||
};
|
||||
export function runOxfmt(
|
||||
files: unknown,
|
||||
params?: Record<string, unknown>,
|
||||
deps?: Record<string, unknown>,
|
||||
): void;
|
||||
export function formatDocs(
|
||||
params?: Record<string, unknown>,
|
||||
deps?: Record<string, unknown>,
|
||||
): {
|
||||
changed: unknown[];
|
||||
fileCount: number;
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env node
|
||||
export function parseArgs(argv: unknown): {
|
||||
sha: string;
|
||||
workflowSha: string;
|
||||
keepBranch: boolean;
|
||||
dryRun: boolean;
|
||||
inputs: {
|
||||
provider: string;
|
||||
mode: string;
|
||||
release_profile: string;
|
||||
rerun_group: string;
|
||||
reuse_evidence: string;
|
||||
};
|
||||
};
|
||||
export function releaseEvidenceVerificationArgs(parentRunId: unknown): string[];
|
||||
export function releaseEvidenceVerifierPath(worktreeRoot: unknown): string;
|
||||
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Resolves the release tag when the release ref is a SHA or tag.
|
||||
*/
|
||||
export function resolveReleaseTag({
|
||||
releaseRef,
|
||||
packageVersion,
|
||||
}: {
|
||||
releaseRef: unknown;
|
||||
packageVersion: unknown;
|
||||
}): unknown;
|
||||
/**
|
||||
* Resolves the previous reachable release tag for dependency diffs.
|
||||
*/
|
||||
export function resolvePreviousReleaseTag({
|
||||
rootDir,
|
||||
execFileSyncImpl,
|
||||
fetchOnMiss,
|
||||
}?: {
|
||||
rootDir?: string | undefined;
|
||||
execFileSyncImpl?: ((command: string, args?: string[]) => string) | undefined;
|
||||
fetchOnMiss?: boolean | undefined;
|
||||
}): string;
|
||||
/**
|
||||
* Creates the dependency evidence manifest payload.
|
||||
*/
|
||||
export function createDependencyEvidenceManifest({
|
||||
generatedAt,
|
||||
releaseTag,
|
||||
releaseRef,
|
||||
releaseSha,
|
||||
npmDistTag,
|
||||
packageVersion,
|
||||
workflowRunId,
|
||||
workflowRunAttempt,
|
||||
dependencyChangeBaseRef,
|
||||
}?: {
|
||||
generatedAt?: string | undefined;
|
||||
releaseTag?: string;
|
||||
releaseRef?: string;
|
||||
releaseSha?: string;
|
||||
npmDistTag?: string;
|
||||
packageVersion?: string;
|
||||
dependencyChangeBaseRef?: string;
|
||||
workflowRunId?: string | undefined;
|
||||
workflowRunAttempt?: string | undefined;
|
||||
}): {
|
||||
schemaVersion: number;
|
||||
generatedAt: string;
|
||||
releaseTag: unknown;
|
||||
releaseRef: unknown;
|
||||
releaseSha: unknown;
|
||||
npmDistTag: unknown;
|
||||
packageName: string;
|
||||
packageVersion: unknown;
|
||||
workflowRunId: string;
|
||||
workflowRunAttempt: string;
|
||||
dependencyChangeBaseRef: unknown;
|
||||
reports: {
|
||||
name: string;
|
||||
command: string;
|
||||
policy: string;
|
||||
json: string;
|
||||
markdown: string;
|
||||
}[];
|
||||
};
|
||||
/**
|
||||
* Reads generated reports and collects summary counts.
|
||||
*/
|
||||
export function collectDependencyEvidenceSummaryCounts(evidenceDir: unknown): Promise<{
|
||||
vulnerabilityBlockers: unknown;
|
||||
vulnerabilityFindings: unknown;
|
||||
transitiveRiskSignals: unknown;
|
||||
workspaceExcludedTransitiveSignals: unknown;
|
||||
transitiveMetadataFailures: unknown;
|
||||
ownershipLockfilePackages: unknown;
|
||||
ownershipBuildRiskPackages: unknown;
|
||||
dependencyFileChanges: unknown;
|
||||
dependencyAddedPackages: unknown;
|
||||
dependencyRemovedPackages: unknown;
|
||||
dependencyChangedPackages: unknown;
|
||||
}>;
|
||||
/**
|
||||
* Renders the dependency evidence Markdown summary.
|
||||
*/
|
||||
export function renderDependencyEvidenceSummary({
|
||||
releaseTag,
|
||||
releaseSha,
|
||||
baseRef,
|
||||
counts,
|
||||
}: {
|
||||
releaseTag: unknown;
|
||||
releaseSha: unknown;
|
||||
baseRef: unknown;
|
||||
counts: unknown;
|
||||
}): string;
|
||||
/**
|
||||
* Renders the GitHub Actions step summary for dependency evidence.
|
||||
*/
|
||||
export function renderDependencyEvidenceStepSummary({
|
||||
evidenceArtifactName,
|
||||
baseRef,
|
||||
counts,
|
||||
}: {
|
||||
evidenceArtifactName: unknown;
|
||||
baseRef: unknown;
|
||||
counts: unknown;
|
||||
}): string;
|
||||
export function parseArgs(argv: string[]): {
|
||||
help?: true;
|
||||
rootDir: string;
|
||||
outputDir: string | null;
|
||||
releaseRef: string | null;
|
||||
npmDistTag: string | null;
|
||||
baseRef: string | null;
|
||||
githubOutput: string | undefined;
|
||||
githubStepSummary: string | undefined;
|
||||
};
|
||||
/**
|
||||
* Runs the dependency release evidence generator CLI.
|
||||
*/
|
||||
export function main(argv?: string[]): Promise<number>;
|
||||
/**
|
||||
* Dependency evidence reports generated for release artifacts.
|
||||
*/
|
||||
export const DEPENDENCY_EVIDENCE_REPORTS: {
|
||||
name: string;
|
||||
command: string;
|
||||
policy: string;
|
||||
json: string;
|
||||
markdown: string;
|
||||
}[];
|
||||
import { execFileSync } from "node:child_process";
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
export namespace testing {
|
||||
export { cleanHeadingText };
|
||||
}
|
||||
declare function cleanHeadingText(value: unknown): unknown;
|
||||
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Resolves the npm command invocation used by shrinkwrap generation.
|
||||
*/
|
||||
export function createNpmShrinkwrapCommand(
|
||||
args: string[],
|
||||
options?: {
|
||||
comSpec?: string;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
execPath?: string;
|
||||
existsSync?: (candidate: string) => boolean;
|
||||
platform?: NodeJS.Platform;
|
||||
},
|
||||
): {
|
||||
args: string[];
|
||||
command: string;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
shell: boolean;
|
||||
windowsVerbatimArguments?: boolean;
|
||||
};
|
||||
/**
|
||||
* Reads a positive integer env override for shrinkwrap subprocess limits.
|
||||
*/
|
||||
export function readPositiveIntEnv(
|
||||
name: unknown,
|
||||
fallback: unknown,
|
||||
env?: NodeJS.ProcessEnv,
|
||||
): number;
|
||||
/**
|
||||
* Builds execFileSync options with bounded timeout and output buffer limits.
|
||||
*/
|
||||
export function createNpmShrinkwrapExecOptions(
|
||||
invocation: unknown,
|
||||
cwd: unknown,
|
||||
env?: NodeJS.ProcessEnv,
|
||||
): {
|
||||
cwd: unknown;
|
||||
env: unknown;
|
||||
maxBuffer: number;
|
||||
shell: unknown;
|
||||
stdio: string[];
|
||||
timeout: number;
|
||||
windowsVerbatimArguments: unknown;
|
||||
};
|
||||
export function resolvePackageDirs(args: string[]): {
|
||||
check: unknown;
|
||||
changedPaths: string[];
|
||||
jobs: number;
|
||||
packageDirs: unknown[];
|
||||
};
|
||||
export function runBoundedTasks<Item, Result>(
|
||||
items: Item[],
|
||||
jobs: number,
|
||||
runTask: (item: Item) => Promise<Result>,
|
||||
): Promise<Result[]>;
|
||||
export function resolveShrinkwrapJobs(
|
||||
rawValue: unknown,
|
||||
env?: NodeJS.ProcessEnv,
|
||||
fallback?: number,
|
||||
): number;
|
||||
export function collectCurrentShrinkwrapOverrides(
|
||||
shrinkwrap: unknown,
|
||||
declaredDependencies?: Set<unknown>,
|
||||
pnpmLockPackages?: Set<unknown>,
|
||||
): unknown;
|
||||
export function collectOverrideViolations(
|
||||
lockfile: unknown,
|
||||
overrideRules: unknown,
|
||||
): {
|
||||
path: string;
|
||||
packageName: unknown;
|
||||
actualVersion: unknown;
|
||||
expectedVersion: unknown;
|
||||
packagePath: {
|
||||
name: unknown;
|
||||
path: string;
|
||||
}[];
|
||||
}[];
|
||||
export function collectPnpmLockViolations(
|
||||
shrinkwrap: unknown,
|
||||
pnpmLockPackages?: Set<unknown>,
|
||||
): {
|
||||
path: string;
|
||||
packageKey: string;
|
||||
}[];
|
||||
export function disableShrinkwrappedOverrideConflictSources(
|
||||
lockfile: unknown,
|
||||
overrideRules: unknown,
|
||||
): string[];
|
||||
export function exactOverrideRulesFromOverrides(overrides: unknown): unknown;
|
||||
export function exactVersionFromOverrideSpec(spec: unknown): string | null;
|
||||
export function mergeOverrides(
|
||||
packageOverrides: unknown,
|
||||
workspaceOverrides: unknown,
|
||||
pnpmLockOverrides: unknown,
|
||||
): unknown;
|
||||
export function applyPackageExtensionPeerMetadata(
|
||||
lockfile: unknown,
|
||||
packageExtensions?: unknown,
|
||||
): unknown;
|
||||
export function normalizeNpmVersionDrift<T>(lockfile: T): T;
|
||||
export function packageJsonForShrinkwrap(
|
||||
packageJson: Record<string, unknown>,
|
||||
shrinkwrapOverrides: Record<string, unknown>,
|
||||
): {
|
||||
dependencies?: Record<string, string>;
|
||||
devDependencies?: Record<string, string>;
|
||||
peerDependencies?: Record<string, string>;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
export function packageDependencyInputsChanged(packageDir: unknown, changedPaths: unknown): unknown;
|
||||
export function pnpmLockOverrideVersionForVersions(versions: unknown): unknown;
|
||||
export function parsePnpmPackageKey(packageKey: unknown): {
|
||||
name: string;
|
||||
version: string;
|
||||
} | null;
|
||||
export function parseLockPackagePath(lockPath: unknown): {
|
||||
name: unknown;
|
||||
path: string;
|
||||
}[];
|
||||
export function readShrinkwrapOverrides(): unknown;
|
||||
export function restoreCurrentPnpmLockedPackages(
|
||||
generated: unknown,
|
||||
current: unknown,
|
||||
pnpmLockPackages?: Set<unknown>,
|
||||
): unknown;
|
||||
export function shouldUseLegacyPeerDepsForShrinkwrap(
|
||||
packageJson: unknown,
|
||||
packageExtensions?: unknown,
|
||||
): boolean;
|
||||
export function shrinkwrapPackageDirsForChangedPaths(changedPaths: string[]): string[];
|
||||
@@ -0,0 +1,21 @@
|
||||
export const managedLabelSpecs: Record<string, { color: string; description: string }>;
|
||||
export const candidateLabels: {
|
||||
blankTemplate: string;
|
||||
lowSignalDocs: string;
|
||||
docsDiscoverability: string;
|
||||
testOnlyNoBug: string;
|
||||
refactorOnly: string;
|
||||
needsPrContext: string;
|
||||
dirtyCandidate: string;
|
||||
riskyInfra: string;
|
||||
externalPluginCandidate: string;
|
||||
};
|
||||
export function classifyPullRequestCandidateLabels(
|
||||
pullRequest: Record<string, unknown>,
|
||||
files: Array<{ filename: string; status: string }>,
|
||||
): string[];
|
||||
export function runBarnacleAutoResponse(params: {
|
||||
github: Record<string, unknown>;
|
||||
context: Record<string, unknown>;
|
||||
core?: Pick<Console, "info">;
|
||||
}): Promise<void>;
|
||||
@@ -0,0 +1,105 @@
|
||||
export const GITHUB_API_REQUEST_TIMEOUT_MS: number;
|
||||
export const GITHUB_ERROR_BODY_MAX_BYTES: number;
|
||||
export const GITHUB_RESPONSE_BODY_MAX_BYTES: number;
|
||||
export const dependencyChangedLabel: "dependencies-changed";
|
||||
|
||||
type Comment = {
|
||||
body?: string;
|
||||
created_at?: string;
|
||||
html_url?: string;
|
||||
user?: { login?: string };
|
||||
};
|
||||
|
||||
type PullRequest = {
|
||||
head?: { ref?: string; repo?: { full_name?: string }; sha?: string };
|
||||
maintainer_can_modify?: boolean;
|
||||
user?: { login?: string };
|
||||
};
|
||||
|
||||
type ActorCandidate = { login: string; source: string };
|
||||
|
||||
export function isDependencyFile(filename: string): boolean;
|
||||
export function isDependencyManifest(filename: string): boolean;
|
||||
export function isPackageLockfile(filename: string): boolean;
|
||||
export function dependencyFieldChanges(
|
||||
baseManifest: Record<string, unknown>,
|
||||
headManifest: Record<string, unknown>,
|
||||
): string[];
|
||||
export function shouldAutoscrubDependencyLockfiles(options: {
|
||||
dependencyFiles?: string[];
|
||||
lockfileChanges: unknown[];
|
||||
dependencyManifestChanges?: unknown[];
|
||||
}): boolean;
|
||||
export function canAutoscrubPullRequest(options: {
|
||||
owner: string;
|
||||
repo: string;
|
||||
pullRequest: PullRequest;
|
||||
}): boolean;
|
||||
export function sanitizeDisplayValue(value: unknown): string;
|
||||
export function markdownCode(value: unknown): string;
|
||||
export function readBoundedGitHubJson(
|
||||
response: Response,
|
||||
maxBytes?: number,
|
||||
options?: { signal?: AbortSignal },
|
||||
): Promise<unknown>;
|
||||
export function findDependencyOverrideCommand(options: {
|
||||
comments: Comment[];
|
||||
expectedSha: string;
|
||||
isSecurityMember: (login: string) => boolean;
|
||||
newerThan?: string;
|
||||
}): { login: string; reason: string | null; sha: string; url?: string } | null;
|
||||
export function findDependencyOverrideCommandAsync(options: {
|
||||
comments: Comment[];
|
||||
expectedSha: string;
|
||||
isSecurityMember: (login: string) => Promise<boolean>;
|
||||
newerThan: string;
|
||||
}): Promise<{ login: string; reason: string | null; sha: string; url?: string } | null>;
|
||||
export function dependencyGuardCommentHeadSha(comment: Comment): string | null;
|
||||
export function dependencyOverrideExpectedSha(
|
||||
existingGuardComment: Comment | null,
|
||||
currentHeadSha: string,
|
||||
): string | null;
|
||||
export function isDependencyGuardAuthorizedForHead(
|
||||
comment: Comment,
|
||||
currentHeadSha: string,
|
||||
): boolean;
|
||||
export function isDependencyGuardTrustedForHead(comment: Comment, currentHeadSha: string): boolean;
|
||||
export function securityApproverSet(value: unknown): Set<string>;
|
||||
export function dependencyGuardCommentAuthors(value?: unknown): Set<string>;
|
||||
export function isDependencyGuardMarkerComment(
|
||||
comment: Comment,
|
||||
marker: string,
|
||||
trustedAuthors: Set<string>,
|
||||
): boolean;
|
||||
export function renderAuthorizedDependencyComment(override: Record<string, unknown>): string;
|
||||
export function renderTrustedDependencyComment(options: {
|
||||
actor: { login: string; reason: string };
|
||||
headSha: string;
|
||||
}): string;
|
||||
export function renderAutoscrubbedDependencyComment(options: {
|
||||
baseBranch: string;
|
||||
lockfileChanges: string[];
|
||||
commitSha: string;
|
||||
}): string;
|
||||
export function isAutoscrubbedDependencyComment(comment: Comment): boolean;
|
||||
export function renderClearedDependencyGuardComment(options: { headSha: string }): string;
|
||||
export function renderBlockedDependencyComment(options: Record<string, unknown>): string;
|
||||
export function dependencyGuardTrustedActorCandidates(options: {
|
||||
pullRequest: PullRequest;
|
||||
event: Record<string, unknown>;
|
||||
currentHeadSha: string;
|
||||
}): ActorCandidate[];
|
||||
export function findTrustedDependencyGuardActor(options: {
|
||||
candidates: ActorCandidate[];
|
||||
isDependencyApprover: (login: string) => Promise<string | null>;
|
||||
}): Promise<{ login: string; reason: string } | null>;
|
||||
export function githubApi(
|
||||
token: string,
|
||||
options?: {
|
||||
fetchImpl?: typeof fetch;
|
||||
responseMaxBodyBytes?: number;
|
||||
timeoutMs?: number;
|
||||
},
|
||||
): { request(path: string, options?: Record<string, unknown>): Promise<unknown> };
|
||||
export function createAutoscrubCommit(...args: unknown[]): Promise<unknown>;
|
||||
export function readBoundedGitHubErrorText(...args: unknown[]): Promise<string>;
|
||||
@@ -0,0 +1,40 @@
|
||||
export const PROOF_OVERRIDE_LABEL: "proof: override";
|
||||
export const PROOF_SUFFICIENT_LABEL: "proof: sufficient";
|
||||
export const NEEDS_PR_CONTEXT_LABEL: "triage: needs-pr-context";
|
||||
export const DEFAULT_GITHUB_API_TIMEOUT_MS: 30000;
|
||||
|
||||
type PullRequest = Record<string, unknown>;
|
||||
type Comment = Record<string, unknown>;
|
||||
type Evaluation = {
|
||||
status: string;
|
||||
reason: string;
|
||||
applies: boolean;
|
||||
passed: boolean;
|
||||
missingSections: string[];
|
||||
};
|
||||
|
||||
export function readBoundedGitHubApiJson(
|
||||
response: Response,
|
||||
label: string,
|
||||
maxBytes?: number,
|
||||
options?: { timeoutMs?: number },
|
||||
): Promise<unknown>;
|
||||
export function isMaintainerTeamMember(params?: {
|
||||
token?: string;
|
||||
org?: string;
|
||||
login?: string;
|
||||
teamSlug?: string;
|
||||
fetch?: typeof globalThis.fetch;
|
||||
timeoutMs?: number;
|
||||
}): Promise<boolean>;
|
||||
export function hasAuthoredPullRequestSection(heading: string, body?: string): boolean;
|
||||
export function hasClawSweeperExactHeadProof(params?: {
|
||||
pullRequest?: PullRequest;
|
||||
comments?: Comment[];
|
||||
}): boolean;
|
||||
export function evaluateClawSweeperExactHeadProof(params?: {
|
||||
pullRequest?: PullRequest;
|
||||
comments?: Comment[];
|
||||
}): Evaluation;
|
||||
export function evaluatePullRequestContext(params?: { pullRequest?: PullRequest }): Evaluation;
|
||||
export function labelsForPullRequestContext(evaluation: Evaluation): string[];
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user