@tea-agent/loop-agent 0.27.1-beta.0 → 0.27.1-beta.2
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.
|
@@ -395,8 +395,55 @@ export function extractFrontendImplementationJson(text) {
|
|
|
395
395
|
}
|
|
396
396
|
}
|
|
397
397
|
};
|
|
398
|
+
const isContract = (candidate) => {
|
|
399
|
+
const record = asRecord(candidate);
|
|
400
|
+
return (record?.schemaVersion === 1 &&
|
|
401
|
+
asRecord(record.targets) !== null &&
|
|
402
|
+
Array.isArray(record.requirements) &&
|
|
403
|
+
Array.isArray(record.verificationTargets));
|
|
404
|
+
};
|
|
398
405
|
if (trimmed.startsWith("{") && trimmed.endsWith("}"))
|
|
399
406
|
return parse(trimmed);
|
|
407
|
+
const balancedObjects = [];
|
|
408
|
+
for (let start = 0; start < trimmed.length; start += 1) {
|
|
409
|
+
if (trimmed[start] !== "{")
|
|
410
|
+
continue;
|
|
411
|
+
let depth = 0;
|
|
412
|
+
let inString = false;
|
|
413
|
+
let escaped = false;
|
|
414
|
+
for (let index = start; index < trimmed.length; index += 1) {
|
|
415
|
+
const character = trimmed[index];
|
|
416
|
+
if (inString) {
|
|
417
|
+
if (escaped)
|
|
418
|
+
escaped = false;
|
|
419
|
+
else if (character === "\\")
|
|
420
|
+
escaped = true;
|
|
421
|
+
else if (character === '"')
|
|
422
|
+
inString = false;
|
|
423
|
+
continue;
|
|
424
|
+
}
|
|
425
|
+
if (character === '"')
|
|
426
|
+
inString = true;
|
|
427
|
+
else if (character === "{")
|
|
428
|
+
depth += 1;
|
|
429
|
+
else if (character === "}" && --depth === 0) {
|
|
430
|
+
try {
|
|
431
|
+
const candidate = parse(trimmed.slice(start, index + 1));
|
|
432
|
+
if (candidate && typeof candidate === "object" && !Array.isArray(candidate))
|
|
433
|
+
balancedObjects.push(candidate);
|
|
434
|
+
}
|
|
435
|
+
catch {
|
|
436
|
+
// Continue scanning for a later complete JSON object.
|
|
437
|
+
}
|
|
438
|
+
break;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
const balancedContracts = balancedObjects.filter(isContract);
|
|
443
|
+
if (balancedContracts.length === 1)
|
|
444
|
+
return balancedContracts[0];
|
|
445
|
+
if (balancedObjects.length === 1)
|
|
446
|
+
return balancedObjects[0];
|
|
400
447
|
const blocks = [...trimmed.matchAll(/```json\s*\n([\s\S]*?)\n```/gi)];
|
|
401
448
|
if (blocks.length === 0)
|
|
402
449
|
throw new Error("output must contain exactly one fenced json object");
|
|
@@ -412,9 +459,14 @@ export function extractFrontendImplementationJson(text) {
|
|
|
412
459
|
// block may still be deterministically recoverable.
|
|
413
460
|
}
|
|
414
461
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
462
|
+
const contractCandidates = candidates.filter(isContract);
|
|
463
|
+
if (contractCandidates.length === 1)
|
|
464
|
+
return contractCandidates[0];
|
|
465
|
+
if (candidates.length === 1)
|
|
466
|
+
return candidates[0];
|
|
467
|
+
if (candidates.length === 0)
|
|
468
|
+
throw new Error("output must contain exactly one valid fenced json object (found 0)");
|
|
469
|
+
throw new Error(`output must contain exactly one valid frontend contract json object (found ${contractCandidates.length || candidates.length})`);
|
|
418
470
|
}
|
|
419
471
|
/**
|
|
420
472
|
* Build the authoritative frontend-implementation-contract sourceBinding from
|
|
@@ -1080,11 +1080,12 @@ function isFrontendLintVerifyCommand(command) {
|
|
|
1080
1080
|
}
|
|
1081
1081
|
function partitionFrontendStaticVerifyCommands(input) {
|
|
1082
1082
|
const commands = input.commands ?? [];
|
|
1083
|
-
|
|
1083
|
+
// Frontend DAGs deliberately never generate lint verification. Existing
|
|
1084
|
+
// project lint debt is allowed to remain outside this workflow, and an
|
|
1085
|
+
// explicitly mentioned lint command must not reintroduce the lint gate.
|
|
1084
1086
|
const staticCommands = commands.filter((command) => !isFrontendLintVerifyCommand(command));
|
|
1085
1087
|
return {
|
|
1086
1088
|
lint: {
|
|
1087
|
-
...(lintCommands.length > 0 ? { commands: lintCommands } : {}),
|
|
1088
1089
|
commandSource: input.commandSource,
|
|
1089
1090
|
},
|
|
1090
1091
|
static: {
|