@tea-agent/loop-agent 0.25.4 → 0.25.6

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 (40) hide show
  1. package/AGENTS.md +6 -0
  2. package/CHANGELOG.md +60 -0
  3. package/dist/commands/client-recovery.js +209 -62
  4. package/dist/commands/init.js +68 -129
  5. package/dist/executors/dag-pi-executor.js +80 -15
  6. package/dist/executors/model-routing.js +1 -1
  7. package/dist/executors/shell-executor.js +127 -0
  8. package/dist/executors/shell-write-guard.js +21 -7
  9. package/dist/worker/console/repo-fingerprint.js +7 -1
  10. package/dist/workflows/dag/backend-test-case-coverage-analysis.js +1281 -0
  11. package/dist/workflows/dag/backend-test-case-manifest.js +59 -1
  12. package/dist/workflows/dag/backend-test-markdown-workflow.js +236 -16
  13. package/dist/workflows/dag/convergence/controller.js +134 -9
  14. package/dist/workflows/dag/frontend-test-l5-report.js +138 -0
  15. package/dist/workflows/dag/init-hybrid.js +270 -80
  16. package/dist/workflows/dag/node-execution.js +64 -11
  17. package/dist/workflows/dag/prompt.js +118 -4
  18. package/dist/workflows/dag/retry-policy.js +5 -4
  19. package/dist/workflows/dag/scheduler.js +32 -5
  20. package/dist/workflows/dag/types.js +7 -4
  21. package/dist/workflows/dag/validate.js +3 -2
  22. package/docs/architecture/dag-execution.md +7 -4
  23. package/docs/architecture/runtime-boundaries.md +1 -1
  24. package/docs/init-surface.manifest.json +3 -1
  25. package/docs/templates/README.md +1 -0
  26. package/docs/templates/agent-dag.base.json +1 -1
  27. package/docs/templates/agent-dag.final-verification.json +1 -1
  28. package/docs/templates/agent-dag.supervised-implementation.json +1 -1
  29. package/docs/templates/backend-test-dag.json +41 -14
  30. package/docs/templates/frontend-test-dag.json +32 -2
  31. package/docs/templates/hybrid-dag.json +1 -1
  32. package/docs/templates/init-managed-agents.md +137 -0
  33. package/examples/decision-gate-agent-dag.json +1 -1
  34. package/examples/example-dag.json +1 -1
  35. package/examples/hybrid-loop-agent-dag.json +1 -1
  36. package/harness.json +1 -1
  37. package/package.json +1 -1
  38. package/skills/loop-agent/references/command-reference.md +5 -4
  39. package/skills/loop-agent/references/hybrid-dag.md +2 -2
  40. package/skills/loop-agent/references/model-routing.md +1 -1
@@ -165,8 +165,8 @@ export function validateShellWriteGuard(input) {
165
165
  return { ok: violations.length === 0, violations };
166
166
  }
167
167
  export async function readGitStatusPorcelain(cwd, options = {}) {
168
- const attempts = Math.max(1, options.attempts ?? 3);
169
- const retryDelayMs = Math.max(0, options.retryDelayMs ?? 100);
168
+ const attempts = Math.max(1, options.attempts ?? 5);
169
+ const retryDelayMs = Math.max(0, options.retryDelayMs ?? 150);
170
170
  let lastError;
171
171
  for (let attempt = 1; attempt <= attempts; attempt += 1) {
172
172
  try {
@@ -179,14 +179,24 @@ export async function readGitStatusPorcelain(cwd, options = {}) {
179
179
  }
180
180
  }
181
181
  }
182
- throw lastError instanceof Error
183
- ? lastError
184
- : new Error(`git status failed after ${attempts} attempts`);
182
+ const detail = lastError instanceof Error ? lastError.message : String(lastError);
183
+ const exitCode = lastError instanceof Error &&
184
+ "exitCode" in lastError &&
185
+ typeof lastError.exitCode === "number"
186
+ ? String(lastError.exitCode)
187
+ : "unavailable";
188
+ const signal = lastError instanceof Error &&
189
+ "signal" in lastError &&
190
+ typeof lastError.signal === "string"
191
+ ? lastError.signal
192
+ : "unavailable";
193
+ throw new Error(`git status failed after ${attempts} attempts (exit code=${exitCode}, signal=${signal}, cwd=${path.resolve(cwd)}): ${detail}`, { cause: lastError });
185
194
  }
186
195
  function readGitStatusPorcelainOnce(cwd) {
187
196
  return new Promise((resolve, reject) => {
188
197
  const child = spawn("git", ["status", "--porcelain=v1", "--untracked-files=all"], {
189
198
  cwd,
199
+ env: { ...process.env, GIT_OPTIONAL_LOCKS: "0" },
190
200
  stdio: ["ignore", "pipe", "pipe"],
191
201
  });
192
202
  let stdout = "";
@@ -200,12 +210,16 @@ function readGitStatusPorcelainOnce(cwd) {
200
210
  stderr += chunk;
201
211
  });
202
212
  child.on("error", reject);
203
- child.on("close", (code) => {
213
+ child.on("close", (code, signal) => {
204
214
  if (code === 0) {
205
215
  resolve(stdout);
206
216
  return;
207
217
  }
208
- reject(new Error(`git status failed: ${stderr.trim() || stdout.trim()}`));
218
+ const detail = stderr.trim() || stdout.trim() || "no stderr/stdout";
219
+ const error = new Error(`git status failed: ${detail}`);
220
+ error.exitCode = code;
221
+ error.signal = signal;
222
+ reject(error);
209
223
  });
210
224
  });
211
225
  }
@@ -7,7 +7,13 @@ import path from "node:path";
7
7
  * (except a bare root). No extra case-folding on macOS/Windows.
8
8
  */
9
9
  export function normalizeWorktreeRealpath(repoRoot) {
10
- let resolved = realpathSync(path.resolve(repoRoot));
10
+ // The legacy JS implementation preserves an input 8.3 path such as
11
+ // C:\\Users\\MICROS~1 on Windows. The native implementation expands the
12
+ // short and long aliases to the same physical path before hashing.
13
+ const absolute = path.resolve(repoRoot);
14
+ let resolved = process.platform === "win32"
15
+ ? realpathSync.native(absolute)
16
+ : realpathSync(absolute);
11
17
  if (/^[a-zA-Z]:/.test(resolved)) {
12
18
  resolved = resolved[0].toUpperCase() + resolved.slice(1);
13
19
  }