@galda/cli 0.10.77 → 0.10.79
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/app/index.html +14 -8
- package/engine/lib.mjs +1 -1
- package/engine/server.mjs +16 -0
- package/package.json +1 -1
package/app/index.html
CHANGED
|
@@ -3595,6 +3595,12 @@ function reviewCardConfigFor(projectId){ return { ...DEFAULT_REVIEW_DEFINITION.r
|
|
|
3595
3595
|
// goal's own request language, same as the planner/worker; ja/en pin the
|
|
3596
3596
|
// project to one language regardless of what a given goal was typed in.
|
|
3597
3597
|
function reviewLangFor(projectId){ const l = reviewDefinitionFor(projectId).language; return (l === 'en' || l === 'ja') ? l : 'auto'; }
|
|
3598
|
+
function retryCopy(projectId){
|
|
3599
|
+
const ja = reviewLangFor(projectId) === 'ja';
|
|
3600
|
+
return ja
|
|
3601
|
+
? { infra: '検証基盤エラー', retry: '再検証', retrying: '再検証中…', failed: '再検証に失敗' }
|
|
3602
|
+
: { infra: 'Verification infrastructure error', retry: 'Retry verification', retrying: 'Retrying…', failed: 'Verification retry failed' };
|
|
3603
|
+
}
|
|
3598
3604
|
|
|
3599
3605
|
function esc(s){ const d = document.createElement('div'); d.textContent = s ?? ''; return d.innerHTML; }
|
|
3600
3606
|
|
|
@@ -4636,7 +4642,7 @@ function renderTasks(){
|
|
|
4636
4642
|
const rs = g.reviewSummary ?? {};
|
|
4637
4643
|
const checkLine = (rs.check || g.plan?.[0] || g.text || '').replace(/\s+/g, ' ').slice(0, 58);
|
|
4638
4644
|
return `<div class="task revrow" data-goal="${g.id}"><div class="ic fail">!</div><div class="tx"><div class="name">${esc(checkLine)} ${goalSourceBadge(g.source)}</div>
|
|
4639
|
-
<div class="cond"><span class="blockreason">${esc(g.blocked?.reason ?? 'blocked')}</span> <button type="button" class="retrybtn" data-goalreverify="${g.id}"
|
|
4645
|
+
<div class="cond"><span class="blockreason">${esc(g.blocked?.reason ?? 'blocked')}</span> <button type="button" class="retrybtn" data-goalreverify="${g.id}">${retryCopy(g.projectId).retry}</button> <button type="button" class="retrybtn skip" data-archivegoal="${g.id}" title="Archive without rework">Archive</button></div></div></div>`;
|
|
4640
4646
|
}).join('');
|
|
4641
4647
|
const attention = blockedGoals + list.filter((t) => ['failed', 'interrupted'].includes(t.status)).map((t) => row(t, { retry: 1 })).join('');
|
|
4642
4648
|
const doing = grouped(list.filter((t) => t.status === 'running'), (t) => row(t));
|
|
@@ -4833,10 +4839,10 @@ function renderTasks(){
|
|
|
4833
4839
|
}
|
|
4834
4840
|
// Manager-verified gate: re-run tests + re-capture proof for a blocked goal.
|
|
4835
4841
|
for (const b of $('tasklist').querySelectorAll('[data-goalreverify]')) {
|
|
4836
|
-
b.onclick = async (e) => { e.stopPropagation(); b.disabled = true; b.textContent =
|
|
4842
|
+
b.onclick = async (e) => { e.stopPropagation(); const copy = retryCopy(state.active); b.disabled = true; b.textContent = copy.retrying;
|
|
4837
4843
|
let r; try { r = await fetch(withKey(`/api/goals/${b.dataset.goalreverify}/reverify`), { method: 'POST' }); }
|
|
4838
|
-
catch { showErr(
|
|
4839
|
-
qrefresh(r,
|
|
4844
|
+
catch { showErr(copy.failed); return; }
|
|
4845
|
+
qrefresh(r, copy.failed); };
|
|
4840
4846
|
}
|
|
4841
4847
|
for (const b of $('tasklist').querySelectorAll('[data-qreply]')) {
|
|
4842
4848
|
b.onclick = (e) => { e.stopPropagation();
|
|
@@ -5404,7 +5410,7 @@ function renderReviewChecklist(){
|
|
|
5404
5410
|
: '';
|
|
5405
5411
|
const infra = goal.verificationInfraError;
|
|
5406
5412
|
const infraHtml = infra?.detail
|
|
5407
|
-
? `<div class="rvinfra"><span class="rvlbl">${esc(infra.title ||
|
|
5413
|
+
? `<div class="rvinfra"><span class="rvlbl">${esc(infra.title || retryCopy(goal.projectId).infra)}</span>${esc(infra.detail)} <button type="button" class="retrybtn" data-goalreverify="${goal.id}">${retryCopy(goal.projectId).retry}</button></div>`
|
|
5408
5414
|
: '';
|
|
5409
5415
|
$('reviewSummary').innerHTML =
|
|
5410
5416
|
vfyHtml
|
|
@@ -5477,10 +5483,10 @@ function renderReviewChecklist(){
|
|
|
5477
5483
|
b.onclick = async (e) => {
|
|
5478
5484
|
e.stopPropagation();
|
|
5479
5485
|
b.disabled = true;
|
|
5480
|
-
b.textContent =
|
|
5486
|
+
b.textContent = retryCopy(goal.projectId).retrying;
|
|
5481
5487
|
let r; try { r = await fetch(withKey(`/api/goals/${b.dataset.goalreverify}/reverify`), { method: 'POST' }); }
|
|
5482
|
-
catch { showErr(
|
|
5483
|
-
if (r.ok) await refresh(); else showErr(
|
|
5488
|
+
catch { showErr(retryCopy(goal.projectId).failed); b.disabled = false; return; }
|
|
5489
|
+
if (r.ok) await refresh(); else showErr(retryCopy(goal.projectId).failed);
|
|
5484
5490
|
};
|
|
5485
5491
|
}
|
|
5486
5492
|
for (const b of $('reviewList').querySelectorAll('.reqsend')) {
|
package/engine/lib.mjs
CHANGED
|
@@ -2843,7 +2843,7 @@ export function replayQueueLog(rawText, reviewDefinitions = {}) {
|
|
|
2843
2843
|
try {
|
|
2844
2844
|
const e = JSON.parse(line);
|
|
2845
2845
|
if (e.kind === 'goal') { goals = goals.filter((g) => g.id !== e.id); if (!e.deleted) goals.push(e); }
|
|
2846
|
-
else { tasks = tasks.filter((t) => t.id !== e.id); tasks.push(e); }
|
|
2846
|
+
else if (e.kind === 'task') { tasks = tasks.filter((t) => t.id !== e.id); if (!e.deleted) tasks.push(e); }
|
|
2847
2847
|
} catch { /* skip a corrupt line rather than lose the whole log */ }
|
|
2848
2848
|
}
|
|
2849
2849
|
for (const t of tasks) {
|
package/engine/server.mjs
CHANGED
|
@@ -2589,6 +2589,12 @@ function installPreviewReaper() {
|
|
|
2589
2589
|
async function startPreview(task) {
|
|
2590
2590
|
installPreviewReaper();
|
|
2591
2591
|
const { cmd, url, dir } = task.run;
|
|
2592
|
+
// Attached static artifacts are already served by this Manager at /upload.
|
|
2593
|
+
// They never need a child process; treating them like a Manager app made
|
|
2594
|
+
// "Open it" fail even though the HTML artifact was ready to view.
|
|
2595
|
+
if (!cmd && typeof url === 'string' && url.startsWith('/upload/')) {
|
|
2596
|
+
return { url, reused: false, started: false };
|
|
2597
|
+
}
|
|
2592
2598
|
const live = previews.get(task.id);
|
|
2593
2599
|
if (live && live.proc.exitCode === null) {
|
|
2594
2600
|
live.expires = Date.now() + PREVIEW_IDLE_MS;
|
|
@@ -4159,6 +4165,16 @@ const server = createServer(async (req, res) => {
|
|
|
4159
4165
|
|| tasks.some((t) => t.projectId === project.id && ['running', 'queued'].includes(t.status));
|
|
4160
4166
|
if (active) return json(res, 409, { error: 'cannot delete a project with active work' });
|
|
4161
4167
|
const idx = projects.findIndex((p) => p.id === project.id);
|
|
4168
|
+
// A project id can be reused after deletion (for example "New project").
|
|
4169
|
+
// Remove its complete history before freeing that id, otherwise its old
|
|
4170
|
+
// Review cards appear in the newly created project.
|
|
4171
|
+
const removedGoals = goals.filter((g) => g.projectId === project.id);
|
|
4172
|
+
const removedGoalIds = new Set(removedGoals.map((g) => g.id));
|
|
4173
|
+
const removedTasks = tasks.filter((t) => t.projectId === project.id || removedGoalIds.has(t.goalId));
|
|
4174
|
+
goals = goals.filter((g) => g.projectId !== project.id);
|
|
4175
|
+
tasks = tasks.filter((t) => t.projectId !== project.id && !removedGoalIds.has(t.goalId));
|
|
4176
|
+
for (const g of removedGoals) logAppend(JSON.stringify({ kind: 'goal', id: g.id, deleted: true }));
|
|
4177
|
+
for (const t of removedTasks) logAppend(JSON.stringify({ kind: 'task', id: t.id, deleted: true }));
|
|
4162
4178
|
projects.splice(idx, 1);
|
|
4163
4179
|
queues.delete(project.id);
|
|
4164
4180
|
saveProjects();
|
package/package.json
CHANGED