chore: update plan automation and chat status UI
This commit is contained in:
@@ -3,7 +3,7 @@ import assert from 'node:assert/strict';
|
||||
import { buildPlanNotificationData } from './plan-notification-service.js';
|
||||
import { shouldNotifyPlanRestart } from './plan-notification-policy.js';
|
||||
import { shouldTriggerRetryFromActionNote } from './plan-retry-policy.js';
|
||||
import { issueActionSchema } from './plan-service.js';
|
||||
import { issueActionSchema, shouldUseLocalMainPlanMode } from './plan-service.js';
|
||||
|
||||
test('shouldTriggerRetryFromActionNote detects missing-fix and verification follow-up requests', () => {
|
||||
assert.equal(shouldTriggerRetryFromActionNote('누락된 거 다시 고쳐서 테스트해 줘'), true);
|
||||
@@ -52,3 +52,9 @@ test('buildPlanNotificationData uses stable task key per plan', () => {
|
||||
notificationKey: 'plan:17',
|
||||
});
|
||||
});
|
||||
|
||||
test('shouldUseLocalMainPlanMode keeps auto_worker on branch workflow', () => {
|
||||
process.env.PLAN_LOCAL_MAIN_MODE = 'true';
|
||||
assert.equal(shouldUseLocalMainPlanMode('auto_worker'), false);
|
||||
assert.equal(shouldUseLocalMainPlanMode('none'), true);
|
||||
});
|
||||
|
||||
@@ -268,6 +268,11 @@ export function buildPlanBranchName(workId: string, id: number) {
|
||||
return `${prefix}/plan-${id}-${token}`;
|
||||
}
|
||||
|
||||
export function shouldUseLocalMainPlanMode(automationType: unknown) {
|
||||
const env = getEnv();
|
||||
return Boolean(env.PLAN_LOCAL_MAIN_MODE) && normalizePlanAutomationType(automationType) !== 'auto_worker';
|
||||
}
|
||||
|
||||
export function mapPlanRow(
|
||||
row: Record<string, unknown>,
|
||||
options?: PlanRowOptions,
|
||||
@@ -2399,7 +2404,6 @@ export async function listPlanIssueSummaries(planItemIds: number[]) {
|
||||
|
||||
export async function claimNextPlanForBranch(workerId: string) {
|
||||
await ensurePlanTable();
|
||||
const env = getEnv();
|
||||
|
||||
return db.transaction(async (trx) => {
|
||||
const row = await trx(PLAN_TABLE)
|
||||
@@ -2417,7 +2421,9 @@ export async function claimNextPlanForBranch(workerId: string) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const assignedBranch = env.PLAN_LOCAL_MAIN_MODE ? env.PLAN_MAIN_BRANCH : buildPlanBranchName(String(row.work_id), Number(row.id));
|
||||
const assignedBranch = shouldUseLocalMainPlanMode(row.automation_type)
|
||||
? String(getEnv().PLAN_MAIN_BRANCH)
|
||||
: buildPlanBranchName(String(row.work_id), Number(row.id));
|
||||
const rows = await trx(PLAN_TABLE)
|
||||
.where({ id: row.id })
|
||||
.update({
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
markPlanReleaseMerged,
|
||||
markPlanMerged,
|
||||
markPlanWorkCompleted,
|
||||
shouldUseLocalMainPlanMode,
|
||||
upsertAutoPlanItem,
|
||||
} from '../services/plan-service.js';
|
||||
import {
|
||||
@@ -200,6 +201,10 @@ export class PlanWorker {
|
||||
return Boolean(getEnv().PLAN_LOCAL_MAIN_MODE);
|
||||
}
|
||||
|
||||
private shouldUseLocalMainModeForPlan(item: { automationType?: unknown }) {
|
||||
return shouldUseLocalMainPlanMode(item.automationType);
|
||||
}
|
||||
|
||||
start() {
|
||||
const env = getEnv();
|
||||
|
||||
@@ -613,8 +618,10 @@ export class PlanWorker {
|
||||
planId: number,
|
||||
workId: string,
|
||||
note: unknown,
|
||||
automationType: unknown,
|
||||
) {
|
||||
const env = getEnv();
|
||||
const useLocalMainMode = shouldUseLocalMainPlanMode(automationType);
|
||||
const runCodexCommandAttempt = async (attempt: number) =>
|
||||
await new Promise<string>((resolve, reject) => {
|
||||
let settled = false;
|
||||
@@ -629,7 +636,7 @@ export class PlanWorker {
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
env: {
|
||||
...process.env,
|
||||
PLAN_REPO_PATH: env.PLAN_LOCAL_MAIN_MODE ? env.PLAN_MAIN_PROJECT_REPO_PATH : env.PLAN_GIT_REPO_PATH,
|
||||
PLAN_REPO_PATH: useLocalMainMode ? env.PLAN_MAIN_PROJECT_REPO_PATH : env.PLAN_GIT_REPO_PATH,
|
||||
PLAN_API_BASE_URL: 'http://127.0.0.1:3100/api',
|
||||
PLAN_ACCESS_TOKEN: ERROR_LOG_VIEW_TOKEN,
|
||||
PLAN_ITEM_ID: String(planId),
|
||||
@@ -637,7 +644,7 @@ export class PlanWorker {
|
||||
PLAN_CODEX_TEMPLATE_HOME: env.PLAN_CODEX_TEMPLATE_HOME,
|
||||
PLAN_GIT_USER_NAME: env.PLAN_GIT_USER_NAME,
|
||||
PLAN_GIT_USER_EMAIL: env.PLAN_GIT_USER_EMAIL,
|
||||
PLAN_LOCAL_MAIN_MODE: env.PLAN_LOCAL_MAIN_MODE ? 'true' : 'false',
|
||||
PLAN_LOCAL_MAIN_MODE: useLocalMainMode ? 'true' : 'false',
|
||||
PLAN_SKIP_WORK_COMPLETE: 'true',
|
||||
},
|
||||
});
|
||||
@@ -907,7 +914,7 @@ export class PlanWorker {
|
||||
const releaseTarget = String(item.releaseTarget ?? env.PLAN_RELEASE_BRANCH);
|
||||
|
||||
try {
|
||||
if (!this.isLocalMainMode()) {
|
||||
if (!this.shouldUseLocalMainModeForPlan(item)) {
|
||||
await cleanAutomationWorktree(env.PLAN_GIT_REPO_PATH);
|
||||
await ensureBranchExists(
|
||||
{
|
||||
@@ -926,8 +933,8 @@ export class PlanWorker {
|
||||
return;
|
||||
}
|
||||
this.logger.info(
|
||||
{ planId, branch: assignedBranch, localMainMode: this.isLocalMainMode() },
|
||||
this.isLocalMainMode() ? 'Plan local main execution prepared' : 'Plan branch created',
|
||||
{ planId, branch: assignedBranch, localMainMode: this.shouldUseLocalMainModeForPlan(item) },
|
||||
this.shouldUseLocalMainModeForPlan(item) ? 'Plan local main execution prepared' : 'Plan branch created',
|
||||
);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : '브랜치 생성에 실패했습니다.';
|
||||
@@ -975,7 +982,7 @@ export class PlanWorker {
|
||||
const autoDeployToMain = Boolean(item.autoDeployToMain ?? true);
|
||||
|
||||
try {
|
||||
if (this.isLocalMainMode()) {
|
||||
if (this.shouldUseLocalMainModeForPlan(item)) {
|
||||
const completedRow = await markPlanAsCompleted(
|
||||
planId,
|
||||
'로컬 main 직접 작업 모드에서 release/main 반영 단계를 건너뛰고 완료 처리했습니다.',
|
||||
@@ -1071,7 +1078,7 @@ export class PlanWorker {
|
||||
const planLabel = formatPlanNotificationLabel(workId, planId);
|
||||
|
||||
try {
|
||||
if (this.isLocalMainMode()) {
|
||||
if (this.shouldUseLocalMainModeForPlan(item)) {
|
||||
const completedRow = await markPlanAsCompleted(
|
||||
planId,
|
||||
'로컬 main 직접 작업 모드에서 main 반영 단계를 건너뛰고 완료 처리했습니다.',
|
||||
@@ -1201,7 +1208,7 @@ export class PlanWorker {
|
||||
'work-started',
|
||||
);
|
||||
|
||||
const output = await this.runCodexCommandWithProgressNotifications(planId, workId, item.note);
|
||||
const output = await this.runCodexCommandWithProgressNotifications(planId, workId, item.note, item.automationType);
|
||||
|
||||
if (output.includes('처리할 Plan 항목이 없습니다.')) {
|
||||
throw new Error('자동 작업 대상 Plan 항목을 찾지 못했습니다. 상태 전환 로직을 확인해 주세요.');
|
||||
@@ -1229,7 +1236,7 @@ export class PlanWorker {
|
||||
return;
|
||||
}
|
||||
|
||||
const finalCompletedRow = this.isLocalMainMode()
|
||||
const finalCompletedRow = this.shouldUseLocalMainModeForPlan(item)
|
||||
? await markPlanAsCompleted(planId, '로컬 main 직접 작업으로 자동 작업을 완료했습니다.')
|
||||
: await markPlanWorkCompleted(planId, this.workerId, '자동 작업을 완료했습니다.');
|
||||
if (!finalCompletedRow) {
|
||||
@@ -1240,7 +1247,9 @@ export class PlanWorker {
|
||||
planId,
|
||||
workId,
|
||||
planLabel,
|
||||
this.isLocalMainMode() ? '자동 작업이 로컬 main 작업본에 직접 반영되어 완료되었습니다.' : this.buildExecutionCompletedBody(autoDeployToMain),
|
||||
this.shouldUseLocalMainModeForPlan(item)
|
||||
? '자동 작업이 로컬 main 작업본에 직접 반영되어 완료되었습니다.'
|
||||
: this.buildExecutionCompletedBody(autoDeployToMain),
|
||||
'work-completed',
|
||||
);
|
||||
this.logger.info({ planId }, 'Plan Codex execution completed');
|
||||
|
||||
Reference in New Issue
Block a user