@tea-agent/loop-agent 0.39.0-next.30 → 0.39.0-next.31
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 +3 -0
- package/dist/build-stamp.json +2 -2
- package/dist/executors/pi-playwright-cli-tool.js +43 -11
- package/dist/shared/playwright-cli-command-policy.js +15 -0
- package/dist/task/source-prepare/parse-intent.js +24 -4
- package/dist/worker/console/dag-execution-receipt.js +33 -0
- package/dist/worker/console/operator-user-error.js +1 -1
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-CiGOV5eG.js → abnfDiagram-N423BO3Z-gauhD9kD.js} +1 -1
- package/dist/worker/console/static/assets/{arc-Ds9Gyfd8.js → arc-pm3c2Rsl.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-C6V6uC98.js → architectureDiagram-T3A2C74G-D_JAg3wH.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-DezF7Ol9.js → blockDiagram-VBNYF7ZC-Dk7-ex52.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BCWk3gCT.js → c4Diagram-5PPSVZJV-Uval9oRI.js} +1 -1
- package/dist/worker/console/static/assets/channel-CVrnUdZl.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-DbYr-Cxy.js → chunk-2GRJ4B5K-BSYjHs-v.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-XSlusW4G.js → chunk-2Q5K7J3B-KGUuBXI8.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BtcKAj9i.js → chunk-5RXB4S5H-JqAtxD9N.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-BF57lhXj.js → chunk-5VM5RSS4-D6EJOVQK.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DJIlR25o.js → chunk-6Q2QTUOP-B1JriSjm.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-DklNc7dm.js → chunk-GF5L2VYU-D62b96Jd.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-fZNtEdQZ.js → chunk-JWPE2WC7-BsNKEC_r.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BBgLqV4h.js → chunk-KBJHAD2P-B56v6-ZP.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-Dl9e5n_J.js → chunk-RYQCIY6F-D2KPnd8K.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-B0JK51NT.js → chunk-XXDRQBXY-kzKSCaaL.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-aX91WTya.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-aX91WTya.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-Ch-ajv4O.js → cose-bilkent-JH36ORCC-C6N6KNJd.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-xn_NxcfB.js → cynefin-VYW2F7L2-DiyymT2D.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-DRD0fyga.js → cynefinDiagram-MW4NZA55-BeKAXvf3.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-COtnKp4B.js → dagre-VZM6K2ZE-TkIdXfPF.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-BQp_CAqG.js → diagram-7IWD3JNH-BFmSG3ks.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-x0y-vNgq.js → diagram-B4RE2ZJO-DqpJT2Fs.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-N2ezwL31.js → diagram-LBJQPF4R-r5ATN43t.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-CSaxRH6Q.js → diagram-Q27KOJAE-DEcSCMuR.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-6Ro7Kpbd.js → diagram-UB23O5K3-VOvYRLVc.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-CrIIQEAI.js → ebnfDiagram-BXEA7PRR-D7f4Cb1u.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DivKcq8g.js → erDiagram-JOGREHBK-ziUf3U0G.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-BXrfDo8y.js → flowDiagram-UKHOOZJN-BoRdQ-1y.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-LTTQmMRJ.js → ganttDiagram-PKOTCBZU-B1-GncNm.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-DP3o_5qd.js → gitGraphDiagram-DS77QQ5N-CTW-ph8W.js} +1 -1
- package/dist/worker/console/static/assets/{index-C2jmYBfu.js → index-DEbyrEfW.js} +2 -2
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-wVfSY1WH.js → infoDiagram-6WML65LV-BFA337tZ.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-BRKfFL0I.js → ishikawaDiagram-WSZJBQD7-BtEujgRR.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DEml3jLb.js → journeyDiagram-NVQOT4AX-C8ZwD2Jp.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-DTzBmOqN.js → kanban-definition-27J2QSJJ-Ck-z8B11.js} +1 -1
- package/dist/worker/console/static/assets/{linear-Cpy1d873.js → linear-CAyXjQjN.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-C1cSavOy.js → mermaid.core-CcWKn6tS.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-BEBSKvYM.js → mindmap-definition-FAOFIHXS-C2NuDO7E.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-BrLs4Oac.js → pegDiagram-VL7TDLO6-BFub3PDz.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-B47AZcLa.js → pieDiagram-7S7Q4E2Y-BJx5THZ5.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-s0dVeYR2.js → quadrantDiagram-CIZ2JOQS-DhalkDWV.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-lW8aJ7Q6.js → railroadDiagram-AXF67PYL-CVcBM36o.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-BcHJPf6Q.js → requirementDiagram-LRYGKXZP-D_vy4n0w.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-DdegpUUf.js → sankeyDiagram-W5VNT64P-DGYdJL1D.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-BxFWqNv8.js → sequenceDiagram-SI44F4Z6-C1xJFg3k.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-cOdUDPbR.js → sizeCapture-X5ZJPWSS-D_Fc43df.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-DpxlYl8P.js → stateDiagram-OKZ733FA-BhGbIjbu.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DUt1lyFL.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-DQOfurE0.js → swimlanes-SLNWSIFB-DVkNcO-V.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BM6SGr7j.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CIp3tC6V.js → timeline-definition-Z64GVDOM-BQU9ufV0.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-C-adIPKn.js → vennDiagram-T6HMQDX7-BCQhRmYB.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CiYrar9M.js → wardleyDiagram-T6FBY63Y-DWerOyHO.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-WHrdTV0-.js → xychartDiagram-ELKLHX3M-DxLeebQU.js} +1 -1
- package/dist/worker/console/static/index.html +1 -1
- package/dist/worker/loop-agent/loop-agent-client.js +7 -3
- package/dist/worker/observe/static/views/failures.js +5 -2
- package/dist/workflows/dag/frontend-repair.js +14 -0
- package/dist/workflows/dag/frontend-risk.js +15 -2
- package/dist/workflows/dag/frontend-test-case-checklist.js +26 -2
- package/dist/workflows/dag/frontend-test-case-manifest.js +5 -0
- package/dist/workflows/dag/frontend-test-result-contract.js +151 -11
- package/dist/workflows/dag/frontend-verification-trace.js +29 -4
- package/dist/workflows/dag/init-hybrid.js +90 -14
- package/harness.json +2 -2
- package/package.json +1 -1
- package/skills/fe-test-ui-scout/SKILL.md +65 -0
- package/skills/fe-test-ui-scout/references/ledger-schema.md +62 -0
- package/skills/fe-test-ui-scout/references/recon-protocol.md +54 -0
- package/skills/playwright-cli/SKILL.md +22 -0
- package/skills/playwright-cli-case-generator/SKILL.md +20 -1
- package/dist/worker/console/static/assets/channel-DMvu1nmi.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DVzM-02m.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DVzM-02m.js +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BwecGAkM.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-D5WW_LbN.js +0 -8
package/CHANGELOG.md
CHANGED
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
### 重点更新
|
|
6
6
|
|
|
7
|
+
- 前端风险分级细分 manifest 触及语义:`allowedPaths` 含 `package.json`/lockfile 或需求文本提到 package.json 不再单独触发 `new-dependency` high-risk(改一行 script、调构建参数的任务不再被顶到强制全门禁并误标高风险),只有任务文本同时出现安装语言(npm install / yarn add / pnpm add / 新增依赖等)才升级;仅路径触及时记 `new-dependency:manifest-path-without-install-language` 拒绝信号,审计可溯。
|
|
8
|
+
- 前端验证 fallback 生成期诚实化:真实项目无可读取的 `package.json` scripts 且未探测到本地 tsc 时,不再注入必然失败的 `npm run typecheck` / `npm run build` / `npm test`(纯静态 / vanilla JS 站点原会在 verify 阶段假失败),改为执行显式 no-op 标记命令(`No frontend verification command configured`,进入冻结命令集可被 contract 引用,trace 如实记录 not-run),并写生成期 advisory 提示用 `--verify` 或执行约束显式声明验证命令后重新生成 DAG。无 repoRoot 的单测 fixture 保留历史 generic fallback。**标记不构成验证证据(fail-closed)**:verification trace 将绑定标记的 target 判为失败、只含标记的 static 证据判为 unavailable,repair 分类归为 non-repairable `contract`,verify 节点以 `frontend verification unavailable` 硬失败阻断 review/closeout——无真实验证命令的 run 无法走完绿灯链。
|
|
7
9
|
- frontend-test `passed` 回执链改按 dispatch 序号判序(B-HASH-01):`summarizePlaywrightCliReceipts` 先按 `sequence` 排序再判 open→find→cleanup 连续链;并行 `find`/`screenshot` 按完成时间落盘导致的乱序不再误杀执行已通过的 case(Wave 1 实测 4 条 passed 被改判 `browser-command-evidence-missing`)。真 gap / 重复序号仍 fail-closed。
|
|
8
10
|
- `tool-policy` 失败归一为 `executor`(B-REC-03):前端 preflight 能力拒绝(缺 `@playwright/cli` JS entry、allowlist 拒绝)不再落 `unknown`→`manual-review`+`humanRequired`;`dag report` 给出 `rerun-after-fix`,Console `standaloneTaskRerun` 的 R2 gate 放行 run-failed 同 task 整单重跑,无需人工决策门或 sibling task。
|
|
9
11
|
- Operator Chrome Band1 模式切换入口补显式 `aria-label`(B-FIND-01,方案 A):`操作`/`观测` mode link 原为 inline-flex 裸文本节点,不参与 name-from-content,a11y snapshot 序列化为无名 link,`find` 无法断言;补 `aria-label` 后实测 `find "观测"` 1 命中、click 后 `find "运行总览"` 1 命中,AC-FE-CHROME-003 恢复可见断言路径。
|
|
12
|
+
- Inspect 异常 Task 页空态文案统一(B-FIND-02):`failures.js` 运行时空态由 `当前没有失败或阻塞的 Task。` 改回与静态 `#failures-empty`、页面标题及回归目录 AC-FE-INS-004 一致的 `当前没有异常 Task`,消除静态/运行时文案漂移;实测新文案 find 1 命中、旧文案 0 命中。
|
|
10
13
|
|
|
11
14
|
- `next-release.yml` 防重复发布守卫补充幂等语义:`mode=recover`(dist-tags.next 已指向出自本 HEAD 的 tarball)时,手动 `workflow_dispatch` 重入不再撞 duplicate publish 硬失败,改为写 summary 后干净退出(§5.1 规则 4);非 recover 的重复发布仍硬失败。
|
|
12
15
|
|
package/dist/build-stamp.json
CHANGED
|
@@ -4,7 +4,7 @@ import { appendFile, lstat, mkdir, readFile, realpath, stat, } from "node:fs/pro
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { processTreeSpawnOptions, terminateProcessTree, } from "./process-tree.js";
|
|
6
6
|
import { resolvePlaywrightCliLauncher } from "./playwright-cli-launcher.js";
|
|
7
|
-
import { PLAYWRIGHT_CLI_ALLOWED_COMMANDS, isPlaywrightCliCommand, } from "../shared/playwright-cli-command-policy.js";
|
|
7
|
+
import { PLAYWRIGHT_CLI_ALLOWED_COMMANDS, isPlaywrightCliCommand, parsePlaywrightCliFindMatchCount, } from "../shared/playwright-cli-command-policy.js";
|
|
8
8
|
export { PLAYWRIGHT_CLI_ALLOWED_COMMANDS, isPlaywrightCliCommand, };
|
|
9
9
|
/** Logical capability name only; execution always uses the verified JS launcher. */
|
|
10
10
|
export const PLAYWRIGHT_CLI_EXECUTABLE = "playwright-cli";
|
|
@@ -144,8 +144,10 @@ export function summarizePlaywrightCliReceipts(receipts) {
|
|
|
144
144
|
if (PLAYWRIGHT_CLI_INTERACTION_COMMANDS.has(receipt.command) && succeeded) {
|
|
145
145
|
hasInteractionOrAssertion = true;
|
|
146
146
|
}
|
|
147
|
-
// A successful find
|
|
148
|
-
|
|
147
|
+
// A successful find (or find-unique, its semantic wrapper) is the only
|
|
148
|
+
// model-visible semantic assertion in v1.
|
|
149
|
+
if ((receipt.command === "find" || receipt.command === "find-unique") &&
|
|
150
|
+
succeeded) {
|
|
149
151
|
hasMeaningfulAssertion = true;
|
|
150
152
|
if (ordered && sawOpen)
|
|
151
153
|
sawMeaningfulAssertionAfterOpen = true;
|
|
@@ -530,6 +532,17 @@ export function preparePlaywrightCliArgv(input, ctx) {
|
|
|
530
532
|
else if (command === "pdf" || command === "snapshot") {
|
|
531
533
|
args = normalizePdfOrSnapshotArgs(command, rawArgs, ctx);
|
|
532
534
|
}
|
|
535
|
+
else if (command === "find-unique") {
|
|
536
|
+
// find-unique is a controller-side semantic wrapper: the underlying CLI
|
|
537
|
+
// only knows `find`; uniqueness (matchCount === 1) is judged by the
|
|
538
|
+
// executor after parsing the find output. Require exactly one text
|
|
539
|
+
// literal — a unique-control assertion is meaningless with multiple.
|
|
540
|
+
const literals = rawArgs.filter((arg) => !arg.startsWith("-"));
|
|
541
|
+
if (rawArgs.length !== 1 || literals.length !== 1) {
|
|
542
|
+
throw new PlaywrightCliPolicyError("find-unique-args", "find-unique requires exactly one text literal and no flags");
|
|
543
|
+
}
|
|
544
|
+
args = literals;
|
|
545
|
+
}
|
|
533
546
|
else {
|
|
534
547
|
args = rewriteArgsForPaths(command, rawArgs, ctx);
|
|
535
548
|
}
|
|
@@ -825,7 +838,10 @@ export async function executePlaywrightCliCommand(input, ctx, signal) {
|
|
|
825
838
|
};
|
|
826
839
|
}
|
|
827
840
|
let executable = PLAYWRIGHT_CLI_EXECUTABLE;
|
|
828
|
-
|
|
841
|
+
// find-unique executes as the underlying CLI `find` command; uniqueness is
|
|
842
|
+
// a controller-side judgment on the parsed match count.
|
|
843
|
+
const cliCommand = command === "find-unique" ? "find" : command;
|
|
844
|
+
let argv = [cliCommand, ...args];
|
|
829
845
|
try {
|
|
830
846
|
await validatePlaywrightCliOutputPath(command, args, ctx);
|
|
831
847
|
await validatePlaywrightCliInputFiles(command, args, ctx);
|
|
@@ -834,7 +850,7 @@ export async function executePlaywrightCliCommand(input, ctx, signal) {
|
|
|
834
850
|
if (!ctx.runCommand) {
|
|
835
851
|
const launcher = resolvePlaywrightCliLauncher(ctx.repoRoot);
|
|
836
852
|
executable = launcher.executable;
|
|
837
|
-
argv = [...launcher.argvPrefix,
|
|
853
|
+
argv = [...launcher.argvPrefix, cliCommand, ...args];
|
|
838
854
|
}
|
|
839
855
|
}
|
|
840
856
|
catch (error) {
|
|
@@ -894,6 +910,19 @@ export async function executePlaywrightCliCommand(input, ctx, signal) {
|
|
|
894
910
|
}
|
|
895
911
|
const finishedAt = new Date();
|
|
896
912
|
const combined = `${runResult.stdout}\n${runResult.stderr}`;
|
|
913
|
+
// find-family commands report their match count in stdout with exit code
|
|
914
|
+
// 0 even on zero matches — parse the count so receipts carry the real
|
|
915
|
+
// assertion signal for finalize-side audits.
|
|
916
|
+
const matchCount = command === "find" || command === "find-unique"
|
|
917
|
+
? parsePlaywrightCliFindMatchCount(runResult.stdout || "")
|
|
918
|
+
: undefined;
|
|
919
|
+
// find-unique fails closed unless exactly one match was found (including
|
|
920
|
+
// zero and unparseable outputs).
|
|
921
|
+
const findUniqueFailed = command === "find-unique" && matchCount !== 1 && !runResult.timedOut;
|
|
922
|
+
const effectiveExitCode = findUniqueFailed && runResult.exitCode === 0 ? 1 : runResult.exitCode;
|
|
923
|
+
const effectiveStderr = findUniqueFailed
|
|
924
|
+
? `${runResult.stderr}${runResult.stderr ? "\n" : ""}find-unique: expected exactly 1 match, got ${matchCount === undefined ? "unparseable output" : `${matchCount}`}`
|
|
925
|
+
: runResult.stderr;
|
|
897
926
|
const receipt = {
|
|
898
927
|
schemaVersion: 1,
|
|
899
928
|
caseId: ctx.caseId,
|
|
@@ -902,25 +931,28 @@ export async function executePlaywrightCliCommand(input, ctx, signal) {
|
|
|
902
931
|
argsRedacted: redactPlaywrightCliArgs(command, args),
|
|
903
932
|
startedAt: startedAt.toISOString(),
|
|
904
933
|
finishedAt: finishedAt.toISOString(),
|
|
905
|
-
exitCode:
|
|
934
|
+
exitCode: effectiveExitCode,
|
|
906
935
|
durationMs: finishedAt.getTime() - startedAt.getTime(),
|
|
907
936
|
outputSha256: createHash("sha256").update(combined).digest("hex"),
|
|
908
937
|
toolVersion: ctx.toolVersion ?? "unknown",
|
|
909
938
|
timedOut: runResult.timedOut || undefined,
|
|
939
|
+
...(matchCount !== undefined ? { matchCount } : {}),
|
|
910
940
|
errorClass: runResult.timedOut
|
|
911
941
|
? "timeout"
|
|
912
942
|
: runResult.signal === "abort"
|
|
913
943
|
? "abort"
|
|
914
|
-
:
|
|
944
|
+
: effectiveExitCode === 0
|
|
915
945
|
? undefined
|
|
916
|
-
:
|
|
946
|
+
: findUniqueFailed
|
|
947
|
+
? "find-unique-count-mismatch"
|
|
948
|
+
: "nonzero-exit",
|
|
917
949
|
};
|
|
918
950
|
await appendReceipt(ctx, receipt);
|
|
919
951
|
return {
|
|
920
|
-
ok:
|
|
921
|
-
exitCode:
|
|
952
|
+
ok: effectiveExitCode === 0 && !runResult.timedOut,
|
|
953
|
+
exitCode: effectiveExitCode,
|
|
922
954
|
stdout: runResult.stdout,
|
|
923
|
-
stderr:
|
|
955
|
+
stderr: effectiveStderr,
|
|
924
956
|
timedOut: runResult.timedOut,
|
|
925
957
|
receipt,
|
|
926
958
|
errorClass: receipt.errorClass,
|
|
@@ -9,6 +9,7 @@ export const PLAYWRIGHT_CLI_ALLOWED_COMMANDS = [
|
|
|
9
9
|
"goto",
|
|
10
10
|
"snapshot",
|
|
11
11
|
"find",
|
|
12
|
+
"find-unique",
|
|
12
13
|
"click",
|
|
13
14
|
"dblclick",
|
|
14
15
|
"fill",
|
|
@@ -35,6 +36,20 @@ export const PLAYWRIGHT_CLI_ALLOWED_COMMANDS = [
|
|
|
35
36
|
"requests",
|
|
36
37
|
"request",
|
|
37
38
|
];
|
|
39
|
+
/**
|
|
40
|
+
* Parse the match count from a playwright-cli find output. The CLI prints
|
|
41
|
+
* `Found N match(es) for "...":` on success and `No matches found for "...".`
|
|
42
|
+
* on zero — both with exit code 0, so the count is the only assertion signal.
|
|
43
|
+
* Returns undefined when the output shape is unrecognized (e.g. error pages).
|
|
44
|
+
*/
|
|
45
|
+
export function parsePlaywrightCliFindMatchCount(output) {
|
|
46
|
+
const found = /Found\s+(\d+)\s+match(?:es)?\s+for\b/i.exec(output);
|
|
47
|
+
if (found)
|
|
48
|
+
return Number(found[1]);
|
|
49
|
+
if (/No matches found for\b/i.test(output))
|
|
50
|
+
return 0;
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
38
53
|
const allowedCommandSet = new Set(PLAYWRIGHT_CLI_ALLOWED_COMMANDS);
|
|
39
54
|
export function isPlaywrightCliCommand(value) {
|
|
40
55
|
return allowedCommandSet.has(value);
|
|
@@ -35,8 +35,15 @@ const HEADING_ALIASES = {
|
|
|
35
35
|
assumptions: new Set(["假设", "assumptions"]),
|
|
36
36
|
};
|
|
37
37
|
const OBJECTIVE_MAX_CHARS = 1200;
|
|
38
|
-
/**
|
|
39
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Product Requirement V3/V4 style embedded AC heading, e.g. AC-FE-001 /
|
|
40
|
+
* AC-BE-12 / AC-001 — and catalog-qualified feature segments such as
|
|
41
|
+
* AC-FE-INS-001 / AC-FE-CHAT-005 (uppercase letter/digit segments).
|
|
42
|
+
* Catalog ids embedded in bold (“**AC-FE-INS-001**:…”) must bind as-is;
|
|
43
|
+
* falling through to a minted AC-00N historically produced dual ids and
|
|
44
|
+
* acceptanceCoverage.missing noise (2026-08-23 fe-test loop finding 5).
|
|
45
|
+
*/
|
|
46
|
+
const EMBEDDED_AC_HEADING = /^(AC(?:[-_](?:FE|BE|UI|API))?[-_]?[A-Z0-9]+(?:[-_][A-Z0-9]+)*)\s*[::]?\s*(.*)$/u;
|
|
40
47
|
function stripFencedAndComments(text) {
|
|
41
48
|
// Remove fenced code blocks and HTML comments so headings inside them are ignored.
|
|
42
49
|
return text
|
|
@@ -52,12 +59,25 @@ function normalizeAcceptanceId(raw) {
|
|
|
52
59
|
.replace(/^(AC)(FE|BE|UI|API)(?=-|\d)/u, "$1-$2");
|
|
53
60
|
}
|
|
54
61
|
function parseEmbeddedAcHeading(headingText) {
|
|
55
|
-
const normalized = headingText
|
|
62
|
+
const normalized = headingText
|
|
63
|
+
.trim()
|
|
64
|
+
// Strip leading section numbers ("2.1、" style) and bold/emphasis
|
|
65
|
+
// wrappers ("**AC-FE-INS-001**") so embedded catalog ids bind.
|
|
66
|
+
.replace(/^(?:\d+(?:\.\d+)*[..、]?\s*)+/u, "")
|
|
67
|
+
.replace(/^\*\*|\*\*$/g, "")
|
|
68
|
+
.replace(/^__|__$/g, "")
|
|
69
|
+
.trim();
|
|
56
70
|
const match = EMBEDDED_AC_HEADING.exec(normalized);
|
|
57
71
|
if (!match)
|
|
58
72
|
return null;
|
|
59
73
|
const id = normalizeAcceptanceId(match[1]);
|
|
60
|
-
|
|
74
|
+
// Bold-wrapped ids leave their closing marker inside the captured text
|
|
75
|
+
// ("**AC-FE-INS-001**:xxx" captures "**:xxx"); strip emphasis remnants
|
|
76
|
+
// and leading separators so the bound text is clean prose.
|
|
77
|
+
const text = (match[2] ?? "")
|
|
78
|
+
.replace(/^[*_]+\s*/, "")
|
|
79
|
+
.replace(/^\s*[::]\s*/, "")
|
|
80
|
+
.trim() || id;
|
|
61
81
|
return { id, text };
|
|
62
82
|
}
|
|
63
83
|
function normalizeHeadingText(raw) {
|
|
@@ -35,6 +35,32 @@ import { hashDagBytes, } from "./dag-confirmation.js";
|
|
|
35
35
|
* framework invocations that don't embed the word "verify".
|
|
36
36
|
*/
|
|
37
37
|
export const STRUCTURED_VERIFICATION_COMMAND_RE = /\b(vitest|jest|playwright|cypress|pytest|py-test|go\s+test|cargo\s+test|npm\s+run\s+(lint|typecheck|test|verify)|npm\s+(test|run\s+test)|check-repo\.sh|loop-agent-standard-verify)\b/i;
|
|
38
|
+
/**
|
|
39
|
+
* Deterministic shell preset keys whose executors are themselves structured
|
|
40
|
+
* verification/gate materializers: their shell.commands[] is empty and the
|
|
41
|
+
* preset alone carries the verification authority (hash-bound artifact
|
|
42
|
+
* gates, evidence validators, report finalize). Mirrors the named-shell
|
|
43
|
+
* handler registry in shell-executor.ts so preset-only workflows
|
|
44
|
+
* (frontend-test finalize/reports, backend-test pipeline, verify-evidence
|
|
45
|
+
* gates) pass the G2 autonomous execution gate without depending on node-id
|
|
46
|
+
* naming conventions.
|
|
47
|
+
*/
|
|
48
|
+
export const STRUCTURED_VERIFICATION_SHELL_PRESETS = new Set([
|
|
49
|
+
"frontendTestCaseChecklist",
|
|
50
|
+
"frontendTestCaseManifest",
|
|
51
|
+
"frontendTestEvidenceValidation",
|
|
52
|
+
"frontendTestResultFinalize",
|
|
53
|
+
"frontendTestL5Report",
|
|
54
|
+
"frontendTestHtmlReport",
|
|
55
|
+
"frontendTestReports",
|
|
56
|
+
"backendTestPipeline",
|
|
57
|
+
"verifyEvidence",
|
|
58
|
+
"repairArtifactGate",
|
|
59
|
+
"jacocoCoverage",
|
|
60
|
+
"requirementCoverageGate",
|
|
61
|
+
"jsonArtifactGate",
|
|
62
|
+
"verdictGate",
|
|
63
|
+
]);
|
|
38
64
|
export const DEFAULT_EXECUTION_RECEIPT_TTL_MS = 30 * 60 * 1000;
|
|
39
65
|
function normalizePathEntry(entry) {
|
|
40
66
|
return entry.trim().replace(/\\/g, "/").replace(/^\.\//, "");
|
|
@@ -157,6 +183,13 @@ export function deriveEligibilityFactsFromDagSpec(input) {
|
|
|
157
183
|
return false;
|
|
158
184
|
if (/verify|verification/i.test(task.id ?? ""))
|
|
159
185
|
return true;
|
|
186
|
+
// Preset-only verification shells (empty commands[]): the preset key is
|
|
187
|
+
// the verification authority (frontend-test finalize, backend-test
|
|
188
|
+
// pipeline, evidence/artifact gates).
|
|
189
|
+
const shellRecord = task.shell;
|
|
190
|
+
const hasVerificationPreset = Object.keys(shellRecord).some((key) => STRUCTURED_VERIFICATION_SHELL_PRESETS.has(key));
|
|
191
|
+
if (hasVerificationPreset)
|
|
192
|
+
return true;
|
|
160
193
|
const commands = stringList(task.shell.commands);
|
|
161
194
|
return commands.some((command) => STRUCTURED_VERIFICATION_COMMAND_RE.test(command));
|
|
162
195
|
});
|
|
@@ -23,7 +23,7 @@ export function formatOperatorUserError(message) {
|
|
|
23
23
|
if (recovery)
|
|
24
24
|
return recovery;
|
|
25
25
|
if (/controller identity changed|package fingerprint changed|entry binary sha256 changed/i.test(raw)) {
|
|
26
|
-
return "控制器版本已变更(Console
|
|
26
|
+
return "控制器版本已变更(Console 启动后代码被重新编译,或提交了 package.json / bin / dist / skills 等指纹范围文件)。请重启 Console 进程使其重新加载当前构建后再重试本操作;一次会话中途不要重建控制器。";
|
|
27
27
|
}
|
|
28
28
|
if (/Pi session file missing or not openable|cannot reopen chat session .* no persisted Pi session file/i.test(raw)) {
|
|
29
29
|
return "该对话的 Pi 会话文件已丢失,无法恢复上下文。请新建对话继续(历史记录无法重开)。";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-
|
|
1
|
+
import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-B1JriSjm.js";import{p as f}from"./chunk-JWPE2WC7-BsNKEC_r.js";import{_ as n,l as o}from"./mermaid.core-CcWKn6tS.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-DiyymT2D.js";import"./index-DEbyrEfW.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-
|
|
1
|
+
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-CcWKn6tS.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|