@hamp10/agentforge 0.2.42 → 0.2.43
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 +15 -0
- package/src/OpenClawCLI.js +14 -10
package/package.json
CHANGED
|
@@ -1064,6 +1064,21 @@ assert.match(
|
|
|
1064
1064
|
/isHttpUiReferenceUrl/i,
|
|
1065
1065
|
'comparable UI visual context should allow same-site non-target reference pages, not only localhost'
|
|
1066
1066
|
);
|
|
1067
|
+
assert.match(
|
|
1068
|
+
openClawSource,
|
|
1069
|
+
/browser verification used a file:\/\/ URL/i,
|
|
1070
|
+
'scoped UI verification should reject file:// after edits because it can bypass local server behavior'
|
|
1071
|
+
);
|
|
1072
|
+
assert.doesNotMatch(
|
|
1073
|
+
openClawSource,
|
|
1074
|
+
/localhost\/127\.0\.0\.1 or file:\/\//i,
|
|
1075
|
+
'post-edit scoped UI verification should require localhost/127.0.0.1 instead of file://'
|
|
1076
|
+
);
|
|
1077
|
+
assert.doesNotMatch(
|
|
1078
|
+
openClawSource,
|
|
1079
|
+
/pathToFileURL/i,
|
|
1080
|
+
'auto-verification should not fall back to file:// URLs for edited scoped pages'
|
|
1081
|
+
);
|
|
1067
1082
|
assert.match(
|
|
1068
1083
|
openClawSource,
|
|
1069
1084
|
/scopeViolationThisBatch \|\| comparableContextBlockThisBatch\) break/i,
|
package/src/OpenClawCLI.js
CHANGED
|
@@ -3,7 +3,6 @@ import { mkdirSync, writeFileSync, readFileSync, existsSync, readdirSync, unlink
|
|
|
3
3
|
import { EventEmitter } from 'events';
|
|
4
4
|
import { homedir } from 'os';
|
|
5
5
|
import path from 'path';
|
|
6
|
-
import { pathToFileURL } from 'url';
|
|
7
6
|
import { inflateSync } from 'zlib';
|
|
8
7
|
import { resolveOpenclawBin } from './resolveOpenclaw.js';
|
|
9
8
|
import {
|
|
@@ -4159,11 +4158,20 @@ export class OpenClawCLI extends EventEmitter {
|
|
|
4159
4158
|
summary.text ? `Visible text:\n${summary.text}` : '',
|
|
4160
4159
|
].filter(Boolean).join('\n');
|
|
4161
4160
|
}
|
|
4162
|
-
const
|
|
4161
|
+
const isFileVerificationUrl = /^file:/i.test(summaryUrl || requestedUrl || '');
|
|
4162
|
+
const isLocalVerificationUrl = /^(?:https?:\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\])(?::\d+)?(?:\/|$))/i.test(summaryUrl || requestedUrl || '');
|
|
4163
|
+
if (options?.afterMutation && isScopedBrowserTarget && isFileVerificationUrl) {
|
|
4164
|
+
return [
|
|
4165
|
+
`Visual warning: browser verification used a file:// URL (${summaryUrl || requestedUrl || '(current tab)'}) after local file edits.`,
|
|
4166
|
+
'File URLs can skip the project server, component includes, routing, assets, and browser permissions that real users get. Start or use the local dev/static server and verify the changed target screen on localhost or 127.0.0.1.',
|
|
4167
|
+
`URL: ${summary.url || requestedUrl || '(current tab)'}`,
|
|
4168
|
+
summary.text ? `Visible text:\n${summary.text}` : '',
|
|
4169
|
+
].filter(Boolean).join('\n');
|
|
4170
|
+
}
|
|
4163
4171
|
if (options?.afterMutation && isScopedBrowserTarget && !isLocalVerificationUrl) {
|
|
4164
4172
|
return [
|
|
4165
4173
|
`Visual warning: browser verification used a remote URL (${summaryUrl || requestedUrl || '(current tab)'}) after local file edits.`,
|
|
4166
|
-
'Remote pages do not prove the edited local files render correctly before commit/push. Start or use the local preview server and verify the changed target screen on localhost
|
|
4174
|
+
'Remote pages do not prove the edited local files render correctly before commit/push. Start or use the local preview server and verify the changed target screen on localhost or 127.0.0.1.',
|
|
4167
4175
|
`URL: ${summary.url || requestedUrl || '(current tab)'}`,
|
|
4168
4176
|
summary.text ? `Visible text:\n${summary.text}` : '',
|
|
4169
4177
|
].filter(Boolean).join('\n');
|
|
@@ -4940,7 +4948,7 @@ export class OpenClawCLI extends EventEmitter {
|
|
|
4940
4948
|
}
|
|
4941
4949
|
};
|
|
4942
4950
|
const isLocalUiUrl = (url) =>
|
|
4943
|
-
/^(?:https?:\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\])(?::\d+)?(?:\/|$)
|
|
4951
|
+
/^(?:https?:\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\])(?::\d+)?(?:\/|$))/i.test(String(url || ''));
|
|
4944
4952
|
const isHttpUiReferenceUrl = (url) => {
|
|
4945
4953
|
try {
|
|
4946
4954
|
const parsed = new URL(String(url || ''));
|
|
@@ -5021,7 +5029,7 @@ export class OpenClawCLI extends EventEmitter {
|
|
|
5021
5029
|
const inferredText = inferred.length > 0
|
|
5022
5030
|
? ` Suggested local target URL(s): ${inferred.map(item => `${item.slug} -> ${item.url}`).join('; ')}.`
|
|
5023
5031
|
: '';
|
|
5024
|
-
return `Missing clean local browser verification for edited scoped target(s): ${missing.join(', ')}. Each edited scoped page must be opened on localhost/127.0.0.1
|
|
5032
|
+
return `Missing clean local browser verification for edited scoped target(s): ${missing.join(', ')}. Each edited scoped page must be opened on localhost/127.0.0.1 after its latest edit.${inferredText} Do not use a site index, listing index, shared style file, or reference page as final verification for a scoped page edit.`;
|
|
5025
5033
|
};
|
|
5026
5034
|
const inferLocalUrlForScope = (slug) => {
|
|
5027
5035
|
if (directLocalUrlsByScope.has(slug)) return directLocalUrlsByScope.get(slug);
|
|
@@ -5032,10 +5040,6 @@ export class OpenClawCLI extends EventEmitter {
|
|
|
5032
5040
|
}
|
|
5033
5041
|
}
|
|
5034
5042
|
}
|
|
5035
|
-
const mutationFile = directScopeLastMutationFiles.get(slug);
|
|
5036
|
-
if (mutationFile && this._isDirectPageSourcePath(mutationFile) && existsSync(mutationFile)) {
|
|
5037
|
-
return pathToFileURL(mutationFile).href;
|
|
5038
|
-
}
|
|
5039
5043
|
return '';
|
|
5040
5044
|
};
|
|
5041
5045
|
const autoVerifyMissingScopedTargets = async () => {
|
|
@@ -5098,7 +5102,7 @@ export class OpenClawCLI extends EventEmitter {
|
|
|
5098
5102
|
if (!urlText) return false;
|
|
5099
5103
|
const { slugs } = this._extractDirectExplicitScope(semanticTask);
|
|
5100
5104
|
if (slugs.length > 0 && scopeSlugsMatchingText(urlText, slugs).length === 0) return false;
|
|
5101
|
-
return /^(?:https?:\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\])(?::\d+)?(?:\/|$)
|
|
5105
|
+
return /^(?:https?:\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\])(?::\d+)?(?:\/|$))/i.test(urlText);
|
|
5102
5106
|
};
|
|
5103
5107
|
const extractVisualWarning = (result) => {
|
|
5104
5108
|
const warnings = String(result || '')
|