@tea-agent/loop-agent 0.43.0-next.16 → 0.43.0-next.18
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 +8 -1
- package/dist/application/dag/args.js +8 -0
- package/dist/build-stamp.json +3 -3
- package/dist/cli/command-definitions.js +2 -0
- package/dist/cli/program.js +3 -1
- package/dist/cli/update/init-surface-notifier.js +2 -0
- package/dist/cli/update/policy.js +2 -0
- package/dist/commands/cursor-prompt.js +2 -0
- package/dist/commands/dag-approve.js +2 -0
- package/dist/commands/dag-final-verification.js +2 -0
- package/dist/commands/dag-init-hybrid.js +2 -0
- package/dist/commands/dag-reconcile-tasks.js +2 -0
- package/dist/commands/dag-reject.js +2 -0
- package/dist/commands/dag-report.js +2 -0
- package/dist/commands/dag-rerun.js +2 -0
- package/dist/commands/dag-resume.js +2 -0
- package/dist/commands/dag-workflow-compile.js +2 -0
- package/dist/commands/dag-workflow-plan.js +2 -0
- package/dist/commands/dag-workflow-validate.js +2 -0
- package/dist/commands/delegate.js +2 -0
- package/dist/commands/examples.js +2 -0
- package/dist/commands/import-prd.js +2 -0
- package/dist/commands/init-model-catalog.js +2 -0
- package/dist/commands/init.js +6 -4
- package/dist/commands/instructions.js +2 -0
- package/dist/commands/knowledge.js +2 -0
- package/dist/commands/loop-benchmark.js +2 -0
- package/dist/commands/pi-prompt.js +2 -0
- package/dist/commands/pi-reuse-benchmark.js +2 -0
- package/dist/commands/promote-run.js +2 -0
- package/dist/commands/stats.js +1 -1
- package/dist/commands/study-init.js +2 -0
- package/dist/commands/task-advance.js +2 -0
- package/dist/commands/task-source-prepare.js +2 -0
- package/dist/commands/worktree-create.js +2 -0
- package/dist/commands/worktree-remove.js +2 -0
- package/dist/executors/dag-pi-executor.js +25 -6
- package/dist/executors/shell-verification.js +3 -0
- package/dist/governance/exec-plans.js +6 -3
- package/dist/infrastructure/console/app-data.js +6 -0
- package/dist/shared/artifacts-core.js +2 -0
- package/dist/shared/git-progress.js +2 -0
- package/dist/shared/one-shot-prompt-args.js +2 -0
- package/dist/shared/package-metadata.js +6 -4
- package/dist/shared/pi-context-pressure/sift-bridge.js +1 -1
- package/dist/shared/reference-context.js +2 -0
- package/dist/task/contract/recover.js +6 -0
- package/dist/task/source-prepare/artifact-meta.js +9 -2
- package/dist/task/source-prepare/fragment-inventory.js +4 -1
- package/dist/task/source-prepare/parse-intent.js +36 -11
- package/dist/task/task-demand-routing.js +5 -2
- package/dist/worker/console/chat/browser-automation.js +468 -308
- package/dist/worker/console/chat/browser-routes.js +175 -57
- package/dist/worker/console/chat/explore-tools.js +5 -2
- package/dist/worker/console/chat/pi-runtime/custom-tools/browser-tools.js +115 -20
- package/dist/worker/console/chat/pi-runtime.js +9 -1
- package/dist/worker/console/chat/routes.js +1 -1
- package/dist/worker/console/chat/sdd-data-alignment.js +1 -1
- package/dist/worker/console/chat/session-mode.js +1 -1
- package/dist/worker/console/chat/tools.js +7 -1
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-C4NXyedy.js → abnfDiagram-N423BO3Z-B_UDknhR.js} +1 -1
- package/dist/worker/console/static/assets/{arc-NZ3qXvBI.js → arc-D6hU0drN.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-COZSRvml.js → architectureDiagram-T3A2C74G-DmVikdRK.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-Ck0Gxi9C.js → blockDiagram-VBNYF7ZC-DydABCRg.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BX5HQ4Ox.js → c4Diagram-5PPSVZJV-DrXKC2Jl.js} +1 -1
- package/dist/worker/console/static/assets/channel-Drecd94a.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-CoviemSL.js → chunk-2GRJ4B5K-D2-qFxr7.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-DbOdOkbZ.js → chunk-2Q5K7J3B-ChfeF41P.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BsG2pmdQ.js → chunk-5RXB4S5H-Drwrz55x.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-DGdvrNm8.js → chunk-5VM5RSS4-CAQGErL7.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-BAy7Yd6y.js → chunk-6Q2QTUOP-DHO38w5U.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-D9UA7hUb.js → chunk-GF5L2VYU-EYIN0EOI.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-DPz7SZ8V.js → chunk-JWPE2WC7-CrFLKqkT.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BmuEOIh7.js → chunk-KBJHAD2P-DMchffoo.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CIhBWnd8.js → chunk-RYQCIY6F-DaSvtKQa.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CScR6mDD.js → chunk-XXDRQBXY-DcW8W9Qj.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-8Udu0t8-.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-8Udu0t8-.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-BjpfWaUr.js → cose-bilkent-JH36ORCC-BUirrMEi.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BFQohJgT.js → cynefin-VYW2F7L2-BXzO8iXR.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-D3gzRJnS.js → cynefinDiagram-MW4NZA55-DAtgaxIn.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-5eojkhoA.js → dagre-VZM6K2ZE-C1re9Noh.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-CpD8LWu_.js → diagram-7IWD3JNH-N8Kj08J9.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-B8_4qJ2a.js → diagram-B4RE2ZJO-D6BpSLs3.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-HOsXf0eu.js → diagram-LBJQPF4R-C2Vlgnl4.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-BqwRwiWP.js → diagram-Q27KOJAE-CMbqtVLS.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-BRVCNZe1.js → diagram-UB23O5K3-A770Eb-0.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-Cvb1TgGh.js → ebnfDiagram-BXEA7PRR-LV2w_2pT.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DS0O0qG9.js → erDiagram-JOGREHBK-bwqf56ah.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-BHIRvRr3.js → flowDiagram-UKHOOZJN-BnVtHhZh.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-DcCJ1JWx.js → ganttDiagram-PKOTCBZU-BGVToEqc.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-B9ia5ony.js → gitGraphDiagram-DS77QQ5N-DL2l7Vne.js} +1 -1
- package/dist/worker/console/static/assets/{index-wXlQohNs.js → index-B_V4wvXs.js} +44 -44
- package/dist/worker/console/static/assets/{index-B9goN3S5.css → index-DcudonhZ.css} +1 -1
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-3ogpgegn.js → infoDiagram-6WML65LV-BWIpubOx.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-4tgpQ5SL.js → ishikawaDiagram-WSZJBQD7-DjYBD8vv.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DNfgHqFx.js → journeyDiagram-NVQOT4AX-C0_mBaHb.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-Dz7ngC8z.js → kanban-definition-27J2QSJJ-Cy71zbX6.js} +1 -1
- package/dist/worker/console/static/assets/{linear-DI7Jv62E.js → linear-Dt3_w3Vn.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-CQA4Nzmo.js → mermaid.core-DnNOlfEP.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-CtsMc8Mf.js → mindmap-definition-FAOFIHXS-DAbTspwq.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-ByppE9yH.js → pegDiagram-VL7TDLO6-NNiM141p.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-B5PtgFgt.js → pieDiagram-7S7Q4E2Y-CN80Z1Do.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-Cq4p0k2K.js → quadrantDiagram-CIZ2JOQS-Bxyfh0JU.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-DjfkyljN.js → railroadDiagram-AXF67PYL-BlWnC79M.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-DzynNRSl.js → requirementDiagram-LRYGKXZP-BrEu4P_e.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Cj7TCpTJ.js → sankeyDiagram-W5VNT64P-Bt70igBr.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-C73C6ykA.js → sequenceDiagram-SI44F4Z6-C8DQR-r9.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-BiNLgN2x.js → sizeCapture-X5ZJPWSS-DEMinJAT.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-UwvjS64-.js → stateDiagram-OKZ733FA-DDdDBzQc.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-CyCiS0Lt.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-CC7DH98r.js → swimlanes-SLNWSIFB-G2wcBs3T.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-U0lhi6N0.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-LSBXTR70.js → timeline-definition-Z64GVDOM-Dzn4g2gJ.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-BAuxWwGP.js → vennDiagram-T6HMQDX7-5v2rP9oO.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y--E5_gjZx.js → wardleyDiagram-T6FBY63Y-B4EOx7ew.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-dJWNmyzF.js → xychartDiagram-ELKLHX3M-CQ1v8eYP.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/operator-chat/slash-palette-nav.js +15 -5
- package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +2 -0
- package/dist/worker/console/static-src/prd-file-import.js +3 -1
- package/dist/worker/console/workspace-context.js +6 -1
- package/dist/worker/delivery/git-transaction.js +2 -0
- package/dist/worker/feature/fullstack-validate.js +2 -0
- package/dist/worker/loop-agent/loop-agent-client.js +8 -2
- package/dist/worker/materialize/harness-task-materializer.js +4 -1
- package/dist/worker/metrics/projector.js +1 -1
- package/dist/worker/observability/event-store.js +4 -1
- package/dist/worker/observability/read-model.js +4 -1
- package/dist/worker/observe/node-transparency.js +23 -1
- package/dist/worker/observe/routes.js +4 -0
- package/dist/worker/outcomes/declared-artifacts.js +2 -0
- package/dist/worker/preflight.js +3 -0
- package/dist/worker/task-spec/validate.js +4 -1
- package/dist/workflows/dag/decision-envelope.js +2 -0
- package/dist/workflows/dag/dynamic-runtime/shared.js +2 -2
- package/dist/workflows/dag/frontend-verification-trace.js +14 -10
- package/dist/workflows/dag/init-hybrid.js +105 -11
- package/dist/workflows/dag/interrupt-request.js +2 -0
- package/dist/workflows/dag/lifecycle.js +4 -0
- package/dist/workflows/dag/node-execution.js +2 -0
- package/dist/workflows/dag/reconcile-run.js +2 -0
- package/dist/workflows/dag/repair-artifact.js +3 -1
- package/dist/workflows/dag/report.js +2 -0
- package/dist/workflows/dag/rerun-task.js +2 -0
- package/dist/workflows/dag/types.js +21 -6
- package/dist/workflows/dag/validate.js +4 -0
- package/docs/governance/README.md +1 -0
- package/package.json +3 -1
- package/dist/worker/console/static/assets/channel-BxdTlb_5.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-_ByA1Nf8.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-_ByA1Nf8.js +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-nLgMZ0D3.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BcYqTady.js +0 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
- 修复后端标准与前端研发工作流对同一 PRD 编号风格容忍度不一致:验收标准写作 `AC1`(不加连字符)时后端一次通过、前端却在 DAG 生成期硬失败,且只报 `Invalid` 加一个 JSON 指针;需求 id 现统一规范化为 `AC-1` 形式,非法形态的报错也自带期望格式。
|
|
6
|
+
- 前端实现不再对没有构建步骤的合法项目无意义失败:静态验证改为按序取项目**真实拥有**的检查(`build` → 任务声明的静态 `--verify` → 项目自身 `typecheck`/`check`),不再在 writer 已交付正确且测试全过之后才因缺少 `npm run build` 报失败;两者都没有时仍保持原有 `build` 命令,不以 no-op 伪造验证。lint 继续不进入本工作流。
|
|
7
|
+
- 修复契约重复提交同一需求导致前端 Plan 节点确定性失败(`coverage must partition complete execution groups exactly once`):覆盖率归属前对需求 id 做保序去重。
|
|
8
|
+
- 修复前端 Mock 策略提示词自相矛盾(同时要求“只允许 not-needed”与“有项目证据可选安全策略”)导致 Plan 误选策略、被下游门禁拒绝后整轮失败;硬约束生效时不再输出那句许可性指令。
|
|
9
|
+
|
|
10
|
+
- Operator Chat 新增对话驱动的真实浏览器自动化:右侧「浏览器」面板改为工作区级 iframe 视图并同步共享浏览器状态,登录态与下载隔离保存在仓库外应用数据;模型可操作同一浏览器进行地址导航、搜索、AI 结构化快照与元素操作、标签页、弹窗、滚动、等待和截图;面板轮询不再生成截图与结构化树,浏览保持流畅,自动化不读取或修改仓库文件,也不暴露任意页面脚本执行。
|
|
11
|
+
- 模型驱动的共享浏览器默认改为可见外部窗口,并保留右侧 iframe 预览;地址、搜索和元素操作不再默认生成大截图,搜索从首页逐字填写并提交真实表单,浏览器启动降低自动化指纹,侧边栏轻量同步外部标题与地址并可聚焦窗口,拒绝嵌入的页面也提供外部状态与聚焦入口,用户可在同一持久 profile 中完成站点安全验证。
|
|
12
|
+
|
|
5
13
|
- 修复前端实现因测试名称没有 VT 编号而反复失败:按测试命令与文件关联执行结果,保留已有测试名称及测试失败阻断。
|
|
6
14
|
|
|
7
15
|
- 整理设置弹窗布局:当前工作区优先、待处理文件紧凑分组、详情按需展开,全局程序信息收拢;窄屏导航改为横向排列。
|
|
@@ -10,7 +18,6 @@
|
|
|
10
18
|
|
|
11
19
|
- 前端实现恢复已有测试维护与执行:优先任务声明,否则复用项目测试入口;没有测试时不强制补框架,避免只构建通过却遗漏旧单测回归。
|
|
12
20
|
|
|
13
|
-
- Operator Chat 新增对话驱动的侧边栏浏览器自动化:模型可在工作流 / Pi 会话调用 `browser_navigate` / `browser_search` / `browser_inspect` / `browser_act`,把百度等页面打开到右侧浏览器面板,执行静态搜索、GET 表单填充提交、链接点击并返回结构化页面元素;命令通道按工作区隔离,自动化不读取或修改仓库文件,也不执行页面脚本。
|
|
14
21
|
|
|
15
22
|
- 修复前端 Plan 无法提交实现步骤的问题:finalize_plan 支持按 AC 绑定实施动作,缺漏在节点内返回修正,避免空计划反复进入设计审查。
|
|
16
23
|
|
|
@@ -34,6 +34,8 @@ export function parseDagRunTaskArgs(args, defaultCwd) {
|
|
|
34
34
|
let profileExplicit = false;
|
|
35
35
|
for (let i = 0; i < args.length; i += 1) {
|
|
36
36
|
const arg = args[i];
|
|
37
|
+
if (arg === undefined)
|
|
38
|
+
break;
|
|
37
39
|
if (arg === "--output" || arg === "-o") {
|
|
38
40
|
outputPath = args[++i];
|
|
39
41
|
if (!outputPath) {
|
|
@@ -165,6 +167,8 @@ export function parseDagValidateArgs(args) {
|
|
|
165
167
|
let spineTaskId;
|
|
166
168
|
for (let i = 0; i < args.length; i += 1) {
|
|
167
169
|
const arg = args[i];
|
|
170
|
+
if (arg === undefined)
|
|
171
|
+
break;
|
|
168
172
|
if (arg === "--dag") {
|
|
169
173
|
dagPath = args[++i];
|
|
170
174
|
if (!dagPath) {
|
|
@@ -264,6 +268,8 @@ export function parseRunDagArgs(args, defaultCwd) {
|
|
|
264
268
|
let workerAssociation;
|
|
265
269
|
for (let i = 0; i < args.length; i += 1) {
|
|
266
270
|
const arg = args[i];
|
|
271
|
+
if (arg === undefined)
|
|
272
|
+
break;
|
|
267
273
|
if (arg === "--dag") {
|
|
268
274
|
dagPath = args[++i];
|
|
269
275
|
}
|
|
@@ -398,6 +404,8 @@ export function parseDagReportArgs(args) {
|
|
|
398
404
|
let action;
|
|
399
405
|
for (let i = 0; i < args.length; i += 1) {
|
|
400
406
|
const arg = args[i];
|
|
407
|
+
if (arg === undefined)
|
|
408
|
+
break;
|
|
401
409
|
if (arg === "--run-id") {
|
|
402
410
|
runId = args[++i];
|
|
403
411
|
continue;
|
package/dist/build-stamp.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.43.0-next.
|
|
4
|
-
"gitSha": "
|
|
5
|
-
"builtAt": "2026-09-
|
|
3
|
+
"version": "0.43.0-next.18",
|
|
4
|
+
"gitSha": "bc11e1415f26468377416cbd2142982dcc6e1dc8",
|
|
5
|
+
"builtAt": "2026-09-12T15:10:11.966Z"
|
|
6
6
|
}
|
|
@@ -67,6 +67,8 @@ export function formatSubcommandUsageError(name, subcommands) {
|
|
|
67
67
|
export function parseSummaryFlag(tokens) {
|
|
68
68
|
for (let i = 0; i < tokens.length; i += 1) {
|
|
69
69
|
const token = tokens[i];
|
|
70
|
+
if (token === undefined)
|
|
71
|
+
continue;
|
|
70
72
|
if (token === "--summary") {
|
|
71
73
|
return tokens[i + 1];
|
|
72
74
|
}
|
package/dist/cli/program.js
CHANGED
|
@@ -96,7 +96,7 @@ function commandChain(command) {
|
|
|
96
96
|
async function dispatchRegisteredCommand(commandObject, defaultRepoRoot, rawArgs) {
|
|
97
97
|
const chain = commandChain(commandObject);
|
|
98
98
|
const command = chain[0] ?? "";
|
|
99
|
-
const [subcommand, ...rest] = chain.length <= 1 ? rawArgs : [chain[1], ...chain.slice(2), ...rawArgs];
|
|
99
|
+
const [subcommand, ...rest] = chain.length <= 1 ? rawArgs : [chain[1] ?? "", ...chain.slice(2), ...rawArgs];
|
|
100
100
|
const options = collectGlobalOptions(commandObject);
|
|
101
101
|
const quiet = (command === "doctor" &&
|
|
102
102
|
[...rest, ...rawArgs].some((token) => token === "--json")) ||
|
|
@@ -397,6 +397,8 @@ function compactArgs(args) {
|
|
|
397
397
|
function parsePlanSummaryFlag(tokens) {
|
|
398
398
|
for (let i = 0; i < tokens.length; i += 1) {
|
|
399
399
|
const token = tokens[i];
|
|
400
|
+
if (token === undefined)
|
|
401
|
+
continue;
|
|
400
402
|
if (token === "--summary") {
|
|
401
403
|
return tokens[i + 1];
|
|
402
404
|
}
|
|
@@ -136,6 +136,8 @@ export function resolveInitSurfaceRepoRoot(argv, defaultRepoRoot) {
|
|
|
136
136
|
let selected = defaultRepoRoot;
|
|
137
137
|
for (let index = 0; index < argv.length; index += 1) {
|
|
138
138
|
const arg = argv[index];
|
|
139
|
+
if (arg === undefined)
|
|
140
|
+
break;
|
|
139
141
|
if (arg === "--repo-root") {
|
|
140
142
|
const value = argv[index + 1];
|
|
141
143
|
if (value && !value.startsWith("-"))
|
|
@@ -81,6 +81,8 @@ export function evaluateLatestVersion(input) {
|
|
|
81
81
|
function firstCommand(argv) {
|
|
82
82
|
for (let index = 0; index < argv.length; index += 1) {
|
|
83
83
|
const arg = argv[index];
|
|
84
|
+
if (arg === undefined)
|
|
85
|
+
break;
|
|
84
86
|
if (GLOBAL_VALUE_FLAGS.has(arg)) {
|
|
85
87
|
index += 1;
|
|
86
88
|
continue;
|
|
@@ -10,6 +10,8 @@ export function parseDagFinalVerificationArgs(args) {
|
|
|
10
10
|
let closeoutPath;
|
|
11
11
|
for (let i = 0; i < args.length; i += 1) {
|
|
12
12
|
const arg = args[i];
|
|
13
|
+
if (arg === undefined)
|
|
14
|
+
break;
|
|
13
15
|
if (arg === '--output' || arg === '-o') {
|
|
14
16
|
outputPath = requiredValue(args[++i], '--output');
|
|
15
17
|
}
|
|
@@ -9,6 +9,8 @@ export function parseDagInitHybridArgs(args) {
|
|
|
9
9
|
let outputPath;
|
|
10
10
|
for (let i = 0; i < args.length; i += 1) {
|
|
11
11
|
const arg = args[i];
|
|
12
|
+
if (arg === undefined)
|
|
13
|
+
break;
|
|
12
14
|
if (arg === "--output" || arg === "-o") {
|
|
13
15
|
outputPath = args[++i];
|
|
14
16
|
if (!outputPath) {
|
|
@@ -29,6 +29,8 @@ export function parseDagCloseoutDraftArgs(args) {
|
|
|
29
29
|
let outputPath;
|
|
30
30
|
for (let i = 0; i < args.length; i += 1) {
|
|
31
31
|
const arg = args[i];
|
|
32
|
+
if (arg === undefined)
|
|
33
|
+
break;
|
|
32
34
|
const requireValue = (flag) => {
|
|
33
35
|
const value = args[++i];
|
|
34
36
|
if (!value || value.startsWith("-")) {
|
|
@@ -22,6 +22,8 @@ export function parseDagRerunArgs(args) {
|
|
|
22
22
|
const promptOverrideAppendSpecs = [];
|
|
23
23
|
for (let index = 0; index < args.length; index += 1) {
|
|
24
24
|
const arg = args[index];
|
|
25
|
+
if (arg === undefined)
|
|
26
|
+
break;
|
|
25
27
|
if (arg === "--run-id")
|
|
26
28
|
parentRunId = args[++index];
|
|
27
29
|
else if (arg.startsWith("--run-id="))
|
|
@@ -12,6 +12,8 @@ export function parseDagWorkflowCompileArgs(args) {
|
|
|
12
12
|
let manifestPath;
|
|
13
13
|
for (let i = 0; i < args.length; i += 1) {
|
|
14
14
|
const arg = args[i];
|
|
15
|
+
if (arg === undefined)
|
|
16
|
+
break;
|
|
15
17
|
if (arg === "--workflow") {
|
|
16
18
|
workflowPath = args[++i];
|
|
17
19
|
if (!workflowPath) {
|
|
@@ -11,6 +11,8 @@ export function parseDagWorkflowValidateArgs(args) {
|
|
|
11
11
|
let strictGovernance = false;
|
|
12
12
|
for (let i = 0; i < args.length; i += 1) {
|
|
13
13
|
const arg = args[i];
|
|
14
|
+
if (arg === undefined)
|
|
15
|
+
break;
|
|
14
16
|
if (arg === "--workflow") {
|
|
15
17
|
workflowPath = args[++i];
|
|
16
18
|
if (!workflowPath) {
|
|
@@ -5,6 +5,8 @@ export function parseImportPrdArgs(args) {
|
|
|
5
5
|
const positional = [];
|
|
6
6
|
for (let index = 0; index < args.length; index += 1) {
|
|
7
7
|
const token = args[index];
|
|
8
|
+
if (token === undefined)
|
|
9
|
+
continue;
|
|
8
10
|
if (token === "--file" || token === "-f") {
|
|
9
11
|
options.file = args[index + 1];
|
|
10
12
|
index += 1;
|
|
@@ -252,6 +252,8 @@ export function parseOpenCodeModelReferences(value, credentialProviders = new Se
|
|
|
252
252
|
if (!match)
|
|
253
253
|
continue;
|
|
254
254
|
const [, provider, modelId] = match;
|
|
255
|
+
if (provider === undefined || modelId === undefined)
|
|
256
|
+
continue;
|
|
255
257
|
const model = createCatalogEntry({
|
|
256
258
|
source: "opencode",
|
|
257
259
|
provider,
|
package/dist/commands/init.js
CHANGED
|
@@ -2842,7 +2842,7 @@ function modelMergeTaskFor(pathName, state, allPaths, recordedState) {
|
|
|
2842
2842
|
taskId: `init-merge-${sha256Text(pathName).slice(0, 12)}`,
|
|
2843
2843
|
path: pathName,
|
|
2844
2844
|
reason: "target file exists but does not match the current loop-agent initialization surface",
|
|
2845
|
-
sourcePath: state
|
|
2845
|
+
sourcePath: state?.sourcePath,
|
|
2846
2846
|
allowedPaths: [pathName],
|
|
2847
2847
|
forbiddenPaths: [
|
|
2848
2848
|
...allPaths.filter((candidate) => candidate !== pathName),
|
|
@@ -2861,9 +2861,9 @@ function modelMergeTaskFor(pathName, state, allPaths, recordedState) {
|
|
|
2861
2861
|
],
|
|
2862
2862
|
evidence: {
|
|
2863
2863
|
baseSha256: recordedState?.files[pathName]?.currentSha256,
|
|
2864
|
-
currentSha256: state
|
|
2865
|
-
desiredSha256: state
|
|
2866
|
-
sourceAnchorSha256: state
|
|
2864
|
+
currentSha256: state?.currentSha256,
|
|
2865
|
+
desiredSha256: state?.sourceSha256,
|
|
2866
|
+
sourceAnchorSha256: state?.sourceAnchorSha256,
|
|
2867
2867
|
},
|
|
2868
2868
|
};
|
|
2869
2869
|
}
|
|
@@ -3743,6 +3743,8 @@ function parseInitArgs(repoRoot, args) {
|
|
|
3743
3743
|
let versionChoice;
|
|
3744
3744
|
for (let i = 0; i < args.length; i += 1) {
|
|
3745
3745
|
const arg = args[i];
|
|
3746
|
+
if (arg === undefined)
|
|
3747
|
+
break;
|
|
3746
3748
|
if ((arg === "instructions" ||
|
|
3747
3749
|
arg === "doctor" ||
|
|
3748
3750
|
arg === "model-catalog" ||
|
package/dist/commands/stats.js
CHANGED
|
@@ -6,7 +6,7 @@ function percentile(values, p) {
|
|
|
6
6
|
return null;
|
|
7
7
|
const sorted = [...values].sort((a, b) => a - b);
|
|
8
8
|
const index = Math.ceil((p / 100) * sorted.length) - 1;
|
|
9
|
-
return sorted[Math.max(0, index)];
|
|
9
|
+
return sorted[Math.max(0, index)] ?? null;
|
|
10
10
|
}
|
|
11
11
|
function formatMs(ms) {
|
|
12
12
|
if (ms >= 60_000)
|
|
@@ -84,6 +84,8 @@ export function parseTaskAdvanceArgs(args) {
|
|
|
84
84
|
const positional = [];
|
|
85
85
|
for (let i = 0; i < args.length; i += 1) {
|
|
86
86
|
const token = args[i];
|
|
87
|
+
if (token === undefined)
|
|
88
|
+
continue;
|
|
87
89
|
const next = () => {
|
|
88
90
|
const value = args[i + 1];
|
|
89
91
|
if (value === undefined || value.startsWith("-")) {
|
|
@@ -43,6 +43,8 @@ export function parseTaskSourcePrepareArgs(args) {
|
|
|
43
43
|
const positional = [];
|
|
44
44
|
for (let i = 0; i < args.length; i += 1) {
|
|
45
45
|
const token = args[i];
|
|
46
|
+
if (token === undefined)
|
|
47
|
+
continue;
|
|
46
48
|
const next = () => {
|
|
47
49
|
const value = args[i + 1];
|
|
48
50
|
if (value === undefined || value.startsWith("-")) {
|
|
@@ -4560,6 +4560,27 @@ function buildFrontendPlanWorkload(input) {
|
|
|
4560
4560
|
countFrontendPlanTargetSurfaces(input.basePrompt) === 1,
|
|
4561
4561
|
};
|
|
4562
4562
|
}
|
|
4563
|
+
/**
|
|
4564
|
+
* Requirement ids the plan coverage layout must own, in first-commit order.
|
|
4565
|
+
*
|
|
4566
|
+
* The contract ledger is append-only and `record_requirement` is incremental, so
|
|
4567
|
+
* the same id can legitimately be committed more than once. Deduplicating here is
|
|
4568
|
+
* load-bearing: `buildFrontendPlanWorkload` seeds one `unclassified` work group per
|
|
4569
|
+
* list entry without re-checking membership, so a repeated id produced two groups,
|
|
4570
|
+
* `buildWorkBatches` emitted the id twice, and the coverage-layout validator then
|
|
4571
|
+
* rejected the layout the runtime had derived itself (members 8 !== owners 7) as
|
|
4572
|
+
* FRONTEND_PLAN_LAYOUT_INVALID with failureCategory tool-policy - killing the run
|
|
4573
|
+
* at the plan node over a completely ordinary ledger.
|
|
4574
|
+
*/
|
|
4575
|
+
export function collectFrontendPlanRequirementIds(contractFacts) {
|
|
4576
|
+
return [
|
|
4577
|
+
...new Set(contractFacts
|
|
4578
|
+
.filter((record) => record.fact?.kind ===
|
|
4579
|
+
"requirement")
|
|
4580
|
+
.map((record) => record.fact?.id)
|
|
4581
|
+
.filter((id) => typeof id === "string")),
|
|
4582
|
+
];
|
|
4583
|
+
}
|
|
4563
4584
|
const frontendPlanCoverageLayoutSchema = z.object({
|
|
4564
4585
|
schemaVersion: z.literal(1),
|
|
4565
4586
|
bindingSha256: z.string(),
|
|
@@ -4901,6 +4922,8 @@ export async function runFrontendPlanSegmentedSessions(input) {
|
|
|
4901
4922
|
let lastDurableCount = input.committedFactCount();
|
|
4902
4923
|
while (index < queue.length) {
|
|
4903
4924
|
const session = queue[index];
|
|
4925
|
+
if (!session)
|
|
4926
|
+
break;
|
|
4904
4927
|
if (input.attempt > 1 && input.committedFacts && session.id === "ux-registry" &&
|
|
4905
4928
|
collectFrontendPlanPhaseMissingFacts({ phase: "ux-registry", requirementIds: allRequirementIds, committedFacts: input.committedFacts() }).length === 0) {
|
|
4906
4929
|
index += 1;
|
|
@@ -5112,7 +5135,7 @@ export async function runFrontendPlanSegmentedSessions(input) {
|
|
|
5112
5135
|
if (recovery === "stop")
|
|
5113
5136
|
return { ...result, ok: false };
|
|
5114
5137
|
if ((recovery === "output" || (session.atomicRecovery && result.ok)) && input.committedFacts &&
|
|
5115
|
-
!(missingPhaseFacts.length === 1 && missingPhaseFacts[0]
|
|
5138
|
+
!(missingPhaseFacts.length === 1 && missingPhaseFacts[0]?.kind === "plan-requirement") &&
|
|
5116
5139
|
(session.coverageOnly || isUxRegistrySession || isUxLocalSession || session.id.startsWith("global-mock-data"))) {
|
|
5117
5140
|
if (missingPhaseFacts.length === 0) {
|
|
5118
5141
|
// A complete validated slice does not need a successful prose turn.
|
|
@@ -6042,11 +6065,7 @@ export async function executeDagPiNode(input, meta, piStepFn = executePiStep, wr
|
|
|
6042
6065
|
// (SPLIT-*) that all have ids — feeding those into the coverage
|
|
6043
6066
|
// batches made the model record non-frozen plan-requirement ids
|
|
6044
6067
|
// that finalize's canonical-coverage gate then rejected (r-ext2).
|
|
6045
|
-
planRequirementIds = contractFacts
|
|
6046
|
-
.filter((record) => record.fact
|
|
6047
|
-
?.kind === "requirement")
|
|
6048
|
-
.map((record) => record.fact?.id)
|
|
6049
|
-
.filter((id) => typeof id === "string");
|
|
6068
|
+
planRequirementIds = collectFrontendPlanRequirementIds(contractFacts);
|
|
6050
6069
|
for (const fact of resolveFrontendContractRequirements(contractFacts.map((record) => record.fact))) {
|
|
6051
6070
|
if (fact.evidence.behavior === "required")
|
|
6052
6071
|
behaviorRequiredRequirementIds.push(fact.id);
|
|
@@ -138,6 +138,9 @@ export function renderVerifyReport(results) {
|
|
|
138
138
|
export async function executeCommand(command, defaultTimeoutMs = DEFAULT_VERIFY_TIMEOUT_MS) {
|
|
139
139
|
return new Promise((resolve, reject) => {
|
|
140
140
|
const [binary, ...args] = command.args;
|
|
141
|
+
if (binary === undefined) {
|
|
142
|
+
throw new Error("verify command requires a non-empty args array");
|
|
143
|
+
}
|
|
141
144
|
const timeoutMs = command.timeoutMs ?? defaultTimeoutMs;
|
|
142
145
|
const startedAt = Date.now();
|
|
143
146
|
const child = spawn(binary, args, {
|
|
@@ -174,7 +174,7 @@ function localIndexReference(rawReference) {
|
|
|
174
174
|
.trim()
|
|
175
175
|
.replace(/^<|>$/g, "")
|
|
176
176
|
.split(/[?#]/, 1)[0]
|
|
177
|
-
|
|
177
|
+
?.replaceAll("\\", "/") ?? "";
|
|
178
178
|
if (!normalized.endsWith(".md") || normalized.includes("/"))
|
|
179
179
|
return null;
|
|
180
180
|
// Naming-convention placeholders (e.g. `YYYY-MM-DD-<topic>.md`) and other
|
|
@@ -332,6 +332,8 @@ function findInsertionPointForActiveEntry(lines) {
|
|
|
332
332
|
// trailing section (blank-line separated context), or at the end.
|
|
333
333
|
for (let i = 0; i < lines.length; i += 1) {
|
|
334
334
|
const line = lines[i];
|
|
335
|
+
if (line === undefined)
|
|
336
|
+
break;
|
|
335
337
|
if (/^[-*]\s+已归档/.test(line))
|
|
336
338
|
return i;
|
|
337
339
|
if (/^[-*]\s+`[^`]+\.md`/.test(line)) {
|
|
@@ -357,7 +359,8 @@ function removeIndexEntries(indexContent, file) {
|
|
|
357
359
|
const lines = indexContent.split(/\r?\n/);
|
|
358
360
|
const filtered = lines.filter((line) => {
|
|
359
361
|
const linkMatch = line.match(/\[[^\]]*\]\(([^)]+)\)/);
|
|
360
|
-
|
|
362
|
+
const linkTarget = linkMatch?.[1];
|
|
363
|
+
if (linkTarget !== undefined && path.basename(linkTarget) === file)
|
|
361
364
|
return false;
|
|
362
365
|
if (line.includes(`\`${file}\``))
|
|
363
366
|
return false;
|
|
@@ -375,7 +378,7 @@ function collapseBlankRuns(lines) {
|
|
|
375
378
|
result.push(line);
|
|
376
379
|
prevBlank = isBlank;
|
|
377
380
|
}
|
|
378
|
-
while (result.length > 0 && result[result.length - 1]
|
|
381
|
+
while (result.length > 0 && result[result.length - 1]?.trim() === "") {
|
|
379
382
|
result.pop();
|
|
380
383
|
}
|
|
381
384
|
return result;
|
|
@@ -45,6 +45,9 @@ export function openConsoleAppData(options) {
|
|
|
45
45
|
chats: path.join(repoNamespace, "chats"),
|
|
46
46
|
chatSessions: path.join(repoNamespace, "chat-sessions"),
|
|
47
47
|
chatEvents: path.join(repoNamespace, "chat-events"),
|
|
48
|
+
browserProfile: path.join(repoNamespace, "browser-profile"),
|
|
49
|
+
browserDownloads: path.join(repoNamespace, "browser-downloads"),
|
|
50
|
+
browserScreenshots: path.join(repoNamespace, "browser-screenshots"),
|
|
48
51
|
resourcePreferences: path.join(repoNamespace, "resource-preferences.json"),
|
|
49
52
|
};
|
|
50
53
|
for (const dir of [
|
|
@@ -60,6 +63,9 @@ export function openConsoleAppData(options) {
|
|
|
60
63
|
paths.chats,
|
|
61
64
|
paths.chatSessions,
|
|
62
65
|
paths.chatEvents,
|
|
66
|
+
paths.browserProfile,
|
|
67
|
+
paths.browserDownloads,
|
|
68
|
+
paths.browserScreenshots,
|
|
63
69
|
path.dirname(paths.resourcePreferences),
|
|
64
70
|
]) {
|
|
65
71
|
ensureSecureDir(dir);
|
|
@@ -81,6 +81,8 @@ function isUnchangedNewTaskTemplate(step, content) {
|
|
|
81
81
|
}
|
|
82
82
|
function firstRequiredSectionIsEmpty(step, content) {
|
|
83
83
|
const [, firstSectionHeading] = REQUIRED_HEADINGS[step];
|
|
84
|
+
if (!firstSectionHeading)
|
|
85
|
+
return false;
|
|
84
86
|
const headingIndex = content.indexOf(firstSectionHeading);
|
|
85
87
|
if (headingIndex < 0) {
|
|
86
88
|
return false;
|
|
@@ -112,6 +112,8 @@ function globToRegExp(pattern) {
|
|
|
112
112
|
let regex = '^';
|
|
113
113
|
for (let i = 0; i < normalized.length; i += 1) {
|
|
114
114
|
const char = normalized[i];
|
|
115
|
+
if (char === undefined)
|
|
116
|
+
continue;
|
|
115
117
|
const next = normalized[i + 1];
|
|
116
118
|
if (char === '*' && next === '*') {
|
|
117
119
|
const afterGlobstar = normalized[i + 2];
|
|
@@ -8,6 +8,8 @@ export function createOneShotPromptParseAccum() {
|
|
|
8
8
|
}
|
|
9
9
|
export function parseOneShotCommonFlag(args, index, accum) {
|
|
10
10
|
const arg = args[index];
|
|
11
|
+
if (arg === undefined)
|
|
12
|
+
return { kind: "not-common" };
|
|
11
13
|
if (arg === "--stdin") {
|
|
12
14
|
accum.fromStdin = true;
|
|
13
15
|
return { kind: "consumed", nextIndex: index };
|
|
@@ -134,8 +134,10 @@ export function computePackageFingerprint(packageRoot) {
|
|
|
134
134
|
const bBuf = Buffer.from(b.relativePath, "utf-8");
|
|
135
135
|
const minLen = Math.min(aBuf.length, bBuf.length);
|
|
136
136
|
for (let i = 0; i < minLen; i++) {
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
const aByte = aBuf[i];
|
|
138
|
+
const bByte = bBuf[i];
|
|
139
|
+
if (aByte !== bByte)
|
|
140
|
+
return (aByte ?? 0) - (bByte ?? 0);
|
|
139
141
|
}
|
|
140
142
|
return aBuf.length - bBuf.length;
|
|
141
143
|
});
|
|
@@ -183,8 +185,8 @@ export function resolveBinPaths(requested, resolvedAt, inputs) {
|
|
|
183
185
|
// Search PATH
|
|
184
186
|
const pathEnv = env.PATH ?? env.Path ?? env.path ?? "";
|
|
185
187
|
const candidates = resolveFromPath(requested, pathEnv, osPlatform, env.PATHEXT ?? env.Pathext ?? env.pathext, cwd);
|
|
186
|
-
|
|
187
|
-
|
|
188
|
+
const entry = candidates[0];
|
|
189
|
+
if (entry !== undefined) {
|
|
188
190
|
assertRegularFile(entry, requested);
|
|
189
191
|
return { requested, entry, realEntry: realpathSync(entry), resolvedAt };
|
|
190
192
|
}
|
|
@@ -268,7 +268,7 @@ export function sliceUtf8Range(text, offset, maxBytes) {
|
|
|
268
268
|
}
|
|
269
269
|
const buffer = Buffer.from(text, "utf8");
|
|
270
270
|
let end = Math.min(totalBytes, start + limit);
|
|
271
|
-
while (end > start && (buffer[end] & 0b1100_0000) === 0b1000_0000) {
|
|
271
|
+
while (end > start && ((buffer[end] ?? 0) & 0b1100_0000) === 0b1000_0000) {
|
|
272
272
|
end -= 1;
|
|
273
273
|
}
|
|
274
274
|
const slice = buffer.subarray(start, end).toString("utf8");
|