@hamp10/agentforge 0.2.36 → 0.2.37
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 +32 -0
- package/src/OpenClawCLI.js +24 -3
package/package.json
CHANGED
|
@@ -540,6 +540,38 @@ try {
|
|
|
540
540
|
),
|
|
541
541
|
'direct UI validation should allow standard tooling/license source comments'
|
|
542
542
|
);
|
|
543
|
+
const richExistingPageHtml = [
|
|
544
|
+
'<!doctype html><html><body><main>',
|
|
545
|
+
'<section><h1>AgentForge.ai</h1><p>' + 'Detailed product positioning and buyer rationale. '.repeat(12) + '</p></section>',
|
|
546
|
+
'<section><h2>Market Context</h2><p>' + 'Category analysis, comparable sales, and audience fit. '.repeat(10) + '</p></section>',
|
|
547
|
+
'<section><h2>Use Cases</h2><p>' + 'Platform applications, operator workflows, and strategic value. '.repeat(10) + '</p></section>',
|
|
548
|
+
'<section><h2>Acquisition</h2><p>' + 'Inquiry process, domain transfer notes, and buyer confidence. '.repeat(8) + '</p></section>',
|
|
549
|
+
'</main></body></html>',
|
|
550
|
+
].join('\n');
|
|
551
|
+
const thinReplacementPageHtml = '<!doctype html><html><body><main><section><h1>AgentForge.ai</h1><p>Short replacement.</p></section></main></body></html>';
|
|
552
|
+
assert.throws(
|
|
553
|
+
() => cli._validateDirectUiFileContent(
|
|
554
|
+
path.join(fixture.repo, 'public_html', 'domains', 'agentforge-ai.html'),
|
|
555
|
+
thinReplacementPageHtml,
|
|
556
|
+
{
|
|
557
|
+
task: 'Work on the Example.com listing pages for Alpha.ai, Beta.ai, and AgentForge.ai. Delete and rebuild Alpha.ai and Beta.ai from a clean start, and fix AgentForge.ai so all three are visually polished.',
|
|
558
|
+
oldContent: richExistingPageHtml,
|
|
559
|
+
}
|
|
560
|
+
),
|
|
561
|
+
/substantial target-page content was removed/i,
|
|
562
|
+
'clean-start permission for some scoped targets should not allow destructive content loss on a different fix-only target'
|
|
563
|
+
);
|
|
564
|
+
assert.doesNotThrow(
|
|
565
|
+
() => cli._validateDirectUiFileContent(
|
|
566
|
+
path.join(fixture.repo, 'public_html', 'domains', 'alpha.html'),
|
|
567
|
+
thinReplacementPageHtml.replace(/AgentForge\.ai/g, 'Alpha.ai'),
|
|
568
|
+
{
|
|
569
|
+
task: 'Work on the Example.com listing pages for Alpha.ai, Beta.ai, and AgentForge.ai. Delete and rebuild Alpha.ai and Beta.ai from a clean start, and fix AgentForge.ai so all three are visually polished.',
|
|
570
|
+
oldContent: richExistingPageHtml.replace(/AgentForge\.ai/g, 'Alpha.ai'),
|
|
571
|
+
}
|
|
572
|
+
),
|
|
573
|
+
'clean-start permission should still allow substantial replacement on the specific target named in the rebuild clause'
|
|
574
|
+
);
|
|
543
575
|
const protectedReplacementFile = path.join(fixture.repo, 'public_html', 'domains', 'alpha.html');
|
|
544
576
|
const protectedReplacementOriginal = readFileSync(protectedReplacementFile, 'utf-8');
|
|
545
577
|
await assert.rejects(
|
package/src/OpenClawCLI.js
CHANGED
|
@@ -1193,7 +1193,7 @@ export class OpenClawCLI extends EventEmitter {
|
|
|
1193
1193
|
if (!this._isDirectBroadUiQualityTask(options?.task)) return;
|
|
1194
1194
|
if (!/\.css$/i.test(String(filePath || ''))) return;
|
|
1195
1195
|
const taskText = String(options?.task || '');
|
|
1196
|
-
const isCleanStartTask = /\b(?:delete|rebuild|clean start|from scratch|start over|fresh|remake)\b/i
|
|
1196
|
+
const isCleanStartTask = this._directTaskAllowsContentReductionForPath(filePath, taskText, /\b(?:delete|rebuild|clean start|from scratch|start over|fresh|remake)\b/i);
|
|
1197
1197
|
if (!isCleanStartTask) return;
|
|
1198
1198
|
const { slugs, pageOnly } = this._extractDirectExplicitScope(options?.task);
|
|
1199
1199
|
if (!pageOnly || slugs.length === 0) return;
|
|
@@ -1289,7 +1289,7 @@ export class OpenClawCLI extends EventEmitter {
|
|
|
1289
1289
|
if (!this._isDirectBroadUiQualityTask(options?.task)) return;
|
|
1290
1290
|
if (!/\.(?:html?|xhtml|astro|mdx?)$/i.test(String(filePath || ''))) return;
|
|
1291
1291
|
const taskText = String(options?.task || '');
|
|
1292
|
-
const isCleanStartTask = /\b(?:delete|rebuild|clean start|from scratch|start over|fresh|remake)\b/i
|
|
1292
|
+
const isCleanStartTask = this._directTaskAllowsContentReductionForPath(filePath, taskText, /\b(?:delete|rebuild|clean start|from scratch|start over|fresh|remake)\b/i);
|
|
1293
1293
|
if (!isCleanStartTask) return;
|
|
1294
1294
|
const { slugs, pageOnly } = this._extractDirectExplicitScope(options?.task);
|
|
1295
1295
|
if (!pageOnly || slugs.length === 0) return;
|
|
@@ -1351,6 +1351,27 @@ export class OpenClawCLI extends EventEmitter {
|
|
|
1351
1351
|
throw err;
|
|
1352
1352
|
}
|
|
1353
1353
|
|
|
1354
|
+
_directTaskActionClauses(taskText) {
|
|
1355
|
+
return String(taskText || '')
|
|
1356
|
+
.split(/(?:[.!?;]\s+|,\s*(?:but|then)\s+|,\s*and\s+(?=(?:fix|repair|update|improve|polish|address|adjust|correct)\b)|\band\s+(?=(?:fix|repair|update|improve|polish|address|adjust|correct)\b))/i)
|
|
1357
|
+
.map(clause => clause.trim())
|
|
1358
|
+
.filter(Boolean);
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
_directTaskAllowsContentReductionForPath(filePath, taskText, actionRe = /\b(?:remove|delete|strip|simplif(?:y|ied|ication)|shorten|condense|reduce|minimal|less content|cleanup|clean up|prune)\b/i) {
|
|
1362
|
+
const text = String(taskText || '');
|
|
1363
|
+
if (!actionRe.test(text)) return false;
|
|
1364
|
+
const { slugs, pageOnly } = this._extractDirectExplicitScope(text);
|
|
1365
|
+
if (!pageOnly || slugs.length <= 1) return true;
|
|
1366
|
+
const matchingSlugs = this._directScopeSlugsMatchingText(String(filePath || '').toLowerCase(), slugs);
|
|
1367
|
+
if (matchingSlugs.length === 0) return false;
|
|
1368
|
+
const clauses = this._directTaskActionClauses(text);
|
|
1369
|
+
return matchingSlugs.some(slug => clauses.some(clause =>
|
|
1370
|
+
actionRe.test(clause) &&
|
|
1371
|
+
this._directScopeSlugsMatchingText(clause.toLowerCase(), [slug]).length > 0
|
|
1372
|
+
));
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1354
1375
|
_validateDirectUiImplementationArtifacts(filePath, content, options = {}) {
|
|
1355
1376
|
if (!this._isDirectBroadUiQualityTask(options?.task)) return;
|
|
1356
1377
|
if (!/\.(?:html?|xhtml|css|s[ac]ss|jsx?|tsx?|vue|svelte|astro|mdx?)$/i.test(String(filePath || ''))) return;
|
|
@@ -1427,7 +1448,7 @@ export class OpenClawCLI extends EventEmitter {
|
|
|
1427
1448
|
}
|
|
1428
1449
|
}
|
|
1429
1450
|
|
|
1430
|
-
const taskAllowsContentReduction =
|
|
1451
|
+
const taskAllowsContentReduction = this._directTaskAllowsContentReductionForPath(filePath, taskText);
|
|
1431
1452
|
if (!taskAllowsContentReduction && (oldText.trim() || headText.trim()) && /\.(?:html?|xhtml|jsx?|tsx?|vue|svelte|astro|mdx?)$/i.test(String(filePath || ''))) {
|
|
1432
1453
|
const visibleTextApprox = (value) => String(value || '')
|
|
1433
1454
|
.replace(/<script\b[\s\S]*?<\/script>/gi, ' ')
|