@hamp10/agentforge 0.2.38 → 0.2.40
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 +1 -1
- package/scripts/check-task-semantics.js +58 -0
- package/src/worker.js +113 -11
package/package.json
CHANGED
|
@@ -282,6 +282,64 @@ try {
|
|
|
282
282
|
'tracked same-name nested project copies should not pollute current page source discovery'
|
|
283
283
|
);
|
|
284
284
|
git(fixture.repo, ['restore', '--', nestedAlphaRel]);
|
|
285
|
+
const untrackedGammaRel = 'public_html/domains/gamma.html';
|
|
286
|
+
writeFileSync(
|
|
287
|
+
path.join(fixture.repo, untrackedGammaRel),
|
|
288
|
+
'<!doctype html><html><body><main><section><h1>Gamma</h1><p>New scoped page.</p></section></main></body></html>'
|
|
289
|
+
);
|
|
290
|
+
assert.equal(
|
|
291
|
+
worker._buildIncompleteScopedUiTargetsNudge(
|
|
292
|
+
[{ root: fixture.repo, head: fixture.head, initialDirtyPaths: [] }],
|
|
293
|
+
'Work on the Example.com listing pages for Alpha.ai, Beta.ai, and Gamma.ai. Make all three pages visually polished.'
|
|
294
|
+
),
|
|
295
|
+
'',
|
|
296
|
+
'new untracked scoped page files should count as touched UI targets'
|
|
297
|
+
);
|
|
298
|
+
rmSync(path.join(fixture.repo, untrackedGammaRel), { force: true });
|
|
299
|
+
const untrackedShallowGammaHtml = [
|
|
300
|
+
'<!doctype html>',
|
|
301
|
+
'<html>',
|
|
302
|
+
'<head>',
|
|
303
|
+
'<style>',
|
|
304
|
+
...Array.from({ length: 36 }, (_, i) =>
|
|
305
|
+
`.hero-gloss-${i} { color: #fff; background: #${String(120000 + i).slice(0, 6)}; padding: ${i + 4}px; margin: ${i}px; box-shadow: 0 0 ${i + 1}px rgba(0,0,0,.12); }`
|
|
306
|
+
),
|
|
307
|
+
'</style>',
|
|
308
|
+
'</head>',
|
|
309
|
+
'<body>',
|
|
310
|
+
'<main>',
|
|
311
|
+
'<section class="property-hero hero-gloss-1">',
|
|
312
|
+
'<h1 class="property-title">Gamma.ai</h1>',
|
|
313
|
+
'<p class="property-subtitle">Short generated hero copy.</p>',
|
|
314
|
+
'</section>',
|
|
315
|
+
'</main>',
|
|
316
|
+
'</body>',
|
|
317
|
+
'</html>',
|
|
318
|
+
].join('\n');
|
|
319
|
+
writeFileSync(path.join(fixture.repo, untrackedGammaRel), untrackedShallowGammaHtml);
|
|
320
|
+
const generatedQualityMessage = 'Work on the Example.com listing page for Gamma.ai. Make it visually polished.';
|
|
321
|
+
assert.match(
|
|
322
|
+
worker._buildShallowUiSurfaceNudge(
|
|
323
|
+
[{ root: fixture.repo, head: fixture.head, initialDirtyPaths: [] }],
|
|
324
|
+
generatedQualityMessage
|
|
325
|
+
),
|
|
326
|
+
/gamma\.html/i,
|
|
327
|
+
'untracked generated scoped page files should participate in shallow UI quality checks'
|
|
328
|
+
);
|
|
329
|
+
const generatedReset = worker._restoreGeneratedScopedUiTargets(
|
|
330
|
+
[{ root: fixture.repo, head: fixture.head, initialDirtyPaths: [] }],
|
|
331
|
+
generatedQualityMessage
|
|
332
|
+
);
|
|
333
|
+
assert.equal(
|
|
334
|
+
existsSync(path.join(fixture.repo, untrackedGammaRel)),
|
|
335
|
+
false,
|
|
336
|
+
'UI quality retries should remove rejected generated scoped pages before the next attempt'
|
|
337
|
+
);
|
|
338
|
+
assert.match(
|
|
339
|
+
worker._formatGeneratedScopedUiResetNudge(generatedReset),
|
|
340
|
+
/removed 1 rejected generated scoped file/i,
|
|
341
|
+
'retry feedback should tell the agent that generated scoped pages were removed as failed output'
|
|
342
|
+
);
|
|
285
343
|
const projectsRoot = mkdtempSync(path.join(tmpdir(), 'agentforge-project-list-'));
|
|
286
344
|
let agentWorkspace = null;
|
|
287
345
|
try {
|
package/src/worker.js
CHANGED
|
@@ -530,6 +530,24 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
530
530
|
return stats;
|
|
531
531
|
}
|
|
532
532
|
|
|
533
|
+
_listUntrackedUiFiles(baseline, userMessage, { scopedOnly = false } = {}) {
|
|
534
|
+
if (!baseline?.root) return [];
|
|
535
|
+
const uiFileRe = /\.(html?|css|s[ac]ss|jsx?|tsx?|vue|svelte|astro|mdx?)$/i;
|
|
536
|
+
const initialDirty = new Set(baseline.initialDirtyPaths || []);
|
|
537
|
+
const { slugs: allowedSlugs, pageOnly } = this._extractExplicitScope(userMessage);
|
|
538
|
+
return String(this._gitOutput(baseline.root, ['ls-files', '--others', '--exclude-standard'], 10000) || '')
|
|
539
|
+
.split('\n')
|
|
540
|
+
.map(line => line.trim())
|
|
541
|
+
.filter(Boolean)
|
|
542
|
+
.filter(rel => uiFileRe.test(rel))
|
|
543
|
+
.filter(rel => !initialDirty.has(rel))
|
|
544
|
+
.filter(rel => !this._isNestedProjectCopyRel(baseline.root, rel, baseline.head || 'HEAD'))
|
|
545
|
+
.filter(rel => {
|
|
546
|
+
if (!scopedOnly || allowedSlugs.length === 0) return true;
|
|
547
|
+
return this._scopeAllowsChangedPath(baseline, rel, allowedSlugs, pageOnly, userMessage);
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
|
|
533
551
|
_findDestructiveRepoChanges(repoBaselines, userMessage) {
|
|
534
552
|
if (!Array.isArray(repoBaselines) || repoBaselines.length === 0) return [];
|
|
535
553
|
if (this._allowsLargeDestructiveChange(userMessage)) return [];
|
|
@@ -1158,7 +1176,20 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
1158
1176
|
this._gitOutput(baseline.root, ['diff', '--numstat'], 10000),
|
|
1159
1177
|
'working tree'
|
|
1160
1178
|
);
|
|
1161
|
-
const
|
|
1179
|
+
const untracked = this._listUntrackedUiFiles(baseline, userMessage, { scopedOnly: true })
|
|
1180
|
+
.map(rel => {
|
|
1181
|
+
let additions = 0;
|
|
1182
|
+
try {
|
|
1183
|
+
additions = String(readFileSync(path.join(baseline.root, rel), 'utf-8') || '')
|
|
1184
|
+
.split('\n')
|
|
1185
|
+
.filter(line => line.trim())
|
|
1186
|
+
.length;
|
|
1187
|
+
} catch {
|
|
1188
|
+
additions = 1;
|
|
1189
|
+
}
|
|
1190
|
+
return { additions, deletions: 0, path: rel, source: 'untracked' };
|
|
1191
|
+
});
|
|
1192
|
+
const combined = [...committed, ...working, ...untracked]
|
|
1162
1193
|
.filter(stat => /\.(html?|css|s[ac]ss|jsx?|tsx?|vue|svelte|astro|mdx?)$/i.test(stat.path));
|
|
1163
1194
|
if (combined.length === 0) continue;
|
|
1164
1195
|
|
|
@@ -1272,10 +1303,45 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
1272
1303
|
}
|
|
1273
1304
|
};
|
|
1274
1305
|
|
|
1306
|
+
const scanUntracked = (baseline, byPath) => {
|
|
1307
|
+
for (const currentFile of this._listUntrackedUiFiles(baseline, userMessage, { scopedOnly: true })) {
|
|
1308
|
+
let content = '';
|
|
1309
|
+
try {
|
|
1310
|
+
content = readFileSync(path.join(baseline.root, currentFile), 'utf-8');
|
|
1311
|
+
} catch {
|
|
1312
|
+
continue;
|
|
1313
|
+
}
|
|
1314
|
+
for (const line of String(content || '').split('\n')) {
|
|
1315
|
+
const raw = line.trim();
|
|
1316
|
+
if (!raw || /^(?:\/\*|\*|\/\/|<!--|-->|})$/.test(raw)) continue;
|
|
1317
|
+
const stat = byPath.get(currentFile) || {
|
|
1318
|
+
path: currentFile,
|
|
1319
|
+
changed: 0,
|
|
1320
|
+
shallow: 0,
|
|
1321
|
+
semanticAdds: 0,
|
|
1322
|
+
inlineStyleAdds: 0,
|
|
1323
|
+
sources: new Set(),
|
|
1324
|
+
};
|
|
1325
|
+
stat.changed += 1;
|
|
1326
|
+
stat.sources.add('untracked');
|
|
1327
|
+
if (shallowLineRe.test(raw)) stat.shallow += 1;
|
|
1328
|
+
if (/\bstyle=["'][^"']+["']/i.test(raw)) stat.inlineStyleAdds += 1;
|
|
1329
|
+
const text = visibleText(raw);
|
|
1330
|
+
const hasStructuralMarkup = /<(?:section|article|aside|ul|ol|li|h2|h3|p|form|table|figure)\b/i.test(raw);
|
|
1331
|
+
const hasSubstantiveClassWithText = structuralClassRe.test(raw) && /<[^>]+>/i.test(raw) && text.length >= 24;
|
|
1332
|
+
if ((hasStructuralMarkup && text.length >= 35) || hasSubstantiveClassWithText) {
|
|
1333
|
+
stat.semanticAdds += 1;
|
|
1334
|
+
}
|
|
1335
|
+
byPath.set(currentFile, stat);
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
|
|
1275
1340
|
for (const baseline of repoBaselines) {
|
|
1276
1341
|
const byPath = new Map();
|
|
1277
1342
|
scanDiff(baseline, ['diff', '--unified=0', `${baseline.head}..HEAD`], 'committed', byPath);
|
|
1278
1343
|
scanDiff(baseline, ['diff', '--unified=0'], 'working tree', byPath);
|
|
1344
|
+
scanUntracked(baseline, byPath);
|
|
1279
1345
|
const changedFiles = [...byPath.values()];
|
|
1280
1346
|
if (changedFiles.length === 0) continue;
|
|
1281
1347
|
|
|
@@ -1540,9 +1606,18 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
1540
1606
|
this._gitOutput(baseline.root, ['diff', '--numstat'], 10000),
|
|
1541
1607
|
'working tree'
|
|
1542
1608
|
);
|
|
1609
|
+
const initialDirty = new Set(baseline.initialDirtyPaths || []);
|
|
1610
|
+
const untracked = String(this._gitOutput(baseline.root, ['ls-files', '--others', '--exclude-standard'], 10000) || '')
|
|
1611
|
+
.split('\n')
|
|
1612
|
+
.map(line => line.trim())
|
|
1613
|
+
.filter(Boolean)
|
|
1614
|
+
.filter(rel => uiFileRe.test(rel))
|
|
1615
|
+
.filter(rel => !initialDirty.has(rel))
|
|
1616
|
+
.filter(rel => !this._isNestedProjectCopyRel(baseline.root, rel, baseline.head || 'HEAD'));
|
|
1543
1617
|
const changedFiles = [...committed, ...working]
|
|
1544
1618
|
.filter(stat => uiFileRe.test(stat.path))
|
|
1545
|
-
.map(stat => stat.path)
|
|
1619
|
+
.map(stat => stat.path)
|
|
1620
|
+
.concat(untracked);
|
|
1546
1621
|
if (changedFiles.length === 0) continue;
|
|
1547
1622
|
|
|
1548
1623
|
const touchedSlugs = new Set();
|
|
@@ -4151,12 +4226,15 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
4151
4226
|
: '';
|
|
4152
4227
|
if (interimUiImplementationArtifactNudge) {
|
|
4153
4228
|
const restoreNudge = this._formatUiQualityRestoreNudge(this._restoreUiQualityWarningPaths(interimUiImplementationArtifactWarnings), nudgeCount + 1);
|
|
4229
|
+
const generatedResetNudge = this._formatGeneratedScopedUiResetNudge(
|
|
4230
|
+
this._restoreGeneratedScopedUiTargets(repoBaselines, scopeAwareUserMessage)
|
|
4231
|
+
);
|
|
4154
4232
|
const interimScopedUiTargetSetNudge = this._buildScopedUiTargetSetNudge(repoBaselines, scopeAwareUserMessage);
|
|
4155
4233
|
nudgeCount++;
|
|
4156
4234
|
const repairBudget = consumeUiRepairNudge('patch artifacts', interimUiImplementationArtifactNudge);
|
|
4157
4235
|
if (nudgeCount < UI_QUALITY_NUDGE_LIMIT) {
|
|
4158
4236
|
console.log(`[${taskId}] Iteration had patch artifacts — correcting (${nudgeCount}/${UI_QUALITY_NUDGE_LIMIT}, total UI repairs ${repairBudget})`);
|
|
4159
|
-
const combinedNudge = [interimUiImplementationArtifactNudge, restoreNudge, interimScopedUiTargetSetNudge].filter(Boolean).join('\n\n');
|
|
4237
|
+
const combinedNudge = [interimUiImplementationArtifactNudge, restoreNudge, generatedResetNudge, interimScopedUiTargetSetNudge].filter(Boolean).join('\n\n');
|
|
4160
4238
|
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${combinedNudge}\n\nContinue from the restored files and already-inspected context. Clean the implementation, address every requested scoped target page, and verify each edited target screen after the final edit.`);
|
|
4161
4239
|
continue;
|
|
4162
4240
|
}
|
|
@@ -4181,12 +4259,15 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
4181
4259
|
: '';
|
|
4182
4260
|
if (interimShallowUiSurfaceNudge) {
|
|
4183
4261
|
const restoreNudge = this._formatUiQualityRestoreNudge(this._restoreUiQualityWarningPaths(interimShallowUiSurfaceWarnings), nudgeCount + 1);
|
|
4262
|
+
const generatedResetNudge = this._formatGeneratedScopedUiResetNudge(
|
|
4263
|
+
this._restoreGeneratedScopedUiTargets(repoBaselines, scopeAwareUserMessage)
|
|
4264
|
+
);
|
|
4184
4265
|
const scopedTargetSetNudge = this._formatScopedUiTargetSetReminder(scopeAwareUserMessage);
|
|
4185
4266
|
nudgeCount++;
|
|
4186
4267
|
const repairBudget = consumeUiRepairNudge('shallow UI surface changes', interimShallowUiSurfaceNudge);
|
|
4187
4268
|
if (nudgeCount < UI_QUALITY_NUDGE_LIMIT) {
|
|
4188
4269
|
console.log(`[${taskId}] Iteration had shallow UI surface changes — continuing (${nudgeCount}/${UI_QUALITY_NUDGE_LIMIT}, total UI repairs ${repairBudget})`);
|
|
4189
|
-
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[interimShallowUiSurfaceNudge, restoreNudge, scopedTargetSetNudge].filter(Boolean).join('\n\n')}\n\nContinue from the restored files and already-inspected context. Make the requested scoped UI materially better across the page-owned surface, then verify the edited target screens after the final edit.`);
|
|
4270
|
+
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[interimShallowUiSurfaceNudge, restoreNudge, generatedResetNudge, scopedTargetSetNudge].filter(Boolean).join('\n\n')}\n\nContinue from the restored files and already-inspected context. Make the requested scoped UI materially better across the page-owned surface, then verify the edited target screens after the final edit.`);
|
|
4190
4271
|
continue;
|
|
4191
4272
|
}
|
|
4192
4273
|
throw new Error(`Task produced shallow UI surface changes after repeated retries:\n${interimShallowUiSurfaceNudge}`);
|
|
@@ -4198,12 +4279,15 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
4198
4279
|
: '';
|
|
4199
4280
|
if (interimThinUiChangeNudge) {
|
|
4200
4281
|
const restoreNudge = this._formatUiQualityRestoreNudge(this._restoreUiQualityWarningPaths(interimThinUiChangeWarnings), nudgeCount + 1);
|
|
4282
|
+
const generatedResetNudge = this._formatGeneratedScopedUiResetNudge(
|
|
4283
|
+
this._restoreGeneratedScopedUiTargets(repoBaselines, scopeAwareUserMessage)
|
|
4284
|
+
);
|
|
4201
4285
|
const scopedTargetSetNudge = this._formatScopedUiTargetSetReminder(scopeAwareUserMessage);
|
|
4202
4286
|
nudgeCount++;
|
|
4203
4287
|
const repairBudget = consumeUiRepairNudge('too-thin UI changes', interimThinUiChangeNudge);
|
|
4204
4288
|
if (nudgeCount < UI_QUALITY_NUDGE_LIMIT) {
|
|
4205
4289
|
console.log(`[${taskId}] Iteration had too-thin UI changes — continuing (${nudgeCount}/${UI_QUALITY_NUDGE_LIMIT}, total UI repairs ${repairBudget})`);
|
|
4206
|
-
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[interimThinUiChangeNudge, restoreNudge, scopedTargetSetNudge].filter(Boolean).join('\n\n')}\n\nContinue from the restored files and already-inspected context. Make the requested scoped UI materially better, then verify the edited target screens after the final edit.`);
|
|
4290
|
+
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[interimThinUiChangeNudge, restoreNudge, generatedResetNudge, scopedTargetSetNudge].filter(Boolean).join('\n\n')}\n\nContinue from the restored files and already-inspected context. Make the requested scoped UI materially better, then verify the edited target screens after the final edit.`);
|
|
4207
4291
|
continue;
|
|
4208
4292
|
}
|
|
4209
4293
|
throw new Error(`Task produced too-thin UI changes after repeated retries:\n${interimThinUiChangeNudge}`);
|
|
@@ -4305,12 +4389,15 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
4305
4389
|
: '';
|
|
4306
4390
|
if (uiImplementationArtifactNudge) {
|
|
4307
4391
|
const restoreNudge = this._formatUiQualityRestoreNudge(this._restoreUiQualityWarningPaths(uiImplementationArtifactWarnings), nudgeCount + 1);
|
|
4392
|
+
const generatedResetNudge = this._formatGeneratedScopedUiResetNudge(
|
|
4393
|
+
this._restoreGeneratedScopedUiTargets(repoBaselines, scopeAwareUserMessage)
|
|
4394
|
+
);
|
|
4308
4395
|
const scopedUiTargetSetNudge = this._buildScopedUiTargetSetNudge(repoBaselines, scopeAwareUserMessage);
|
|
4309
4396
|
nudgeCount++;
|
|
4310
4397
|
const repairBudget = consumeUiRepairNudge('completion patch artifacts', uiImplementationArtifactNudge);
|
|
4311
4398
|
if (nudgeCount < UI_QUALITY_NUDGE_LIMIT) {
|
|
4312
4399
|
console.log(`[${taskId}] UI completion had patch artifacts — nudging (${nudgeCount}/${UI_QUALITY_NUDGE_LIMIT}, total UI repairs ${repairBudget})`);
|
|
4313
|
-
const combinedNudge = [uiImplementationArtifactNudge, restoreNudge, scopedUiTargetSetNudge].filter(Boolean).join('\n\n');
|
|
4400
|
+
const combinedNudge = [uiImplementationArtifactNudge, restoreNudge, generatedResetNudge, scopedUiTargetSetNudge].filter(Boolean).join('\n\n');
|
|
4314
4401
|
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${combinedNudge}\n\nContinue from the restored files and already-inspected context. Do not mark complete until the UI source reads like finished product code and every requested scoped target screen is visually verified.`);
|
|
4315
4402
|
continue;
|
|
4316
4403
|
}
|
|
@@ -4333,12 +4420,15 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
4333
4420
|
: '';
|
|
4334
4421
|
if (shallowUiSurfaceNudge) {
|
|
4335
4422
|
const restoreNudge = this._formatUiQualityRestoreNudge(this._restoreUiQualityWarningPaths(shallowUiSurfaceWarnings), nudgeCount + 1);
|
|
4423
|
+
const generatedResetNudge = this._formatGeneratedScopedUiResetNudge(
|
|
4424
|
+
this._restoreGeneratedScopedUiTargets(repoBaselines, scopeAwareUserMessage)
|
|
4425
|
+
);
|
|
4336
4426
|
const scopedTargetSetNudge = this._formatScopedUiTargetSetReminder(scopeAwareUserMessage);
|
|
4337
4427
|
nudgeCount++;
|
|
4338
4428
|
const repairBudget = consumeUiRepairNudge('completion shallow UI surface changes', shallowUiSurfaceNudge);
|
|
4339
4429
|
if (nudgeCount < UI_QUALITY_NUDGE_LIMIT) {
|
|
4340
4430
|
console.log(`[${taskId}] UI completion had shallow surface diff — nudging (${nudgeCount}/${UI_QUALITY_NUDGE_LIMIT}, total UI repairs ${repairBudget})`);
|
|
4341
|
-
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[shallowUiSurfaceNudge, restoreNudge, scopedTargetSetNudge].filter(Boolean).join('\n\n')}\n\nDo not mark complete until the requested scoped UI is improved across the page-owned product surface and visually verified.`);
|
|
4431
|
+
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[shallowUiSurfaceNudge, restoreNudge, generatedResetNudge, scopedTargetSetNudge].filter(Boolean).join('\n\n')}\n\nDo not mark complete until the requested scoped UI is improved across the page-owned product surface and visually verified.`);
|
|
4342
4432
|
continue;
|
|
4343
4433
|
}
|
|
4344
4434
|
throw new Error(`UI task claimed completion with shallow UI surface changes after repeated retries:\n${shallowUiSurfaceNudge}`);
|
|
@@ -4349,12 +4439,15 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
4349
4439
|
: '';
|
|
4350
4440
|
if (thinUiChangeNudge) {
|
|
4351
4441
|
const restoreNudge = this._formatUiQualityRestoreNudge(this._restoreUiQualityWarningPaths(thinUiChangeWarnings), nudgeCount + 1);
|
|
4442
|
+
const generatedResetNudge = this._formatGeneratedScopedUiResetNudge(
|
|
4443
|
+
this._restoreGeneratedScopedUiTargets(repoBaselines, scopeAwareUserMessage)
|
|
4444
|
+
);
|
|
4352
4445
|
const scopedTargetSetNudge = this._formatScopedUiTargetSetReminder(scopeAwareUserMessage);
|
|
4353
4446
|
nudgeCount++;
|
|
4354
4447
|
const repairBudget = consumeUiRepairNudge('completion too-thin UI changes', thinUiChangeNudge);
|
|
4355
4448
|
if (nudgeCount < UI_QUALITY_NUDGE_LIMIT) {
|
|
4356
4449
|
console.log(`[${taskId}] UI completion had too-thin diff — nudging (${nudgeCount}/${UI_QUALITY_NUDGE_LIMIT}, total UI repairs ${repairBudget})`);
|
|
4357
|
-
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[thinUiChangeNudge, restoreNudge, scopedTargetSetNudge].filter(Boolean).join('\n\n')}\n\nDo not mark complete until the requested scoped UI is substantively improved and visually verified.`);
|
|
4450
|
+
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[thinUiChangeNudge, restoreNudge, generatedResetNudge, scopedTargetSetNudge].filter(Boolean).join('\n\n')}\n\nDo not mark complete until the requested scoped UI is substantively improved and visually verified.`);
|
|
4358
4451
|
continue;
|
|
4359
4452
|
}
|
|
4360
4453
|
throw new Error(`UI task claimed completion with too-thin diff after repeated retries:\n${thinUiChangeNudge}`);
|
|
@@ -4563,12 +4656,15 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
4563
4656
|
: '';
|
|
4564
4657
|
if (uiImplementationArtifactNudge) {
|
|
4565
4658
|
const restoreNudge = this._formatUiQualityRestoreNudge(this._restoreUiQualityWarningPaths(uiImplementationArtifactWarnings), nudgeCount + 1);
|
|
4659
|
+
const generatedResetNudge = this._formatGeneratedScopedUiResetNudge(
|
|
4660
|
+
this._restoreGeneratedScopedUiTargets(repoBaselines, scopeAwareUserMessage)
|
|
4661
|
+
);
|
|
4566
4662
|
const scopedUiTargetSetNudge = this._buildScopedUiTargetSetNudge(repoBaselines, scopeAwareUserMessage);
|
|
4567
4663
|
nudgeCount++;
|
|
4568
4664
|
const repairBudget = consumeUiRepairNudge('publish patch artifacts', uiImplementationArtifactNudge);
|
|
4569
4665
|
if (nudgeCount < UI_QUALITY_NUDGE_LIMIT) {
|
|
4570
4666
|
console.log(`[${taskId}] Publish evidence had patch artifacts — continuing (${nudgeCount}/${UI_QUALITY_NUDGE_LIMIT}, total UI repairs ${repairBudget})`);
|
|
4571
|
-
const combinedNudge = [uiImplementationArtifactNudge, restoreNudge, scopedUiTargetSetNudge].filter(Boolean).join('\n\n');
|
|
4667
|
+
const combinedNudge = [uiImplementationArtifactNudge, restoreNudge, generatedResetNudge, scopedUiTargetSetNudge].filter(Boolean).join('\n\n');
|
|
4572
4668
|
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${combinedNudge}\n\nContinue from the restored files and already-inspected context, clean up the UI implementation, address every requested scoped target page, verify each target screen visually, then commit/push any additional changes before reporting delivery complete.`);
|
|
4573
4669
|
continue;
|
|
4574
4670
|
}
|
|
@@ -4591,12 +4687,15 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
4591
4687
|
: '';
|
|
4592
4688
|
if (shallowUiSurfaceNudge) {
|
|
4593
4689
|
const restoreNudge = this._formatUiQualityRestoreNudge(this._restoreUiQualityWarningPaths(shallowUiSurfaceWarnings), nudgeCount + 1);
|
|
4690
|
+
const generatedResetNudge = this._formatGeneratedScopedUiResetNudge(
|
|
4691
|
+
this._restoreGeneratedScopedUiTargets(repoBaselines, scopeAwareUserMessage)
|
|
4692
|
+
);
|
|
4594
4693
|
const scopedTargetSetNudge = this._formatScopedUiTargetSetReminder(scopeAwareUserMessage);
|
|
4595
4694
|
nudgeCount++;
|
|
4596
4695
|
const repairBudget = consumeUiRepairNudge('publish shallow UI surface changes', shallowUiSurfaceNudge);
|
|
4597
4696
|
if (nudgeCount < UI_QUALITY_NUDGE_LIMIT) {
|
|
4598
4697
|
console.log(`[${taskId}] Publish evidence had shallow UI surface diff — continuing (${nudgeCount}/${UI_QUALITY_NUDGE_LIMIT}, total UI repairs ${repairBudget})`);
|
|
4599
|
-
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[shallowUiSurfaceNudge, restoreNudge, scopedTargetSetNudge].filter(Boolean).join('\n\n')}\n\nContinue from the restored files and already-inspected context, improve the requested scoped UI across the page-owned product surface, verify it visually, then commit/push any additional changes before reporting delivery complete.`);
|
|
4698
|
+
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[shallowUiSurfaceNudge, restoreNudge, generatedResetNudge, scopedTargetSetNudge].filter(Boolean).join('\n\n')}\n\nContinue from the restored files and already-inspected context, improve the requested scoped UI across the page-owned product surface, verify it visually, then commit/push any additional changes before reporting delivery complete.`);
|
|
4600
4699
|
continue;
|
|
4601
4700
|
}
|
|
4602
4701
|
throw new Error('Publish task had shallow UI surface changes after repeated retries');
|
|
@@ -4607,12 +4706,15 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
4607
4706
|
: '';
|
|
4608
4707
|
if (thinUiChangeNudge) {
|
|
4609
4708
|
const restoreNudge = this._formatUiQualityRestoreNudge(this._restoreUiQualityWarningPaths(thinUiChangeWarnings), nudgeCount + 1);
|
|
4709
|
+
const generatedResetNudge = this._formatGeneratedScopedUiResetNudge(
|
|
4710
|
+
this._restoreGeneratedScopedUiTargets(repoBaselines, scopeAwareUserMessage)
|
|
4711
|
+
);
|
|
4610
4712
|
const scopedTargetSetNudge = this._formatScopedUiTargetSetReminder(scopeAwareUserMessage);
|
|
4611
4713
|
nudgeCount++;
|
|
4612
4714
|
const repairBudget = consumeUiRepairNudge('publish too-thin UI changes', thinUiChangeNudge);
|
|
4613
4715
|
if (nudgeCount < UI_QUALITY_NUDGE_LIMIT) {
|
|
4614
4716
|
console.log(`[${taskId}] Publish evidence had too-thin UI diff — continuing (${nudgeCount}/${UI_QUALITY_NUDGE_LIMIT}, total UI repairs ${repairBudget})`);
|
|
4615
|
-
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[thinUiChangeNudge, restoreNudge, scopedTargetSetNudge].filter(Boolean).join('\n\n')}\n\nContinue from the restored files and already-inspected context, make the requested scoped UI improvement substantive, verify it visually, then commit/push any additional changes before reporting delivery complete.`);
|
|
4717
|
+
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[thinUiChangeNudge, restoreNudge, generatedResetNudge, scopedTargetSetNudge].filter(Boolean).join('\n\n')}\n\nContinue from the restored files and already-inspected context, make the requested scoped UI improvement substantive, verify it visually, then commit/push any additional changes before reporting delivery complete.`);
|
|
4616
4718
|
continue;
|
|
4617
4719
|
}
|
|
4618
4720
|
throw new Error('Publish task had too-thin UI diff after repeated retries');
|