@tea-agent/loop-agent 0.3.0 → 0.4.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 +135 -133
- package/CHANGELOG.md +88 -63
- package/README.md +171 -168
- package/bin/agent-worker.js +22 -0
- package/bin/loop-agent.js +21 -21
- package/dist/commands/init.js +457 -457
- 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/dag-pi-executor.js +8 -1
- package/dist/task/runtime.js +27 -27
- package/dist/worker/cli.js +119 -0
- package/dist/worker/loop-agent/command-result.js +1 -0
- package/dist/worker/loop-agent/loop-agent-client.js +105 -0
- package/dist/worker/loop-agent/parse-json.js +14 -0
- package/dist/worker/materialize/harness-task-materializer.js +157 -0
- package/dist/worker/pool/failure-routing.js +98 -0
- package/dist/worker/pool/run-store.js +117 -0
- package/dist/worker/pool/types.js +1 -0
- package/dist/worker/preflight.js +108 -0
- package/dist/worker/profile-mapping.js +76 -0
- package/dist/worker/progress-reporter.js +81 -0
- package/dist/worker/report/morning-report.js +69 -0
- package/dist/worker/repos/repo-resolver.js +23 -0
- package/dist/worker/run-task/run-task.js +359 -0
- package/dist/worker/runner/run-ready.js +216 -0
- package/dist/worker/task-graph/acceptance-schema.js +25 -0
- package/dist/worker/task-graph/ready-queue.js +23 -0
- package/dist/worker/task-graph/task-graph-schema.js +28 -0
- package/dist/worker/task-graph/types.js +1 -0
- package/dist/worker/task-graph/validate.js +188 -0
- package/dist/worker/task-spec/complexity-mapping.js +8 -0
- package/dist/worker/task-spec/schema.js +116 -0
- package/dist/worker/task-spec/types.js +1 -0
- package/dist/worker/task-spec/validate.js +352 -0
- package/dist/workflows/dag/canvas-observer.js +275 -275
- package/docs/README.md +65 -61
- package/docs/agent-dag-recovery-playbook.md +184 -184
- package/docs/agent-dag-runner.md +42 -42
- package/docs/architecture/runtime-boundaries.md +147 -147
- package/docs/cursor-executor-usage.md +25 -25
- package/docs/decisions/README.md +3 -3
- package/docs/design/README.md +36 -36
- package/docs/development-principles.md +73 -71
- 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 +7 -7
- package/docs/exec-plans/completed/README.md +19 -11
- package/docs/feature-workflow.md +186 -186
- 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/loop-agent-harness.md +42 -42
- package/docs/production-readiness.md +96 -96
- package/docs/progress/README.md +3 -3
- package/docs/reports/README.md +5 -5
- package/docs/skills/README.md +6 -6
- package/docs/skills/vetted-skill-registry.md +22 -22
- 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/hybrid-dag.json +193 -193
- 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/verification-matrix.md +41 -41
- 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 +89 -89
- package/package.json +60 -58
- 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/loop-agent/SKILL.md +147 -145
- package/skills/loop-agent/references/README.md +67 -67
- package/skills/loop-agent/references/command-reference.md +368 -340
- package/skills/loop-agent/references/harness-policy.md +259 -258
- 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 +84 -84
- package/skills/loop-agent/references/verification-and-failure-handling.md +128 -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
package/dist/commands/init.js
CHANGED
|
@@ -90,474 +90,474 @@ const COMPAT_PROMPTS = {
|
|
|
90
90
|
].join("\n"),
|
|
91
91
|
};
|
|
92
92
|
const GOVERNANCE_ROOT_TOKEN = "__LOOP_AGENT_GOVERNANCE_ROOT__";
|
|
93
|
-
const INIT_CHECK_ENGINEERING_STRUCTURE_SH = `#!/usr/bin/env bash
|
|
94
|
-
set -euo pipefail
|
|
95
|
-
|
|
96
|
-
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
97
|
-
cd "\${ROOT_DIR}"
|
|
98
|
-
|
|
99
|
-
required_paths=(
|
|
100
|
-
"README.md"
|
|
101
|
-
"harness.json"
|
|
102
|
-
"AGENTS.md"
|
|
103
|
-
"${GOVERNANCE_ROOT_TOKEN}/README.md"
|
|
104
|
-
"${GOVERNANCE_ROOT_TOKEN}/development-principles.md"
|
|
105
|
-
"${GOVERNANCE_ROOT_TOKEN}/feature-workflow.md"
|
|
106
|
-
"${GOVERNANCE_ROOT_TOKEN}/verification-matrix.md"
|
|
107
|
-
"${GOVERNANCE_ROOT_TOKEN}/architecture/runtime-boundaries.md"
|
|
108
|
-
"${GOVERNANCE_ROOT_TOKEN}/templates"
|
|
109
|
-
"skills/loop-agent/SKILL.md"
|
|
110
|
-
".harness/prompts/analyze.md"
|
|
111
|
-
".harness/prompts/plan.md"
|
|
112
|
-
".harness/tasks"
|
|
113
|
-
".harness/dag-runs/active"
|
|
114
|
-
".harness/dag-runs/completed"
|
|
115
|
-
".harness/dag-runs/paused"
|
|
116
|
-
".harness/runs/active"
|
|
117
|
-
".harness/runs/completed"
|
|
118
|
-
".harness/runs/failed"
|
|
119
|
-
"scripts/check-engineering-structure.sh"
|
|
120
|
-
"scripts/check-doc-index.sh"
|
|
121
|
-
"scripts/check-doc-links.sh"
|
|
122
|
-
"scripts/check-active-plan-status.sh"
|
|
123
|
-
"scripts/check-exec-plan-index-sync.sh"
|
|
124
|
-
"scripts/check-harness-runtime-clean.sh"
|
|
125
|
-
"scripts/check-architecture-boundaries.sh"
|
|
126
|
-
"scripts/check-skill-entry.sh"
|
|
127
|
-
"scripts/check-repo.sh"
|
|
128
|
-
"scripts/ci-governance.sh"
|
|
129
|
-
"scripts/ci-tests.sh"
|
|
130
|
-
"scripts/ci.sh"
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
missing=()
|
|
134
|
-
for item in "\${required_paths[@]}"; do
|
|
135
|
-
if [[ ! -e "\${item}" ]]; then
|
|
136
|
-
missing+=("\${item}")
|
|
137
|
-
fi
|
|
138
|
-
done
|
|
139
|
-
|
|
140
|
-
if (( \${#missing[@]} > 0 )); then
|
|
141
|
-
echo "loop-agent 初始化检查失败,缺少必要路径:"
|
|
142
|
-
for item in "\${missing[@]}"; do
|
|
143
|
-
echo " - \${item}"
|
|
144
|
-
done
|
|
145
|
-
exit 1
|
|
146
|
-
fi
|
|
147
|
-
|
|
148
|
-
echo "loop-agent 工程结构检查通过"
|
|
93
|
+
const INIT_CHECK_ENGINEERING_STRUCTURE_SH = `#!/usr/bin/env bash
|
|
94
|
+
set -euo pipefail
|
|
95
|
+
|
|
96
|
+
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
97
|
+
cd "\${ROOT_DIR}"
|
|
98
|
+
|
|
99
|
+
required_paths=(
|
|
100
|
+
"README.md"
|
|
101
|
+
"harness.json"
|
|
102
|
+
"AGENTS.md"
|
|
103
|
+
"${GOVERNANCE_ROOT_TOKEN}/README.md"
|
|
104
|
+
"${GOVERNANCE_ROOT_TOKEN}/development-principles.md"
|
|
105
|
+
"${GOVERNANCE_ROOT_TOKEN}/feature-workflow.md"
|
|
106
|
+
"${GOVERNANCE_ROOT_TOKEN}/verification-matrix.md"
|
|
107
|
+
"${GOVERNANCE_ROOT_TOKEN}/architecture/runtime-boundaries.md"
|
|
108
|
+
"${GOVERNANCE_ROOT_TOKEN}/templates"
|
|
109
|
+
"skills/loop-agent/SKILL.md"
|
|
110
|
+
".harness/prompts/analyze.md"
|
|
111
|
+
".harness/prompts/plan.md"
|
|
112
|
+
".harness/tasks"
|
|
113
|
+
".harness/dag-runs/active"
|
|
114
|
+
".harness/dag-runs/completed"
|
|
115
|
+
".harness/dag-runs/paused"
|
|
116
|
+
".harness/runs/active"
|
|
117
|
+
".harness/runs/completed"
|
|
118
|
+
".harness/runs/failed"
|
|
119
|
+
"scripts/check-engineering-structure.sh"
|
|
120
|
+
"scripts/check-doc-index.sh"
|
|
121
|
+
"scripts/check-doc-links.sh"
|
|
122
|
+
"scripts/check-active-plan-status.sh"
|
|
123
|
+
"scripts/check-exec-plan-index-sync.sh"
|
|
124
|
+
"scripts/check-harness-runtime-clean.sh"
|
|
125
|
+
"scripts/check-architecture-boundaries.sh"
|
|
126
|
+
"scripts/check-skill-entry.sh"
|
|
127
|
+
"scripts/check-repo.sh"
|
|
128
|
+
"scripts/ci-governance.sh"
|
|
129
|
+
"scripts/ci-tests.sh"
|
|
130
|
+
"scripts/ci.sh"
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
missing=()
|
|
134
|
+
for item in "\${required_paths[@]}"; do
|
|
135
|
+
if [[ ! -e "\${item}" ]]; then
|
|
136
|
+
missing+=("\${item}")
|
|
137
|
+
fi
|
|
138
|
+
done
|
|
139
|
+
|
|
140
|
+
if (( \${#missing[@]} > 0 )); then
|
|
141
|
+
echo "loop-agent 初始化检查失败,缺少必要路径:"
|
|
142
|
+
for item in "\${missing[@]}"; do
|
|
143
|
+
echo " - \${item}"
|
|
144
|
+
done
|
|
145
|
+
exit 1
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
echo "loop-agent 工程结构检查通过"
|
|
149
149
|
`;
|
|
150
|
-
const INIT_CHECK_DOC_INDEX_SH = `#!/usr/bin/env bash
|
|
151
|
-
set -euo pipefail
|
|
152
|
-
|
|
153
|
-
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
154
|
-
cd "\${ROOT_DIR}"
|
|
155
|
-
|
|
156
|
-
required_docs=(
|
|
157
|
-
"${GOVERNANCE_ROOT_TOKEN}/README.md"
|
|
158
|
-
"${GOVERNANCE_ROOT_TOKEN}/development-principles.md"
|
|
159
|
-
"${GOVERNANCE_ROOT_TOKEN}/feature-workflow.md"
|
|
160
|
-
"${GOVERNANCE_ROOT_TOKEN}/verification-matrix.md"
|
|
161
|
-
"${GOVERNANCE_ROOT_TOKEN}/architecture/runtime-boundaries.md"
|
|
162
|
-
"${GOVERNANCE_ROOT_TOKEN}/loop-agent-harness.md"
|
|
163
|
-
"${GOVERNANCE_ROOT_TOKEN}/harness-methodology-tdd.md"
|
|
164
|
-
"${GOVERNANCE_ROOT_TOKEN}/harness-methodology-verification.md"
|
|
165
|
-
"${GOVERNANCE_ROOT_TOKEN}/harness-methodology-debugging.md"
|
|
166
|
-
"${GOVERNANCE_ROOT_TOKEN}/templates"
|
|
167
|
-
"${GOVERNANCE_ROOT_TOKEN}/exec-plans/active/README.md"
|
|
168
|
-
"${GOVERNANCE_ROOT_TOKEN}/exec-plans/completed/README.md"
|
|
169
|
-
"${GOVERNANCE_ROOT_TOKEN}/progress/README.md"
|
|
170
|
-
"${GOVERNANCE_ROOT_TOKEN}/reports/README.md"
|
|
171
|
-
"${GOVERNANCE_ROOT_TOKEN}/decisions/README.md"
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
missing=()
|
|
175
|
-
for item in "\${required_docs[@]}"; do
|
|
176
|
-
if [[ ! -e "\${item}" ]]; then
|
|
177
|
-
missing+=("\${item}")
|
|
178
|
-
fi
|
|
179
|
-
done
|
|
180
|
-
|
|
181
|
-
if (( \${#missing[@]} > 0 )); then
|
|
182
|
-
echo "docs 索引检查失败,缺少必要文档或目录:" >&2
|
|
183
|
-
for item in "\${missing[@]}"; do
|
|
184
|
-
echo " - \${item}" >&2
|
|
185
|
-
done
|
|
186
|
-
exit 1
|
|
187
|
-
fi
|
|
188
|
-
|
|
189
|
-
echo "docs 索引检查通过"
|
|
150
|
+
const INIT_CHECK_DOC_INDEX_SH = `#!/usr/bin/env bash
|
|
151
|
+
set -euo pipefail
|
|
152
|
+
|
|
153
|
+
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
154
|
+
cd "\${ROOT_DIR}"
|
|
155
|
+
|
|
156
|
+
required_docs=(
|
|
157
|
+
"${GOVERNANCE_ROOT_TOKEN}/README.md"
|
|
158
|
+
"${GOVERNANCE_ROOT_TOKEN}/development-principles.md"
|
|
159
|
+
"${GOVERNANCE_ROOT_TOKEN}/feature-workflow.md"
|
|
160
|
+
"${GOVERNANCE_ROOT_TOKEN}/verification-matrix.md"
|
|
161
|
+
"${GOVERNANCE_ROOT_TOKEN}/architecture/runtime-boundaries.md"
|
|
162
|
+
"${GOVERNANCE_ROOT_TOKEN}/loop-agent-harness.md"
|
|
163
|
+
"${GOVERNANCE_ROOT_TOKEN}/harness-methodology-tdd.md"
|
|
164
|
+
"${GOVERNANCE_ROOT_TOKEN}/harness-methodology-verification.md"
|
|
165
|
+
"${GOVERNANCE_ROOT_TOKEN}/harness-methodology-debugging.md"
|
|
166
|
+
"${GOVERNANCE_ROOT_TOKEN}/templates"
|
|
167
|
+
"${GOVERNANCE_ROOT_TOKEN}/exec-plans/active/README.md"
|
|
168
|
+
"${GOVERNANCE_ROOT_TOKEN}/exec-plans/completed/README.md"
|
|
169
|
+
"${GOVERNANCE_ROOT_TOKEN}/progress/README.md"
|
|
170
|
+
"${GOVERNANCE_ROOT_TOKEN}/reports/README.md"
|
|
171
|
+
"${GOVERNANCE_ROOT_TOKEN}/decisions/README.md"
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
missing=()
|
|
175
|
+
for item in "\${required_docs[@]}"; do
|
|
176
|
+
if [[ ! -e "\${item}" ]]; then
|
|
177
|
+
missing+=("\${item}")
|
|
178
|
+
fi
|
|
179
|
+
done
|
|
180
|
+
|
|
181
|
+
if (( \${#missing[@]} > 0 )); then
|
|
182
|
+
echo "docs 索引检查失败,缺少必要文档或目录:" >&2
|
|
183
|
+
for item in "\${missing[@]}"; do
|
|
184
|
+
echo " - \${item}" >&2
|
|
185
|
+
done
|
|
186
|
+
exit 1
|
|
187
|
+
fi
|
|
188
|
+
|
|
189
|
+
echo "docs 索引检查通过"
|
|
190
190
|
`;
|
|
191
|
-
const INIT_CHECK_DOC_LINKS_SH = `#!/usr/bin/env bash
|
|
192
|
-
set -euo pipefail
|
|
193
|
-
|
|
194
|
-
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
195
|
-
cd "\${ROOT_DIR}"
|
|
196
|
-
|
|
197
|
-
if [[ ! -d "${GOVERNANCE_ROOT_TOKEN}" ]]; then
|
|
198
|
-
echo "docs 链接检查失败:缺少 ${GOVERNANCE_ROOT_TOKEN}/" >&2
|
|
199
|
-
exit 1
|
|
200
|
-
fi
|
|
201
|
-
|
|
202
|
-
missing=()
|
|
203
|
-
while IFS= read -r -d '' file; do
|
|
204
|
-
while IFS= read -r link; do
|
|
205
|
-
[[ -z "\${link}" ]] && continue
|
|
206
|
-
[[ "\${link}" == http://* || "\${link}" == https://* || "\${link}" == mailto:* || "\${link}" == "#"* ]] && continue
|
|
207
|
-
[[ "\${link}" == *"://"* ]] && continue
|
|
208
|
-
target="\${link%%#*}"
|
|
209
|
-
[[ -z "\${target}" ]] && continue
|
|
210
|
-
[[ "\${target}" == /* ]] && continue
|
|
211
|
-
base="$(dirname "\${file}")"
|
|
212
|
-
if [[ ! -e "\${base}/\${target}" ]]; then
|
|
213
|
-
missing+=("\${file}: \${link}")
|
|
214
|
-
fi
|
|
215
|
-
done < <(grep -Eo '\\[[^]]+\\]\\([^)]+\\)' "\${file}" | sed -E 's/^.*\\(([^)]+)\\)$/\\1/' || true)
|
|
216
|
-
done < <(find "${GOVERNANCE_ROOT_TOKEN}" -type f -name '*.md' -print0)
|
|
217
|
-
|
|
218
|
-
if (( \${#missing[@]} > 0 )); then
|
|
219
|
-
echo "docs 链接检查失败:" >&2
|
|
220
|
-
for item in "\${missing[@]}"; do
|
|
221
|
-
echo " - \${item}" >&2
|
|
222
|
-
done
|
|
223
|
-
exit 1
|
|
224
|
-
fi
|
|
225
|
-
|
|
226
|
-
echo "docs 链接检查通过"
|
|
191
|
+
const INIT_CHECK_DOC_LINKS_SH = `#!/usr/bin/env bash
|
|
192
|
+
set -euo pipefail
|
|
193
|
+
|
|
194
|
+
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
195
|
+
cd "\${ROOT_DIR}"
|
|
196
|
+
|
|
197
|
+
if [[ ! -d "${GOVERNANCE_ROOT_TOKEN}" ]]; then
|
|
198
|
+
echo "docs 链接检查失败:缺少 ${GOVERNANCE_ROOT_TOKEN}/" >&2
|
|
199
|
+
exit 1
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
missing=()
|
|
203
|
+
while IFS= read -r -d '' file; do
|
|
204
|
+
while IFS= read -r link; do
|
|
205
|
+
[[ -z "\${link}" ]] && continue
|
|
206
|
+
[[ "\${link}" == http://* || "\${link}" == https://* || "\${link}" == mailto:* || "\${link}" == "#"* ]] && continue
|
|
207
|
+
[[ "\${link}" == *"://"* ]] && continue
|
|
208
|
+
target="\${link%%#*}"
|
|
209
|
+
[[ -z "\${target}" ]] && continue
|
|
210
|
+
[[ "\${target}" == /* ]] && continue
|
|
211
|
+
base="$(dirname "\${file}")"
|
|
212
|
+
if [[ ! -e "\${base}/\${target}" ]]; then
|
|
213
|
+
missing+=("\${file}: \${link}")
|
|
214
|
+
fi
|
|
215
|
+
done < <(grep -Eo '\\[[^]]+\\]\\([^)]+\\)' "\${file}" | sed -E 's/^.*\\(([^)]+)\\)$/\\1/' || true)
|
|
216
|
+
done < <(find "${GOVERNANCE_ROOT_TOKEN}" -type f -name '*.md' -print0)
|
|
217
|
+
|
|
218
|
+
if (( \${#missing[@]} > 0 )); then
|
|
219
|
+
echo "docs 链接检查失败:" >&2
|
|
220
|
+
for item in "\${missing[@]}"; do
|
|
221
|
+
echo " - \${item}" >&2
|
|
222
|
+
done
|
|
223
|
+
exit 1
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
echo "docs 链接检查通过"
|
|
227
227
|
`;
|
|
228
|
-
const INIT_CHECK_ACTIVE_PLAN_STATUS_SH = `#!/usr/bin/env bash
|
|
229
|
-
set -euo pipefail
|
|
230
|
-
|
|
231
|
-
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
232
|
-
cd "\${ROOT_DIR}"
|
|
233
|
-
|
|
234
|
-
active_dir="${GOVERNANCE_ROOT_TOKEN}/exec-plans/active"
|
|
235
|
-
[[ -d "\${active_dir}" ]] || { echo "active plan 检查失败:缺少 \${active_dir}" >&2; exit 1; }
|
|
236
|
-
|
|
237
|
-
bad=()
|
|
238
|
-
while IFS= read -r -d '' file; do
|
|
239
|
-
name="$(basename "\${file}")"
|
|
240
|
-
[[ "\${name}" == "README.md" ]] && continue
|
|
241
|
-
if grep -Eiq 'status:[[:space:]]*(completed|done|closed)|状态[::][[:space:]]*(已完成|完成|关闭)' "\${file}"; then
|
|
242
|
-
bad+=("\${file}")
|
|
243
|
-
fi
|
|
244
|
-
done < <(find "\${active_dir}" -maxdepth 1 -type f -name '*.md' -print0)
|
|
245
|
-
|
|
246
|
-
if (( \${#bad[@]} > 0 )); then
|
|
247
|
-
echo "active plan 状态检查失败:已完成计划不应留在 active 目录:" >&2
|
|
248
|
-
for item in "\${bad[@]}"; do
|
|
249
|
-
echo " - \${item}" >&2
|
|
250
|
-
done
|
|
251
|
-
exit 1
|
|
252
|
-
fi
|
|
253
|
-
|
|
254
|
-
echo "active plan 状态检查通过"
|
|
228
|
+
const INIT_CHECK_ACTIVE_PLAN_STATUS_SH = `#!/usr/bin/env bash
|
|
229
|
+
set -euo pipefail
|
|
230
|
+
|
|
231
|
+
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
232
|
+
cd "\${ROOT_DIR}"
|
|
233
|
+
|
|
234
|
+
active_dir="${GOVERNANCE_ROOT_TOKEN}/exec-plans/active"
|
|
235
|
+
[[ -d "\${active_dir}" ]] || { echo "active plan 检查失败:缺少 \${active_dir}" >&2; exit 1; }
|
|
236
|
+
|
|
237
|
+
bad=()
|
|
238
|
+
while IFS= read -r -d '' file; do
|
|
239
|
+
name="$(basename "\${file}")"
|
|
240
|
+
[[ "\${name}" == "README.md" ]] && continue
|
|
241
|
+
if grep -Eiq 'status:[[:space:]]*(completed|done|closed)|状态[::][[:space:]]*(已完成|完成|关闭)' "\${file}"; then
|
|
242
|
+
bad+=("\${file}")
|
|
243
|
+
fi
|
|
244
|
+
done < <(find "\${active_dir}" -maxdepth 1 -type f -name '*.md' -print0)
|
|
245
|
+
|
|
246
|
+
if (( \${#bad[@]} > 0 )); then
|
|
247
|
+
echo "active plan 状态检查失败:已完成计划不应留在 active 目录:" >&2
|
|
248
|
+
for item in "\${bad[@]}"; do
|
|
249
|
+
echo " - \${item}" >&2
|
|
250
|
+
done
|
|
251
|
+
exit 1
|
|
252
|
+
fi
|
|
253
|
+
|
|
254
|
+
echo "active plan 状态检查通过"
|
|
255
255
|
`;
|
|
256
|
-
const INIT_CHECK_EXEC_PLAN_INDEX_SYNC_SH = `#!/usr/bin/env bash
|
|
257
|
-
set -euo pipefail
|
|
258
|
-
|
|
259
|
-
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
260
|
-
cd "\${ROOT_DIR}"
|
|
261
|
-
|
|
262
|
-
required=(
|
|
263
|
-
"${GOVERNANCE_ROOT_TOKEN}/exec-plans/README.md"
|
|
264
|
-
"${GOVERNANCE_ROOT_TOKEN}/exec-plans/active/README.md"
|
|
265
|
-
"${GOVERNANCE_ROOT_TOKEN}/exec-plans/completed/README.md"
|
|
266
|
-
)
|
|
267
|
-
|
|
268
|
-
for item in "\${required[@]}"; do
|
|
269
|
-
if [[ ! -f "\${item}" ]]; then
|
|
270
|
-
echo "exec-plan 索引同步检查失败:缺少 \${item}" >&2
|
|
271
|
-
exit 1
|
|
272
|
-
fi
|
|
273
|
-
done
|
|
274
|
-
|
|
275
|
-
echo "exec-plan 索引同步检查通过"
|
|
256
|
+
const INIT_CHECK_EXEC_PLAN_INDEX_SYNC_SH = `#!/usr/bin/env bash
|
|
257
|
+
set -euo pipefail
|
|
258
|
+
|
|
259
|
+
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
260
|
+
cd "\${ROOT_DIR}"
|
|
261
|
+
|
|
262
|
+
required=(
|
|
263
|
+
"${GOVERNANCE_ROOT_TOKEN}/exec-plans/README.md"
|
|
264
|
+
"${GOVERNANCE_ROOT_TOKEN}/exec-plans/active/README.md"
|
|
265
|
+
"${GOVERNANCE_ROOT_TOKEN}/exec-plans/completed/README.md"
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
for item in "\${required[@]}"; do
|
|
269
|
+
if [[ ! -f "\${item}" ]]; then
|
|
270
|
+
echo "exec-plan 索引同步检查失败:缺少 \${item}" >&2
|
|
271
|
+
exit 1
|
|
272
|
+
fi
|
|
273
|
+
done
|
|
274
|
+
|
|
275
|
+
echo "exec-plan 索引同步检查通过"
|
|
276
276
|
`;
|
|
277
|
-
const INIT_CHECK_HARNESS_RUNTIME_CLEAN_SH = `#!/usr/bin/env bash
|
|
278
|
-
set -euo pipefail
|
|
279
|
-
|
|
280
|
-
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
281
|
-
cd "\${ROOT_DIR}"
|
|
282
|
-
|
|
283
|
-
failures=()
|
|
284
|
-
|
|
285
|
-
count_entries() {
|
|
286
|
-
local dir="$1"
|
|
287
|
-
if [[ ! -d "\${dir}" ]]; then
|
|
288
|
-
echo 0
|
|
289
|
-
return
|
|
290
|
-
fi
|
|
291
|
-
find "\${dir}" -mindepth 1 -maxdepth 1 ! -name .gitkeep | wc -l | tr -d ' '
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if [[ "\${HARNESS_ALLOW_ACTIVE_DAG_RUNS:-}" != "1" ]]; then
|
|
295
|
-
active_dag_count="$(count_entries ".harness/dag-runs/active")"
|
|
296
|
-
[[ "\${active_dag_count}" == "0" ]] || failures+=(".harness/dag-runs/active contains \${active_dag_count} entries")
|
|
297
|
-
fi
|
|
298
|
-
|
|
299
|
-
if [[ "\${HARNESS_ALLOW_ACTIVE_TOOL_RUNS:-\${HARNESS_ALLOW_ACTIVE_ONE_SHOT_RUNS:-}}" != "1" ]]; then
|
|
300
|
-
active_run_count="$(count_entries ".harness/runs/active")"
|
|
301
|
-
[[ "\${active_run_count}" == "0" ]] || failures+=(".harness/runs/active contains \${active_run_count} entries")
|
|
302
|
-
fi
|
|
303
|
-
|
|
304
|
-
if [[ -d artifacts ]]; then
|
|
305
|
-
artifact_count="$(find artifacts -mindepth 1 -maxdepth 1 ! -name .gitkeep | wc -l | tr -d ' ')"
|
|
306
|
-
[[ "\${artifact_count}" == "0" ]] || failures+=("root artifacts/ contains \${artifact_count} entries; use docs/reports or .harness run artifacts")
|
|
307
|
-
fi
|
|
308
|
-
|
|
309
|
-
if (( \${#failures[@]} > 0 )); then
|
|
310
|
-
echo "[HARNESS RUNTIME DIRTY]" >&2
|
|
311
|
-
for item in "\${failures[@]}"; do
|
|
312
|
-
echo " - \${item}" >&2
|
|
313
|
-
done
|
|
314
|
-
exit 1
|
|
315
|
-
fi
|
|
316
|
-
|
|
317
|
-
echo "harness runtime clean check passed"
|
|
277
|
+
const INIT_CHECK_HARNESS_RUNTIME_CLEAN_SH = `#!/usr/bin/env bash
|
|
278
|
+
set -euo pipefail
|
|
279
|
+
|
|
280
|
+
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
281
|
+
cd "\${ROOT_DIR}"
|
|
282
|
+
|
|
283
|
+
failures=()
|
|
284
|
+
|
|
285
|
+
count_entries() {
|
|
286
|
+
local dir="$1"
|
|
287
|
+
if [[ ! -d "\${dir}" ]]; then
|
|
288
|
+
echo 0
|
|
289
|
+
return
|
|
290
|
+
fi
|
|
291
|
+
find "\${dir}" -mindepth 1 -maxdepth 1 ! -name .gitkeep | wc -l | tr -d ' '
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if [[ "\${HARNESS_ALLOW_ACTIVE_DAG_RUNS:-}" != "1" ]]; then
|
|
295
|
+
active_dag_count="$(count_entries ".harness/dag-runs/active")"
|
|
296
|
+
[[ "\${active_dag_count}" == "0" ]] || failures+=(".harness/dag-runs/active contains \${active_dag_count} entries")
|
|
297
|
+
fi
|
|
298
|
+
|
|
299
|
+
if [[ "\${HARNESS_ALLOW_ACTIVE_TOOL_RUNS:-\${HARNESS_ALLOW_ACTIVE_ONE_SHOT_RUNS:-}}" != "1" ]]; then
|
|
300
|
+
active_run_count="$(count_entries ".harness/runs/active")"
|
|
301
|
+
[[ "\${active_run_count}" == "0" ]] || failures+=(".harness/runs/active contains \${active_run_count} entries")
|
|
302
|
+
fi
|
|
303
|
+
|
|
304
|
+
if [[ -d artifacts ]]; then
|
|
305
|
+
artifact_count="$(find artifacts -mindepth 1 -maxdepth 1 ! -name .gitkeep | wc -l | tr -d ' ')"
|
|
306
|
+
[[ "\${artifact_count}" == "0" ]] || failures+=("root artifacts/ contains \${artifact_count} entries; use docs/reports or .harness run artifacts")
|
|
307
|
+
fi
|
|
308
|
+
|
|
309
|
+
if (( \${#failures[@]} > 0 )); then
|
|
310
|
+
echo "[HARNESS RUNTIME DIRTY]" >&2
|
|
311
|
+
for item in "\${failures[@]}"; do
|
|
312
|
+
echo " - \${item}" >&2
|
|
313
|
+
done
|
|
314
|
+
exit 1
|
|
315
|
+
fi
|
|
316
|
+
|
|
317
|
+
echo "harness runtime clean check passed"
|
|
318
318
|
`;
|
|
319
|
-
const INIT_CHECK_ARCHITECTURE_BOUNDARIES_SH = `#!/usr/bin/env bash
|
|
320
|
-
set -euo pipefail
|
|
321
|
-
|
|
322
|
-
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
323
|
-
cd "\${ROOT_DIR}"
|
|
324
|
-
|
|
325
|
-
boundary_doc="${GOVERNANCE_ROOT_TOKEN}/architecture/runtime-boundaries.md"
|
|
326
|
-
if [[ ! -f "\${boundary_doc}" ]]; then
|
|
327
|
-
echo "architecture boundary 检查失败:缺少 \${boundary_doc}" >&2
|
|
328
|
-
exit 1
|
|
329
|
-
fi
|
|
330
|
-
|
|
331
|
-
violations=()
|
|
332
|
-
|
|
333
|
-
check_ts_import_boundary() {
|
|
334
|
-
local from_dir="$1"
|
|
335
|
-
local forbidden_dir="$2"
|
|
336
|
-
local label="$3"
|
|
337
|
-
[[ -d "\${from_dir}" && -d "\${forbidden_dir}" ]] || return 0
|
|
338
|
-
while IFS= read -r -d '' file; do
|
|
339
|
-
if grep -Eq "from ['\\\"][^'\\\"]*\${forbidden_dir}/|import\\(['\\\"][^'\\\"]*\${forbidden_dir}/|require\\(['\\\"][^'\\\"]*\${forbidden_dir}/" "\${file}"; then
|
|
340
|
-
violations+=("\${label}: \${file} imports \${forbidden_dir}")
|
|
341
|
-
fi
|
|
342
|
-
done < <(find "\${from_dir}" -type f \\( -name '*.ts' -o -name '*.tsx' -o -name '*.js' -o -name '*.jsx' -o -name '*.mjs' -o -name '*.cjs' \\) -print0)
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
# These checks are intentionally optional and stack-agnostic. They activate only
|
|
346
|
-
# when a target repository has recognizable source directories.
|
|
347
|
-
check_ts_import_boundary "src/workflows" "src/commands" "workflow-runtime"
|
|
348
|
-
check_ts_import_boundary "src/executors" "src/commands" "executors"
|
|
349
|
-
check_ts_import_boundary "src/domain" "src/infrastructure" "domain"
|
|
350
|
-
|
|
351
|
-
if (( \${#violations[@]} > 0 )); then
|
|
352
|
-
echo "architecture boundary 检查失败:" >&2
|
|
353
|
-
for item in "\${violations[@]}"; do
|
|
354
|
-
echo " - \${item}" >&2
|
|
355
|
-
done
|
|
356
|
-
echo "请更新 \${boundary_doc} 中的层边界,或修正反向依赖。" >&2
|
|
357
|
-
exit 1
|
|
358
|
-
fi
|
|
359
|
-
|
|
360
|
-
echo "architecture boundary 检查通过"
|
|
319
|
+
const INIT_CHECK_ARCHITECTURE_BOUNDARIES_SH = `#!/usr/bin/env bash
|
|
320
|
+
set -euo pipefail
|
|
321
|
+
|
|
322
|
+
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
323
|
+
cd "\${ROOT_DIR}"
|
|
324
|
+
|
|
325
|
+
boundary_doc="${GOVERNANCE_ROOT_TOKEN}/architecture/runtime-boundaries.md"
|
|
326
|
+
if [[ ! -f "\${boundary_doc}" ]]; then
|
|
327
|
+
echo "architecture boundary 检查失败:缺少 \${boundary_doc}" >&2
|
|
328
|
+
exit 1
|
|
329
|
+
fi
|
|
330
|
+
|
|
331
|
+
violations=()
|
|
332
|
+
|
|
333
|
+
check_ts_import_boundary() {
|
|
334
|
+
local from_dir="$1"
|
|
335
|
+
local forbidden_dir="$2"
|
|
336
|
+
local label="$3"
|
|
337
|
+
[[ -d "\${from_dir}" && -d "\${forbidden_dir}" ]] || return 0
|
|
338
|
+
while IFS= read -r -d '' file; do
|
|
339
|
+
if grep -Eq "from ['\\\"][^'\\\"]*\${forbidden_dir}/|import\\(['\\\"][^'\\\"]*\${forbidden_dir}/|require\\(['\\\"][^'\\\"]*\${forbidden_dir}/" "\${file}"; then
|
|
340
|
+
violations+=("\${label}: \${file} imports \${forbidden_dir}")
|
|
341
|
+
fi
|
|
342
|
+
done < <(find "\${from_dir}" -type f \\( -name '*.ts' -o -name '*.tsx' -o -name '*.js' -o -name '*.jsx' -o -name '*.mjs' -o -name '*.cjs' \\) -print0)
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
# These checks are intentionally optional and stack-agnostic. They activate only
|
|
346
|
+
# when a target repository has recognizable source directories.
|
|
347
|
+
check_ts_import_boundary "src/workflows" "src/commands" "workflow-runtime"
|
|
348
|
+
check_ts_import_boundary "src/executors" "src/commands" "executors"
|
|
349
|
+
check_ts_import_boundary "src/domain" "src/infrastructure" "domain"
|
|
350
|
+
|
|
351
|
+
if (( \${#violations[@]} > 0 )); then
|
|
352
|
+
echo "architecture boundary 检查失败:" >&2
|
|
353
|
+
for item in "\${violations[@]}"; do
|
|
354
|
+
echo " - \${item}" >&2
|
|
355
|
+
done
|
|
356
|
+
echo "请更新 \${boundary_doc} 中的层边界,或修正反向依赖。" >&2
|
|
357
|
+
exit 1
|
|
358
|
+
fi
|
|
359
|
+
|
|
360
|
+
echo "architecture boundary 检查通过"
|
|
361
361
|
`;
|
|
362
|
-
const INIT_CHECK_SKILL_ENTRY_SH = `#!/usr/bin/env bash
|
|
363
|
-
set -euo pipefail
|
|
364
|
-
|
|
365
|
-
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
366
|
-
cd "\${ROOT_DIR}"
|
|
367
|
-
|
|
368
|
-
skill_md="skills/loop-agent/SKILL.md"
|
|
369
|
-
if [[ ! -f "\${skill_md}" ]]; then
|
|
370
|
-
echo "skill entry 检查失败:缺少 \${skill_md}" >&2
|
|
371
|
-
exit 1
|
|
372
|
-
fi
|
|
373
|
-
|
|
374
|
-
required_refs=(
|
|
375
|
-
"references/harness-policy.md"
|
|
376
|
-
"references/hybrid-dag.md"
|
|
377
|
-
"references/verification-and-failure-handling.md"
|
|
378
|
-
"references/command-reference.md"
|
|
379
|
-
)
|
|
380
|
-
|
|
381
|
-
missing=()
|
|
382
|
-
for ref in "\${required_refs[@]}"; do
|
|
383
|
-
[[ -f "skills/loop-agent/\${ref}" ]] || missing+=("\${ref}")
|
|
384
|
-
done
|
|
385
|
-
|
|
386
|
-
while IFS= read -r ref; do
|
|
387
|
-
[[ -z "\${ref}" ]] && continue
|
|
388
|
-
[[ -f "skills/loop-agent/\${ref}" ]] || missing+=("\${ref}")
|
|
389
|
-
done < <(grep -Eo 'references/[A-Za-z0-9._/-]+\\.md' "\${skill_md}" | sort -u || true)
|
|
390
|
-
|
|
391
|
-
if (( \${#missing[@]} > 0 )); then
|
|
392
|
-
echo "skill entry 检查失败:引用的 reference 文件不存在:" >&2
|
|
393
|
-
printf ' - %s\\n' "\${missing[@]}" >&2
|
|
394
|
-
exit 1
|
|
395
|
-
fi
|
|
396
|
-
|
|
397
|
-
line_count="$(wc -l < "\${skill_md}" | tr -d ' ')"
|
|
398
|
-
if [[ "\${line_count}" =~ ^[0-9]+$ && "\${line_count}" -gt 220 ]]; then
|
|
399
|
-
echo "skill entry 检查警告:\${skill_md} 行数为 \${line_count},建议保持入口精简并把细节放入 references/" >&2
|
|
400
|
-
fi
|
|
401
|
-
|
|
402
|
-
echo "skill entry 检查通过:references ok, lines=\${line_count}"
|
|
362
|
+
const INIT_CHECK_SKILL_ENTRY_SH = `#!/usr/bin/env bash
|
|
363
|
+
set -euo pipefail
|
|
364
|
+
|
|
365
|
+
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
366
|
+
cd "\${ROOT_DIR}"
|
|
367
|
+
|
|
368
|
+
skill_md="skills/loop-agent/SKILL.md"
|
|
369
|
+
if [[ ! -f "\${skill_md}" ]]; then
|
|
370
|
+
echo "skill entry 检查失败:缺少 \${skill_md}" >&2
|
|
371
|
+
exit 1
|
|
372
|
+
fi
|
|
373
|
+
|
|
374
|
+
required_refs=(
|
|
375
|
+
"references/harness-policy.md"
|
|
376
|
+
"references/hybrid-dag.md"
|
|
377
|
+
"references/verification-and-failure-handling.md"
|
|
378
|
+
"references/command-reference.md"
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
missing=()
|
|
382
|
+
for ref in "\${required_refs[@]}"; do
|
|
383
|
+
[[ -f "skills/loop-agent/\${ref}" ]] || missing+=("\${ref}")
|
|
384
|
+
done
|
|
385
|
+
|
|
386
|
+
while IFS= read -r ref; do
|
|
387
|
+
[[ -z "\${ref}" ]] && continue
|
|
388
|
+
[[ -f "skills/loop-agent/\${ref}" ]] || missing+=("\${ref}")
|
|
389
|
+
done < <(grep -Eo 'references/[A-Za-z0-9._/-]+\\.md' "\${skill_md}" | sort -u || true)
|
|
390
|
+
|
|
391
|
+
if (( \${#missing[@]} > 0 )); then
|
|
392
|
+
echo "skill entry 检查失败:引用的 reference 文件不存在:" >&2
|
|
393
|
+
printf ' - %s\\n' "\${missing[@]}" >&2
|
|
394
|
+
exit 1
|
|
395
|
+
fi
|
|
396
|
+
|
|
397
|
+
line_count="$(wc -l < "\${skill_md}" | tr -d ' ')"
|
|
398
|
+
if [[ "\${line_count}" =~ ^[0-9]+$ && "\${line_count}" -gt 220 ]]; then
|
|
399
|
+
echo "skill entry 检查警告:\${skill_md} 行数为 \${line_count},建议保持入口精简并把细节放入 references/" >&2
|
|
400
|
+
fi
|
|
401
|
+
|
|
402
|
+
echo "skill entry 检查通过:references ok, lines=\${line_count}"
|
|
403
403
|
`;
|
|
404
|
-
const INIT_CHECK_REPO_SH = `#!/usr/bin/env bash
|
|
405
|
-
set -euo pipefail
|
|
406
|
-
|
|
407
|
-
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
408
|
-
cd "\${ROOT_DIR}"
|
|
409
|
-
|
|
410
|
-
checks=(
|
|
411
|
-
"scripts/check-engineering-structure.sh"
|
|
412
|
-
"scripts/check-doc-index.sh"
|
|
413
|
-
"scripts/check-doc-links.sh"
|
|
414
|
-
"scripts/check-active-plan-status.sh"
|
|
415
|
-
"scripts/check-exec-plan-index-sync.sh"
|
|
416
|
-
"scripts/check-harness-runtime-clean.sh"
|
|
417
|
-
"scripts/check-architecture-boundaries.sh"
|
|
418
|
-
"scripts/check-skill-entry.sh"
|
|
419
|
-
)
|
|
420
|
-
|
|
421
|
-
for check in "\${checks[@]}"; do
|
|
422
|
-
echo "==> bash \${check}"
|
|
423
|
-
bash "\${check}"
|
|
424
|
-
echo
|
|
425
|
-
done
|
|
426
|
-
|
|
427
|
-
echo "仓库治理检查全部通过"
|
|
404
|
+
const INIT_CHECK_REPO_SH = `#!/usr/bin/env bash
|
|
405
|
+
set -euo pipefail
|
|
406
|
+
|
|
407
|
+
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
408
|
+
cd "\${ROOT_DIR}"
|
|
409
|
+
|
|
410
|
+
checks=(
|
|
411
|
+
"scripts/check-engineering-structure.sh"
|
|
412
|
+
"scripts/check-doc-index.sh"
|
|
413
|
+
"scripts/check-doc-links.sh"
|
|
414
|
+
"scripts/check-active-plan-status.sh"
|
|
415
|
+
"scripts/check-exec-plan-index-sync.sh"
|
|
416
|
+
"scripts/check-harness-runtime-clean.sh"
|
|
417
|
+
"scripts/check-architecture-boundaries.sh"
|
|
418
|
+
"scripts/check-skill-entry.sh"
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
for check in "\${checks[@]}"; do
|
|
422
|
+
echo "==> bash \${check}"
|
|
423
|
+
bash "\${check}"
|
|
424
|
+
echo
|
|
425
|
+
done
|
|
426
|
+
|
|
427
|
+
echo "仓库治理检查全部通过"
|
|
428
428
|
`;
|
|
429
|
-
const INIT_CI_GOVERNANCE_SH = `#!/usr/bin/env bash
|
|
430
|
-
set -euo pipefail
|
|
431
|
-
|
|
432
|
-
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
433
|
-
cd "\${ROOT_DIR}"
|
|
434
|
-
|
|
435
|
-
bash scripts/check-repo.sh
|
|
429
|
+
const INIT_CI_GOVERNANCE_SH = `#!/usr/bin/env bash
|
|
430
|
+
set -euo pipefail
|
|
431
|
+
|
|
432
|
+
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
433
|
+
cd "\${ROOT_DIR}"
|
|
434
|
+
|
|
435
|
+
bash scripts/check-repo.sh
|
|
436
436
|
`;
|
|
437
|
-
const INIT_CI_TESTS_SH = `#!/usr/bin/env bash
|
|
438
|
-
set -euo pipefail
|
|
439
|
-
|
|
440
|
-
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
441
|
-
cd "\${ROOT_DIR}"
|
|
442
|
-
|
|
443
|
-
ran=0
|
|
444
|
-
notes=()
|
|
445
|
-
|
|
446
|
-
run_cmd() {
|
|
447
|
-
echo "==> $*"
|
|
448
|
-
"$@"
|
|
449
|
-
ran=1
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
run_bash() {
|
|
453
|
-
echo "==> $*"
|
|
454
|
-
bash -lc "$*"
|
|
455
|
-
ran=1
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
has_make_target() {
|
|
459
|
-
local target="$1"
|
|
460
|
-
[[ -f Makefile || -f makefile ]] || return 1
|
|
461
|
-
grep -Eq "^[[:alnum:]_.-]*\${target}[[:alnum:]_.-]*:" Makefile makefile 2>/dev/null
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
has_npm_script() {
|
|
465
|
-
local script="$1"
|
|
466
|
-
[[ -f package.json ]] || return 1
|
|
467
|
-
command -v node >/dev/null 2>&1 || return 1
|
|
468
|
-
node -e "const fs=require('fs'); const p=JSON.parse(fs.readFileSync('package.json','utf8')); process.exit(p.scripts && p.scripts[process.argv[1]] ? 0 : 1)" "\${script}" >/dev/null 2>&1
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
if [[ -f package.json ]]; then
|
|
472
|
-
if command -v npm >/dev/null 2>&1; then
|
|
473
|
-
for script in lint typecheck test build; do
|
|
474
|
-
if has_npm_script "\${script}"; then
|
|
475
|
-
run_cmd npm run "\${script}"
|
|
476
|
-
fi
|
|
477
|
-
done
|
|
478
|
-
else
|
|
479
|
-
notes+=("package.json exists but npm is not available")
|
|
480
|
-
fi
|
|
481
|
-
fi
|
|
482
|
-
|
|
483
|
-
if has_make_target verify; then
|
|
484
|
-
run_cmd make verify
|
|
485
|
-
elif has_make_target test; then
|
|
486
|
-
run_cmd make test
|
|
487
|
-
fi
|
|
488
|
-
|
|
489
|
-
if [[ -f go.mod ]]; then
|
|
490
|
-
if command -v go >/dev/null 2>&1; then
|
|
491
|
-
run_cmd go test ./...
|
|
492
|
-
else
|
|
493
|
-
notes+=("go.mod exists but go is not available")
|
|
494
|
-
fi
|
|
495
|
-
fi
|
|
496
|
-
|
|
497
|
-
if [[ -f Cargo.toml ]]; then
|
|
498
|
-
if command -v cargo >/dev/null 2>&1; then
|
|
499
|
-
run_cmd cargo test
|
|
500
|
-
else
|
|
501
|
-
notes+=("Cargo.toml exists but cargo is not available")
|
|
502
|
-
fi
|
|
503
|
-
fi
|
|
504
|
-
|
|
505
|
-
if [[ -f pyproject.toml || -f pytest.ini || -f tox.ini ]]; then
|
|
506
|
-
if command -v pytest >/dev/null 2>&1; then
|
|
507
|
-
run_cmd pytest
|
|
508
|
-
elif command -v tox >/dev/null 2>&1 && [[ -f tox.ini ]]; then
|
|
509
|
-
run_cmd tox
|
|
510
|
-
else
|
|
511
|
-
notes+=("Python project metadata found but pytest/tox is not available")
|
|
512
|
-
fi
|
|
513
|
-
fi
|
|
514
|
-
|
|
515
|
-
if [[ -f pom.xml ]]; then
|
|
516
|
-
if command -v mvn >/dev/null 2>&1; then
|
|
517
|
-
run_cmd mvn test
|
|
518
|
-
else
|
|
519
|
-
notes+=("pom.xml exists but mvn is not available")
|
|
520
|
-
fi
|
|
521
|
-
fi
|
|
522
|
-
|
|
523
|
-
if [[ -f build.gradle || -f build.gradle.kts || -f settings.gradle || -f settings.gradle.kts ]]; then
|
|
524
|
-
if [[ -x ./gradlew ]]; then
|
|
525
|
-
run_cmd ./gradlew test
|
|
526
|
-
elif command -v gradle >/dev/null 2>&1; then
|
|
527
|
-
run_cmd gradle test
|
|
528
|
-
else
|
|
529
|
-
notes+=("Gradle project metadata found but gradle/gradlew is not available")
|
|
530
|
-
fi
|
|
531
|
-
fi
|
|
532
|
-
|
|
533
|
-
if compgen -G "*.sln" >/dev/null || compgen -G "*.csproj" >/dev/null; then
|
|
534
|
-
if command -v dotnet >/dev/null 2>&1; then
|
|
535
|
-
run_cmd dotnet test
|
|
536
|
-
else
|
|
537
|
-
notes+=(".NET project metadata found but dotnet is not available")
|
|
538
|
-
fi
|
|
539
|
-
fi
|
|
540
|
-
|
|
541
|
-
if (( ran == 0 )); then
|
|
542
|
-
echo "未检测到可安全自动运行的项目测试入口。"
|
|
543
|
-
echo "loop-agent 治理检查仍可运行;请让初始化模型根据目标项目技术栈补充 scripts/ci-tests.sh 与 docs/verification-matrix.md。"
|
|
544
|
-
fi
|
|
545
|
-
|
|
546
|
-
if (( \${#notes[@]} > 0 )); then
|
|
547
|
-
echo "项目验证探测备注:"
|
|
548
|
-
for note in "\${notes[@]}"; do
|
|
549
|
-
echo " - \${note}"
|
|
550
|
-
done
|
|
551
|
-
fi
|
|
437
|
+
const INIT_CI_TESTS_SH = `#!/usr/bin/env bash
|
|
438
|
+
set -euo pipefail
|
|
439
|
+
|
|
440
|
+
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
441
|
+
cd "\${ROOT_DIR}"
|
|
442
|
+
|
|
443
|
+
ran=0
|
|
444
|
+
notes=()
|
|
445
|
+
|
|
446
|
+
run_cmd() {
|
|
447
|
+
echo "==> $*"
|
|
448
|
+
"$@"
|
|
449
|
+
ran=1
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
run_bash() {
|
|
453
|
+
echo "==> $*"
|
|
454
|
+
bash -lc "$*"
|
|
455
|
+
ran=1
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
has_make_target() {
|
|
459
|
+
local target="$1"
|
|
460
|
+
[[ -f Makefile || -f makefile ]] || return 1
|
|
461
|
+
grep -Eq "^[[:alnum:]_.-]*\${target}[[:alnum:]_.-]*:" Makefile makefile 2>/dev/null
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
has_npm_script() {
|
|
465
|
+
local script="$1"
|
|
466
|
+
[[ -f package.json ]] || return 1
|
|
467
|
+
command -v node >/dev/null 2>&1 || return 1
|
|
468
|
+
node -e "const fs=require('fs'); const p=JSON.parse(fs.readFileSync('package.json','utf8')); process.exit(p.scripts && p.scripts[process.argv[1]] ? 0 : 1)" "\${script}" >/dev/null 2>&1
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if [[ -f package.json ]]; then
|
|
472
|
+
if command -v npm >/dev/null 2>&1; then
|
|
473
|
+
for script in lint typecheck test build; do
|
|
474
|
+
if has_npm_script "\${script}"; then
|
|
475
|
+
run_cmd npm run "\${script}"
|
|
476
|
+
fi
|
|
477
|
+
done
|
|
478
|
+
else
|
|
479
|
+
notes+=("package.json exists but npm is not available")
|
|
480
|
+
fi
|
|
481
|
+
fi
|
|
482
|
+
|
|
483
|
+
if has_make_target verify; then
|
|
484
|
+
run_cmd make verify
|
|
485
|
+
elif has_make_target test; then
|
|
486
|
+
run_cmd make test
|
|
487
|
+
fi
|
|
488
|
+
|
|
489
|
+
if [[ -f go.mod ]]; then
|
|
490
|
+
if command -v go >/dev/null 2>&1; then
|
|
491
|
+
run_cmd go test ./...
|
|
492
|
+
else
|
|
493
|
+
notes+=("go.mod exists but go is not available")
|
|
494
|
+
fi
|
|
495
|
+
fi
|
|
496
|
+
|
|
497
|
+
if [[ -f Cargo.toml ]]; then
|
|
498
|
+
if command -v cargo >/dev/null 2>&1; then
|
|
499
|
+
run_cmd cargo test
|
|
500
|
+
else
|
|
501
|
+
notes+=("Cargo.toml exists but cargo is not available")
|
|
502
|
+
fi
|
|
503
|
+
fi
|
|
504
|
+
|
|
505
|
+
if [[ -f pyproject.toml || -f pytest.ini || -f tox.ini ]]; then
|
|
506
|
+
if command -v pytest >/dev/null 2>&1; then
|
|
507
|
+
run_cmd pytest
|
|
508
|
+
elif command -v tox >/dev/null 2>&1 && [[ -f tox.ini ]]; then
|
|
509
|
+
run_cmd tox
|
|
510
|
+
else
|
|
511
|
+
notes+=("Python project metadata found but pytest/tox is not available")
|
|
512
|
+
fi
|
|
513
|
+
fi
|
|
514
|
+
|
|
515
|
+
if [[ -f pom.xml ]]; then
|
|
516
|
+
if command -v mvn >/dev/null 2>&1; then
|
|
517
|
+
run_cmd mvn test
|
|
518
|
+
else
|
|
519
|
+
notes+=("pom.xml exists but mvn is not available")
|
|
520
|
+
fi
|
|
521
|
+
fi
|
|
522
|
+
|
|
523
|
+
if [[ -f build.gradle || -f build.gradle.kts || -f settings.gradle || -f settings.gradle.kts ]]; then
|
|
524
|
+
if [[ -x ./gradlew ]]; then
|
|
525
|
+
run_cmd ./gradlew test
|
|
526
|
+
elif command -v gradle >/dev/null 2>&1; then
|
|
527
|
+
run_cmd gradle test
|
|
528
|
+
else
|
|
529
|
+
notes+=("Gradle project metadata found but gradle/gradlew is not available")
|
|
530
|
+
fi
|
|
531
|
+
fi
|
|
532
|
+
|
|
533
|
+
if compgen -G "*.sln" >/dev/null || compgen -G "*.csproj" >/dev/null; then
|
|
534
|
+
if command -v dotnet >/dev/null 2>&1; then
|
|
535
|
+
run_cmd dotnet test
|
|
536
|
+
else
|
|
537
|
+
notes+=(".NET project metadata found but dotnet is not available")
|
|
538
|
+
fi
|
|
539
|
+
fi
|
|
540
|
+
|
|
541
|
+
if (( ran == 0 )); then
|
|
542
|
+
echo "未检测到可安全自动运行的项目测试入口。"
|
|
543
|
+
echo "loop-agent 治理检查仍可运行;请让初始化模型根据目标项目技术栈补充 scripts/ci-tests.sh 与 docs/verification-matrix.md。"
|
|
544
|
+
fi
|
|
545
|
+
|
|
546
|
+
if (( \${#notes[@]} > 0 )); then
|
|
547
|
+
echo "项目验证探测备注:"
|
|
548
|
+
for note in "\${notes[@]}"; do
|
|
549
|
+
echo " - \${note}"
|
|
550
|
+
done
|
|
551
|
+
fi
|
|
552
552
|
`;
|
|
553
|
-
const INIT_CI_SH = `#!/usr/bin/env bash
|
|
554
|
-
set -euo pipefail
|
|
555
|
-
|
|
556
|
-
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
557
|
-
cd "\${ROOT_DIR}"
|
|
558
|
-
|
|
559
|
-
bash scripts/ci-governance.sh
|
|
560
|
-
bash scripts/ci-tests.sh
|
|
553
|
+
const INIT_CI_SH = `#!/usr/bin/env bash
|
|
554
|
+
set -euo pipefail
|
|
555
|
+
|
|
556
|
+
ROOT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
557
|
+
cd "\${ROOT_DIR}"
|
|
558
|
+
|
|
559
|
+
bash scripts/ci-governance.sh
|
|
560
|
+
bash scripts/ci-tests.sh
|
|
561
561
|
`;
|
|
562
562
|
const INIT_SCRIPT_FILES = {
|
|
563
563
|
"scripts/check-engineering-structure.sh": INIT_CHECK_ENGINEERING_STRUCTURE_SH,
|