@tea-agent/loop-agent 0.23.1 → 0.24.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/README.md +1 -1
  3. package/bin/agent-worker.js +0 -0
  4. package/dist/executors/shell-executor.js +20 -7
  5. package/dist/shared/operator/capabilities.js +475 -2
  6. package/dist/worker/console/app-data.js +2 -0
  7. package/dist/worker/console/chat/artifact-card.js +23 -0
  8. package/dist/worker/console/chat/chat-event-store.js +495 -0
  9. package/dist/worker/console/chat/chat-ui-policy.js +25 -0
  10. package/dist/worker/console/chat/composer-draft-store.js +45 -0
  11. package/dist/worker/console/chat/context-panel.js +54 -0
  12. package/dist/worker/console/chat/contract-apply-receipt-store.js +174 -0
  13. package/dist/worker/console/chat/explore-tools.js +299 -0
  14. package/dist/worker/console/chat/human-gate-card.js +37 -0
  15. package/dist/worker/console/chat/interview-adapter.js +136 -0
  16. package/dist/worker/console/chat/operation-card.js +23 -0
  17. package/dist/worker/console/chat/pi-console-config.js +158 -0
  18. package/dist/worker/console/chat/pi-runtime.js +581 -43
  19. package/dist/worker/console/chat/repo-browser.js +140 -0
  20. package/dist/worker/console/chat/repo-walk.js +116 -0
  21. package/dist/worker/console/chat/resource-loader.js +18 -17
  22. package/dist/worker/console/chat/routes.js +1354 -65
  23. package/dist/worker/console/chat/runtime-context.js +24 -0
  24. package/dist/worker/console/chat/runtime-selection.js +37 -0
  25. package/dist/worker/console/chat/session-store.js +210 -11
  26. package/dist/worker/console/chat/shortcuts.js +15 -0
  27. package/dist/worker/console/chat/tool-adapter.js +81 -194
  28. package/dist/worker/console/chat/tools.js +72 -48
  29. package/dist/worker/console/chat/usage.js +37 -0
  30. package/dist/worker/console/chat/workspace-landing.js +56 -0
  31. package/dist/worker/console/dag-confirmation.js +42 -8
  32. package/dist/worker/console/human-gate-token.js +130 -0
  33. package/dist/worker/console/mutation-gate-receipt-store.js +184 -0
  34. package/dist/worker/console/operation-runner.js +6 -2
  35. package/dist/worker/console/operation-sse.js +26 -0
  36. package/dist/worker/console/operator-actions.js +420 -7
  37. package/dist/worker/console/server.js +14 -2
  38. package/dist/worker/console/static/assets/index-BTbrEHnO.css +1 -0
  39. package/dist/worker/console/static/assets/index-D9qLevoP.js +27 -0
  40. package/dist/worker/console/static/index.html +2 -2
  41. package/dist/workflows/dag/backend-test-markdown-workflow.js +9 -5
  42. package/dist/workflows/dag/backend-test-result-contract.js +229 -0
  43. package/dist/workflows/dag/frontend-lint-baseline.js +4 -4
  44. package/dist/workflows/dag/init-hybrid.js +2 -1
  45. package/docs/README.md +1 -1
  46. package/docs/architecture/README.md +5 -5
  47. package/docs/architecture/evolution.md +4 -4
  48. package/docs/architecture/worker-and-feature.md +1 -1
  49. package/docs/templates/backend-test-dag.json +2 -2
  50. package/harness.json +1 -1
  51. package/package.json +1 -1
  52. package/dist/worker/console/static/assets/index-DVl7Jxt5.js +0 -25
  53. package/dist/worker/console/static/assets/index-lVcIr9Ju.css +0 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.24.0] - 2026-07-27
