Extract paired source ref helpers

This commit is contained in:
ejclaw
2026-04-29 10:22:33 +09:00
parent 8051505413
commit 247a710ae7
5 changed files with 55 additions and 50 deletions

View File

@@ -11,12 +11,14 @@ import { logger } from './logger.js';
import { markPairedTaskReviewReady } from './paired-workspace-manager.js';
import {
applyPairedTaskPatch,
hasCodeChangesSinceRef,
requestArbiterOrEscalate,
resolveCanonicalSourceRef,
transitionPairedTaskStatus,
} from './paired-execution-context-shared.js';
import { resolveOwnerCompletionSignal } from './paired-completion-signals.js';
import {
hasCodeChangesSinceRef,
resolveCanonicalSourceRef,
} from './paired-source-ref.js';
import { parseVisibleVerdict } from './paired-verdict.js';
import type { PairedTask } from './types.js';

View File

@@ -3,13 +3,13 @@ import { getPairedWorkspace } from './db.js';
import { logger } from './logger.js';
import {
requestArbiterOrEscalate,
resolveCanonicalSourceRef,
transitionPairedTaskStatus,
} from './paired-execution-context-shared.js';
import {
resolveReviewerCompletionSignal,
resolveReviewerFailureSignal,
} from './paired-completion-signals.js';
import { resolveCanonicalSourceRef } from './paired-source-ref.js';
import { parseVisibleVerdict } from './paired-verdict.js';
import type { PairedTask } from './types.js';

View File

@@ -1,5 +1,3 @@
import { execFileSync } from 'child_process';
import { isArbiterEnabled } from './config.js';
import { updatePairedTaskIfUnchanged } from './db.js';
import { logger } from './logger.js';
@@ -16,50 +14,10 @@ export {
parseVisibleVerdict,
} from './paired-verdict.js';
export type { ArbiterVerdictResult, VisibleVerdict } from './paired-verdict.js';
export function resolveCanonicalSourceRef(workDir: string): string {
const treeHash = resolveCanonicalTreeHash(workDir);
return treeHash || 'HEAD';
}
function resolveCanonicalTreeHash(workDir: string): string | null {
try {
const treeHash = execFileSync('git', ['rev-parse', 'HEAD^{tree}'], {
cwd: workDir,
encoding: 'utf-8',
stdio: ['ignore', 'pipe', 'pipe'],
}).trim();
return treeHash || null;
} catch {
return null;
}
}
export function hasCodeChangesSinceRef(
workDir: string,
sourceRef: string | null | undefined,
): boolean | null {
if (!sourceRef) return null;
try {
execFileSync('git', ['diff', '--quiet', sourceRef, 'HEAD'], {
cwd: workDir,
stdio: ['ignore', 'pipe', 'pipe'],
});
return false;
} catch (error) {
const exitCode =
typeof error === 'object' &&
error !== null &&
'status' in error &&
typeof (error as { status?: unknown }).status === 'number'
? (error as { status: number }).status
: null;
if (exitCode === 1) {
return true;
}
return null;
}
}
export {
hasCodeChangesSinceRef,
resolveCanonicalSourceRef,
} from './paired-source-ref.js';
const ALLOWED_PAIRED_STATUS_TRANSITIONS: Record<
PairedTaskStatus,

View File

@@ -48,10 +48,10 @@ import {
} from './paired-execution-context-reviewer.js';
import {
applyPairedTaskPatch,
resolveCanonicalSourceRef,
requestArbiterOrEscalate,
transitionPairedTaskStatus,
} from './paired-execution-context-shared.js';
import { resolveCanonicalSourceRef } from './paired-source-ref.js';
import {
isOwnerWorkspaceRepairNeededError,
markPairedTaskReviewReady,

45
src/paired-source-ref.ts Normal file
View File

@@ -0,0 +1,45 @@
import { execFileSync } from 'child_process';
export function resolveCanonicalSourceRef(workDir: string): string {
const treeHash = resolveCanonicalTreeHash(workDir);
return treeHash || 'HEAD';
}
function resolveCanonicalTreeHash(workDir: string): string | null {
try {
const treeHash = execFileSync('git', ['rev-parse', 'HEAD^{tree}'], {
cwd: workDir,
encoding: 'utf-8',
stdio: ['ignore', 'pipe', 'pipe'],
}).trim();
return treeHash || null;
} catch {
return null;
}
}
export function hasCodeChangesSinceRef(
workDir: string,
sourceRef: string | null | undefined,
): boolean | null {
if (!sourceRef) return null;
try {
execFileSync('git', ['diff', '--quiet', sourceRef, 'HEAD'], {
cwd: workDir,
stdio: ['ignore', 'pipe', 'pipe'],
});
return false;
} catch (error) {
const exitCode =
typeof error === 'object' &&
error !== null &&
'status' in error &&
typeof (error as { status?: unknown }).status === 'number'
? (error as { status: number }).status
: null;
if (exitCode === 1) {
return true;
}
return null;
}
}