ucode-agent 1.48.0 → 1.49.0
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/src/core/loop.js +3022 -3014
- package/src/tools/browser.js +13 -4
- package/src/tools/index.js +5 -3
- package/src/tools/scaffold.js +1 -1
package/src/tools/browser.js
CHANGED
|
@@ -188,7 +188,11 @@ export function forgetReviews() {
|
|
|
188
188
|
const PROBE_TEXT = 'ucode check';
|
|
189
189
|
|
|
190
190
|
/** Did anything at all happen on the page? */
|
|
191
|
-
|
|
191
|
+
// The markup itself, not its length: a timer going 25:00 -> 24:59, a counter
|
|
192
|
+
// going 0 -> 1 or a task ticked off by a class change keeps every length the
|
|
193
|
+
// same, and was reported as "NOTHING HAPPENS" — a false accusation the model
|
|
194
|
+
// then "fixed" by rewriting script that worked.
|
|
195
|
+
const moved = (a, b) => a.nodes !== b.nodes || a.html !== b.html || a.stored !== b.stored;
|
|
192
196
|
|
|
193
197
|
/**
|
|
194
198
|
* Use the app, rather than only looking at it.
|
|
@@ -218,6 +222,7 @@ async function useTheApp(page) {
|
|
|
218
222
|
const snapshot = () => page.evaluate(() => ({
|
|
219
223
|
nodes: document.body.querySelectorAll('*').length,
|
|
220
224
|
text: document.body.innerText.replace(/\s+/g, ' ').trim().length,
|
|
225
|
+
html: document.body.innerHTML,
|
|
221
226
|
stored: (() => { try { return JSON.stringify(localStorage).length; } catch { return 0; } })(),
|
|
222
227
|
}));
|
|
223
228
|
|
|
@@ -326,7 +331,7 @@ export async function withStaticServer(dir, fn) {
|
|
|
326
331
|
}
|
|
327
332
|
}
|
|
328
333
|
|
|
329
|
-
export async function lookAtApp({ url, paths = ['/'] }) {
|
|
334
|
+
export async function lookAtApp({ url, paths = ['/'], review: withReview = true }) {
|
|
330
335
|
const base = String(url ?? '').trim().replace(/\/+$/, '');
|
|
331
336
|
if (!LOCAL.test(`${base}/`)) {
|
|
332
337
|
throw new ToolFailure({
|
|
@@ -355,6 +360,10 @@ export async function lookAtApp({ url, paths = ['/'] }) {
|
|
|
355
360
|
const errors = [];
|
|
356
361
|
const failed = [];
|
|
357
362
|
page.on('console', (m) => {
|
|
363
|
+
// The browser asks for /favicon.ico on its own. A page without one is
|
|
364
|
+
// not broken, and counting that 404 sent every plain-html build round
|
|
365
|
+
// a fix loop it did not need.
|
|
366
|
+
if (/\/favicon\.ico$/i.test(m.location()?.url ?? '')) return;
|
|
358
367
|
if (m.type() === 'error' && !/devtools|download the react/i.test(m.text())) errors.push(m.text().slice(0, 200));
|
|
359
368
|
});
|
|
360
369
|
page.on('pageerror', (e) => errors.push(`uncaught: ${String(e.message).slice(0, 200)}`));
|
|
@@ -513,7 +522,7 @@ export async function lookAtApp({ url, paths = ['/'] }) {
|
|
|
513
522
|
// error overlay is a minute spent on nothing.
|
|
514
523
|
let critique = '';
|
|
515
524
|
const state = reviews.get(base) ?? { done: false, tries: 0 };
|
|
516
|
-
if (!broken && !state.done && state.tries < 2 && toReview.length) {
|
|
525
|
+
if (withReview && !broken && !state.done && state.tries < 2 && toReview.length) {
|
|
517
526
|
state.tries++;
|
|
518
527
|
reviews.set(base, state);
|
|
519
528
|
try {
|
|
@@ -530,7 +539,7 @@ export async function lookAtApp({ url, paths = ['/'] }) {
|
|
|
530
539
|
critique ? `## Visual review\n${critique}` : '',
|
|
531
540
|
'',
|
|
532
541
|
problems
|
|
533
|
-
? 'Fix the problems above
|
|
542
|
+
? 'Fix the problems above - only those; leave everything that works as it is.'
|
|
534
543
|
: state.done && critique
|
|
535
544
|
? 'The automatic checks found nothing. Weigh the visual review, fix what is worth fixing - ' +
|
|
536
545
|
'the next look re-runs only the fast checks.'
|
package/src/tools/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { addBlock, BLOCK_NAMES, PLAIN_BLOCK_NAMES, ALL_BLOCK_NAMES } from './blo
|
|
|
12
12
|
import { typeOf } from './types.js';
|
|
13
13
|
import { runCommand, runCommands } from './shell.js';
|
|
14
14
|
import { webSearch } from './web.js';
|
|
15
|
-
import { createApp, TEMPLATE_NAMES, TEMPLATE_NOTES } from './scaffold.js';
|
|
15
|
+
import { createApp, normaliseFiles, TEMPLATE_NAMES, TEMPLATE_NOTES } from './scaffold.js';
|
|
16
16
|
import { deploy } from './deploy.js';
|
|
17
17
|
import { clip, READ_LINES } from './shared.js';
|
|
18
18
|
|
|
@@ -702,13 +702,15 @@ export function describe(name, args = {}) {
|
|
|
702
702
|
return `Running ${args.commands?.length ?? 0} commands together`;
|
|
703
703
|
case 'deploy':
|
|
704
704
|
return `Deploying ${clip(args.folder || '.', 30)} to Vercel`;
|
|
705
|
-
case 'create_app':
|
|
705
|
+
case 'create_app': {
|
|
706
|
+
const files = normaliseFiles(args.files).length;
|
|
706
707
|
// Say which starter it actually is. Hardcoding one of them meant a plain
|
|
707
708
|
// HTML app announced itself as Next.js, which is a line that is simply
|
|
708
709
|
// untrue on screen while the opposite happens on disk.
|
|
709
710
|
return `Creating ${clip(args.name || args.folder, 30)} from the ` +
|
|
710
711
|
`${args.template === 'next-shadcn' ? 'Next.js' : 'HTML'} starter` +
|
|
711
|
-
`${
|
|
712
|
+
`${files ? ` with ${files} file${files === 1 ? '' : 's'}` : ''}`;
|
|
713
|
+
}
|
|
712
714
|
case 'look_at_app':
|
|
713
715
|
return `Looking at ${clip(args.url, 40)} on a phone and a desktop`;
|
|
714
716
|
case 'web_search':
|
package/src/tools/scaffold.js
CHANGED
|
@@ -48,7 +48,7 @@ const SHOW_BACK = { 'plain-html': ['index.html', 'styles.css', 'app.js'] };
|
|
|
48
48
|
* something adjacent. Each of those, refused, is a round trip spent being
|
|
49
49
|
* told what could have been read — so they are all read.
|
|
50
50
|
*/
|
|
51
|
-
function normaliseFiles(files) {
|
|
51
|
+
export function normaliseFiles(files) {
|
|
52
52
|
let value = files;
|
|
53
53
|
if (typeof value === 'string') {
|
|
54
54
|
try { value = JSON.parse(value); } catch { return []; }
|