6
+
7
+ ### 新增
8
+
9
+ - align chat workspace with pi web UX
10
+ - operator chat workspace UX + async runtime race guards
11
+ - operator chat M3-M7 (draft interview, human-gate, input context, artifacts, branching, landing)
12
+ - pytest-html report + filename mapping + Windows path fix (#71)
13
+
14
+ ### 改进
15
+
16
+ - style(console): 收紧 Operator Chat 工作台密度与侧栏体验
17
+ - style(console): prettier-format Operator Chat + keep UI-contract text intact
18
+
19
+ ### 修复
20
+
21
+ - operator chat M2 closure tracer + code review followups
22
+
5
23
  ## [0.23.1] - 2026-07-26
6
24
 
7
25
  ### 重点更新
@@ -69,7 +87,6 @@
69
87
  - Console Phase 4 Chat P1 审查修复:`createSessionFromServices` 显式传 `tools:[bash,read,grep,find,ls]`(SDK 默认 builtin 不含 grep/find/ls,否则 setActiveToolsByName 静默 no-op);schema↔dispatcher 契约对齐(contractValidate/Diff 用 draftJson、workerTaskRetry 补 featureId、动态发现 fail-closed);server.close() 先 chatRuntime.disposeAll();resource-loader/system prompt 统一到 widening(hasBash:true)
70
88
  - CI 治理:7 个 versionConsumer 文档版本漂移 0.22.0→0.23.0;check-task-pool-root.sh allowlist 增补 codify-constraints.md
71
89
 
72
-
73
90
  ## [0.22.0] - 2026-07-24
74
91
 
75
92
  ### 重点更新
package/README.md CHANGED
@@ -100,7 +100,7 @@ agent-worker console doctor --repo .
100
100
 
101
101
  ```
102
102
 
103
- 访问 Console <http://127.0.0.1:8790/>;顶部「检视」以及 `/inspect/` 提供原 Observe 的只读 Dashboard、DAG、时间线与 artifacts。需要保留的旧书签或脚本仍可在兼容窗口使用 Observe `:8787`。openCode 等主会话仍是 **Compatibility / Operator Assist**,不得升级为与 Official 同等保证。
103
+ 访问 Console <http://127.0.0.1:8790/>;**Operator Chat Official** 是 Console 内的主引导交互。构建时设置 `VITE_OPERATOR_CHAT_DEFAULT_LANDING=chat` 可将 Chat 作为默认 landing;flag 未开启时仍默认进入 Tasks,旧 Task Ops tab 始终保留。顶部「检视」以及 `/inspect/` 提供只读 Dashboard、DAG、时间线与 artifacts;`loop-agent …` / `agent-worker …` CLI direct path 仍是受治理 fallback。当前状态为 **code ready, dogfood pending/unmet**,不宣称已替代 openCode 或其他外部主会话。
104
104
 
105
105
  ## 核心边界
106
106
 
File without changes
@@ -17,7 +17,7 @@ import { formatFrontendReviewContextStdout, runFrontendReviewContextGate, } from
17
17
  import { materializeFrontendLintAssessment, materializeFrontendLintBaseline, } from "../workflows/dag/frontend-lint-baseline.js";
18
18
  import { formatTraceabilityGateStdout, materializeBackendTestCaseManifest, runBackendTestTraceabilityGate, } from "../workflows/dag/backend-test-case-manifest.js";
19
19
  import { materializeBackendTestExecutionContract } from "../workflows/dag/backend-test-execution-contract.js";
20
- import { materializeBackendTestResultFromRunDir, parseJunitXml } from "../workflows/dag/backend-test-result-contract.js";
20
+ import { materializeBackendTestResultFromRunDir, parsePytestHtmlReport } from "../workflows/dag/backend-test-result-contract.js";
21
21
  import { collectBackendTestHumanCaseCatalog, collectBackendTestMappedPytestScripts, hasBlockingBackendMarkdownSafetyFindings, inspectBackendTestEnvironment, requiredBackendMarkdownCaseAcIds, renderBackendTestFacts, renderBackendTestHtml, redactBackendTestOutput, validateBackendMarkdownCases, validateBackendMarkdownTraceability, writeRunReport, } from "../workflows/dag/backend-test-markdown-workflow.js";
22
22
  import { buildBackendTestCanonicalResultFromInitialShellSnippet, materializeBackendTestClassification, } from "../workflows/dag/backend-test-classification-contract.js";
23
23
  import { backendTestSemanticReviewSchema, materializeBackendTestSemanticReview, } from "../workflows/dag/backend-test-semantic-review-contract.js";
@@ -102,7 +102,12 @@ export async function executeShellCommand(input) {
102
102
  const startedAt = Date.now();
103
103
  const injectedEnv = input.dagRunMeta
104
104
  ? {
105
- HARNESS_DAG_RUN_DIR: input.dagRunMeta.runDir,
105
+ // Git Bash treats backslashes as escape characters inside double
106
+ // quotes. On Windows, path.join() produces backslash runDirs like
107
+ // D:\\...\\active\\<runId>, which corrupt "${HARNESS_DAG_RUN_DIR}/..."
108
+ // expansions. Normalize to POSIX separators so bash sees a stable
109
+ // path regardless of host platform.
110
+ HARNESS_DAG_RUN_DIR: input.dagRunMeta.runDir.replaceAll(path.sep, "/"),
106
111
  HARNESS_DAG_RUN_ID: input.dagRunMeta.runId,
107
112
  }
108
113
  : undefined;
@@ -384,10 +389,18 @@ async function executeBackendTestPipeline(input, meta) {
384
389
  'mkdir -p "${HARNESS_DAG_RUN_DIR}/reports"',
385
390
  'PYTHON_BIN="$(command -v python || command -v python3 || true)"',
386
391
  'if [ -z "${PYTHON_BIN}" ]; then echo "python/python3 is required for backend-test execution" >&2; exit 127; fi',
387
- `PYTHONUTF8=1 PYTHONIOENCODING=utf-8 PYTHONDONTWRITEBYTECODE=1 "\${PYTHON_BIN}" -m pytest ${pytestTargets} -v -p no:cacheprovider -o junit_logging=all -o junit_log_passing_tests=true --junitxml="\${HARNESS_DAG_RUN_DIR}/reports/backend-test.junit.xml"`,
392
+ // Run pytest exactly once and emit the native pytest-html
393
+ // self-contained report. The HTML/facts renderers read per-case
394
+ // captured stdout (HTTP_REQUEST/HTTP_RESPONSE) directly from the
395
+ // pytest-html data-jsonblob island, so a JUnit XML report is no
396
+ // longer generated.
397
+ `PYTHONUTF8=1 PYTHONIOENCODING=utf-8 PYTHONDONTWRITEBYTECODE=1 "\${PYTHON_BIN}" -m pytest ${pytestTargets} -v -p no:cacheprovider --html="\${HARNESS_DAG_RUN_DIR}/reports/backend-test.html" --self-contained-html`,
388
398
  "STATUS=$?",
389
399
  'printf "%s" "${STATUS}" > "${HARNESS_DAG_RUN_DIR}/reports/backend-test-pytest-exit.txt"',
390
- 'if { [ "${STATUS}" -eq 0 ] || [ "${STATUS}" -eq 1 ]; } && [ -s "${HARNESS_DAG_RUN_DIR}/reports/backend-test.junit.xml" ]; then exit 0; fi',
400
+ // exit 0 (all pass) or 1 (assertion failures) with a valid
401
+ // pytest-html report are reportable; collection errors / crashes
402
+ // (exit >= 2) or a missing report surface as a pipeline error below.
403
+ 'if { [ "${STATUS}" -eq 0 ] || [ "${STATUS}" -eq 1 ]; } && [ -s "${HARNESS_DAG_RUN_DIR}/reports/backend-test.html" ]; then exit 0; fi',
391
404
  'exit "${STATUS}"',
392
405
  ].join("; ");
393
406
  const results = await executePipelineCommands(input, meta, [pytestCommand]);
@@ -396,11 +409,11 @@ async function executeBackendTestPipeline(input, meta) {
396
409
  return { ok: false, stdout: results.map((result) => result.stdout).join("\n"), stderr: failure.stderr, failureCategory: failure.failureCategory, durationMs: Date.now() - started };
397
410
  }
398
411
  const reportsDir = path.join(meta.runDir, "reports");
399
- const junitContent = await readFile(path.join(reportsDir, "backend-test.junit.xml"), "utf8");
412
+ const pytestHtmlContent = await readFile(path.join(reportsDir, "backend-test.html"), "utf8");
400
413
  const pytestExitCode = Number.parseInt((await readFile(path.join(reportsDir, "backend-test-pytest-exit.txt"), "utf8")).trim(), 10);
401
414
  if (![0, 1].includes(pytestExitCode))
402
415
  throw new Error(`pytest did not complete with a reportable exit code: ${pytestExitCode}`);
403
- const parsed = parseJunitXml(junitContent);
416
+ const parsed = parsePytestHtmlReport(pytestHtmlContent);
404
417
  const cases = await collectBackendTestHumanCaseCatalog(input.cwd);
405
418
  const caseValidationSummary = await readRequiredRunReport(reportsDir, "backend-md-case-validation.md");
406
419
  const traceabilitySummary = await readRequiredRunReport(reportsDir, "backend-test-traceability.md");
@@ -413,7 +426,7 @@ async function executeBackendTestPipeline(input, meta) {
413
426
  traceabilitySummary,
414
427
  });
415
428
  const htmlPath = await writeRunReport(meta.runDir, "backend-test.html", htmlContent);
416
- const facts = renderBackendTestFacts({ parsed, cases, pytestExitCode, junitRelativePath: "reports/backend-test.junit.xml", htmlRelativePath: "reports/backend-test.html", junitContent, htmlContent, caseValidationSummary, traceabilitySummary });
429
+ const facts = renderBackendTestFacts({ parsed, cases, pytestExitCode, htmlRelativePath: "reports/backend-test.html", htmlContent, caseValidationSummary, traceabilitySummary });
417
430
  const markdownPath = await writeRunReport(meta.runDir, "backend-test.md", facts);
418
431
  const factsPath = await writeRunReport(meta.runDir, "backend-test-facts.md", facts);
419
432
  const sanitizedOutputs = results.map((result) => redactBackendTestOutput(result.stdout));