@tea-agent/loop-agent 0.7.5 → 0.9.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.
- package/AGENTS.md +145 -142
- package/CHANGELOG.md +161 -158
- package/README.md +206 -204
- package/bin/agent-worker.js +22 -22
- package/bin/loop-agent.js +21 -21
- package/dist/application/dag/args.js +9 -2
- package/dist/commands/init.js +518 -488
- package/dist/commands/loop-benchmark.js +11 -11
- package/dist/commands/pi-reuse-benchmark.js +16 -16
- package/dist/executors/cursor-executor.js +1 -1
- package/dist/executors/shell-executor.js +74 -8
- package/dist/governance/manifest-types.js +1 -1
- package/dist/shared/reference-context.js +48 -22
- package/dist/task/config-types.js +1 -1
- package/dist/task/runtime.js +28 -28
- package/dist/worker/cli.js +3 -3
- package/dist/worker/loop-agent/loop-agent-client.js +51 -10
- package/dist/worker/observability/event-store.js +2 -1
- package/dist/worker/observability/read-model.js +13 -11
- package/dist/worker/observe/paths.js +2 -2
- package/dist/worker/observe/routes.js +82 -23
- package/dist/worker/observe/server.js +8 -6
- package/dist/worker/observe/static/app.js +1965 -1480
- package/dist/worker/observe/static/dag-layout.d.ts +31 -31
- package/dist/worker/observe/static/dag-layout.js +83 -83
- package/dist/worker/observe/static/index.html +88 -63
- package/dist/worker/observe/static/styles.css +598 -722
- package/dist/worker/pool/run-store.js +7 -8
- package/dist/worker/run-task/run-task.js +11 -2
- package/dist/worker/runner/run-ready.js +1 -1
- package/dist/workflows/dag/canvas-observer.js +275 -275
- package/docs/README.md +84 -79
- package/docs/agent-dag-recovery-playbook.md +184 -184
- package/docs/agent-dag-runner.md +42 -42
- package/docs/architecture/runtime-boundaries.md +162 -162
- package/docs/cursor-executor-usage.md +25 -25
- package/docs/decisions/README.md +3 -3
- package/docs/design/README.md +49 -49
- package/docs/development-principles.md +73 -73
- package/docs/dynamic-workflow-dag-engine-roadmap.md +1749 -1749
- package/docs/exec-plans/README.md +6 -6
- package/docs/exec-plans/active/README.md +11 -11
- package/docs/exec-plans/completed/README.md +43 -34
- package/docs/feature-workflow.md +187 -187
- package/docs/harness-methodology-debugging.md +153 -153
- package/docs/harness-methodology-tdd.md +130 -130
- package/docs/harness-methodology-verification.md +27 -27
- package/docs/init-surface.manifest.json +245 -241
- package/docs/loop-agent-harness.md +63 -55
- package/docs/production-readiness.md +96 -96
- package/docs/progress/README.md +3 -3
- package/docs/reports/README.md +12 -9
- package/docs/skills/README.md +6 -6
- package/docs/skills/vetted-skill-registry.md +26 -26
- 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-dogfood-report.md +117 -117
- 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 +454 -454
- package/docs/templates/agent-dag-review-verdict.prompt.md +68 -68
- package/docs/templates/agent-dag.base.json +195 -195
- package/docs/templates/agent-dag.final-verification.json +190 -190
- package/docs/templates/agent-dag.schema.json +316 -316
- package/docs/templates/agent-dag.supervised-implementation.json +500 -500
- package/docs/templates/exec-plan.md +64 -64
- package/docs/templates/feature-spec.md +53 -53
- package/docs/templates/harness.schema.json +218 -0
- package/docs/templates/hybrid-dag.json +193 -193
- package/docs/templates/init-evolution-review.md +33 -33
- package/docs/templates/interactive-ui-round2-experiment.md +66 -66
- package/docs/templates/product-line/AGENTS.md +8 -8
- package/docs/templates/product-line/README.md +9 -9
- package/docs/templates/product-line/acceptance.yaml +14 -14
- 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/task-graph.yaml +15 -15
- package/docs/templates/product-line/task.yaml +65 -65
- package/docs/templates/product-line/test-plan.md +7 -7
- package/docs/templates/production-readiness-checklist.md +57 -57
- package/docs/templates/progress-log.md +17 -17
- 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 +52 -52
- package/docs/templates/worker-dogfood-setup.md +48 -48
- package/docs/verification-matrix.md +49 -49
- package/examples/decision-gate-agent-dag.json +123 -123
- package/examples/example-dag.json +51 -51
- package/examples/hybrid-loop-agent-dag.json +194 -194
- package/harness.json +73 -71
- package/package.json +68 -67
- package/scripts/check-product-line-docs.sh +22 -22
- package/scripts/check-task-pool-root.sh +32 -0
- package/skills/ai-engineering-context/SKILL.md +48 -48
- package/skills/code-review-core/SKILL.md +20 -20
- package/skills/codebase-scout/SKILL.md +19 -19
- package/skills/init-capability-evolution/SKILL.md +69 -69
- package/skills/loop-agent/SKILL.md +149 -149
- package/skills/loop-agent/references/README.md +67 -67
- package/skills/loop-agent/references/command-reference.md +432 -412
- package/skills/loop-agent/references/harness-policy.md +263 -263
- package/skills/loop-agent/references/hybrid-dag.md +216 -216
- package/skills/loop-agent/references/learned/README.md +21 -21
- package/skills/loop-agent/references/long-running-loop.md +59 -59
- package/skills/loop-agent/references/model-routing.md +36 -36
- package/skills/loop-agent/references/multi-worktree.md +54 -54
- package/skills/loop-agent/references/one-shot-runs.md +85 -85
- package/skills/loop-agent/references/orchestrator-and-interventions.md +169 -169
- package/skills/loop-agent/references/pi-prompt.md +23 -23
- package/skills/loop-agent/references/pi-subagent-assisted-mode.md +81 -81
- package/skills/loop-agent/references/post-implementation-and-patterns.md +44 -44
- package/skills/loop-agent/references/task-workflow.md +89 -89
- package/skills/loop-agent/references/verification-and-failure-handling.md +133 -128
- 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/SKILL.md +296 -296
- 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/test-driven-development/SKILL.md +20 -20
- package/skills/verification-before-completion/SKILL.md +154 -154
- package/skills/webapp-testing/SKILL.md +19 -19
|
@@ -1,31 +1,31 @@
|
|
|
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 function layoutDag(
|
|
21
|
-
nodes?: DagLayoutNodeInput[],
|
|
22
|
-
edges?: DagLayoutEdgeInput[],
|
|
23
|
-
ranks?: string[][],
|
|
24
|
-
options?: Partial<{
|
|
25
|
-
nodeWidth: number;
|
|
26
|
-
nodeHeight: number;
|
|
27
|
-
rankGap: number;
|
|
28
|
-
nodeGap: number;
|
|
29
|
-
padding: number;
|
|
30
|
-
}>,
|
|
31
|
-
): 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 function layoutDag(
|
|
21
|
+
nodes?: DagLayoutNodeInput[],
|
|
22
|
+
edges?: DagLayoutEdgeInput[],
|
|
23
|
+
ranks?: string[][],
|
|
24
|
+
options?: Partial<{
|
|
25
|
+
nodeWidth: number;
|
|
26
|
+
nodeHeight: number;
|
|
27
|
+
rankGap: number;
|
|
28
|
+
nodeGap: number;
|
|
29
|
+
padding: number;
|
|
30
|
+
}>,
|
|
31
|
+
): DagLayout;
|
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
const DEFAULTS = {
|
|
2
|
-
nodeWidth: 216,
|
|
3
|
-
nodeHeight: 92,
|
|
4
|
-
rankGap: 104,
|
|
5
|
-
nodeGap: 28,
|
|
6
|
-
padding: 32,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export function layoutDag(nodes = [], edges = [], ranks = [], options = {}) {
|
|
10
|
-
const config = { ...DEFAULTS, ...options };
|
|
11
|
-
const nodeIds = [...new Set(nodes.map((node) => node.nodeId).filter(Boolean))].sort();
|
|
12
|
-
if (nodeIds.length === 0) return { width: 320, height: 160, nodes: [], edges: [] };
|
|
13
|
-
const known = new Set(nodeIds);
|
|
14
|
-
const validEdges = edges
|
|
15
|
-
.filter((edge) => known.has(edge.from) && known.has(edge.to) && edge.from !== edge.to)
|
|
16
|
-
.sort((a, b) => a.from.localeCompare(b.from) || a.to.localeCompare(b.to));
|
|
17
|
-
const layers = normalizeLayers(nodeIds, validEdges, ranks);
|
|
18
|
-
const positioned = [];
|
|
19
|
-
for (let rank = 0; rank < layers.length; rank++) {
|
|
20
|
-
const ids = layers[rank];
|
|
21
|
-
for (let index = 0; index < ids.length; index++) {
|
|
22
|
-
positioned.push({
|
|
23
|
-
nodeId: ids[index], rank, index,
|
|
24
|
-
x: config.padding + rank * (config.nodeWidth + config.rankGap),
|
|
25
|
-
y: config.padding + index * (config.nodeHeight + config.nodeGap),
|
|
26
|
-
width: config.nodeWidth, height: config.nodeHeight,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
const byId = new Map(positioned.map((node) => [node.nodeId, node]));
|
|
31
|
-
const routed = validEdges.map((edge) => {
|
|
32
|
-
const from = byId.get(edge.from);
|
|
33
|
-
const to = byId.get(edge.to);
|
|
34
|
-
const x1 = from.x + from.width;
|
|
35
|
-
const y1 = from.y + from.height / 2;
|
|
36
|
-
const x2 = to.x;
|
|
37
|
-
const y2 = to.y + to.height / 2;
|
|
38
|
-
const bend = Math.max(36, (x2 - x1) / 2);
|
|
39
|
-
return { ...edge, path: `M ${x1} ${y1} C ${x1 + bend} ${y1}, ${x2 - bend} ${y2}, ${x2} ${y2}` };
|
|
40
|
-
});
|
|
41
|
-
const maxRows = Math.max(...layers.map((layer) => layer.length), 1);
|
|
42
|
-
return {
|
|
43
|
-
width: config.padding * 2 + layers.length * config.nodeWidth + (layers.length - 1) * config.rankGap,
|
|
44
|
-
height: config.padding * 2 + maxRows * config.nodeHeight + (maxRows - 1) * config.nodeGap,
|
|
45
|
-
nodes: positioned,
|
|
46
|
-
edges: routed,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function normalizeLayers(nodeIds, edges, ranks) {
|
|
51
|
-
const known = new Set(nodeIds);
|
|
52
|
-
const seen = new Set();
|
|
53
|
-
const layers = [];
|
|
54
|
-
if (Array.isArray(ranks)) {
|
|
55
|
-
for (const rank of ranks) {
|
|
56
|
-
if (!Array.isArray(rank)) continue;
|
|
57
|
-
const ids = [...new Set(rank.filter((id) => known.has(id) && !seen.has(id)))].sort();
|
|
58
|
-
ids.forEach((id) => seen.add(id));
|
|
59
|
-
if (ids.length > 0) layers.push(ids);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
if (layers.length === 0 && edges.length > 0) {
|
|
63
|
-
const level = new Map(nodeIds.map((id) => [id, 0]));
|
|
64
|
-
for (let pass = 0; pass < nodeIds.length; pass++) {
|
|
65
|
-
let changed = false;
|
|
66
|
-
for (const edge of edges) {
|
|
67
|
-
const next = Math.min(nodeIds.length - 1, level.get(edge.from) + 1);
|
|
68
|
-
if (next > level.get(edge.to)) { level.set(edge.to, next); changed = true; }
|
|
69
|
-
}
|
|
70
|
-
if (!changed) break;
|
|
71
|
-
}
|
|
72
|
-
for (const id of nodeIds) {
|
|
73
|
-
const rank = level.get(id);
|
|
74
|
-
(layers[rank] ??= []).push(id);
|
|
75
|
-
seen.add(id);
|
|
76
|
-
}
|
|
77
|
-
for (const layer of layers) layer?.sort();
|
|
78
|
-
}
|
|
79
|
-
for (const id of nodeIds) {
|
|
80
|
-
if (!seen.has(id)) (layers[0] ??= []).push(id);
|
|
81
|
-
}
|
|
82
|
-
return layers.filter(Boolean);
|
|
83
|
-
}
|
|
1
|
+
const DEFAULTS = {
|
|
2
|
+
nodeWidth: 216,
|
|
3
|
+
nodeHeight: 92,
|
|
4
|
+
rankGap: 104,
|
|
5
|
+
nodeGap: 28,
|
|
6
|
+
padding: 32,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export function layoutDag(nodes = [], edges = [], ranks = [], options = {}) {
|
|
10
|
+
const config = { ...DEFAULTS, ...options };
|
|
11
|
+
const nodeIds = [...new Set(nodes.map((node) => node.nodeId).filter(Boolean))].sort();
|
|
12
|
+
if (nodeIds.length === 0) return { width: 320, height: 160, nodes: [], edges: [] };
|
|
13
|
+
const known = new Set(nodeIds);
|
|
14
|
+
const validEdges = edges
|
|
15
|
+
.filter((edge) => known.has(edge.from) && known.has(edge.to) && edge.from !== edge.to)
|
|
16
|
+
.sort((a, b) => a.from.localeCompare(b.from) || a.to.localeCompare(b.to));
|
|
17
|
+
const layers = normalizeLayers(nodeIds, validEdges, ranks);
|
|
18
|
+
const positioned = [];
|
|
19
|
+
for (let rank = 0; rank < layers.length; rank++) {
|
|
20
|
+
const ids = layers[rank];
|
|
21
|
+
for (let index = 0; index < ids.length; index++) {
|
|
22
|
+
positioned.push({
|
|
23
|
+
nodeId: ids[index], rank, index,
|
|
24
|
+
x: config.padding + rank * (config.nodeWidth + config.rankGap),
|
|
25
|
+
y: config.padding + index * (config.nodeHeight + config.nodeGap),
|
|
26
|
+
width: config.nodeWidth, height: config.nodeHeight,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const byId = new Map(positioned.map((node) => [node.nodeId, node]));
|
|
31
|
+
const routed = validEdges.map((edge) => {
|
|
32
|
+
const from = byId.get(edge.from);
|
|
33
|
+
const to = byId.get(edge.to);
|
|
34
|
+
const x1 = from.x + from.width;
|
|
35
|
+
const y1 = from.y + from.height / 2;
|
|
36
|
+
const x2 = to.x;
|
|
37
|
+
const y2 = to.y + to.height / 2;
|
|
38
|
+
const bend = Math.max(36, (x2 - x1) / 2);
|
|
39
|
+
return { ...edge, path: `M ${x1} ${y1} C ${x1 + bend} ${y1}, ${x2 - bend} ${y2}, ${x2} ${y2}` };
|
|
40
|
+
});
|
|
41
|
+
const maxRows = Math.max(...layers.map((layer) => layer.length), 1);
|
|
42
|
+
return {
|
|
43
|
+
width: config.padding * 2 + layers.length * config.nodeWidth + (layers.length - 1) * config.rankGap,
|
|
44
|
+
height: config.padding * 2 + maxRows * config.nodeHeight + (maxRows - 1) * config.nodeGap,
|
|
45
|
+
nodes: positioned,
|
|
46
|
+
edges: routed,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function normalizeLayers(nodeIds, edges, ranks) {
|
|
51
|
+
const known = new Set(nodeIds);
|
|
52
|
+
const seen = new Set();
|
|
53
|
+
const layers = [];
|
|
54
|
+
if (Array.isArray(ranks)) {
|
|
55
|
+
for (const rank of ranks) {
|
|
56
|
+
if (!Array.isArray(rank)) continue;
|
|
57
|
+
const ids = [...new Set(rank.filter((id) => known.has(id) && !seen.has(id)))].sort();
|
|
58
|
+
ids.forEach((id) => seen.add(id));
|
|
59
|
+
if (ids.length > 0) layers.push(ids);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (layers.length === 0 && edges.length > 0) {
|
|
63
|
+
const level = new Map(nodeIds.map((id) => [id, 0]));
|
|
64
|
+
for (let pass = 0; pass < nodeIds.length; pass++) {
|
|
65
|
+
let changed = false;
|
|
66
|
+
for (const edge of edges) {
|
|
67
|
+
const next = Math.min(nodeIds.length - 1, level.get(edge.from) + 1);
|
|
68
|
+
if (next > level.get(edge.to)) { level.set(edge.to, next); changed = true; }
|
|
69
|
+
}
|
|
70
|
+
if (!changed) break;
|
|
71
|
+
}
|
|
72
|
+
for (const id of nodeIds) {
|
|
73
|
+
const rank = level.get(id);
|
|
74
|
+
(layers[rank] ??= []).push(id);
|
|
75
|
+
seen.add(id);
|
|
76
|
+
}
|
|
77
|
+
for (const layer of layers) layer?.sort();
|
|
78
|
+
}
|
|
79
|
+
for (const id of nodeIds) {
|
|
80
|
+
if (!seen.has(id)) (layers[0] ??= []).push(id);
|
|
81
|
+
}
|
|
82
|
+
return layers.filter(Boolean);
|
|
83
|
+
}
|
|
@@ -1,63 +1,88 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="zh-CN">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>
|
|
7
|
-
<link rel="
|
|
8
|
-
|
|
9
|
-
<
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<div
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Loop Agent</title>
|
|
7
|
+
<link rel="icon" href="data:,">
|
|
8
|
+
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
|
9
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/remixicon@4.6.0/fonts/remixicon.css">
|
|
10
|
+
<link rel="stylesheet" href="/styles.css">
|
|
11
|
+
</head>
|
|
12
|
+
<body data-shell="observe-console">
|
|
13
|
+
<a class="skip-link" href="#main-content">跳到主内容</a>
|
|
14
|
+
<div id="app">
|
|
15
|
+
<header class="site-header">
|
|
16
|
+
<a href="#/" class="logo" aria-label="Loop Agent 运行看板首页">
|
|
17
|
+
<i class="ri-radar-line" aria-hidden="true"></i>
|
|
18
|
+
<span>Loop Agent</span>
|
|
19
|
+
</a>
|
|
20
|
+
<nav class="top-nav" aria-label="主导航">
|
|
21
|
+
<a href="#/" class="nav-link"><i class="ri-dashboard-3-line" aria-hidden="true"></i><span>总览</span></a>
|
|
22
|
+
<a href="#/failures" class="nav-link"><i class="ri-alarm-warning-line" aria-hidden="true"></i><span>异常 Task</span></a>
|
|
23
|
+
</nav>
|
|
24
|
+
<div class="header-meta">
|
|
25
|
+
<i class="ri-live-line" aria-hidden="true"></i>
|
|
26
|
+
<span id="header-refresh" class="header-refresh" aria-live="polite"></span>
|
|
27
|
+
</div>
|
|
28
|
+
<nav id="breadcrumb" class="breadcrumb" aria-label="面包屑"></nav>
|
|
29
|
+
</header>
|
|
30
|
+
|
|
31
|
+
<main id="main-content" class="dashboard-main" tabindex="-1">
|
|
32
|
+
<section data-view="dashboard" id="view-dashboard" class="view view-dashboard">
|
|
33
|
+
<div class="view-heading">
|
|
34
|
+
<p class="view-kicker">OBSERVE</p>
|
|
35
|
+
<h2>运行总览</h2>
|
|
36
|
+
<p>聚焦正在推进的 DAG、需要处理的风险与近期运行记录。</p>
|
|
37
|
+
</div>
|
|
38
|
+
<section id="dashboard-kpi" class="kpi-grid panel panel-kpi" aria-label="运行摘要"></section>
|
|
39
|
+
<div class="dashboard-workspace">
|
|
40
|
+
<section id="dashboard-active-dags" class="panel panel-primary"></section>
|
|
41
|
+
<aside id="dashboard-risk" class="panel panel-risk" aria-label="运行风险"></aside>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="dashboard-secondary">
|
|
44
|
+
<section id="dashboard-dags" class="panel"></section>
|
|
45
|
+
<section id="dashboard-batches" class="panel"></section>
|
|
46
|
+
</div>
|
|
47
|
+
</section>
|
|
48
|
+
|
|
49
|
+
<section data-view="batch" id="view-batch" class="view" hidden>
|
|
50
|
+
<div class="view-heading"><p class="view-kicker">BATCH</p><h2>批次详情</h2></div>
|
|
51
|
+
<section id="batch-meta" class="panel panel-meta"></section>
|
|
52
|
+
<section id="batch-tasks" class="panel panel-table"></section>
|
|
53
|
+
</section>
|
|
54
|
+
|
|
55
|
+
<section data-view="run" id="view-run" class="view" hidden>
|
|
56
|
+
<div class="view-heading"><p class="view-kicker">WORKER RUN</p><h2>运行详情</h2></div>
|
|
57
|
+
<section id="run-meta" class="panel panel-meta"></section>
|
|
58
|
+
<section id="run-dag-progress" class="panel panel-progress"></section>
|
|
59
|
+
<div class="run-detail-workspace">
|
|
60
|
+
<aside id="run-steps" class="panel panel-rail"></aside>
|
|
61
|
+
<div class="run-evidence">
|
|
62
|
+
<section id="run-command" class="panel"></section>
|
|
63
|
+
<section id="run-output" class="panel panel-output"></section>
|
|
64
|
+
</div>
|
|
65
|
+
<aside id="run-artifacts" class="panel panel-artifacts"></aside>
|
|
66
|
+
</div>
|
|
67
|
+
</section>
|
|
68
|
+
|
|
69
|
+
<section data-view="dag" id="view-dag" class="view" hidden>
|
|
70
|
+
<div class="view-heading"><p class="view-kicker">AGENT DAG</p><h2>DAG 详情</h2></div>
|
|
71
|
+
<section id="dag-meta" class="panel panel-meta"></section>
|
|
72
|
+
<div class="dag-detail-workspace">
|
|
73
|
+
<section id="dag-ranks" class="panel panel-graph"></section>
|
|
74
|
+
</div>
|
|
75
|
+
<section id="dag-nodes" class="panel panel-table"></section>
|
|
76
|
+
<aside id="dag-inspector" class="panel dag-inspector" aria-label="选中节点检查器" aria-hidden="true"></aside>
|
|
77
|
+
</section>
|
|
78
|
+
|
|
79
|
+
<section data-view="failures" id="view-failures" class="view" hidden>
|
|
80
|
+
<div class="view-heading"><p class="view-kicker">ATTENTION QUEUE</p><h2>异常 Task</h2><p>按运行状态和建议跟进项集中处理需要人工介入的 Task。</p></div>
|
|
81
|
+
<div id="failures-empty" class="panel empty-state" hidden>当前没有异常 Task</div>
|
|
82
|
+
<section id="failures-list" class="panel panel-table"></section>
|
|
83
|
+
</section>
|
|
84
|
+
</main>
|
|
85
|
+
</div>
|
|
86
|
+
<script type="module" src="/app.js"></script>
|
|
87
|
+
</body>
|
|
88
|
+
</html>
|