@hamp10/agentforge 0.2.37 → 0.2.38
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/taskSemantics.js +3 -2
- package/src/worker.js +22 -5
package/package.json
CHANGED
|
@@ -35,6 +35,12 @@ const cases = [
|
|
|
35
35
|
absent: ['example-com', 'make', 'fix'],
|
|
36
36
|
pageOnly: true,
|
|
37
37
|
},
|
|
38
|
+
{
|
|
39
|
+
text: 'Work on the Example.com listing pages for AlphaBoard.ai, BetaMatch.ai, and GammaForge.ai. Make all three pages visually polished and consistent with the rest of the site.',
|
|
40
|
+
slugs: ['alphaboard-ai', 'betamatch-ai', 'gammaforge-ai'],
|
|
41
|
+
absent: ['example-com', 'three', 'all-three', 'visual', 'polished'],
|
|
42
|
+
pageOnly: true,
|
|
43
|
+
},
|
|
38
44
|
{
|
|
39
45
|
text: 'Work on the Example.com listing pages for AlphaBoard and BetaMatch. Delete and rebuild those two listing page implementations from a clean start, preserving the same URLs and site conventions. Fix the readability and design issues. Only change those two listing pages.',
|
|
40
46
|
slugs: ['alphaboard', 'betamatch'],
|
|
@@ -249,6 +255,33 @@ try {
|
|
|
249
255
|
'clean-start rebuild tasks should still require the scoped target page to be recreated'
|
|
250
256
|
);
|
|
251
257
|
git(fixture.repo, ['restore', '--', 'public_html/domains/alpha.html']);
|
|
258
|
+
const nestedAlphaRel = `${path.basename(fixture.repo)}/public_html/domains/alpha.html`;
|
|
259
|
+
rmSync(path.join(fixture.repo, nestedAlphaRel), { force: true });
|
|
260
|
+
assert.equal(
|
|
261
|
+
worker._buildDeletedScopedPageNudge(
|
|
262
|
+
[{ root: fixture.repo, head: fixture.head }],
|
|
263
|
+
'Delete and rebuild the Alpha listing page from a clean start, preserving the same URL. Only change that listing page.'
|
|
264
|
+
),
|
|
265
|
+
'',
|
|
266
|
+
'tracked same-name nested project copies should not count as missing scoped page sources'
|
|
267
|
+
);
|
|
268
|
+
assert.equal(
|
|
269
|
+
worker._scopeAllowsChangedPath(
|
|
270
|
+
{ root: fixture.repo, head: fixture.head },
|
|
271
|
+
nestedAlphaRel,
|
|
272
|
+
['alpha'],
|
|
273
|
+
true,
|
|
274
|
+
'Delete and rebuild the Alpha listing page from a clean start. Only change that listing page.'
|
|
275
|
+
),
|
|
276
|
+
false,
|
|
277
|
+
'tracked same-name nested project copies should be treated as out-of-scope changes'
|
|
278
|
+
);
|
|
279
|
+
assert.equal(
|
|
280
|
+
worker._allCurrentPageSourceFiles(fixture.repo).includes(nestedAlphaRel),
|
|
281
|
+
false,
|
|
282
|
+
'tracked same-name nested project copies should not pollute current page source discovery'
|
|
283
|
+
);
|
|
284
|
+
git(fixture.repo, ['restore', '--', nestedAlphaRel]);
|
|
252
285
|
const projectsRoot = mkdtempSync(path.join(tmpdir(), 'agentforge-project-list-'));
|
|
253
286
|
let agentWorkspace = null;
|
|
254
287
|
try {
|
package/src/taskSemantics.js
CHANGED
|
@@ -11,8 +11,9 @@ const GENERIC_SCOPE_WORDS = new Set([
|
|
|
11
11
|
'website', 'app', 'readability', 'readable', 'legibility', 'contrast',
|
|
12
12
|
'quality', 'visual', 'content', 'layout', 'styling', 'polish',
|
|
13
13
|
'current', 'target', 'targets', 'requested', 'same', 'rest', 'live',
|
|
14
|
-
'local', 'itself', 'only', 'those', 'these', 'this', 'that',
|
|
15
|
-
'
|
|
14
|
+
'local', 'itself', 'only', 'all', 'those', 'these', 'this', 'that',
|
|
15
|
+
'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine',
|
|
16
|
+
'ten', 'both', 'change', 'edit', 'modify', 'touch', 'make', 'improve', 'fix',
|
|
16
17
|
'update', 'redesign', 'owned', 'source', 'style', 'styles', 'global',
|
|
17
18
|
'shared', 'reference', 'references', 'broaden', 'work', 'wrong', 'bad',
|
|
18
19
|
'broken',
|
package/src/worker.js
CHANGED
|
@@ -650,6 +650,22 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
650
650
|
return /\.(?:html?|xhtml|astro|mdx?)$/i.test(String(relativePath || ''));
|
|
651
651
|
}
|
|
652
652
|
|
|
653
|
+
_nestedProjectCopyCanonicalRel(repo, rel) {
|
|
654
|
+
const normalized = String(rel || '').replace(/^[/\\]+/, '');
|
|
655
|
+
if (!repo || !normalized) return '';
|
|
656
|
+
const parts = normalized.split(/[\\/]+/).filter(Boolean);
|
|
657
|
+
if (parts.length < 2 || parts[0].toLowerCase() !== path.basename(repo).toLowerCase()) return '';
|
|
658
|
+
return parts.slice(1).join('/');
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
_isNestedProjectCopyRel(repo, rel, ref = 'HEAD') {
|
|
662
|
+
const canonicalRel = this._nestedProjectCopyCanonicalRel(repo, rel);
|
|
663
|
+
if (!canonicalRel) return false;
|
|
664
|
+
const canonicalAbs = path.join(repo, ...canonicalRel.split('/'));
|
|
665
|
+
if (existsSync(canonicalAbs) || existsSync(path.dirname(canonicalAbs))) return true;
|
|
666
|
+
return this._gitPathExistsAtRef(repo, ref || 'HEAD', canonicalRel);
|
|
667
|
+
}
|
|
668
|
+
|
|
653
669
|
_isBroadReferenceSourcePath(relativePath) {
|
|
654
670
|
const normalized = String(relativePath || '').replace(/\\/g, '/').toLowerCase();
|
|
655
671
|
const parts = normalized.split('/').filter(Boolean);
|
|
@@ -727,6 +743,7 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
727
743
|
const names = new Set();
|
|
728
744
|
const add = (output) => {
|
|
729
745
|
for (const rel of String(output || '').split('\n').map(line => line.trim()).filter(Boolean)) {
|
|
746
|
+
if (this._isNestedProjectCopyRel(repo, rel)) continue;
|
|
730
747
|
if (this._isPageSourcePath(rel)) names.add(rel);
|
|
731
748
|
}
|
|
732
749
|
};
|
|
@@ -785,6 +802,7 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
785
802
|
|
|
786
803
|
_scopeAllowsChangedPath(baseline, rel, allowedSlugs, pageOnly, userMessage = '') {
|
|
787
804
|
const lower = String(rel || '').toLowerCase();
|
|
805
|
+
if (this._isNestedProjectCopyRel(baseline?.root, rel, baseline?.head || 'HEAD')) return false;
|
|
788
806
|
const slugAllowed = this._scopeSlugsMatchingText(lower, allowedSlugs).length > 0;
|
|
789
807
|
if (slugAllowed) {
|
|
790
808
|
if (this._isNewHtmlPageOutsideExistingCollection(baseline, rel, allowedSlugs, pageOnly)) return false;
|
|
@@ -988,13 +1006,12 @@ export class AgentForgeWorker extends EventEmitter {
|
|
|
988
1006
|
const deleted = [];
|
|
989
1007
|
const status = this._gitStatusPorcelain(baseline.root, 10000);
|
|
990
1008
|
for (const rawLine of String(status || '').split('\n').filter(Boolean)) {
|
|
991
|
-
const
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
const rel = rawLine.length >= 3 && rawLine[2] === ' ' ? rawLine.slice(3) : rawLine.trim().replace(/^..\s+/, '');
|
|
995
|
-
const pathName = rel.includes(' -> ') ? rel.split(' -> ').pop() : rel;
|
|
1009
|
+
const statusCode = rawLine.slice(0, 2);
|
|
1010
|
+
if (!statusCode.includes('D')) continue;
|
|
1011
|
+
const pathName = this._parseGitStatusPaths(rawLine)[0] || '';
|
|
996
1012
|
const lower = String(pathName || '').toLowerCase();
|
|
997
1013
|
if (!this._isPageSourcePath(lower)) continue;
|
|
1014
|
+
if (this._isNestedProjectCopyRel(baseline.root, pathName, baseline.head || 'HEAD')) continue;
|
|
998
1015
|
if (this._scopeSlugsMatchingText(lower, allowedSlugs).length === 0) continue;
|
|
999
1016
|
deleted.push(pathName);
|
|
1000
1017
|
}
|