@tea-agent/loop-agent 0.35.1-beta.0 → 0.35.1-beta.1
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/AGENTS.md +110 -108
- package/CHANGELOG.md +16 -26
- package/README.md +165 -165
- package/bin/agent-worker.js +0 -0
- package/bin/loop-agent.js +57 -21
- package/dist/application/task-lifecycle/advance.js +0 -1
- package/dist/build-stamp.json +6 -0
- package/dist/cli/program.js +2 -2
- package/dist/commands/cursor-prompt.js +6 -6
- package/dist/commands/init-upgrade.js +19 -351
- package/dist/commands/init.js +67 -14
- package/dist/commands/loop-benchmark.js +11 -11
- package/dist/commands/pi-reuse-benchmark.js +16 -16
- package/dist/commands/run-dag-progress.js +0 -14
- package/dist/commands/task-advance.js +3 -33
- package/dist/shared/operator/capabilities.js +1 -38
- package/dist/shared/package-metadata.js +32 -0
- package/dist/sidecars/cursor-prompt/executor.js +1 -1
- package/dist/worker/console/chat/pi-runtime.js +25 -41
- package/dist/worker/console/chat/routes.js +4 -27
- package/dist/worker/console/operation-runner.js +0 -24
- package/dist/worker/console/operator-actions.js +0 -58
- package/dist/worker/console/static/assets/index-fsjzREob.js +56 -0
- package/dist/worker/console/static/assets/{index-Dups4sSM.css → index-hJqCPs_g.css} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +2 -13
- package/dist/worker/console/static-src/operator-chat/useComposer.js +7 -30
- package/dist/worker/loop-agent/loop-agent-client.js +13 -0
- package/dist/worker/observe/static/copy.js +67 -67
- package/dist/worker/observe/static/dag-layout.d.ts +36 -36
- package/dist/worker/observe/static/dom.js +220 -220
- package/dist/worker/observe/static/relations.js +133 -133
- package/dist/worker/observe/static/run-processing.js +148 -148
- package/dist/worker/observe/static/views/batch.js +227 -227
- package/dist/worker/observe/static/views/failures.js +143 -143
- package/dist/worker/observe/static/views/feature.js +492 -492
- package/dist/worker/observe/static/views/run.js +453 -453
- package/dist/worker/observe/static/views/shell.js +7 -7
- package/dist/worker/observe/static/views/timeline.js +163 -163
- package/dist/workflows/dag/canvas-observer.js +275 -275
- package/dist/workflows/dag/contract-output-registry.js +14 -0
- package/dist/workflows/dag/contract-validator-registrations.js +8 -0
- package/dist/workflows/dag/dynamic-runtime/shared.js +9 -1
- package/dist/workflows/dag/frontend-implementation-contract.js +233 -39
- package/dist/workflows/dag/frontend-prewrite-gate.js +364 -61
- package/dist/workflows/dag/frontend-repair.js +219 -18
- package/dist/workflows/dag/frontend-verification-trace.js +47 -32
- package/dist/workflows/dag/init-hybrid.js +41 -24
- package/dist/workflows/dag/node-execution.js +89 -0
- package/dist/workflows/dag/runner.js +52 -3
- package/dist/workflows/dag/scheduler.js +98 -3
- package/dist/workflows/dag/types.js +23 -2
- package/docs/architecture/evolution.md +73 -73
- package/docs/architecture/system-overview.md +100 -100
- package/docs/architecture/worker-and-feature.md +122 -122
- package/docs/skills/README.md +7 -7
- package/docs/templates/adr.md +60 -60
- package/docs/templates/agent-dag-authority-surface-audit.prompt.md +94 -94
- package/docs/templates/agent-dag-decision-envelope.schema.json +213 -213
- package/docs/templates/agent-dag-decision-gate.prompt.md +246 -246
- package/docs/templates/agent-dag-process-supervisor.prompt.md +98 -98
- package/docs/templates/agent-dag-report.schema.json +473 -473
- package/docs/templates/agent-dag-review-verdict.prompt.md +68 -68
- package/docs/templates/backend-test-result.schema.json +99 -99
- package/docs/templates/evaluation/agents-map-slim-v1.md +87 -87
- package/docs/templates/evaluation/agents-map-verbose-v0.md +153 -153
- package/docs/templates/feature-spec.md +53 -53
- package/docs/templates/frontend-design-contract.md +42 -42
- package/docs/templates/frontend-eval/fixtures/failures/01-type-build-error.md +17 -17
- package/docs/templates/frontend-eval/fixtures/failures/02-unit-component-test-fail.md +16 -16
- package/docs/templates/frontend-eval/fixtures/failures/03-fixture-schema-drift.md +16 -16
- package/docs/templates/frontend-eval/fixtures/failures/04-missing-loading-empty-error-state.md +16 -16
- package/docs/templates/frontend-eval/fixtures/failures/05-forbidden-write-writeset-expansion.md +16 -16
- package/docs/templates/frontend-eval/fixtures/failures/06-unapproved-dependency-add.md +16 -16
- package/docs/templates/frontend-eval/fixtures/failures/07-mock-production-on.md +21 -21
- package/docs/templates/frontend-eval/fixtures/functional/01-simple-component-style.md +29 -29
- package/docs/templates/frontend-eval/fixtures/functional/02-form-validation.md +28 -28
- package/docs/templates/frontend-eval/fixtures/functional/03-list-detail-page.md +28 -28
- package/docs/templates/frontend-eval/fixtures/functional/04-api-mock.md +29 -29
- package/docs/templates/frontend-eval/fixtures/functional/05-permission-auth-gated-ui.md +27 -27
- package/docs/templates/frontend-eval/fixtures/functional/06-ssr-server-client-boundary.md +28 -28
- package/docs/templates/frontend-eval/fixtures/functional/07-shared-public-component-api.md +28 -28
- package/docs/templates/frontend-eval/fixtures/functional/08-pure-local-no-remote.md +27 -27
- package/docs/templates/frontend-eval/metrics.md +138 -138
- package/docs/templates/frontend-eval/smoke-targets.md +53 -53
- package/docs/templates/frontend-task-constraints.md +35 -35
- package/docs/templates/frontend-task-requirement.md +70 -70
- package/docs/templates/init-evolution-review.md +35 -35
- package/docs/templates/init-managed-agents.md +154 -156
- package/docs/templates/interactive-ui-round2-experiment.md +66 -66
- package/docs/templates/knowledge-graph-bootstrap-dag.json +118 -118
- package/docs/templates/knowledge-sync-dag.json +178 -178
- package/docs/templates/knowledge-sync-draft.schema.json +71 -71
- package/docs/templates/product-line/closeout.yaml +9 -9
- package/docs/templates/product-line/design.md +13 -13
- package/docs/templates/product-line/links.md +10 -10
- package/docs/templates/product-line/requirement.md +17 -17
- package/docs/templates/product-line/test-plan.md +7 -7
- package/docs/templates/project-start-checklist.md +9 -9
- package/docs/templates/qa-report.md +48 -48
- package/docs/templates/sprint-contract.md +29 -29
- package/docs/templates/worker-dogfood-evidence.md +80 -80
- package/docs/templates/worker-dogfood-setup.md +68 -68
- package/harness.json +2 -5
- package/package.json +2 -2
- package/scripts/kb-bootstrap-init-skeleton.sh +0 -0
- package/scripts/kb-graph-incremental-prepare.mjs +0 -0
- package/scripts/kb-graph-materialize.mjs +105 -105
- package/scripts/kb-graph-promote.mjs +164 -164
- package/scripts/kb-query.mjs +554 -554
- package/skills/agent-worker/SKILL.md +48 -48
- package/skills/agent-worker/references/agent-worker-operator.md +159 -159
- package/skills/ai-engineering-context/SKILL.md +48 -48
- package/skills/analyze-product-dependencies/scripts/test-validators.mjs +0 -0
- package/skills/analyze-product-dependencies/scripts/validate-api-documentation.mjs +0 -0
- package/skills/analyze-product-dependencies/scripts/validate-dependency-analysis.mjs +0 -0
- package/skills/analyze-product-dependencies/scripts/validate-product-requirement-input.mjs +0 -0
- package/skills/analyze-product-requirements/scripts/compute-source-identity.mjs +0 -0
- package/skills/analyze-product-requirements/scripts/test-validators.mjs +0 -0
- package/skills/analyze-product-requirements/scripts/validate-product-analysis.mjs +0 -0
- package/skills/analyze-product-requirements/scripts/validate-product-requirement.mjs +0 -0
- package/skills/analyze-product-requirements/scripts/validate-requirement-clarification.mjs +0 -0
- package/skills/browser-tools/browser-content.js +103 -103
- package/skills/browser-tools/browser-cookies.js +35 -35
- package/skills/browser-tools/browser-eval.js +53 -53
- package/skills/browser-tools/browser-hn-scraper.js +108 -108
- package/skills/browser-tools/browser-nav.js +44 -44
- package/skills/browser-tools/browser-pick.js +162 -162
- package/skills/browser-tools/browser-screenshot.js +34 -34
- package/skills/browser-tools/browser-start.js +86 -86
- package/skills/browser-tools/package-lock.json +2556 -2556
- package/skills/browser-tools/package.json +19 -19
- package/skills/code-review-core/SKILL.md +20 -20
- package/skills/codebase-scout/SKILL.md +19 -19
- package/skills/grill-me/SKILL.md +10 -10
- package/skills/local-jacoco-coverage/scripts/run-coverage-analysis.sh +0 -0
- package/skills/local-jacoco-coverage/scripts/start-jacoco-agent.sh +0 -0
- package/skills/loop-agent/SKILL.md +0 -1
- package/skills/loop-agent/references/command-reference.md +639 -641
- package/skills/loop-agent/references/docs-converge.md +126 -126
- package/skills/loop-agent/references/learned/README.md +21 -21
- package/skills/loop-agent/references/pi-prompt.md +23 -23
- package/skills/loop-agent/references/pi-subagent-assisted-mode.md +84 -84
- package/skills/playwright-cli/references/element-attributes.md +23 -23
- package/skills/playwright-cli/references/playwright-tests.md +39 -39
- package/skills/playwright-cli/references/request-mocking.md +87 -87
- package/skills/playwright-cli/references/running-code.md +241 -241
- package/skills/playwright-cli/references/session-management.md +225 -225
- package/skills/playwright-cli/references/storage-state.md +275 -275
- package/skills/playwright-cli/references/test-generation.md +433 -433
- package/skills/requesting-code-review/SKILL.md +101 -101
- package/skills/requesting-code-review/code-reviewer.md +168 -168
- package/skills/systematic-debugging/CREATION-LOG.md +119 -119
- package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -158
- package/skills/systematic-debugging/condition-based-waiting.md +115 -115
- package/skills/systematic-debugging/defense-in-depth.md +122 -122
- package/skills/systematic-debugging/find-polluter.sh +63 -63
- package/skills/systematic-debugging/root-cause-tracing.md +169 -169
- package/skills/systematic-debugging/test-academic.md +14 -14
- package/skills/systematic-debugging/test-pressure-1.md +58 -58
- package/skills/systematic-debugging/test-pressure-2.md +68 -68
- package/skills/systematic-debugging/test-pressure-3.md +69 -69
- package/skills/using-git-worktrees/SKILL.md +215 -215
- package/skills/verification-before-completion/SKILL.md +154 -154
- package/skills/webapp-testing/SKILL.md +19 -19
- package/dist/worker/console/operation-wait.js +0 -241
- package/dist/worker/console/static/assets/index-SjjjZnV3.js +0 -56
- package/dist/worker/console/static-src/operator-chat/slash-palette-nav.js +0 -141
|
@@ -7,6 +7,10 @@ import { parseCommandJson } from "./parse-json.js";
|
|
|
7
7
|
export const DEFAULT_WORKER_COMMAND_TIMEOUT_MS = 120_000;
|
|
8
8
|
export const DEFAULT_HEARTBEAT_INTERVAL_MS = 15_000;
|
|
9
9
|
export const LOOP_AGENT_PACKAGE_NAME = "@tea-agent/loop-agent";
|
|
10
|
+
/** Grace window between the SIGTERM and SIGKILL stages of a hard timeout, so a
|
|
11
|
+
* runner can persist terminal state (see executeDagCheckpoint) before being
|
|
12
|
+
* force-killed. */
|
|
13
|
+
export const HARD_TIMEOUT_KILL_GRACE_MS = 10_000;
|
|
10
14
|
const MAX_BUFFERED_OUTPUT_BYTES = 64 * 1024;
|
|
11
15
|
/**
|
|
12
16
|
* Bind evidence supplied by an orchestration layer to the identity exposed by
|
|
@@ -381,10 +385,17 @@ function spawnCommand(input) {
|
|
|
381
385
|
});
|
|
382
386
|
};
|
|
383
387
|
let hardTimeout;
|
|
388
|
+
let killGraceTimeout;
|
|
384
389
|
if (input.hardTimeoutMs !== undefined && input.hardTimeoutMs > 0) {
|
|
385
390
|
hardTimeout = setTimeout(() => {
|
|
386
391
|
timedOut = true;
|
|
392
|
+
// Two-stage termination: SIGTERM first so the runner can persist a
|
|
393
|
+
// terminal state (see executeDagCheckpoint signal handler), then
|
|
394
|
+
// SIGKILL only after the grace window expires.
|
|
387
395
|
child.kill("SIGTERM");
|
|
396
|
+
killGraceTimeout = setTimeout(() => {
|
|
397
|
+
child.kill("SIGKILL");
|
|
398
|
+
}, HARD_TIMEOUT_KILL_GRACE_MS);
|
|
388
399
|
}, input.hardTimeoutMs);
|
|
389
400
|
}
|
|
390
401
|
let heartbeatTimer;
|
|
@@ -394,6 +405,8 @@ function spawnCommand(input) {
|
|
|
394
405
|
const clearTimers = () => {
|
|
395
406
|
if (hardTimeout !== undefined)
|
|
396
407
|
clearTimeout(hardTimeout);
|
|
408
|
+
if (killGraceTimeout !== undefined)
|
|
409
|
+
clearTimeout(killGraceTimeout);
|
|
397
410
|
if (heartbeatTimer !== undefined) {
|
|
398
411
|
clearInterval(heartbeatTimer);
|
|
399
412
|
heartbeatTimer = undefined;
|
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
/** Copy-only recommended commands (Observe UI R5). */
|
|
2
|
-
import { el } from "./dom.js";
|
|
3
|
-
|
|
4
|
-
export async function copyText(text) {
|
|
5
|
-
const value = String(text ?? "");
|
|
6
|
-
if (!value) return false;
|
|
7
|
-
try {
|
|
8
|
-
if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) {
|
|
9
|
-
await navigator.clipboard.writeText(value);
|
|
10
|
-
return true;
|
|
11
|
-
}
|
|
12
|
-
} catch {
|
|
13
|
-
// fall through
|
|
14
|
-
}
|
|
15
|
-
try {
|
|
16
|
-
const ta = document.createElement("textarea");
|
|
17
|
-
ta.value = value;
|
|
18
|
-
ta.setAttribute("readonly", "");
|
|
19
|
-
ta.style.position = "fixed";
|
|
20
|
-
ta.style.left = "-9999px";
|
|
21
|
-
document.body.appendChild(ta);
|
|
22
|
-
ta.select();
|
|
23
|
-
const ok = document.execCommand("copy");
|
|
24
|
-
document.body.removeChild(ta);
|
|
25
|
-
return ok;
|
|
26
|
-
} catch {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/** Advisory recommended command: copy-only, never executes. */
|
|
32
|
-
export function renderRecommendedCommand(action) {
|
|
33
|
-
const block = el("div", "recommended-command");
|
|
34
|
-
if (!action) {
|
|
35
|
-
block.appendChild(el("span", "muted", "缺失"));
|
|
36
|
-
return block;
|
|
37
|
-
}
|
|
38
|
-
const head = el("div", "recommended-command-head");
|
|
39
|
-
if (action.kind) {
|
|
40
|
-
head.appendChild(el("span", "recommended-command-kind", action.kind));
|
|
41
|
-
}
|
|
42
|
-
head.appendChild(
|
|
43
|
-
el("span", "recommended-command-label", action.label ?? "—"),
|
|
44
|
-
);
|
|
45
|
-
block.appendChild(head);
|
|
46
|
-
if (action.command) {
|
|
47
|
-
const body = el("div", "recommended-command-body");
|
|
48
|
-
const code = el("code", "recommended-command-text", action.command);
|
|
49
|
-
body.appendChild(code);
|
|
50
|
-
const btn = el("button", "copy-command", "复制");
|
|
51
|
-
btn.type = "button";
|
|
52
|
-
btn.addEventListener("click", (e) => {
|
|
53
|
-
e.preventDefault();
|
|
54
|
-
e.stopPropagation();
|
|
55
|
-
void copyText(action.command).then((ok) => {
|
|
56
|
-
btn.textContent = ok ? "已复制" : "复制失败";
|
|
57
|
-
setTimeout(() => {
|
|
58
|
-
btn.textContent = "复制";
|
|
59
|
-
}, 1500);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
body.appendChild(btn);
|
|
63
|
-
block.appendChild(body);
|
|
64
|
-
}
|
|
65
|
-
return block;
|
|
66
|
-
}
|
|
67
|
-
|
|
1
|
+
/** Copy-only recommended commands (Observe UI R5). */
|
|
2
|
+
import { el } from "./dom.js";
|
|
3
|
+
|
|
4
|
+
export async function copyText(text) {
|
|
5
|
+
const value = String(text ?? "");
|
|
6
|
+
if (!value) return false;
|
|
7
|
+
try {
|
|
8
|
+
if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) {
|
|
9
|
+
await navigator.clipboard.writeText(value);
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
} catch {
|
|
13
|
+
// fall through
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const ta = document.createElement("textarea");
|
|
17
|
+
ta.value = value;
|
|
18
|
+
ta.setAttribute("readonly", "");
|
|
19
|
+
ta.style.position = "fixed";
|
|
20
|
+
ta.style.left = "-9999px";
|
|
21
|
+
document.body.appendChild(ta);
|
|
22
|
+
ta.select();
|
|
23
|
+
const ok = document.execCommand("copy");
|
|
24
|
+
document.body.removeChild(ta);
|
|
25
|
+
return ok;
|
|
26
|
+
} catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Advisory recommended command: copy-only, never executes. */
|
|
32
|
+
export function renderRecommendedCommand(action) {
|
|
33
|
+
const block = el("div", "recommended-command");
|
|
34
|
+
if (!action) {
|
|
35
|
+
block.appendChild(el("span", "muted", "缺失"));
|
|
36
|
+
return block;
|
|
37
|
+
}
|
|
38
|
+
const head = el("div", "recommended-command-head");
|
|
39
|
+
if (action.kind) {
|
|
40
|
+
head.appendChild(el("span", "recommended-command-kind", action.kind));
|
|
41
|
+
}
|
|
42
|
+
head.appendChild(
|
|
43
|
+
el("span", "recommended-command-label", action.label ?? "—"),
|
|
44
|
+
);
|
|
45
|
+
block.appendChild(head);
|
|
46
|
+
if (action.command) {
|
|
47
|
+
const body = el("div", "recommended-command-body");
|
|
48
|
+
const code = el("code", "recommended-command-text", action.command);
|
|
49
|
+
body.appendChild(code);
|
|
50
|
+
const btn = el("button", "copy-command", "复制");
|
|
51
|
+
btn.type = "button";
|
|
52
|
+
btn.addEventListener("click", (e) => {
|
|
53
|
+
e.preventDefault();
|
|
54
|
+
e.stopPropagation();
|
|
55
|
+
void copyText(action.command).then((ok) => {
|
|
56
|
+
btn.textContent = ok ? "已复制" : "复制失败";
|
|
57
|
+
setTimeout(() => {
|
|
58
|
+
btn.textContent = "复制";
|
|
59
|
+
}, 1500);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
body.appendChild(btn);
|
|
63
|
+
block.appendChild(body);
|
|
64
|
+
}
|
|
65
|
+
return block;
|
|
66
|
+
}
|
|
67
|
+
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
export type DagLayoutNodeInput = { nodeId: string };
|
|
2
|
-
export type DagLayoutEdgeInput = { from: string; to: string };
|
|
3
|
-
export type DagLayoutNode = {
|
|
4
|
-
nodeId: string;
|
|
5
|
-
rank: number;
|
|
6
|
-
index: number;
|
|
7
|
-
x: number;
|
|
8
|
-
y: number;
|
|
9
|
-
width: number;
|
|
10
|
-
height: number;
|
|
11
|
-
};
|
|
12
|
-
export type DagLayoutEdge = DagLayoutEdgeInput & { path: string };
|
|
13
|
-
export type DagLayout = {
|
|
14
|
-
width: number;
|
|
15
|
-
height: number;
|
|
16
|
-
nodes: DagLayoutNode[];
|
|
17
|
-
edges: DagLayoutEdge[];
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export type DagLayoutOptions = Partial<{
|
|
21
|
-
nodeWidth: number;
|
|
22
|
-
nodeHeight: number;
|
|
23
|
-
rankGap: number;
|
|
24
|
-
nodeGap: number;
|
|
25
|
-
padding: number;
|
|
26
|
-
controlLaneCount: number;
|
|
27
|
-
/** Per-node visual card height overrides; ordinary ports still use nodeHeight axis. */
|
|
28
|
-
nodeHeights: Record<string, number>;
|
|
29
|
-
}>;
|
|
30
|
-
|
|
31
|
-
export function layoutDag(
|
|
32
|
-
nodes?: DagLayoutNodeInput[],
|
|
33
|
-
edges?: DagLayoutEdgeInput[],
|
|
34
|
-
ranks?: string[][],
|
|
35
|
-
options?: DagLayoutOptions,
|
|
36
|
-
): DagLayout;
|
|
1
|
+
export type DagLayoutNodeInput = { nodeId: string };
|
|
2
|
+
export type DagLayoutEdgeInput = { from: string; to: string };
|
|
3
|
+
export type DagLayoutNode = {
|
|
4
|
+
nodeId: string;
|
|
5
|
+
rank: number;
|
|
6
|
+
index: number;
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
};
|
|
12
|
+
export type DagLayoutEdge = DagLayoutEdgeInput & { path: string };
|
|
13
|
+
export type DagLayout = {
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
nodes: DagLayoutNode[];
|
|
17
|
+
edges: DagLayoutEdge[];
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type DagLayoutOptions = Partial<{
|
|
21
|
+
nodeWidth: number;
|
|
22
|
+
nodeHeight: number;
|
|
23
|
+
rankGap: number;
|
|
24
|
+
nodeGap: number;
|
|
25
|
+
padding: number;
|
|
26
|
+
controlLaneCount: number;
|
|
27
|
+
/** Per-node visual card height overrides; ordinary ports still use nodeHeight axis. */
|
|
28
|
+
nodeHeights: Record<string, number>;
|
|
29
|
+
}>;
|
|
30
|
+
|
|
31
|
+
export function layoutDag(
|
|
32
|
+
nodes?: DagLayoutNodeInput[],
|
|
33
|
+
edges?: DagLayoutEdgeInput[],
|
|
34
|
+
ranks?: string[][],
|
|
35
|
+
options?: DagLayoutOptions,
|
|
36
|
+
): DagLayout;
|