karajan-code 1.47.0 → 1.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/src/hu/store.js
CHANGED
|
@@ -90,7 +90,9 @@ export function updateStoryStatus(batch, storyId, status, extra = {}) {
|
|
|
90
90
|
const story = batch.stories.find(s => s.id === storyId);
|
|
91
91
|
if (!story) throw new Error(`Story ${storyId} not found`);
|
|
92
92
|
story.status = status;
|
|
93
|
-
|
|
93
|
+
const now = new Date().toISOString();
|
|
94
|
+
story.statusChangedAt = now;
|
|
95
|
+
story.updated_at = now;
|
|
94
96
|
Object.assign(story, extra);
|
|
95
97
|
return story;
|
|
96
98
|
}
|
|
@@ -114,13 +114,30 @@ async function runSingleHu({ storyId, batch, batchSessionId, runIterationFn, emi
|
|
|
114
114
|
|
|
115
115
|
updateStoryStatus(batch, story.id, HU_STATUS.CODING);
|
|
116
116
|
await saveHuBatch(batchSessionId, batch);
|
|
117
|
+
emitProgress(emitter, makeEvent("hu:status-change", { ...eventBase, stage: "hu-sub-pipeline" }, {
|
|
118
|
+
message: `HU ${story.id} status → coding`,
|
|
119
|
+
detail: { huId: story.id, status: HU_STATUS.CODING, timestamp: new Date().toISOString() }
|
|
120
|
+
}));
|
|
117
121
|
|
|
118
122
|
try {
|
|
119
123
|
const iterResult = await runIterationFn(huTask);
|
|
120
124
|
const approved = Boolean(iterResult?.approved);
|
|
121
125
|
|
|
126
|
+
// --- Transition to reviewing (post-coder, pre-reviewer evaluation) ---
|
|
127
|
+
updateStoryStatus(batch, story.id, HU_STATUS.REVIEWING);
|
|
128
|
+
await saveHuBatch(batchSessionId, batch);
|
|
129
|
+
emitProgress(emitter, makeEvent("hu:status-change", { ...eventBase, stage: "hu-sub-pipeline" }, {
|
|
130
|
+
message: `HU ${story.id} status → reviewing`,
|
|
131
|
+
detail: { huId: story.id, status: HU_STATUS.REVIEWING, timestamp: new Date().toISOString() }
|
|
132
|
+
}));
|
|
133
|
+
|
|
122
134
|
if (approved) {
|
|
123
135
|
updateStoryStatus(batch, story.id, HU_STATUS.DONE);
|
|
136
|
+
await saveHuBatch(batchSessionId, batch);
|
|
137
|
+
emitProgress(emitter, makeEvent("hu:status-change", { ...eventBase, stage: "hu-sub-pipeline" }, {
|
|
138
|
+
message: `HU ${story.id} status → done`,
|
|
139
|
+
detail: { huId: story.id, status: HU_STATUS.DONE, timestamp: new Date().toISOString() }
|
|
140
|
+
}));
|
|
124
141
|
emitProgress(emitter, makeEvent("hu:end", { ...eventBase, stage: "hu-sub-pipeline" }, {
|
|
125
142
|
status: "ok",
|
|
126
143
|
message: `HU ${story.id} completed successfully`,
|
|
@@ -129,6 +146,11 @@ async function runSingleHu({ storyId, batch, batchSessionId, runIterationFn, emi
|
|
|
129
146
|
return { huId: story.id, approved: true, result: iterResult };
|
|
130
147
|
} else {
|
|
131
148
|
updateStoryStatus(batch, story.id, HU_STATUS.FAILED);
|
|
149
|
+
await saveHuBatch(batchSessionId, batch);
|
|
150
|
+
emitProgress(emitter, makeEvent("hu:status-change", { ...eventBase, stage: "hu-sub-pipeline" }, {
|
|
151
|
+
message: `HU ${story.id} status → failed`,
|
|
152
|
+
detail: { huId: story.id, status: HU_STATUS.FAILED, timestamp: new Date().toISOString() }
|
|
153
|
+
}));
|
|
132
154
|
emitProgress(emitter, makeEvent("hu:end", { ...eventBase, stage: "hu-sub-pipeline" }, {
|
|
133
155
|
status: "fail",
|
|
134
156
|
message: `HU ${story.id} failed`,
|
|
@@ -138,6 +160,11 @@ async function runSingleHu({ storyId, batch, batchSessionId, runIterationFn, emi
|
|
|
138
160
|
}
|
|
139
161
|
} catch (err) {
|
|
140
162
|
updateStoryStatus(batch, story.id, HU_STATUS.FAILED);
|
|
163
|
+
await saveHuBatch(batchSessionId, batch);
|
|
164
|
+
emitProgress(emitter, makeEvent("hu:status-change", { ...eventBase, stage: "hu-sub-pipeline" }, {
|
|
165
|
+
message: `HU ${story.id} status → failed`,
|
|
166
|
+
detail: { huId: story.id, status: HU_STATUS.FAILED, timestamp: new Date().toISOString() }
|
|
167
|
+
}));
|
|
141
168
|
emitProgress(emitter, makeEvent("hu:end", { ...eventBase, stage: "hu-sub-pipeline" }, {
|
|
142
169
|
status: "fail",
|
|
143
170
|
message: `HU ${story.id} threw: ${err.message}`,
|
package/src/orchestrator.js
CHANGED
|
@@ -523,6 +523,10 @@ async function becariaIncrementalPush({ config, session, gitCtx, task, logger, r
|
|
|
523
523
|
const pushResult = await incrementalPush({ gitCtx, task, logger, session });
|
|
524
524
|
if (!pushResult) return;
|
|
525
525
|
|
|
526
|
+
// Accumulate commits for PG card lifecycle tracking
|
|
527
|
+
const { accumulateCommit } = await import("./planning-game/pipeline-adapter.js");
|
|
528
|
+
for (const c of pushResult.commits) accumulateCommit(session, c);
|
|
529
|
+
|
|
526
530
|
session.becaria_commits = [...(session.becaria_commits ?? []), ...pushResult.commits];
|
|
527
531
|
await saveSession(session);
|
|
528
532
|
|
|
@@ -539,6 +543,10 @@ async function becariaCreateEarlyPr({ config, session, emitter, eventBase, gitCt
|
|
|
539
543
|
const earlyPr = await earlyPrCreation({ gitCtx, task, logger, session, stageResults });
|
|
540
544
|
if (!earlyPr) return;
|
|
541
545
|
|
|
546
|
+
// Accumulate commits for PG card lifecycle tracking
|
|
547
|
+
const { accumulateCommit } = await import("./planning-game/pipeline-adapter.js");
|
|
548
|
+
for (const c of earlyPr.commits) accumulateCommit(session, c);
|
|
549
|
+
|
|
542
550
|
session.becaria_pr_number = earlyPr.prNumber;
|
|
543
551
|
session.becaria_pr_url = earlyPr.prUrl;
|
|
544
552
|
session.becaria_commits = earlyPr.commits;
|
|
@@ -740,6 +748,13 @@ async function handlePostLoopStages({ config, session, emitter, eventBase, coder
|
|
|
740
748
|
|
|
741
749
|
async function finalizeApprovedSession({ config, gitCtx, task, logger, session, stageResults, emitter, eventBase, budgetSummary, pgCard, pgProject, review, i }) {
|
|
742
750
|
const gitResult = await finalizeGitAutomation({ config, gitCtx, task, logger, session, stageResults });
|
|
751
|
+
|
|
752
|
+
// Accumulate final commits for PG card lifecycle tracking
|
|
753
|
+
if (gitResult?.commits?.length) {
|
|
754
|
+
const { accumulateCommit } = await import("./planning-game/pipeline-adapter.js");
|
|
755
|
+
for (const c of gitResult.commits) accumulateCommit(session, c);
|
|
756
|
+
}
|
|
757
|
+
|
|
743
758
|
if (stageResults.planner?.ok) {
|
|
744
759
|
stageResults.planner.completedSteps = [...(stageResults.planner.steps ?? [])];
|
|
745
760
|
}
|
|
@@ -94,6 +94,7 @@ export async function handlePgDecomposition({ triageResult, pgTaskId, pgProject,
|
|
|
94
94
|
|
|
95
95
|
/**
|
|
96
96
|
* Mark PG card as "To Validate" on approved session completion.
|
|
97
|
+
* Merges commits from gitResult and session.pg_commits (accumulated during pipeline).
|
|
97
98
|
*/
|
|
98
99
|
export async function markPgCardToValidate({ pgCard, pgProject, config, session, gitResult, logger }) {
|
|
99
100
|
if (!pgCard || !pgProject) return;
|
|
@@ -101,9 +102,21 @@ export async function markPgCardToValidate({ pgCard, pgProject, config, session,
|
|
|
101
102
|
try {
|
|
102
103
|
const { updateCard } = await import("./client.js");
|
|
103
104
|
const { buildCompletionUpdates } = await import("./adapter.js");
|
|
105
|
+
|
|
106
|
+
// Merge commits: session.pg_commits (accumulated) + gitResult.commits (final)
|
|
107
|
+
const accumulatedCommits = session.pg_commits || [];
|
|
108
|
+
const finalCommits = gitResult?.commits || [];
|
|
109
|
+
const seenHashes = new Set(accumulatedCommits.map(c => c.hash));
|
|
110
|
+
const mergedCommits = [...accumulatedCommits];
|
|
111
|
+
for (const c of finalCommits) {
|
|
112
|
+
if (!seenHashes.has(c.hash)) {
|
|
113
|
+
mergedCommits.push(c);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
104
117
|
const pgUpdates = buildCompletionUpdates({
|
|
105
118
|
approved: true,
|
|
106
|
-
commits:
|
|
119
|
+
commits: mergedCommits,
|
|
107
120
|
startDate: session.pg_card?.startDate || session.created_at,
|
|
108
121
|
codeveloper: config.planning_game?.codeveloper || null
|
|
109
122
|
});
|
|
@@ -156,6 +169,25 @@ export function buildHuStoriesFromPgCard(pgCard) {
|
|
|
156
169
|
return [{ id: storyId, text: storyText }];
|
|
157
170
|
}
|
|
158
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Accumulate a commit into the session's pg_commits array.
|
|
174
|
+
* Called after each successful commitAll during the iteration loop.
|
|
175
|
+
* Best-effort: never throws.
|
|
176
|
+
*
|
|
177
|
+
* @param {object} session - Pipeline session (mutated)
|
|
178
|
+
* @param {{ hash: string, message: string, date?: string, author?: string }} commitInfo
|
|
179
|
+
*/
|
|
180
|
+
export function accumulateCommit(session, commitInfo) {
|
|
181
|
+
if (!session || !commitInfo?.hash) return;
|
|
182
|
+
if (!session.pg_commits) session.pg_commits = [];
|
|
183
|
+
session.pg_commits.push({
|
|
184
|
+
hash: commitInfo.hash,
|
|
185
|
+
message: commitInfo.message || "",
|
|
186
|
+
date: commitInfo.date || new Date().toISOString(),
|
|
187
|
+
author: commitInfo.author || "BecarIA"
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
159
191
|
// --- Internal helpers ---
|
|
160
192
|
|
|
161
193
|
async function markPgCardInProgress({ pgTaskId, pgProject, config, logger }) {
|