@kkeve/suite 0.0.1 → 0.0.2
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/README.md +53 -0
- package/dist/bin/keve.d.ts +13 -0
- package/dist/bin/keve.js +164 -0
- package/dist/commands/auth-update.d.ts +16 -0
- package/dist/commands/auth-update.js +88 -0
- package/dist/commands/clean.d.ts +10 -0
- package/dist/commands/clean.js +78 -0
- package/dist/commands/config.d.ts +17 -0
- package/dist/commands/config.js +99 -0
- package/dist/commands/init.d.ts +15 -0
- package/dist/commands/init.js +292 -0
- package/dist/commands/report.d.ts +12 -0
- package/dist/commands/report.js +159 -0
- package/dist/commands/run.d.ts +29 -0
- package/dist/commands/run.js +417 -0
- package/dist/commands/test.d.ts +12 -0
- package/dist/commands/test.js +102 -0
- package/dist/commands/vitest.d.ts +14 -0
- package/dist/commands/vitest.js +166 -0
- package/dist/config.d.ts +109 -0
- package/dist/config.js +291 -0
- package/dist/core/action-log-writer.d.ts +47 -0
- package/dist/{tools/write-file.js → core/action-log-writer.js} +42 -26
- package/dist/core/auth.d.ts +17 -0
- package/dist/core/auth.js +224 -0
- package/dist/core/cdp-resolver.d.ts +5 -0
- package/dist/core/cdp-resolver.js +93 -0
- package/dist/core/generateReport/report.d.ts +19 -0
- package/dist/core/generateReport/report.js +91 -0
- package/dist/core/generateReport/reportData.d.ts +215 -0
- package/dist/core/generateReport/reportData.js +735 -0
- package/dist/core/global-setup.d.ts +6 -0
- package/dist/core/global-setup.js +113 -0
- package/dist/core/keve-aspect.d.ts +54 -0
- package/dist/core/keve-aspect.js +52 -0
- package/dist/core/keve-decorators.d.ts +51 -0
- package/dist/core/keve-decorators.js +95 -0
- package/dist/core/keve-registry.d.ts +38 -0
- package/dist/core/keve-registry.js +25 -0
- package/dist/core/keve-report.d.ts +27 -0
- package/dist/core/keve-report.js +357 -0
- package/dist/core/keve-test.d.ts +36 -0
- package/dist/core/keve-test.js +364 -0
- package/dist/core/learned-actions.d.ts +24 -0
- package/dist/core/learned-actions.js +65 -0
- package/dist/core/pw-config.d.ts +19 -0
- package/dist/core/pw-config.js +180 -0
- package/dist/index.d.ts +8 -23
- package/dist/index.js +36 -43
- package/dist/page-agent/agent.d.ts +129 -0
- package/dist/page-agent/agent.js +585 -0
- package/dist/page-agent/hooks.d.ts +13 -0
- package/dist/page-agent/hooks.js +218 -0
- package/dist/page-agent/tools.d.ts +29 -0
- package/dist/page-agent/tools.js +297 -0
- package/doc/README.md +124 -0
- package/doc/agents/keve-dev-test-agent.md +140 -0
- package/doc/agents/keve-test-agent.md +178 -0
- package/doc/asserts//346/265/213/350/257/225/345/220/204/351/230/266/346/256/265/350/257/264/346/230/216.png +0 -0
- package/doc/keve-agent-demo.html +370 -0
- package/doc/skills/keve-bddcase-gen/SKILL.md +332 -0
- package/doc/skills/keve-bddcase-gen/references/test-case-rules.md +91 -0
- package/doc/skills/keve-bddcase-gen/references/test-cases-example.md +103 -0
- package/doc/skills/keve-component-gen/SKILL.md +255 -0
- package/doc/skills/keve-component-gen/references/component-mock-strategy.md +74 -0
- package/doc/skills/keve-component-gen/references/component-model-template.md +98 -0
- package/doc/skills/keve-component-gen/references/component-test-template.md +100 -0
- package/doc/skills/keve-component-gen/references/vue-test-utils-guide.md +91 -0
- package/doc/skills/keve-e2e-gen/SKILL.md +179 -0
- package/doc/skills/keve-e2e-gen/references/code-analysis-guide.md +208 -0
- package/doc/skills/keve-e2e-gen/references/decisions.md +36 -0
- package/doc/skills/keve-e2e-gen/references/pom-generation-guide.md +140 -0
- package/doc/skills/keve-e2e-gen/references/script-generation-guide.md +236 -0
- package/doc/skills/keve-e2e-gen/references/test-auditor-guide.md +189 -0
- package/doc/skills/keve-e2e-gen/scripts/extract-components.sh +85 -0
- package/doc/skills/keve-e2e-gen/scripts/inject-testids.sh +95 -0
- package/doc/skills/keve-static-analysis/SKILL.md +362 -0
- package/doc/skills/keve-static-analysis/references/codegraph-analysis-guide.md +108 -0
- package/doc/skills/keve-static-analysis/references/git-impact-analysis.md +81 -0
- package/doc/skills/keve-static-analysis/references/lint-fix-guide.md +69 -0
- package/doc/skills/keve-static-analysis/references/runtime-risk-patterns.md +92 -0
- package/doc/skills/keve-static-analysis/references/security-scan-guide.md +32 -0
- package/doc/skills/keve-static-analysis/references/ts-error-patterns.md +98 -0
- package/doc/skills/keve-static-analysis/references/vue-security-guide.md +72 -0
- package/doc/skills/keve-test-eval/SKILL.md +78 -0
- package/doc/skills/keve-test-eval/references/common-fix-guide.md +166 -0
- package/doc/skills/keve-test-eval/references/confidence-data-guide.md +78 -0
- package/doc/skills/keve-test-eval/references/fix-loop-guide.md +67 -0
- package/doc/skills/keve-unit-gen/SKILL.md +203 -0
- package/doc/skills/keve-unit-gen/references/boundary-conditions.md +78 -0
- package/doc/skills/keve-unit-gen/references/unit-mock-strategy.md +71 -0
- package/doc/skills/keve-unit-gen/references/unit-test-template.md +105 -0
- package/package.json +47 -25
- package/dist/agent/factory.d.ts +0 -25
- package/dist/agent/factory.js +0 -99
- package/dist/agent/index.d.ts +0 -3
- package/dist/agent/index.js +0 -7
- package/dist/agent/loader.d.ts +0 -22
- package/dist/agent/loader.js +0 -117
- package/dist/agent/types.d.ts +0 -9
- package/dist/agent/types.js +0 -2
- package/dist/agent-loop/complete-task.d.ts +0 -28
- package/dist/agent-loop/complete-task.js +0 -70
- package/dist/agent-loop/index.d.ts +0 -16
- package/dist/agent-loop/index.js +0 -26
- package/dist/agent-loop/loop.d.ts +0 -42
- package/dist/agent-loop/loop.js +0 -282
- package/dist/agent-loop/runtime.d.ts +0 -40
- package/dist/agent-loop/runtime.js +0 -163
- package/dist/agent-loop/types.d.ts +0 -161
- package/dist/agent-loop/types.js +0 -105
- package/dist/context/index.d.ts +0 -8
- package/dist/context/index.js +0 -29
- package/dist/context/tokenCalculation.d.ts +0 -55
- package/dist/context/tokenCalculation.js +0 -95
- package/dist/context/truncation.d.ts +0 -67
- package/dist/context/truncation.js +0 -142
- package/dist/context/types.d.ts +0 -7
- package/dist/context/types.js +0 -27
- package/dist/llm/OpenAIClient.d.ts +0 -31
- package/dist/llm/OpenAIClient.js +0 -455
- package/dist/llm/constants.d.ts +0 -2
- package/dist/llm/constants.js +0 -6
- package/dist/llm/errors.d.ts +0 -25
- package/dist/llm/errors.js +0 -51
- package/dist/llm/index.d.ts +0 -49
- package/dist/llm/index.js +0 -158
- package/dist/llm/types.d.ts +0 -124
- package/dist/llm/types.js +0 -2
- package/dist/llm/utils.d.ts +0 -29
- package/dist/llm/utils.js +0 -284
- package/dist/skill/frontmatter-parser.d.ts +0 -50
- package/dist/skill/frontmatter-parser.js +0 -152
- package/dist/skill/index.d.ts +0 -12
- package/dist/skill/index.js +0 -17
- package/dist/skill/loader.d.ts +0 -96
- package/dist/skill/loader.js +0 -256
- package/dist/tools/ask-user.d.ts +0 -8
- package/dist/tools/ask-user.js +0 -47
- package/dist/tools/bash.d.ts +0 -47
- package/dist/tools/bash.js +0 -213
- package/dist/tools/edit-file.d.ts +0 -9
- package/dist/tools/edit-file.js +0 -76
- package/dist/tools/glob.d.ts +0 -8
- package/dist/tools/glob.js +0 -101
- package/dist/tools/grep.d.ts +0 -10
- package/dist/tools/grep.js +0 -76
- package/dist/tools/index.d.ts +0 -24
- package/dist/tools/index.js +0 -47
- package/dist/tools/read-files.d.ts +0 -8
- package/dist/tools/read-files.js +0 -81
- package/dist/tools/write-file.d.ts +0 -8
|
@@ -0,0 +1,370 @@
|
|
|
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>KEVE Agent - AI 重建测试流程</title>
|
|
7
|
+
<style>
|
|
8
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
9
|
+
:root{
|
|
10
|
+
--dev:#4F46E5;--dev-l:#818CF8;--dev-bg:#EEF2FF;
|
|
11
|
+
--test:#059669;--test-l:#34D399;--test-bg:#ECFDF5;
|
|
12
|
+
--plat:#7C3AED;--plat-l:#A78BFA;--plat-bg:#F5F3FF;
|
|
13
|
+
--warn:#D97706;--warn-bg:#FEF3C7;
|
|
14
|
+
--in:#0369A1;--in-bg:#E0F2FE;
|
|
15
|
+
--g50:#F9FAFB;--g100:#F3F4F6;--g200:#E5E7EB;--g300:#D1D5DB;
|
|
16
|
+
--g400:#9CA3AF;--g500:#6B7280;--g600:#4B5563;--g700:#374151;
|
|
17
|
+
--g800:#1F2937;--g900:#111827;
|
|
18
|
+
--mono:'SF Mono','Fira Code','Cascadia Code',monospace;
|
|
19
|
+
--sans:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
|
|
20
|
+
}
|
|
21
|
+
body{font-family:var(--sans);height:100vh;overflow:hidden;background:var(--g50);display:flex;flex-direction:column}
|
|
22
|
+
|
|
23
|
+
/* HEADER */
|
|
24
|
+
.Hd{padding:14px 30px 0;display:flex;align-items:center;gap:16px}
|
|
25
|
+
.Hd-ico{width:36px;height:36px;background:var(--dev);border-radius:10px;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:16px;color:white}
|
|
26
|
+
.Hd-t{font-size:20px;font-weight:800;color:var(--g800)}
|
|
27
|
+
.Hd-s{font-size:12px;color:var(--g500)}
|
|
28
|
+
|
|
29
|
+
/* TOP: Flow */
|
|
30
|
+
.Top{padding:8px 30px 0;display:flex;align-items:flex-start;gap:0}
|
|
31
|
+
.Tph{flex:1;background:white;border-radius:12px;padding:12px 14px;border:1.5px solid var(--g200);min-width:0;transition:all .3s}
|
|
32
|
+
.Tph.d{border-color:var(--dev-l)}.Tph.t{border-color:var(--test-l)}.Tph.o{border-color:var(--plat-l)}
|
|
33
|
+
.Tph.act.d{border-color:var(--dev);background:var(--dev-bg)}
|
|
34
|
+
.Tph.act.t{border-color:var(--test);background:var(--test-bg)}
|
|
35
|
+
.Tph.act.o{border-color:var(--plat);background:var(--plat-bg)}
|
|
36
|
+
.Tph-hd{font-size:12px;font-weight:700}
|
|
37
|
+
.Tph.d .Tph-hd{color:var(--dev)}.Tph.t .Tph-hd{color:var(--test)}.Tph.o .Tph-hd{color:var(--plat)}
|
|
38
|
+
.Tph-sub{font-size:10px;color:var(--g500);margin-top:2px;line-height:1.3}
|
|
39
|
+
.Tph-nds{display:flex;gap:6px;margin-top:8px;justify-content:center}
|
|
40
|
+
.Tnd{background:var(--g50);border-radius:7px;padding:7px 10px;cursor:pointer;transition:all .3s;border:1.5px solid var(--g200);min-width:70px;text-align:center;flex:1}
|
|
41
|
+
.Tnd.d{border-color:rgba(79,70,229,.25)}.Tnd.t{border-color:rgba(5,150,105,.25)}.Tnd.o{border-color:rgba(124,58,237,.25)}
|
|
42
|
+
.Tnd.act{transform:scale(1.05)}
|
|
43
|
+
.Tnd.act.d{border-color:var(--dev);background:var(--dev-bg)}
|
|
44
|
+
.Tnd.act.t{border-color:var(--test);background:var(--test-bg)}
|
|
45
|
+
.Tnd.act.o{border-color:var(--plat);background:var(--plat-bg)}
|
|
46
|
+
.Tnd.done{opacity:.35}
|
|
47
|
+
.Tnd .cmd{font-size:9px;font-weight:700;font-family:var(--mono)}
|
|
48
|
+
.Tnd.d .cmd{color:var(--dev)}.Tnd.t .cmd{color:var(--test)}.Tnd.o .cmd{color:var(--plat)}
|
|
49
|
+
.Tnd .nm{font-size:10px;font-weight:600;color:var(--g700);margin-top:1px}
|
|
50
|
+
|
|
51
|
+
.Tarr{width:30px;display:flex;align-items:center;justify-content:center;padding-top:36px}
|
|
52
|
+
.Tarr svg{width:30px;height:18px}
|
|
53
|
+
|
|
54
|
+
/* Timeline */
|
|
55
|
+
.Tl{display:flex;gap:0;overflow-x:auto;padding:6px 30px 0;border-bottom:1px solid var(--g200)}
|
|
56
|
+
.Tl::-webkit-scrollbar{height:2px}.Tl::-webkit-scrollbar-thumb{background:var(--g300);border-radius:2px}
|
|
57
|
+
.Tl-i{flex-shrink:0;padding:6px 8px;font-size:10px;color:var(--g500);cursor:pointer;transition:all .2s;border-bottom:2px solid transparent;white-space:nowrap}
|
|
58
|
+
.Tl-i:hover{background:var(--g100)}
|
|
59
|
+
.Tl-i.act{color:var(--g800);font-weight:600}
|
|
60
|
+
.Tl-i.act.d{border-bottom-color:var(--dev)}.Tl-i.act.t{border-bottom-color:var(--test)}.Tl-i.act.o{border-bottom-color:var(--plat)}
|
|
61
|
+
.Tl-i.done{color:var(--g400)}
|
|
62
|
+
.Tl-sep{flex-shrink:0;width:1px;background:var(--g200);margin:3px 1px}
|
|
63
|
+
|
|
64
|
+
/* MIDDLE: Demo */
|
|
65
|
+
.Mid{flex:1;overflow-y:auto;padding:12px 30px 0}
|
|
66
|
+
.Mid::-webkit-scrollbar{width:4px}.Mid::-webkit-scrollbar-thumb{background:var(--g300);border-radius:2px}
|
|
67
|
+
|
|
68
|
+
/* Controls */
|
|
69
|
+
.Mc{display:flex;align-items:center;gap:8px;padding:0 0 10px}
|
|
70
|
+
.Mbtn{background:var(--dev);color:white;border:none;padding:7px 14px;border-radius:6px;font-size:12px;cursor:pointer;display:flex;align-items:center;gap:5px;font-family:var(--sans);transition:all .2s}
|
|
71
|
+
.Mbtn:hover{filter:brightness(1.15)}.Mbtn.on{background:var(--warn)}
|
|
72
|
+
.Msel{background:var(--g100);color:var(--g600);border:1px solid var(--g200);padding:4px 8px;border-radius:4px;font-size:11px;cursor:pointer;font-family:var(--sans)}
|
|
73
|
+
.Mlbl{font-size:11px;color:var(--g500);margin-left:auto}.Mlbl b{color:var(--g700)}
|
|
74
|
+
.Msc{font-size:11px;padding:5px 10px;background:var(--dev-bg);border-radius:6px;color:var(--g500)}.Msc b{color:var(--dev)}
|
|
75
|
+
|
|
76
|
+
/* Step card */
|
|
77
|
+
.Scard{background:white;border-radius:10px;border:1.5px solid var(--g200);padding:18px 20px;display:none;margin-bottom:12px}
|
|
78
|
+
.Scard.act{display:block}
|
|
79
|
+
.Scard.d{border-left:3px solid var(--dev)}.Scard.t{border-left:3px solid var(--test)}.Scard.o{border-left:3px solid var(--plat)}
|
|
80
|
+
|
|
81
|
+
.Sc-hd{display:flex;align-items:center;gap:10px;margin-bottom:14px}
|
|
82
|
+
.Sc-ph{font-size:10px;font-weight:700;padding:4px 10px;border-radius:6px;letter-spacing:.04em}
|
|
83
|
+
.Sc-ph.d{background:var(--dev-bg);color:var(--dev)}.Sc-ph.t{background:var(--test-bg);color:var(--test)}.Sc-ph.o{background:var(--plat-bg);color:var(--plat)}
|
|
84
|
+
.Sc-nm{font-size:16px;font-weight:700;color:var(--g800)}
|
|
85
|
+
.Sc-tm{font-size:11px;color:var(--g400);font-family:var(--mono);margin-left:auto}
|
|
86
|
+
|
|
87
|
+
/* Input / Output sections */
|
|
88
|
+
.Sc-io{display:flex;gap:16px;margin-bottom:12px}
|
|
89
|
+
.Sc-in,.Sc-out{flex:1;padding:12px 14px;border-radius:8px}
|
|
90
|
+
.Sc-in{background:var(--in-bg);border:1px solid rgba(3,105,161,.1)}
|
|
91
|
+
.Sc-out{background:var(--warn-bg);border:1px solid rgba(217,119,6,.1)}
|
|
92
|
+
.Sc-io-l{font-size:10px;font-weight:700;letter-spacing:.06em;margin-bottom:6px;display:flex;align-items:center;gap:4px}
|
|
93
|
+
.Sc-in .Sc-io-l{color:var(--in)}.Sc-out .Sc-io-l{color:var(--warn)}
|
|
94
|
+
.Sc-io-l .arrow{font-size:12px}
|
|
95
|
+
.Sc-io-v{font-size:12px;color:var(--g600);line-height:1.5}
|
|
96
|
+
.Sc-io-v b{color:var(--g800);font-weight:600}
|
|
97
|
+
.Sc-io-v code{font-family:var(--mono);font-size:11px;background:rgba(0,0,0,.04);padding:1px 4px;border-radius:3px}
|
|
98
|
+
|
|
99
|
+
/* AI thinking */
|
|
100
|
+
.Sc-think{padding:12px 14px;border-radius:8px;margin-bottom:10px;border:1px solid var(--g200)}
|
|
101
|
+
.Sc-think.d{background:rgba(79,70,229,.03);border-color:rgba(79,70,229,.1)}
|
|
102
|
+
.Sc-think.t{background:rgba(5,150,105,.03);border-color:rgba(5,150,105,.1)}
|
|
103
|
+
.Sc-think.o{background:rgba(124,58,237,.03);border-color:rgba(124,58,237,.1)}
|
|
104
|
+
.Sc-thk-l{font-size:10px;font-weight:700;letter-spacing:.06em;margin-bottom:4px;color:var(--g500)}
|
|
105
|
+
|
|
106
|
+
/* Keys */
|
|
107
|
+
.Sc-keys{display:flex;gap:6px;flex-wrap:wrap}
|
|
108
|
+
.Sc-k{font-size:10px;padding:4px 10px;border-radius:5px;font-weight:500}
|
|
109
|
+
.Sc-k.d{background:var(--dev-bg);color:var(--dev)}
|
|
110
|
+
.Sc-k.t{background:var(--test-bg);color:var(--test)}
|
|
111
|
+
.Sc-k.o{background:var(--plat-bg);color:var(--plat)}
|
|
112
|
+
|
|
113
|
+
/* BOTTOM */
|
|
114
|
+
.Btm{padding:10px 30px 14px}
|
|
115
|
+
.Btm-bar{background:var(--g800);border-radius:10px;padding:10px 18px;display:flex;align-items:center;gap:14px}
|
|
116
|
+
.Btm-lbl{font-size:12px;font-weight:700;color:white;white-space:nowrap}
|
|
117
|
+
.Btm-items{display:flex;gap:8px;flex-wrap:wrap;flex:1}
|
|
118
|
+
.Btm-item{font-size:10px;padding:4px 10px;border-radius:5px;background:rgba(255,255,255,.08);color:var(--g300);display:flex;align-items:center;gap:5px}
|
|
119
|
+
.Btm-item b{color:white;font-weight:600}
|
|
120
|
+
.Btm-tag{font-size:8px;padding:2px 6px;border-radius:3px;color:white;font-weight:600}
|
|
121
|
+
|
|
122
|
+
/* Glow */
|
|
123
|
+
@keyframes gd{0%,100%{box-shadow:0 0 10px rgba(79,70,229,.12)}50%{box-shadow:0 0 18px rgba(79,70,229,.25)}}
|
|
124
|
+
@keyframes gt{0%,100%{box-shadow:0 0 10px rgba(5,150,105,.12)}50%{box-shadow:0 0 18px rgba(5,150,105,.25)}}
|
|
125
|
+
@keyframes gp{0%,100%{box-shadow:0 0 10px rgba(124,58,237,.12)}50%{box-shadow:0 0 18px rgba(124,58,237,.25)}}
|
|
126
|
+
.Tnd.act.d{animation:gd 1.4s ease-in-out infinite}
|
|
127
|
+
.Tnd.act.t{animation:gt 1.4s ease-in-out infinite}
|
|
128
|
+
.Tnd.act.o{animation:gp 1.4s ease-in-out infinite}
|
|
129
|
+
</style>
|
|
130
|
+
</head>
|
|
131
|
+
<body>
|
|
132
|
+
|
|
133
|
+
<div class="Hd">
|
|
134
|
+
<div class="Hd-ico">K</div>
|
|
135
|
+
<div><div class="Hd-t">KEVE Agent · AI 重建测试流程</div><div class="Hd-s">开发·自测 → 测试·协同 → 运维·持续保障</div></div>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div class="Top">
|
|
139
|
+
<div class="Tph d" id="ph-d">
|
|
140
|
+
<div class="Tph-hd">开发阶段 · AI自测闭环</div>
|
|
141
|
+
<div class="Tph-sub">提交代码自动触发 · 沉淀项目资产(agent维护)</div>
|
|
142
|
+
<div class="Tph-nds">
|
|
143
|
+
<div class="Tnd d" id="n1" onclick="go(1)">
|
|
144
|
+
<div class="cmd">提交→test</div>
|
|
145
|
+
<div class="nm">AI自测闭环</div>
|
|
146
|
+
</div>
|
|
147
|
+
<div class="Tnd d" id="n2" onclick="go(7)">
|
|
148
|
+
<div class="cmd">report</div>
|
|
149
|
+
<div class="nm">同步平台</div>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
<div class="Tarr"><svg viewBox="0 0 30 18"><path d="M4 9 L26 9 M20 3 L26 9 L20 15" stroke="#D1D5DB" stroke-width="2" fill="none"/></svg></div>
|
|
154
|
+
<div class="Tph t" id="ph-t">
|
|
155
|
+
<div class="Tph-hd">测试阶段 · 人机协同确认</div>
|
|
156
|
+
<div class="Tph-sub">提测触发 → 平台分发 → 参考开发资产二次测试</div>
|
|
157
|
+
<div class="Tph-nds">
|
|
158
|
+
<div class="Tnd t" id="n3" onclick="go(8)">
|
|
159
|
+
<div class="cmd">提测触发</div>
|
|
160
|
+
<div class="nm">分发+通知</div>
|
|
161
|
+
</div>
|
|
162
|
+
<div class="Tnd t" id="n4" onclick="go(10)">
|
|
163
|
+
<div class="cmd">run(桌面)</div>
|
|
164
|
+
<div class="nm">可视化协同</div>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
<div class="Tarr"><svg viewBox="0 0 30 18"><path d="M4 9 L26 9 M20 3 L26 9 L20 15" stroke="#D1D5DB" stroke-width="2" fill="none"/></svg></div>
|
|
169
|
+
<div class="Tph o" id="ph-o">
|
|
170
|
+
<div class="Tph-hd">运维阶段 · 持续保障</div>
|
|
171
|
+
<div class="Tph-sub">可执行脚本+自然语言用例沉淀 · 定时巡检</div>
|
|
172
|
+
<div class="Tph-nds">
|
|
173
|
+
<div class="Tnd o" id="n5" onclick="go(11)">
|
|
174
|
+
<div class="cmd">keve平台</div>
|
|
175
|
+
<div class="nm">脚本沉淀</div>
|
|
176
|
+
</div>
|
|
177
|
+
<div class="Tnd o" id="n6" onclick="go(12)">
|
|
178
|
+
<div class="cmd">keve平台</div>
|
|
179
|
+
<div class="nm">定时巡检</div>
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<div class="Tl" id="tlEl"></div>
|
|
186
|
+
|
|
187
|
+
<div class="Mid">
|
|
188
|
+
<div class="Mc">
|
|
189
|
+
<button class="Mbtn" id="Mbtn" onclick="tp()"><span id="Mi">▶</span><span id="Mt">播放</span></button>
|
|
190
|
+
<select class="Msel" id="Ms" onchange="cs()"><option value="2000">慢 2s</option><option value="1200" selected>中 1.2s</option><option value="600">快 0.6s</option></select>
|
|
191
|
+
<div class="Mlbl">步骤 <b id="Mn">1</b>/10</div>
|
|
192
|
+
<div class="Msc">MR <b>868</b></div>
|
|
193
|
+
</div>
|
|
194
|
+
<div id="cards"></div>
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
<div class="Btm">
|
|
198
|
+
<div class="Btm-bar">
|
|
199
|
+
<div class="Btm-lbl">keve 平台底座</div>
|
|
200
|
+
<div class="Btm-items">
|
|
201
|
+
<div class="Btm-item"><span class="Btm-tag" style="background:var(--dev)">CLI</span><b>keve</b> init / test / run / report</div>
|
|
202
|
+
<div class="Btm-item"><span class="Btm-tag" style="background:var(--test)">桌面端</span><b>keve</b> 可视化协同</div>
|
|
203
|
+
<div class="Btm-item"><span class="Btm-tag" style="background:var(--plat)">Web</span><b>keve</b> 资产沉淀 + 巡检调度</div>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
|
|
208
|
+
<script>
|
|
209
|
+
const S=[
|
|
210
|
+
{ph:'d',nm:'环境初始化(每项目一次)',tm:'一次性',
|
|
211
|
+
in:'<code>项目仓库</code>(llm-agent) → <b>keve init --force</b>',
|
|
212
|
+
out:'<code>.keve/</code> 工作区<br><code>keve_test_spec/poms/</code>(7个Page Object)<br><code>keve_test_spec/fixtures/test-data.ts</code><br><code>keve.yaml</code> + <code>playwright.config.ts</code><br><b>3 Skills</b> + <b>1 Agent</b>',
|
|
213
|
+
th:'keve init只需在每个项目中执行一次。创建工作区、注入Skills和Agent、生成配置。后续每次提交代码不再重复初始化。',
|
|
214
|
+
ks:['keve init','每项目一次','3 Skills','1 Agent']},
|
|
215
|
+
{ph:'d',nm:'AI分析(需求+代码+知识库)',tm:'~5min',
|
|
216
|
+
in:'<b>PRD</b>: xxx/d/home/fcAB5rrt...<br><b>MR 868 代码变更</b> + <b>项目源码</b>',
|
|
217
|
+
out:'<b>case-generation skill</b> → <code>test-cases.yaml</code> 版本1.0<br>5模块: <b>AG</b>(遮罩层,8用例) <b>KB</b>(禁用筛选,4用例) <b>WW</b>(字符限制,5用例) <b>SK</b>(锁定权限,6用例) <b>RG</b>(回归,2用例)<br><b style="color:var(--warn)">需求偏差2处</b>: 欢迎语300≠PRD200 / 去掉"可在DataAgent中@"<br><br><b>script-generation skill</b> → <code>poms/AgentDetailPage.ts</code> (5.21KB) / <code>NotAvailablePage.ts</code> (10.36KB) / <code>SkillDetailPage.ts</code> (12.54KB)<br><code>fixtures/test-data.ts</code> → <b>agents.tcPortal.id=636</b><br><b>@keveModel/@keveScene</b> 打标<br><br><b>有疑惑 → 人工check补齐</b>',
|
|
218
|
+
th:'提交代码时自动触发keve test。两个skill并行工作: case-generation分析PRD+MR生成test-cases.yaml(发现2处需求偏差);script-generation分析项目源码生成POM+test-data.ts+打标。中间有疑惑信息(如定位器歧义、需求模糊)需要人工check补齐。',
|
|
219
|
+
ks:['case-generation','script-generation','需求偏差2处','人工check']},
|
|
220
|
+
{ph:'d',nm:'测试计划设计(可执行脚本)',tm:'~4min',
|
|
221
|
+
in:'<code>test-cases.yaml</code>(25+用例) + <b>POM类</b>(7个) + <code>test-data.ts</code>(tcPortal.id=636)',
|
|
222
|
+
out:'__CODE_BLOCK__',
|
|
223
|
+
th:'基于test-cases.yaml(测试用例)和POM(测试知识),编写6个Playwright可执行测试计划(spec)。每个spec定义模块、场景、测试目标(步骤和预期)。这就是集成/E2E脚本编写。',
|
|
224
|
+
ks:['6 spec','@keveGoal','keveAssert','可执行测试计划']},
|
|
225
|
+
{ph:'d',nm:'执行+评估+修复(loop)',tm:'18轮/4h',
|
|
226
|
+
in:'<b>可执行测试计划</b>(6 Playwright spec) + <code>playwright.config.ts</code> + <b>3 workers</b> 并行',
|
|
227
|
+
out:'<b>测试报告</b>: R18 最终结果 24 fail / 48 total<br>keveAssert评估: <b>confidence</b>评分 + <b>4分类根因</b><br>67% visual(B类-遮罩层断言噪声) / 20% script(D类) / 8% assert(C类) / 5% env(A类)<br><b style="color:var(--warn)">关键结论</b>: B类不应进修复循环 → D类进修复循环(loop) → R2:32→R18:24',
|
|
228
|
+
th:'keve-test-agent编排执行+评估+修复的闭环loop。Round 2执行32 fail→keveAssert智能评估根因→D类(script)进入修复循环→修复spec→重跑→再评估→loop直到通过或达到上限。实际18轮: 67% B类(visual)不应进循环但被混入,导致修复无效。结论: loop应只针对D类。',
|
|
229
|
+
ks:['keve-test-agent','闭环loop','D类修复','B类跳过']},
|
|
230
|
+
{ph:'d',nm:'同步平台(测试计划+结果)',tm:'~30s',
|
|
231
|
+
in:'<code>test-cases.yaml</code>(测试计划) + <b>执行结果</b>(24/48 failed) + <b>MR 868 diff</code>(代码变更) + <b>PRD链接</b>(需求信息)',
|
|
232
|
+
out:'<b>keve平台任务记录</b>(MR 868)<br><b>项目资产沉淀</b>:<br>POM库(7个Page Object) → agent维护<br>test-data.ts → agent维护<br>test-cases.yaml → agent维护<br>评估基线(confidence历史)',
|
|
233
|
+
th:'测试计划和执行结果同步到keve平台。项目资产(POM+用例+数据)由agent持续维护更新。同步不阻塞——失败仅warning。',
|
|
234
|
+
ks:['测试计划','执行结果','代码变更','项目资产']},
|
|
235
|
+
{ph:'t',nm:'提测触发→平台分发',tm:'~1s',
|
|
236
|
+
in:'<b>开发标记提测</b>(MR 868 ready for test)',
|
|
237
|
+
out:'<b>keve平台拉取</b>: 测试计划 + 代码变更 + 需求<br>→ <b>自动分发</b>: 张三(AG+SK模块) / 李四(KB+WW模块)<br>→ <b>桌面推送</b>: "MR 868测试完成, 24个问题"',
|
|
238
|
+
th:'开发标记提测后,keve平台拉取相关信息(测试计划、代码变更、需求),自动分发到各测试人员。桌面应用推送通知。',
|
|
239
|
+
ks:['提测触发','信息拉取','人员分发','桌面推送']},
|
|
240
|
+
{ph:'t',nm:'桌面应用通知',tm:'~实时',
|
|
241
|
+
in:'<b>平台分发信息</b>(MR标题+AI概要+根因+报告链接)',
|
|
242
|
+
out:'<b>桌面推送</b>:<br>MR 868 测试完成<br>24个问题 (67%视觉类)<br>点击查看 → bs3.../report.html',
|
|
243
|
+
th:'keve桌面应用推送通知到测试同学。',
|
|
244
|
+
ks:['桌面推送','即时通知','一键查看']},
|
|
245
|
+
{ph:'t',nm:'可视化查看+二次测试+修正',tm:'~15min',
|
|
246
|
+
in:'<b>开发资产</b>: POM(AgentDetailPage.ts等) + test-cases.yaml + test-data.ts<br><b>AI测试结果</b>: 截图回放 + confidence + 根因标注(B类67%/D类20%)',
|
|
247
|
+
out:'<b>确认</b>: B类为系统性缺陷(断言噪声),非bug<br><b>修正</b>: 遮罩层断言→容忍噪声描述<br><b>补充</b>: 增加WW-06(300字符边界用例)<br><b>筛选</b>: AG核心流程 → 定时巡检',
|
|
248
|
+
th:'测试同学参考开发资产和AI结果二次测试: 确认B类为系统性缺陷而非bug,修正断言容忍噪声,补充遗漏用例,筛选核心流程交给keve平台巡检。',
|
|
249
|
+
ks:['参考开发资产','二次测试','修正断言','筛选巡检']},
|
|
250
|
+
{ph:'o',nm:'沉淀可执行脚本+用例',tm:'持续',
|
|
251
|
+
in:'<b>开发+测试阶段产出</b>: 6 Playwright spec + test-cases.yaml + 7 POM + 修正断言',
|
|
252
|
+
out:'<b>keve平台资产库</b>:<br><code>agent-mask.spec.ts</code> (可执行,含修正后的断言)<br><code>test-cases.yaml</code> (自然语言: AG-01 TC类型无权限状态描述简化)<br><code>poms/*.ts</code> (POM库,可复用)<br><b>agent持续维护更新</b>',
|
|
253
|
+
th:'keve平台沉淀可直接执行的Playwright脚本和自然语言用例。由agent持续维护更新。',
|
|
254
|
+
ks:['可执行脚本','自然语言用例','POM库','agent维护']},
|
|
255
|
+
{ph:'o',nm:'定时巡检调度执行',tm:'定时',
|
|
256
|
+
in:'<b>keve平台资产</b>(spec+yaml) + <b>调度配置</b>(每日10:00 / 每周一)',
|
|
257
|
+
out:'<b>线上巡检结果</b> → 平台报告<br>自动回归: AG核心流程(遮罩层) + SK核心流程(锁定权限)<br>环境稳定性检查',
|
|
258
|
+
th:'keve平台配置调度任务,复用可执行脚本定时线上巡检。',
|
|
259
|
+
ks:['调度配置','脚本复用','线上巡检','自动回归']},
|
|
260
|
+
];
|
|
261
|
+
|
|
262
|
+
const NM=[1,1,1,1,2,3,3,4,5,6];
|
|
263
|
+
// step0→n1(init), step1→n1(AI分析), step2→n1(测试计划), step3→n1(执行loop), step4→n2(同步), step5→n3(分发), step6→n3(通知), step7→n4(协同), step8→n5(沉淀), step9→n6(巡检)
|
|
264
|
+
|
|
265
|
+
const CODE_SPEC=`@keveScene("AG-01: TC类型-无权限状态描述简化")
|
|
266
|
+
static async testTcPortalNoPermissionMask({ page, keveGoal, keveAssert }) {
|
|
267
|
+
const notAvailablePage = new NotAvailablePage(page);
|
|
268
|
+
await keveGoal({
|
|
269
|
+
precondition: "通过链接改id访问TC来源且无权限的智能应用",
|
|
270
|
+
step: "进入TC类型智能应用详情页(无权限)",
|
|
271
|
+
expected: "页面显示遮罩层,描述含...即将下线,不再独立维护"
|
|
272
|
+
}, async () => {
|
|
273
|
+
await notAvailablePage.navigateToAgentDetail(
|
|
274
|
+
testData.agents.tcPortal.id, "edit", false);
|
|
275
|
+
await notAvailablePage.assertNotAvailableVisible(true);
|
|
276
|
+
await keveAssert("遮罩层可见,描述包含...", { label: "AG01-Step1" });
|
|
277
|
+
});
|
|
278
|
+
await keveGoal({
|
|
279
|
+
step: "观察按钮组区域",
|
|
280
|
+
expected: "按钮组不显示,整个按钮组区域被隐藏"
|
|
281
|
+
}, async () => {
|
|
282
|
+
await notAvailablePage.assertButtonGroupHidden();
|
|
283
|
+
await keveAssert("按钮组区域完全隐藏", { label: "AG01-Step2" });
|
|
284
|
+
});
|
|
285
|
+
}`;
|
|
286
|
+
|
|
287
|
+
function mkCode(code){
|
|
288
|
+
const pre=document.createElement('pre');
|
|
289
|
+
pre.style.cssText='font-size:11px;background:#1e293b;color:#e2e8f0;padding:10px 12px;border-radius:6px;margin:6px 0;line-height:1.45;overflow-x:auto;font-family:var(--mono)';
|
|
290
|
+
pre.textContent=code;
|
|
291
|
+
return pre;
|
|
292
|
+
}
|
|
293
|
+
const NDS=[document.getElementById('n1'),document.getElementById('n2'),document.getElementById('n3'),document.getElementById('n4'),document.getElementById('n5'),document.getElementById('n6')];
|
|
294
|
+
const PHS=[document.getElementById('ph-d'),document.getElementById('ph-t'),document.getElementById('ph-o')];
|
|
295
|
+
|
|
296
|
+
let cur=0,playing=false,timer=null,spd=1200;
|
|
297
|
+
const tlEl=document.getElementById('tlEl');
|
|
298
|
+
const cardsEl=document.getElementById('cards');
|
|
299
|
+
|
|
300
|
+
function build(){
|
|
301
|
+
tlEl.innerHTML='';
|
|
302
|
+
let lp='';
|
|
303
|
+
S.forEach((s,i)=>{
|
|
304
|
+
if(s.ph!==lp){lp=s.ph;if(i>0){const sep=document.createElement('div');sep.className='Tl-sep';tlEl.appendChild(sep)}}
|
|
305
|
+
const t=document.createElement('div');t.className='Tl-i '+s.ph;t.onclick=()=>go(i);t.textContent=s.nm;tlEl.appendChild(t);
|
|
306
|
+
});
|
|
307
|
+
cardsEl.innerHTML='';
|
|
308
|
+
S.forEach((s,i)=>{
|
|
309
|
+
const c=document.createElement('div');c.className='Scard '+s.ph;c.id='c'+i;
|
|
310
|
+
const phTxt=s.ph==='d'?'开发阶段':s.ph==='t'?'测试阶段':'运维阶段';
|
|
311
|
+
c.innerHTML=`
|
|
312
|
+
<div class="Sc-hd">
|
|
313
|
+
<div class="Sc-ph ${s.ph}">${phTxt}</div>
|
|
314
|
+
<div class="Sc-nm">${s.nm}</div>
|
|
315
|
+
<div class="Sc-tm">${s.tm}</div>
|
|
316
|
+
</div>
|
|
317
|
+
<div class="Sc-think ${s.ph}">
|
|
318
|
+
<div class="Sc-thk-l">AI 思考过程</div>
|
|
319
|
+
<div style="font-size:12px;color:var(--g600);line-height:1.5">${s.th}</div>
|
|
320
|
+
</div>
|
|
321
|
+
<div class="Sc-io">
|
|
322
|
+
<div class="Sc-in">
|
|
323
|
+
<div class="Sc-io-l">▶ 输入 <span class="arrow">→</span></div>
|
|
324
|
+
<div class="Sc-io-v">${s.in}</div>
|
|
325
|
+
</div>
|
|
326
|
+
<div class="Sc-out">
|
|
327
|
+
<div class="Sc-io-l">▶ 输出 <span class="arrow">→</span></div>
|
|
328
|
+
<div class="Sc-io-v">${s.out==='__CODE_BLOCK__'?'<b>6个可执行Playwright spec</b> — 每个包含模块+场景+测试目标(步骤+预期)<br><br><b>agent-mask.spec.ts</b> (15.49KB) @keveModel("智能应用详情页-遮罩层"):':s.out}</div>
|
|
329
|
+
</div>
|
|
330
|
+
</div>
|
|
331
|
+
<div class="Sc-keys">${s.ks.map(k=>`<div class="Sc-k ${s.ph}">${k}</div>`).join('')}</div>
|
|
332
|
+
`;
|
|
333
|
+
cardsEl.appendChild(c);
|
|
334
|
+
if(s.out==='__CODE_BLOCK__'){
|
|
335
|
+
const outV=c.querySelector('.Sc-out .Sc-io-v');
|
|
336
|
+
if(outV)outV.appendChild(mkCode(CODE_SPEC));
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function go(i){
|
|
342
|
+
cur=i;document.getElementById('Mn').textContent=i+1;
|
|
343
|
+
tlEl.querySelectorAll('.Tl-i').forEach((el,j)=>{el.classList.remove('act','done');if(j===i)el.classList.add('act');else if(j<i)el.classList.add('done')});
|
|
344
|
+
S.forEach((s,j)=>{document.getElementById('c'+j).classList.toggle('act',j===i)});
|
|
345
|
+
const ni=NM[i];
|
|
346
|
+
NDS.forEach((n,j)=>{n.classList.remove('act','done');if(j===ni)n.classList.add('act');else if(j<ni)n.classList.add('done')});
|
|
347
|
+
PHS.forEach((p,j)=>{p.classList.remove('act');
|
|
348
|
+
if(S[i].ph==='d'&&j===0)p.classList.add('act');
|
|
349
|
+
if(S[i].ph==='t'&&j===1)p.classList.add('act');
|
|
350
|
+
if(S[i].ph==='o'&&j===2)p.classList.add('act');
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function tp(){
|
|
355
|
+
if(playing){playing=false;clearTimeout(timer);
|
|
356
|
+
document.getElementById('Mbtn').classList.remove('on');
|
|
357
|
+
document.getElementById('Mi').innerHTML='▶';document.getElementById('Mt').textContent='播放';
|
|
358
|
+
}else{playing=true;if(cur>=9)cur=-1;
|
|
359
|
+
document.getElementById('Mbtn').classList.add('on');
|
|
360
|
+
document.getElementById('Mi').innerHTML='▮▮';document.getElementById('Mt').textContent='停止';
|
|
361
|
+
nx();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
function nx(){if(!playing)return;cur++;if(cur>9){cur=0;tlEl.querySelectorAll('.Tl-i').forEach(e=>e.classList.remove('done'))}go(cur);timer=setTimeout(nx,spd)}
|
|
365
|
+
function cs(){spd=parseInt(document.getElementById('Ms').value);if(playing){clearTimeout(timer);timer=setTimeout(nx,spd)}}
|
|
366
|
+
|
|
367
|
+
build();go(0);
|
|
368
|
+
</script>
|
|
369
|
+
</body>
|
|
370
|
+
</html>
|