@hamp10/agentforge 0.2.44 → 0.2.46
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 +33 -0
- package/src/worker.js +38 -6
package/package.json
CHANGED
|
@@ -303,6 +303,16 @@ try {
|
|
|
303
303
|
'',
|
|
304
304
|
'new untracked scoped page files should count as touched UI targets'
|
|
305
305
|
);
|
|
306
|
+
git(fixture.repo, ['add', untrackedGammaRel]);
|
|
307
|
+
assert.equal(
|
|
308
|
+
worker._buildIncompleteScopedUiTargetsNudge(
|
|
309
|
+
[{ root: fixture.repo, head: fixture.head, initialDirtyPaths: [] }],
|
|
310
|
+
'Work on the Example.com listing pages for Alpha.ai, Beta.ai, and Gamma.ai. Make all three pages visually polished.'
|
|
311
|
+
),
|
|
312
|
+
'',
|
|
313
|
+
'new staged scoped page files should count as touched UI targets'
|
|
314
|
+
);
|
|
315
|
+
git(fixture.repo, ['restore', '--staged', untrackedGammaRel]);
|
|
306
316
|
rmSync(path.join(fixture.repo, untrackedGammaRel), { force: true });
|
|
307
317
|
const untrackedShallowGammaHtml = [
|
|
308
318
|
'<!doctype html>',
|
|
@@ -522,6 +532,14 @@ try {
|
|
|
522
532
|
/current repair strategy is not converging/i,
|
|
523
533
|
'repeated visual failures should force a strategy change instead of another micro-edit loop'
|
|
524
534
|
);
|
|
535
|
+
assert.match(
|
|
536
|
+
worker._formatVisualFailureFocusNudge(
|
|
537
|
+
'gamma-ai: Visual warning: target hero text is clipped.',
|
|
538
|
+
'Work on the Example.com listing pages for Alpha.ai, Beta.ai, and Gamma.ai. Delete and rebuild Alpha.ai and Beta.ai from a clean start, and fix Gamma.ai so all three are visually polished.'
|
|
539
|
+
),
|
|
540
|
+
/Keep other requested target page\(s\) intact[\s\S]*alpha-ai, beta-ai/i,
|
|
541
|
+
'visual-warning retries should focus on the failing target instead of recreating unrelated completed targets'
|
|
542
|
+
);
|
|
525
543
|
assert.match(
|
|
526
544
|
worker._buildScopedUiTargetSetNudge(baseline, message),
|
|
527
545
|
/one delivery set/i,
|
|
@@ -1167,6 +1185,11 @@ assert.match(
|
|
|
1167
1185
|
/_formatRepeatedVisualRepairNudge[\s\S]*current repair strategy is not converging/i,
|
|
1168
1186
|
'repeated visual failures should inject a generic strategy-change nudge'
|
|
1169
1187
|
);
|
|
1188
|
+
assert.match(
|
|
1189
|
+
workerSource,
|
|
1190
|
+
/_formatVisualFailureFocusNudge[\s\S]*Do not delete or recreate already-built target pages during a visual-warning repair/i,
|
|
1191
|
+
'visual-warning retries should preserve completed targets outside the failing page'
|
|
1192
|
+
);
|
|
1170
1193
|
assert.match(
|
|
1171
1194
|
workerSource,
|
|
1172
1195
|
/_formatUiVerificationFailureLogSummary[\s\S]*UI visual verification issue\(s\)/i,
|
|
@@ -1327,6 +1350,16 @@ assert.match(
|
|
|
1327
1350
|
/const visualWarnings = \[\];[\s\S]*visualWarnings\.push\(`\$\{slug\}: \$\{visualWarning\}`\);[\s\S]*continue;[\s\S]*lastDirectVisualWarning = visualWarnings\.join\('\\n'\);/i,
|
|
1328
1351
|
'multi-target scoped verification should inspect every missing target before returning visual warnings'
|
|
1329
1352
|
);
|
|
1353
|
+
assert.match(
|
|
1354
|
+
workerSource,
|
|
1355
|
+
/diff', '--cached', '--numstat'/,
|
|
1356
|
+
'scoped UI target checks should count staged changes as touched targets'
|
|
1357
|
+
);
|
|
1358
|
+
assert.match(
|
|
1359
|
+
workerSource,
|
|
1360
|
+
/diff', '--cached', '--unified=0'/,
|
|
1361
|
+
'UI quality artifact checks should inspect staged source diffs before commit'
|
|
1362
|
+
);
|
|
1330
1363
|
assert.match(
|
|
1331
1364
|
openClawSource,
|
|
1332
1365
|
/Network\.setCacheDisabled[\s\S]*waitForRequestedDocument/i,
|
package/src/worker.js
CHANGED
|
@@ -562,8 +562,12 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
562
562
|
this._gitOutput(baseline.root, ['diff', '--numstat'], 10000),
|
|
563
563
|
'working tree'
|
|
564
564
|
);
|
|
565
|
+
const staged = this._parseNumstat(
|
|
566
|
+
this._gitOutput(baseline.root, ['diff', '--cached', '--numstat'], 10000),
|
|
567
|
+
'staged'
|
|
568
|
+
);
|
|
565
569
|
const byPath = new Map();
|
|
566
|
-
for (const stat of [...committed, ...working]) {
|
|
570
|
+
for (const stat of [...committed, ...staged, ...working]) {
|
|
567
571
|
const key = stat.path;
|
|
568
572
|
const current = byPath.get(key) || { additions: 0, deletions: 0, path: key, sources: new Set() };
|
|
569
573
|
current.additions += stat.additions;
|
|
@@ -1185,6 +1189,10 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
1185
1189
|
this._gitOutput(baseline.root, ['diff', '--numstat'], 10000),
|
|
1186
1190
|
'working tree'
|
|
1187
1191
|
);
|
|
1192
|
+
const staged = this._parseNumstat(
|
|
1193
|
+
this._gitOutput(baseline.root, ['diff', '--cached', '--numstat'], 10000),
|
|
1194
|
+
'staged'
|
|
1195
|
+
);
|
|
1188
1196
|
const untracked = this._listUntrackedUiFiles(baseline, userMessage, { scopedOnly: true })
|
|
1189
1197
|
.map(rel => {
|
|
1190
1198
|
let additions = 0;
|
|
@@ -1198,7 +1206,7 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
1198
1206
|
}
|
|
1199
1207
|
return { additions, deletions: 0, path: rel, source: 'untracked' };
|
|
1200
1208
|
});
|
|
1201
|
-
const combined = [...committed, ...working, ...untracked]
|
|
1209
|
+
const combined = [...committed, ...staged, ...working, ...untracked]
|
|
1202
1210
|
.filter(stat => /\.(html?|css|s[ac]ss|jsx?|tsx?|vue|svelte|astro|mdx?)$/i.test(stat.path));
|
|
1203
1211
|
if (combined.length === 0) continue;
|
|
1204
1212
|
|
|
@@ -1349,6 +1357,7 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
1349
1357
|
for (const baseline of repoBaselines) {
|
|
1350
1358
|
const byPath = new Map();
|
|
1351
1359
|
scanDiff(baseline, ['diff', '--unified=0', `${baseline.head}..HEAD`], 'committed', byPath);
|
|
1360
|
+
scanDiff(baseline, ['diff', '--cached', '--unified=0'], 'staged', byPath);
|
|
1352
1361
|
scanDiff(baseline, ['diff', '--unified=0'], 'working tree', byPath);
|
|
1353
1362
|
scanUntracked(baseline, byPath);
|
|
1354
1363
|
const changedFiles = [...byPath.values()];
|
|
@@ -1467,6 +1476,21 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
1467
1476
|
].join('\n');
|
|
1468
1477
|
}
|
|
1469
1478
|
|
|
1479
|
+
_formatVisualFailureFocusNudge(output, userMessage) {
|
|
1480
|
+
const { slugs: allSlugs } = this._extractExplicitScope(userMessage);
|
|
1481
|
+
const failedSlugs = this._extractUiVerificationFailureSlugs(output, userMessage);
|
|
1482
|
+
if (allSlugs.length < 2 || failedSlugs.length === 0 || failedSlugs.length >= allSlugs.length) return '';
|
|
1483
|
+
const untouched = allSlugs.filter(slug => !failedSlugs.includes(slug));
|
|
1484
|
+
return [
|
|
1485
|
+
`Current visual verification warnings identify target page(s): ${failedSlugs.join(', ')}.`,
|
|
1486
|
+
untouched.length > 0
|
|
1487
|
+
? `Keep other requested target page(s) intact unless their own verification reports a concrete issue: ${untouched.join(', ')}.`
|
|
1488
|
+
: '',
|
|
1489
|
+
'If the original task included delete/rebuild or clean-start language, treat that as already satisfied for target files that now exist. Do not delete or recreate already-built target pages during a visual-warning repair unless the warning is for that same page.',
|
|
1490
|
+
'After fixing the failing target-owned structure, re-verify every requested target page locally before commit or completion.',
|
|
1491
|
+
].filter(Boolean).join('\n');
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1470
1494
|
_formatUiVerificationFailureLogSummary(nudge) {
|
|
1471
1495
|
const lines = String(nudge || '')
|
|
1472
1496
|
.split('\n')
|
|
@@ -1584,6 +1608,7 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
1584
1608
|
|
|
1585
1609
|
for (const baseline of repoBaselines) {
|
|
1586
1610
|
scanDiff(baseline, ['diff', '--unified=0', `${baseline.head}..HEAD`], 'committed');
|
|
1611
|
+
scanDiff(baseline, ['diff', '--cached', '--unified=0'], 'staged');
|
|
1587
1612
|
scanDiff(baseline, ['diff', '--unified=0'], 'working tree');
|
|
1588
1613
|
}
|
|
1589
1614
|
|
|
@@ -1635,6 +1660,10 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
1635
1660
|
this._gitOutput(baseline.root, ['diff', '--numstat'], 10000),
|
|
1636
1661
|
'working tree'
|
|
1637
1662
|
);
|
|
1663
|
+
const staged = this._parseNumstat(
|
|
1664
|
+
this._gitOutput(baseline.root, ['diff', '--cached', '--numstat'], 10000),
|
|
1665
|
+
'staged'
|
|
1666
|
+
);
|
|
1638
1667
|
const initialDirty = new Set(baseline.initialDirtyPaths || []);
|
|
1639
1668
|
const untracked = String(this._gitOutput(baseline.root, ['ls-files', '--others', '--exclude-standard'], 10000) || '')
|
|
1640
1669
|
.split('\n')
|
|
@@ -1643,7 +1672,7 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
1643
1672
|
.filter(rel => uiFileRe.test(rel))
|
|
1644
1673
|
.filter(rel => !initialDirty.has(rel))
|
|
1645
1674
|
.filter(rel => !this._isNestedProjectCopyRel(baseline.root, rel, baseline.head || 'HEAD'));
|
|
1646
|
-
const changedFiles = [...committed, ...working]
|
|
1675
|
+
const changedFiles = [...committed, ...staged, ...working]
|
|
1647
1676
|
.filter(stat => uiFileRe.test(stat.path))
|
|
1648
1677
|
.map(stat => stat.path)
|
|
1649
1678
|
.concat(untracked);
|
|
@@ -4395,13 +4424,14 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
4395
4424
|
const repairBudget = consumeUiRepairNudge('visual verification warnings', uiVerificationFailureNudge);
|
|
4396
4425
|
const scopedTargetSetNudge = this._formatScopedUiTargetSetReminder(scopeAwareUserMessage);
|
|
4397
4426
|
const repeatedVisualRepairNudge = this._formatRepeatedVisualRepairNudge(uiRepairNudgeCount);
|
|
4427
|
+
const visualFailureFocusNudge = this._formatVisualFailureFocusNudge(output, scopeAwareUserMessage);
|
|
4398
4428
|
const visualFailureSummary = this._formatUiVerificationFailureLogSummary(uiVerificationFailureNudge);
|
|
4399
4429
|
if (nudgeCount < MAX_NUDGES) {
|
|
4400
4430
|
console.log(`[${taskId}] UI completion still had visual verification warnings — nudging (${nudgeCount}/${MAX_NUDGES}, total UI repairs ${repairBudget})`);
|
|
4401
4431
|
if (visualFailureSummary) {
|
|
4402
4432
|
console.log(`[${taskId}] UI visual verification issue(s): ${visualFailureSummary}`);
|
|
4403
4433
|
}
|
|
4404
|
-
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[uiVerificationFailureNudge, scopedTargetSetNudge, repeatedVisualRepairNudge].filter(Boolean).join('\n\n')}\n\nFix the visible UI issues, verify again with the browser, and only then end with ✓ TASK_COMPLETE.`);
|
|
4434
|
+
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[uiVerificationFailureNudge, visualFailureFocusNudge, scopedTargetSetNudge, repeatedVisualRepairNudge].filter(Boolean).join('\n\n')}\n\nFix the visible UI issues, verify again with the browser, and only then end with ✓ TASK_COMPLETE.`);
|
|
4405
4435
|
continue;
|
|
4406
4436
|
}
|
|
4407
4437
|
throw new Error('UI task claimed completion while visual verification still reported issues');
|
|
@@ -4667,13 +4697,14 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
4667
4697
|
const repairBudget = consumeUiRepairNudge('publish visual verification warnings', uiVerificationFailureNudge);
|
|
4668
4698
|
const scopedTargetSetNudge = this._formatScopedUiTargetSetReminder(scopeAwareUserMessage);
|
|
4669
4699
|
const repeatedVisualRepairNudge = this._formatRepeatedVisualRepairNudge(uiRepairNudgeCount);
|
|
4700
|
+
const visualFailureFocusNudge = this._formatVisualFailureFocusNudge(output, scopeAwareUserMessage);
|
|
4670
4701
|
const visualFailureSummary = this._formatUiVerificationFailureLogSummary(uiVerificationFailureNudge);
|
|
4671
4702
|
if (nudgeCount < MAX_NUDGES) {
|
|
4672
4703
|
console.log(`[${taskId}] Publish evidence still had visual verification warnings — continuing (${nudgeCount}/${MAX_NUDGES}, total UI repairs ${repairBudget})`);
|
|
4673
4704
|
if (visualFailureSummary) {
|
|
4674
4705
|
console.log(`[${taskId}] UI visual verification issue(s): ${visualFailureSummary}`);
|
|
4675
4706
|
}
|
|
4676
|
-
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[uiVerificationFailureNudge, scopedTargetSetNudge, repeatedVisualRepairNudge].filter(Boolean).join('\n\n')}\n\nContinue from the current repo state, fix the visible UI issues, verify again, then commit/push any additional changes before reporting delivery complete.`);
|
|
4707
|
+
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[uiVerificationFailureNudge, visualFailureFocusNudge, scopedTargetSetNudge, repeatedVisualRepairNudge].filter(Boolean).join('\n\n')}\n\nContinue from the current repo state, fix the visible UI issues, verify again, then commit/push any additional changes before reporting delivery complete.`);
|
|
4677
4708
|
continue;
|
|
4678
4709
|
}
|
|
4679
4710
|
throw new Error('Publish task still had visual verification issues after repeated retries');
|
|
@@ -4811,6 +4842,7 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
4811
4842
|
);
|
|
4812
4843
|
const scopedTargetSetNudge = this._formatScopedUiTargetSetReminder(scopeAwareUserMessage);
|
|
4813
4844
|
const repeatedVisualRepairNudge = this._formatRepeatedVisualRepairNudge(uiVerificationRetryCount);
|
|
4845
|
+
const visualFailureFocusNudge = this._formatVisualFailureFocusNudge(output, scopeAwareUserMessage);
|
|
4814
4846
|
const visualFailureSummary = this._formatUiVerificationFailureLogSummary(visualVerificationFailureNudge);
|
|
4815
4847
|
nudgeCount = 0;
|
|
4816
4848
|
console.log(`[${taskId}] UI task visual verification still reported visible issues — retrying (${uiVerificationRetryCount}/${UI_REPAIR_NUDGE_LIMIT}, total UI repairs ${repairBudget})`);
|
|
@@ -4820,7 +4852,7 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
4820
4852
|
const retryInstruction = generatedResetNudge
|
|
4821
4853
|
? 'Rebuild the removed target page file(s) from already-inspected project context and comparable existing pages. Do not reuse the rejected generated page as the basis for the next attempt. Address every requested target that is currently missing or changed in one coherent pass, fix the visible issues reported by local browser verification, reopen each edited target screen locally after the final edit, and only then end with ✓ TASK_COMPLETE.'
|
|
4822
4854
|
: 'Continue from the current changed files and latest browser evidence. Fix the visible issues reported by the local browser verification, reopen each edited target screen locally after the final edit, and only then end with ✓ TASK_COMPLETE.';
|
|
4823
|
-
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[visualVerificationFailureNudge, generatedResetNudge, scopedTargetSetNudge, repeatedVisualRepairNudge].filter(Boolean).join('\n\n')}\n\n${retryInstruction}`);
|
|
4855
|
+
iterationMessage = withTaskContext(`The task is: "${userMessage}"\n\n${[visualVerificationFailureNudge, visualFailureFocusNudge, generatedResetNudge, scopedTargetSetNudge, repeatedVisualRepairNudge].filter(Boolean).join('\n\n')}\n\n${retryInstruction}`);
|
|
4824
4856
|
} else if (hasMissingLocalUiVerification) {
|
|
4825
4857
|
uiVerificationRetryCount++;
|
|
4826
4858
|
const uiVerificationFailureDetails = this._extractUiVerificationFailureDetails(output);
|