fix: 透传NapCat自动化命令覆盖参数

This commit is contained in:
sunlei 2026-06-25 02:04:45 +08:00
parent fc750ddcf1
commit 30222fd85e
2 changed files with 81 additions and 6 deletions

View File

@ -209,6 +209,61 @@ export async function runSelfTest(): Promise<void> {
) {
throw new Error("NAS Codex bootstrap default alignment self-check failed");
}
const napcatCandidateOverride = buildNapcatSyncCandidateReview({
candidateBranch: "custom-candidate",
lastAcceptedUpstreamBase: "custom-base",
});
const napcatCandidateOverrideCommandText =
napcatCandidateOverride.commands.map((item) => item.command).join("\n");
if (
!napcatCandidateOverrideCommandText.includes("custom-candidate") ||
!napcatCandidateOverrideCommandText.includes("custom-base") ||
napcatCandidateOverrideCommandText.includes(
napcatAutomationDefaults.candidateBranch,
) ||
napcatCandidateOverrideCommandText.includes(
napcatAutomationDefaults.lastAcceptedUpstreamBase,
)
) {
throw new Error("NapCat candidate command override self-check failed");
}
const napcatRuntimeOverride = buildNapcatRuntimeReleaseReadiness({
napcatImageTag: "custom-image",
});
const napcatRuntimeOverrideCommandText =
napcatRuntimeOverride.commands.map((item) => item.command).join("\n");
if (
!napcatRuntimeOverrideCommandText.includes("custom-image") ||
napcatRuntimeOverrideCommandText.includes(
napcatAutomationDefaults.runtimeImageTag,
)
) {
throw new Error("NapCat runtime command override self-check failed");
}
const napcatAuditOverride = buildNapcatUpstreamAudit({
dryMergeConflict: false,
forkBranch: "custom-fork",
forkPatchFiles: [],
lastAcceptedUpstreamBase: "custom-base",
upstreamChangedFiles: [],
upstreamReleaseTag: "custom-upstream",
});
const napcatAuditOverrideCommandText =
napcatAuditOverride.commands.map((item) => item.command).join("\n");
if (
!napcatAuditOverrideCommandText.includes("custom-fork") ||
!napcatAuditOverrideCommandText.includes("custom-base") ||
!napcatAuditOverrideCommandText.includes("custom-upstream") ||
napcatAuditOverrideCommandText.includes(napcatAutomationDefaults.forkBranch) ||
napcatAuditOverrideCommandText.includes(
napcatAutomationDefaults.lastAcceptedUpstreamBase,
) ||
napcatAuditOverrideCommandText.includes(
napcatAutomationDefaults.upstreamReleaseRef,
)
) {
throw new Error("NapCat upstream audit command override self-check failed");
}
const packageJson = JSON.parse(
readFileSync(resolveInsideRoot("mcp/ktWorkflow/package.json"), "utf8"),
) as { scripts?: Record<string, string> };

View File

