@tea-agent/loop-agent 0.35.1-beta.2 → 0.35.1-beta.4
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/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
-
## [0.35.1-beta.
|
|
3
|
+
## [0.35.1-beta.4] - 2026-08-15
|
|
4
|
+
|
|
5
|
+
> 观察面板规范证据不再单列 openspec:读取与检索统一为「规范已读取 / 规范检索」,空态文案同步中性化(beta,发布到 `beta` dist-tag)。
|
|
6
|
+
|
|
7
|
+
## [0.35.1-beta.3] - 2026-08-14
|
|
4
8
|
|
|
5
9
|
> frontend-implementation DAG 优化 v9 全六阶段 + Console 展示层(beta,发布到 `beta` dist-tag)。
|
|
6
10
|
|
package/dist/build-stamp.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.35.1-beta.
|
|
4
|
-
"gitSha": "
|
|
5
|
-
"builtAt": "2026-08-
|
|
3
|
+
"version": "0.35.1-beta.4",
|
|
4
|
+
"gitSha": "69b11bb0e8eaced9b52c7554afe7268aef97e75f",
|
|
5
|
+
"builtAt": "2026-08-15T04:54:32.880Z"
|
|
6
6
|
}
|
|
@@ -359,16 +359,11 @@ export async function extractSpecEvidence(repoRoot, dagRunId, nodeId) {
|
|
|
359
359
|
if (status === "no-evidence") {
|
|
360
360
|
summaryLines.push("未观察到任何规范证据:无 skill 注入、无文件读取、无检索操作。");
|
|
361
361
|
}
|
|
362
|
-
//
|
|
363
|
-
//
|
|
362
|
+
// Openspec directory reads/searches remain in the payload for API consumers
|
|
363
|
+
// (tests and downstream projections); the inspector no longer displays them
|
|
364
|
+
// separately from the generic spec reads/searches.
|
|
364
365
|
const openspecReads = specReads.filter((r) => isOpenspecPath(r.path));
|
|
365
366
|
const openspecSearches = searches.filter((s) => isOpenspecSearch(s.query, s.path));
|
|
366
|
-
if (openspecReads.length > 0) {
|
|
367
|
-
summaryLines.push(`openspec 已读取 ${openspecReads.length} 个文件:${openspecReads.map((r) => r.path).join("、")}`);
|
|
368
|
-
}
|
|
369
|
-
if (openspecSearches.length > 0) {
|
|
370
|
-
summaryLines.push(`openspec 检索 ${openspecSearches.length} 次。`);
|
|
371
|
-
}
|
|
372
367
|
return {
|
|
373
368
|
dagRunId,
|
|
374
369
|
nodeId,
|
|
@@ -360,15 +360,9 @@ async function renderSpecEvidence(content, dagRunId, nodeId, cachedEvidence) {
|
|
|
360
360
|
evidence.sourceBinding?.requirementIds,
|
|
361
361
|
(id) => el("li", null, id),
|
|
362
362
|
);
|
|
363
|
-
const openspecReadPaths = new Set(
|
|
364
|
-
(evidence.openspecReads ?? []).map((entry) => entry.path),
|
|
365
|
-
);
|
|
366
|
-
const otherSpecReads = (evidence.specReads ?? []).filter(
|
|
367
|
-
(entry) => !openspecReadPaths.has(entry.path),
|
|
368
|
-
);
|
|
369
363
|
appendListSection(
|
|
370
|
-
|
|
371
|
-
|
|
364
|
+
`规范已读取(${evidence.specReads?.length ?? 0})`,
|
|
365
|
+
evidence.specReads,
|
|
372
366
|
(read) => {
|
|
373
367
|
const item = el("li", null);
|
|
374
368
|
const button = document.createElement("button");
|
|
@@ -380,7 +374,7 @@ async function renderSpecEvidence(content, dagRunId, nodeId, cachedEvidence) {
|
|
|
380
374
|
button.setAttribute("data-read-at", read.timestamp);
|
|
381
375
|
}
|
|
382
376
|
button.id = `spec-evidence-btn-read-${read.path}`;
|
|
383
|
-
const icon = el("i", "ri-
|
|
377
|
+
const icon = el("i", "ri-book-open-line");
|
|
384
378
|
icon.setAttribute("aria-hidden", "true");
|
|
385
379
|
button.append(icon, el("code", null, read.path));
|
|
386
380
|
if (read.timestamp) {
|
|
@@ -405,9 +399,10 @@ async function renderSpecEvidence(content, dagRunId, nodeId, cachedEvidence) {
|
|
|
405
399
|
item.appendChild(button);
|
|
406
400
|
return item;
|
|
407
401
|
},
|
|
402
|
+
"unavailable:未观察到规范读取。",
|
|
408
403
|
);
|
|
409
404
|
appendListSection(
|
|
410
|
-
|
|
405
|
+
`规范检索(${evidence.specSearches?.length ?? 0})`,
|
|
411
406
|
evidence.specSearches,
|
|
412
407
|
(search) => {
|
|
413
408
|
const item = el("li", null);
|
|
@@ -419,6 +414,7 @@ async function renderSpecEvidence(content, dagRunId, nodeId, cachedEvidence) {
|
|
|
419
414
|
);
|
|
420
415
|
return item;
|
|
421
416
|
},
|
|
417
|
+
"unavailable:未观察到规范检索。",
|
|
422
418
|
);
|
|
423
419
|
appendListSection(
|
|
424
420
|
`知识库查询(${evidence.knowledgeBaseQueries?.length ?? 0})`,
|
|
@@ -433,67 +429,6 @@ async function renderSpecEvidence(content, dagRunId, nodeId, cachedEvidence) {
|
|
|
433
429
|
"unavailable:未观察到知识库查询;connector 可能未配置或未调用。",
|
|
434
430
|
);
|
|
435
431
|
|
|
436
|
-
// openspec reads are displayed independently from skill/docs reads.
|
|
437
|
-
appendListSection(
|
|
438
|
-
`openspec 已读取(${evidence.openspecReads?.length ?? 0})`,
|
|
439
|
-
evidence.openspecReads,
|
|
440
|
-
(read) => {
|
|
441
|
-
const item = el("li", null);
|
|
442
|
-
const button = document.createElement("button");
|
|
443
|
-
button.type = "button";
|
|
444
|
-
button.className = "spec-evidence-file-btn";
|
|
445
|
-
button.setAttribute("data-source", "read");
|
|
446
|
-
button.setAttribute("data-path", read.path);
|
|
447
|
-
if (read.timestamp) {
|
|
448
|
-
button.setAttribute("data-read-at", read.timestamp);
|
|
449
|
-
}
|
|
450
|
-
button.id = `spec-evidence-btn-read-${read.path}`;
|
|
451
|
-
const icon = el("i", "ri-book-open-line");
|
|
452
|
-
icon.setAttribute("aria-hidden", "true");
|
|
453
|
-
button.append(icon, el("code", null, read.path));
|
|
454
|
-
if (read.timestamp) {
|
|
455
|
-
button.appendChild(
|
|
456
|
-
el(
|
|
457
|
-
"span",
|
|
458
|
-
"spec-evidence-time",
|
|
459
|
-
formatSessionEventTime({ timestamp: read.timestamp }),
|
|
460
|
-
),
|
|
461
|
-
);
|
|
462
|
-
}
|
|
463
|
-
button.addEventListener("click", () =>
|
|
464
|
-
onSpecEvidenceFileClick(
|
|
465
|
-
content,
|
|
466
|
-
dagRunId,
|
|
467
|
-
nodeId,
|
|
468
|
-
"read",
|
|
469
|
-
read.path,
|
|
470
|
-
button,
|
|
471
|
-
),
|
|
472
|
-
);
|
|
473
|
-
item.appendChild(button);
|
|
474
|
-
return item;
|
|
475
|
-
},
|
|
476
|
-
evidence.openspecSearches?.length
|
|
477
|
-
? "已检索但未观察到 openspec 成功读取;若生成期存在候选,预写门禁会阻断 writer。"
|
|
478
|
-
: "unavailable:未观察到 openspec 成功读取。",
|
|
479
|
-
);
|
|
480
|
-
|
|
481
|
-
appendListSection(
|
|
482
|
-
`openspec 检索(${evidence.openspecSearches?.length ?? 0})`,
|
|
483
|
-
evidence.openspecSearches,
|
|
484
|
-
(search) => {
|
|
485
|
-
const item = el("li", null);
|
|
486
|
-
const icon = el("i", "ri-search-line");
|
|
487
|
-
icon.setAttribute("aria-hidden", "true");
|
|
488
|
-
item.append(
|
|
489
|
-
icon,
|
|
490
|
-
document.createTextNode(` ${search.tool}: ${search.query}`),
|
|
491
|
-
);
|
|
492
|
-
return item;
|
|
493
|
-
},
|
|
494
|
-
"unavailable:未观察到 openspec 检索。",
|
|
495
|
-
);
|
|
496
|
-
|
|
497
432
|
if (
|
|
498
433
|
evidence.status === "source-bound" ||
|
|
499
434
|
evidence.status === "spec-injected" ||
|
|
@@ -2359,6 +2359,12 @@ async function buildFrontendHybridDagFromTask(sources) {
|
|
|
2359
2359
|
`Every requirement MUST have a non-empty expectedOutcome. Every interaction MUST have non-empty trigger and expectedBehavior. UI states with applicable=true MUST have non-empty expectedBehavior. Empty strings or omitted fields for these will cause contract rejection.`,
|
|
2360
2360
|
].join("\n")
|
|
2361
2361
|
: "";
|
|
2362
|
+
const verificationTargetFileInstruction = [
|
|
2363
|
+
`## Verification target file semantics`,
|
|
2364
|
+
`verificationTargets[].file is the code file that the target verifies (the file the writer changes), NOT where the command is defined.`,
|
|
2365
|
+
`Non-static targets (type unit/component/integration/mock) MUST set file to a concrete code file inside the implementation writeSet (task allowedPaths); the prewrite gate rejects any non-static target whose file falls outside the writeSet.`,
|
|
2366
|
+
`Command-level checks that run project-wide (all tests, typecheck, build, governance) MUST use type "static" and must NOT be bound as non-static targets with file=package.json/tsconfig.json/vite.config.ts/scripts/*. Static targets are exempt from the writeSet containment check.`,
|
|
2367
|
+
].join("\n");
|
|
2362
2368
|
const strategy = resolveDagVerifyStrategy(taskConfig);
|
|
2363
2369
|
const readOnlyPaths = taskConfig.allowedPaths.length > 0 ? taskConfig.allowedPaths : ["**"];
|
|
2364
2370
|
const behaviorPaths = deriveFrontendBehaviorPaths(taskConfig);
|
|
@@ -2570,6 +2576,7 @@ async function buildFrontendHybridDagFromTask(sources) {
|
|
|
2570
2576
|
"Each requirement must state its user-observable or logic-observable expectedOutcome. Each interaction must state its trigger and expectedBehavior. IDs plus file paths are not sufficient behavior semantics.",
|
|
2571
2577
|
requirementCoverageInstruction,
|
|
2572
2578
|
"verificationTargets[].commandLabel MUST be one of the frozen command labels listed above. Any other value will be rejected at contract materialization.",
|
|
2579
|
+
verificationTargetFileInstruction,
|
|
2573
2580
|
"Read-only: do not modify code, docs, artifacts, or repository files.",
|
|
2574
2581
|
fixedVerificationContext,
|
|
2575
2582
|
sourceContext,
|
|
@@ -2627,6 +2634,7 @@ async function buildFrontendHybridDagFromTask(sources) {
|
|
|
2627
2634
|
"End the response with exactly one fenced json object conforming to frontend-implementation-contract-v1. This node is the single contract JSON producer when the design review requests revision: the fenced block is the authoritative contract the prewrite gate materializes. Do not emit any raw JSON, JSON in prose, or a second fenced block anywhere in the response. Bind it to the supplied task sources; map every requirement and applicable UI state to concrete implementation and verification targets or an explicit blocking evidence gap. Do not include secrets or unsafe paths.",
|
|
2628
2635
|
"Preserve each requirement expectedOutcome and each interaction trigger/expectedBehavior in the revised contract; do not reduce behavior semantics to IDs and paths.",
|
|
2629
2636
|
"verificationTargets[].commandLabel MUST be one of the frozen command labels listed above. Any other value will be rejected at contract materialization.",
|
|
2637
|
+
verificationTargetFileInstruction,
|
|
2630
2638
|
fixedVerificationContext,
|
|
2631
2639
|
sourceContext,
|
|
2632
2640
|
frontendContractSchemaBlock,
|