@tea-agent/loop-agent 0.33.6 → 0.34.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/CHANGELOG.md +21 -0
- package/dist/worker/console/chat/model-resolver.js +17 -0
- package/dist/worker/console/chat/pi-runtime.js +397 -132
- package/dist/worker/console/chat/routes.js +185 -25
- package/dist/worker/console/chat/session-store.js +39 -0
- package/dist/worker/console/static/assets/index-BQkhJpV8.css +1 -0
- package/dist/worker/console/static/assets/index-CMHovlqG.js +32 -0
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/operator-chat/landing-density.js +23 -0
- package/dist/worker/console/static-src/operator-chat/session-title-watcher.js +128 -0
- package/dist/worker/console/static-src/operator-chat/sidebar-split.js +90 -0
- package/dist/worker/console/static-src/operator-chat/spatial-overlay.js +37 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +109 -22
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +6 -1
- package/dist/worker/console/static-src/operator-chat/useOverlayFocus.js +84 -0
- package/dist/worker/console/static-src/operator-chat/useWorkspaceLayout.js +58 -0
- package/dist/worker/console/static-src/operator-chat/workspace-layout-mode.js +31 -0
- package/harness.json +1 -1
- package/package.json +1 -1
- package/skills/local-jacoco-coverage/SKILL.md +281 -0
- package/skills/local-jacoco-coverage/references/requirement-to-source-mapping.md +85 -0
- package/skills/local-jacoco-coverage/references/runtime-alignment.md +106 -0
- package/skills/local-jacoco-coverage/scripts/run-coverage-analysis.sh +148 -0
- package/skills/local-jacoco-coverage/scripts/start-jacoco-agent.sh +110 -0
- package/dist/worker/console/static/assets/index-BUOLppPr.js +0 -28
- package/dist/worker/console/static/assets/index-C1KzazY5.css +0 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# run-coverage-analysis.sh
|
|
3
|
+
# 端到端串联 Step 3:读取 requirement-source-mapping.json,对每个需求调一次
|
|
4
|
+
# `loop-agent coverage report`,把 Markdown 切片落到 --output-dir,并生成 index.md 汇总。
|
|
5
|
+
#
|
|
6
|
+
# 本脚本只调 CLI + 聚合文件,不自己解析 jacoco.xml、不算覆盖率数字。
|
|
7
|
+
# 需求:loop-agent 已安装并可在 PATH 中执行(或通过 --loop-agent 指定)。
|
|
8
|
+
#
|
|
9
|
+
# 用法:
|
|
10
|
+
# bash run-coverage-analysis.sh \
|
|
11
|
+
# --jacoco-xml <run-dir>/reports/jacoco.xml \
|
|
12
|
+
# --mapping docs/test-reports/coverage/requirement-source-mapping.json \
|
|
13
|
+
# --output-dir docs/test-reports/coverage \
|
|
14
|
+
# [--loop-agent <path>] [--language java]
|
|
15
|
+
#
|
|
16
|
+
# 退出码:
|
|
17
|
+
# 0 全部需求切片成功(含 unavailable 标注)
|
|
18
|
+
# 2 参数错误
|
|
19
|
+
# 3 --jacoco-xml 不存在或为空
|
|
20
|
+
# 4 --mapping 不存在或不是合法 JSON
|
|
21
|
+
# 5 mapping 里 requirements 为空
|
|
22
|
+
# * 继承最后一个 coverage report 的非零退出码
|
|
23
|
+
|
|
24
|
+
set -euo pipefail
|
|
25
|
+
|
|
26
|
+
log() { printf '[run-coverage-analysis] %s\n' "$*" >&2; }
|
|
27
|
+
die() { printf '[run-coverage-analysis] ERROR: %s\n' "$*" >&2; exit "${2:-1}"; }
|
|
28
|
+
|
|
29
|
+
JACOCO_XML=""
|
|
30
|
+
MAPPING=""
|
|
31
|
+
OUTPUT_DIR=""
|
|
32
|
+
LOOP_AGENT="${LOOP_AGENT:-loop-agent}"
|
|
33
|
+
LANGUAGE="java"
|
|
34
|
+
|
|
35
|
+
args=("$@")
|
|
36
|
+
for ((i = 0; i < ${#args[@]}; i++)); do
|
|
37
|
+
case "${args[$i]}" in
|
|
38
|
+
--jacoco-xml)
|
|
39
|
+
((i + 1 < ${#args[@]})) || die "--jacoco-xml 需要一个值" 2
|
|
40
|
+
JACOCO_XML="${args[$((i + 1))]}"; ((i++))
|
|
41
|
+
;;
|
|
42
|
+
--mapping)
|
|
43
|
+
((i + 1 < ${#args[@]})) || die "--mapping 需要一个值" 2
|
|
44
|
+
MAPPING="${args[$((i + 1))]}"; ((i++))
|
|
45
|
+
;;
|
|
46
|
+
--output-dir)
|
|
47
|
+
((i + 1 < ${#args[@]})) || die "--output-dir 需要一个值" 2
|
|
48
|
+
OUTPUT_DIR="${args[$((i + 1))]}"; ((i++))
|
|
49
|
+
;;
|
|
50
|
+
--loop-agent)
|
|
51
|
+
((i + 1 < ${#args[@]})) || die "--loop-agent 需要一个值" 2
|
|
52
|
+
LOOP_AGENT="${args[$((i + 1))]}"; ((i++))
|
|
53
|
+
;;
|
|
54
|
+
--language)
|
|
55
|
+
((i + 1 < ${#args[@]})) || die "--language 需要一个值" 2
|
|
56
|
+
LANGUAGE="${args[$((i + 1))]}"; ((i++))
|
|
57
|
+
;;
|
|
58
|
+
--help|-h)
|
|
59
|
+
sed -n '2,30p' "$0"
|
|
60
|
+
exit 0
|
|
61
|
+
;;
|
|
62
|
+
*)
|
|
63
|
+
die "未知参数: ${args[$i]}" 2
|
|
64
|
+
;;
|
|
65
|
+
esac
|
|
66
|
+
done
|
|
67
|
+
|
|
68
|
+
[[ -n "$JACOCO_XML" ]] || die "缺少必填 --jacoco-xml <path>" 2
|
|
69
|
+
[[ -s "$JACOCO_XML" ]] || die "--jacoco-xml 不存在或为空: $JACOCO_XML" 3
|
|
70
|
+
[[ -n "$MAPPING" ]] || die "缺少必填 --mapping <path>" 2
|
|
71
|
+
[[ -f "$MAPPING" ]] || die "--mapping 不存在: $MAPPING" 4
|
|
72
|
+
[[ -n "$OUTPUT_DIR" ]] || die "缺少必填 --output-dir <path>" 2
|
|
73
|
+
|
|
74
|
+
command -v jq >/dev/null 2>&1 || die "需要 jq 来解析 mapping 文件" 2
|
|
75
|
+
command -v "$LOOP_AGENT" >/dev/null 2>&1 || die "找不到 loop-agent 可执行文件(可用 --loop-agent 指定): $LOOP_AGENT" 2
|
|
76
|
+
|
|
77
|
+
mkdir -p "$OUTPUT_DIR"
|
|
78
|
+
|
|
79
|
+
# 校验 mapping 结构
|
|
80
|
+
req_count=$(jq '.requirements | length' "$MAPPING")
|
|
81
|
+
[[ "$req_count" -gt 0 ]] || die "mapping 里 requirements 为空" 5
|
|
82
|
+
|
|
83
|
+
log "jacoco xml : $JACOCO_XML"
|
|
84
|
+
log "mapping : $MAPPING"
|
|
85
|
+
log "output dir : $OUTPUT_DIR"
|
|
86
|
+
log "loop-agent : $LOOP_AGENT"
|
|
87
|
+
log "requirements: $req_count"
|
|
88
|
+
log ""
|
|
89
|
+
|
|
90
|
+
INDEX="$OUTPUT_DIR/index.md"
|
|
91
|
+
{
|
|
92
|
+
printf '%s\n\n' '# 需求覆盖率切片汇总'
|
|
93
|
+
printf '%s\n' "- 输入: \`$JACOCO_XML\`"
|
|
94
|
+
printf '%s\n' "- mapping: \`$MAPPING\`"
|
|
95
|
+
printf '%s\n' "- 生成时间: $(date -u '+%Y-%m-%dT%H:%M:%SZ')"
|
|
96
|
+
printf '%s\n' ''
|
|
97
|
+
printf '%s\n' '| 需求 ID | source files | line | branch | function | 状态 | 切片文件 |'
|
|
98
|
+
printf '%s\n' '| --- | ---: | ---: | ---: | ---: | --- | --- |'
|
|
99
|
+
} > "$INDEX"
|
|
100
|
+
|
|
101
|
+
last_exit=0
|
|
102
|
+
for ((i = 0; i < req_count; i++)); do
|
|
103
|
+
ids_json=$(jq -c ".requirements[$i].ids" "$MAPPING")
|
|
104
|
+
scope_json=$(jq -c ".requirements[$i].sourceScope" "$MAPPING")
|
|
105
|
+
|
|
106
|
+
# 拼 CLI 参数
|
|
107
|
+
req_args=()
|
|
108
|
+
while IFS= read -r id; do
|
|
109
|
+
[[ -n "$id" ]] && req_args+=(--requirement-id "$id")
|
|
110
|
+
done < <(jq -r '.[]' <<<"$ids_json")
|
|
111
|
+
|
|
112
|
+
scope_csv=$(jq -r '. | map(.) | join(",")' <<<"$scope_json")
|
|
113
|
+
scope_n=$(jq -r 'length' <<<"$scope_json")
|
|
114
|
+
first_id=$(jq -r '.[0]' <<<"$ids_json")
|
|
115
|
+
|
|
116
|
+
out_file="$OUTPUT_DIR/${first_id}.md"
|
|
117
|
+
log "[$((i + 1))/$req_count] $first_id (source files: $scope_n)"
|
|
118
|
+
|
|
119
|
+
# 调 runtime 归一化器
|
|
120
|
+
if "$LOOP_AGENT" coverage report \
|
|
121
|
+
--language "$LANGUAGE" \
|
|
122
|
+
--input "$JACOCO_XML" \
|
|
123
|
+
"${req_args[@]}" \
|
|
124
|
+
--source-scope "$scope_csv" \
|
|
125
|
+
--markdown \
|
|
126
|
+
--output "$out_file"; then
|
|
127
|
+
|
|
128
|
+
# 从产出的 markdown 里抓 line/branch/function 覆盖率(容错:抓不到就标 unavailable)
|
|
129
|
+
line_pct=$(grep -iE '^\- *line' "$out_file" | grep -oE '[0-9]+(\.[0-9]+)?%' | head -1 || true)
|
|
130
|
+
branch_pct=$(grep -iE '^\- *branch' "$out_file" | grep -oE '[0-9]+(\.[0-9]+)?%' | head -1 || true)
|
|
131
|
+
func_pct=$(grep -iE '^\- *function' "$out_file" | grep -oE '[0-9]+(\.[0-9]+)?%' | head -1 || true)
|
|
132
|
+
status="COVERED"
|
|
133
|
+
[[ -z "$line_pct" && -z "$branch_pct" ]] && status="unavailable/PARTIAL"
|
|
134
|
+
|
|
135
|
+
printf '| %s | %d | %s | %s | %s | %s | [%s](%s) |\n' \
|
|
136
|
+
"$first_id" "$scope_n" \
|
|
137
|
+
"${line_pct:-unavailable}" "${branch_pct:-unavailable}" "${func_pct:-unavailable}" \
|
|
138
|
+
"$status" "$first_id.md" "$first_id" >> "$INDEX"
|
|
139
|
+
else
|
|
140
|
+
last_exit=$?
|
|
141
|
+
log "[$((i + 1))/$req_count] $first_id coverage report 失败 (exit $last_exit)"
|
|
142
|
+
printf '| %s | %d | - | - | - | ERROR(exit %d) | - |\n' "$first_id" "$scope_n" "$last_exit" >> "$INDEX"
|
|
143
|
+
fi
|
|
144
|
+
done
|
|
145
|
+
|
|
146
|
+
log ""
|
|
147
|
+
log "汇总已写入: $INDEX"
|
|
148
|
+
exit "$last_exit"
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# start-jacoco-agent.sh
|
|
3
|
+
# 在本地/测试环境启动 Java 后端服务并挂载 JaCoCo agent(tcpserver 模式)。
|
|
4
|
+
# 本脚本只做三件事:校验 --agent-jar 存在、拼装 -javaagent 参数、把 -- 之后的原始启动命令交给 exec。
|
|
5
|
+
# 它不修改启动命令的语义,只前置 agent 参数。
|
|
6
|
+
#
|
|
7
|
+
# 用法:
|
|
8
|
+
# bash start-jacoco-agent.sh --agent-jar <path> [--includes <pkg>] [--port <n>]
|
|
9
|
+
# [--address <ip>] [--append <bool>] -- <启动命令...>
|
|
10
|
+
# 示例:
|
|
11
|
+
# bash start-jacoco-agent.sh --agent-jar /opt/jacoco/jacocoagent.jar \
|
|
12
|
+
# --includes "com.yourcompany.*" --port 6300 -- mvn spring-boot:run
|
|
13
|
+
# bash start-jacoco-agent.sh --agent-jar /opt/jacoco/jacocoagent.jar \
|
|
14
|
+
# --includes "com.yourcompany.*" -- java -jar your-app.jar
|
|
15
|
+
#
|
|
16
|
+
# 退出码:
|
|
17
|
+
# 0 服务正常退出
|
|
18
|
+
# 2 参数错误
|
|
19
|
+
# 3 --agent-jar 不存在
|
|
20
|
+
# 4 未提供 -- 之后的启动命令
|
|
21
|
+
# * 继承被启动命令的退出码
|
|
22
|
+
|
|
23
|
+
set -euo pipefail
|
|
24
|
+
|
|
25
|
+
log() { printf '[start-jacoco-agent] %s\n' "$*" >&2; }
|
|
26
|
+
die() { printf '[start-jacoco-agent] ERROR: %s\n' "$*" >&2; exit "${2:-1}"; }
|
|
27
|
+
|
|
28
|
+
AGENT_JAR=""
|
|
29
|
+
INCLUDES="*"
|
|
30
|
+
PORT="6300"
|
|
31
|
+
ADDRESS="0.0.0.0"
|
|
32
|
+
APPEND="false"
|
|
33
|
+
SEPARATOR_IDX=-1
|
|
34
|
+
|
|
35
|
+
args=("$@")
|
|
36
|
+
for ((i = 0; i < ${#args[@]}; i++)); do
|
|
37
|
+
case "${args[$i]}" in
|
|
38
|
+
--agent-jar)
|
|
39
|
+
((i + 1 < ${#args[@]})) || die "--agent-jar 需要一个值" 2
|
|
40
|
+
AGENT_JAR="${args[$((i + 1))]}"
|
|
41
|
+
((i++))
|
|
42
|
+
;;
|
|
43
|
+
--includes)
|
|
44
|
+
((i + 1 < ${#args[@]})) || die "--includes 需要一个值" 2
|
|
45
|
+
INCLUDES="${args[$((i + 1))]}"
|
|
46
|
+
((i++))
|
|
47
|
+
;;
|
|
48
|
+
--port)
|
|
49
|
+
((i + 1 < ${#args[@]})) || die "--port 需要一个值" 2
|
|
50
|
+
PORT="${args[$((i + 1))]}"
|
|
51
|
+
((i++))
|
|
52
|
+
;;
|
|
53
|
+
--address)
|
|
54
|
+
((i + 1 < ${#args[@]})) || die "--address 需要一个值" 2
|
|
55
|
+
ADDRESS="${args[$((i + 1))]}"
|
|
56
|
+
((i++))
|
|
57
|
+
;;
|
|
58
|
+
--append)
|
|
59
|
+
((i + 1 < ${#args[@]})) || die "--append 需要一个值" 2
|
|
60
|
+
APPEND="${args[$((i + 1))]}"
|
|
61
|
+
((i++))
|
|
62
|
+
;;
|
|
63
|
+
--)
|
|
64
|
+
SEPARATOR_IDX=$((i + 1))
|
|
65
|
+
break
|
|
66
|
+
;;
|
|
67
|
+
--help|-h)
|
|
68
|
+
sed -n '2,30p' "$0"
|
|
69
|
+
exit 0
|
|
70
|
+
;;
|
|
71
|
+
*)
|
|
72
|
+
die "未知参数: ${args[$i]}(启动命令请放在 -- 之后)" 2
|
|
73
|
+
;;
|
|
74
|
+
esac
|
|
75
|
+
done
|
|
76
|
+
|
|
77
|
+
[[ -n "$AGENT_JAR" ]] || die "缺少必填 --agent-jar <path>" 2
|
|
78
|
+
[[ -f "$AGENT_JAR" ]] || die "--agent-jar 不存在: $AGENT_JAR" 3
|
|
79
|
+
[[ "$SEPARATOR_IDX" -ge 0 && "$SEPARATOR_IDX" -lt ${#args[@]} ]] || die "未提供 -- 之后的启动命令" 4
|
|
80
|
+
|
|
81
|
+
# 拼装 -javaagent 参数(JaCoCo tcpserver 模式)
|
|
82
|
+
AGENT_OPTS="output=tcpserver,address=${ADDRESS},port=${PORT},includes=${INCLUDES},append=${APPEND}"
|
|
83
|
+
JAVA_AGENT="-javaagent:${AGENT_JAR}=${AGENT_OPTS}"
|
|
84
|
+
|
|
85
|
+
# 取出 -- 之后的启动命令
|
|
86
|
+
launch=("${args[@]:$SEPARATOR_IDX}")
|
|
87
|
+
[[ ${#launch[@]} -gt 0 ]] || die "-- 之后没有启动命令" 4
|
|
88
|
+
|
|
89
|
+
log "agent jar : $AGENT_JAR"
|
|
90
|
+
log "agent options : $AGENT_OPTS"
|
|
91
|
+
log "launch command: ${launch[*]}"
|
|
92
|
+
log ""
|
|
93
|
+
log "⚠️ JaCoCo agent 仅限测试环境;生产环境严禁挂载。"
|
|
94
|
+
log "⚠️ address=$ADDRESS 意味着任何能访问 $PORT 的机器都能 dump,请用安全组限制。"
|
|
95
|
+
log ""
|
|
96
|
+
|
|
97
|
+
# 若启动命令是 java*,直接前置 -javaagent;
|
|
98
|
+
# 若是 mvn*,转成 -Dspring-boot.run.jvmArguments(Spring Boot Maven 插件约定);
|
|
99
|
+
# 其它命令:前置 JAVA_TOOL_OPTIONS(最通用,但无法覆盖命令里已有的 -javaagent)。
|
|
100
|
+
case "${launch[0]}" in
|
|
101
|
+
java)
|
|
102
|
+
exec "${launch[0]}" "$JAVA_AGENT" "${launch[@]:1}"
|
|
103
|
+
;;
|
|
104
|
+
mvn)
|
|
105
|
+
exec "${launch[0]}" "${launch[@]:1}" "-Dspring-boot.run.jvmArguments=$JAVA_AGENT"
|
|
106
|
+
;;
|
|
107
|
+
*)
|
|
108
|
+
JAVA_TOOL_OPTIONS="$JAVA_AGENT" exec "${launch[@]}"
|
|
109
|
+
;;
|
|
110
|
+
esac
|