From 247a710ae77d9d9b54ee12cabc2d062da725e299 Mon Sep 17 00:00:00 2001 From: ejclaw Date: Wed, 29 Apr 2026 10:22:33 +0900 Subject: [PATCH] Extract paired source ref helpers --- src/paired-execution-context-owner.ts | 6 ++- src/paired-execution-context-reviewer.ts | 2 +- src/paired-execution-context-shared.ts | 50 ++---------------------- src/paired-execution-context.ts | 2 +- src/paired-source-ref.ts | 45 +++++++++++++++++++++ 5 files changed, 55 insertions(+), 50 deletions(-) create mode 100644 src/paired-source-ref.ts diff --git a/src/paired-execution-context-owner.ts b/src/paired-execution-context-owner.ts index 03fa0d4..95d3bf6 100644 --- a/src/paired-execution-context-owner.ts +++ b/src/paired-execution-context-owner.ts @@ -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'; diff --git a/src/paired-execution-context-reviewer.ts b/src/paired-execution-context-reviewer.ts index 2bacb76..693a1ae 100644 --- a/src/paired-execution-context-reviewer.ts +++ b/src/paired-execution-context-reviewer.ts @@ -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'; diff --git a/src/paired-execution-context-shared.ts b/src/paired-execution-context-shared.ts index def652a..06b9e5c 100644 --- a/src/paired-execution-context-shared.ts +++ b/src/paired-execution-context-shared.ts @@ -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, diff --git a/src/paired-execution-context.ts b/src/paired-execution-context.ts index e8777ea..24236ed 100644 --- a/src/paired-execution-context.ts +++ b/src/paired-execution-context.ts @@ -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, diff --git a/src/paired-source-ref.ts b/src/paired-source-ref.ts new file mode 100644 index 0000000..d522984 --- /dev/null +++ b/src/paired-source-ref.ts @@ -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; + } +}