@ -221,13 +221,13 @@ export function buildNapcatSyncCandidateReview(
},
{
command:
`git log --oneline --decorate -n 20 "\${CANDIDATE_BRANCH:-${napcatAutomationDefaults.candidateBranch}}"`,
`git log --oneline --decorate -n 20 ${shellEnvFallback('CANDIDATE_BRANCH', context.candidateBranch)}`,
description: 'Inspect recent candidate commits without changing refs.',
readOnly: true,
},
{
command:
`git diff --stat "\${LAST_ACCEPTED_UPSTREAM_BASE:-${napcatAutomationDefaults.lastAcceptedUpstreamBase}}..\${CANDIDATE_BRANCH:-${napcatAutomationDefaults.candidateBranch}}"`,
`git diff --stat ${shellEnvFallback('LAST_ACCEPTED_UPSTREAM_BASE', context.lastAcceptedUpstreamBase)}..${shellEnvFallback('CANDIDATE_BRANCH', context.candidateBranch)}`,
description: 'Summarize candidate file churn for human review.',
readOnly: true,
},
@ -271,7 +271,7 @@ export function buildNapcatRuntimeReleaseReadiness(
},
{
command:
'docker image inspect "${NAPCAT_IMAGE_TAG:-kt-napcat-desktop-cn:desktop-cn}"',
`docker image inspect ${shellEnvFallback('NAPCAT_IMAGE_TAG', context.napcatImageTag)}`,
description: 'Read the NAS-local NapCat image metadata without pulling or building.',
readOnly: true,
},
@ -395,6 +395,21 @@ function shellQuotePath(value: string): string {
return `'${value.replace(/'/g, `'\\''`)}'`;
}
/**
* Builds a double-quoted POSIX shell parameter expansion with a resolved fallback value.
* @param variableName - Environment variable name that may override the generated command at execution time.
* @param fallbackValue - Resolved builder context value used when the environment variable is unset.
* @returns A shell token such as `"${NAME:-fallback}"` with double-quote metacharacters escaped.
*/
function shellEnvFallback(variableName: string, fallbackValue: string): string {
const escapedFallback = fallbackValue
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\$/g, '\\$')
.replace(/`/g, '\\`');
return `"\${${variableName}:-${escapedFallback}}"`;
}
/**
* Derives the default trusted Codex home from the NAS workspace root layout.
* @param workspaceRoot - Linux workspace root passed to `codex exec --cd`, usually `/vol1/docker/kt-codex/workspace/KT`.
@ -1022,6 +1037,11 @@ export function buildNapcatUpstreamAudit(
): NapcatUpstreamAuditResult {
const classification = classifyNapcatUpstreamAudit(input);
const artifactRoot = resolveNapcatArtifactRoot(input.artifactRoot);
const forkBranch = input.forkBranch ?? napcatAutomationDefaults.forkBranch;
const lastAcceptedUpstreamBase =
input.lastAcceptedUpstreamBase ?? napcatAutomationDefaults.lastAcceptedUpstreamBase;
const upstreamReleaseTag =
input.upstreamReleaseTag ?? napcatAutomationDefaults.upstreamReleaseRef;
const commands: NapcatAuditCommand[] = [
{
command: 'git status --short --branch',
@ -1042,19 +1062,19 @@ export function buildNapcatUpstreamAudit(
},
{
command:
`git diff --name-only "\${LAST_ACCEPTED_UPSTREAM_BASE:-${napcatAutomationDefaults.lastAcceptedUpstreamBase}}..\${UPSTREAM_RELEASE_REF:-${napcatAutomationDefaults.upstreamReleaseRef}}"`,
`git diff --name-only ${shellEnvFallback('LAST_ACCEPTED_UPSTREAM_BASE', lastAcceptedUpstreamBase)}..${shellEnvFallback('UPSTREAM_RELEASE_REF', upstreamReleaseTag)}`,
description: 'List upstream release files changed since the last accepted base.',
readOnly: true,
},
{
command:
`git diff --name-only "\${LAST_ACCEPTED_UPSTREAM_BASE:-${napcatAutomationDefaults.lastAcceptedUpstreamBase}}..\${FORK_BRANCH:-${napcatAutomationDefaults.forkBranch}}"`,
`git diff --name-only ${shellEnvFallback('LAST_ACCEPTED_UPSTREAM_BASE', lastAcceptedUpstreamBase)}..${shellEnvFallback('FORK_BRANCH', forkBranch)}`,
description: 'List KT fork patch files for deterministic overlap checks.',
readOnly: true,
},
{
command:
`git merge-tree "\${FORK_BRANCH:-${napcatAutomationDefaults.forkBranch}}" "\${UPSTREAM_RELEASE_REF:-${napcatAutomationDefaults.upstreamReleaseRef}}"`,
`git merge-tree ${shellEnvFallback('FORK_BRANCH', forkBranch)} ${shellEnvFallback('UPSTREAM_RELEASE_REF', upstreamReleaseTag)}`,
description: 'Probe the dry merge shape without updating the worktree or refs.',
readOnly: true,
},