@cxi-lmai/ci-agent-platform 3.1.4 → 3.1.5
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cxi-lmai/ci-agent-platform",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.5",
|
|
4
4
|
"description": "Autonomous dev pipeline on plain GitLab CI or GitHub Actions, driven by Claude Code. A labeled issue goes in, an open merge request comes out.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -277,10 +277,16 @@ pipe_run_claude() {
|
|
|
277
277
|
# $3 = allowed tools (optional), $4 = model for the main loop (optional,
|
|
278
278
|
# e.g. $PIPE_MODEL_REVIEW; subagents keep their frontmatter models),
|
|
279
279
|
# stdin = extra prompt (optional, usually empty)
|
|
280
|
+
#
|
|
281
|
+
# Always returns 0, so a caller running under `set -e` keeps control over what
|
|
282
|
+
# a failed agent means for its job. The agent's real exit code lands in
|
|
283
|
+
# PIPE_AGENT_RC. A caller that must not read a crashed agent as a clean run
|
|
284
|
+
# checks that variable, or calls pipe_require_agent_ran below.
|
|
280
285
|
local label="$1" skill="$2" tools="${3:-Agent,Read,Write,Edit,Glob,Grep,Bash}" model="${4:-}"
|
|
281
286
|
pipe_require_harness claude
|
|
282
287
|
local stdin_file; stdin_file=$(mktemp)
|
|
283
288
|
cat > "$stdin_file" || true
|
|
289
|
+
PIPE_AGENT_RC=0
|
|
284
290
|
|
|
285
291
|
if [ "$(id -u)" -eq 0 ]; then
|
|
286
292
|
local runuser="pipelinebot"
|
|
@@ -315,7 +321,7 @@ pipe_run_claude() {
|
|
|
315
321
|
} > "$runner"
|
|
316
322
|
chmod +x "$runner"
|
|
317
323
|
chown "$runuser:$runuser" "$runner"
|
|
318
|
-
su -m "$runuser" -s /bin/bash "$runner" ||
|
|
324
|
+
su -m "$runuser" -s /bin/bash "$runner" || PIPE_AGENT_RC=$?
|
|
319
325
|
chown -R root:root "$PWD" 2>/dev/null || true
|
|
320
326
|
rm -f "$runner"
|
|
321
327
|
else
|
|
@@ -327,9 +333,32 @@ pipe_run_claude() {
|
|
|
327
333
|
else
|
|
328
334
|
capture_claude "$label" -- --dangerously-skip-permissions --allowedTools "$tools" -p "$skill" < "$stdin_file"
|
|
329
335
|
fi
|
|
330
|
-
) ||
|
|
336
|
+
) || PIPE_AGENT_RC=$?
|
|
331
337
|
fi
|
|
332
338
|
rm -f "$stdin_file"
|
|
339
|
+
[ "$PIPE_AGENT_RC" -eq 0 ] || pipe_log "agent exited with code $PIPE_AGENT_RC"
|
|
340
|
+
return 0
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
pipe_require_agent_ran() {
|
|
344
|
+
# $1 = file the skill was supposed to write (empty to check the exit code
|
|
345
|
+
# only, for skills whose marker is legitimately optional), $2 = human label.
|
|
346
|
+
# Fails the job when the agent crashed or wrote nothing. Without this an
|
|
347
|
+
# agent that never started is indistinguishable from one that ran and found
|
|
348
|
+
# nothing: every caller reads its marker file, misses it, and falls back to
|
|
349
|
+
# the "all clear" default, so the job goes green without a review, fix, or
|
|
350
|
+
# triage having happened.
|
|
351
|
+
local marker="$1" what="${2:-agent}"
|
|
352
|
+
if [ "${PIPE_AGENT_RC:-0}" -ne 0 ]; then
|
|
353
|
+
pipe_log "ERROR: $what did not complete (exit code $PIPE_AGENT_RC). See the job log above."
|
|
354
|
+
return 1
|
|
355
|
+
fi
|
|
356
|
+
[ -n "$marker" ] || return 0
|
|
357
|
+
if [ ! -s "$marker" ]; then
|
|
358
|
+
pipe_log "ERROR: $what produced no output ($marker is missing or empty)."
|
|
359
|
+
return 1
|
|
360
|
+
fi
|
|
361
|
+
return 0
|
|
333
362
|
}
|
|
334
363
|
|
|
335
364
|
# --- omp invocation -----------------------------------------------------
|
|
@@ -418,6 +447,9 @@ pipe_run_omp() {
|
|
|
418
447
|
# internally), $4 = model for the main loop (optional, e.g.
|
|
419
448
|
# $PIPE_MODEL_REVIEW; subagents keep the models from their own
|
|
420
449
|
# frontmatter), stdin = extra prompt (optional, usually empty).
|
|
450
|
+
#
|
|
451
|
+
# Same contract as pipe_run_claude: always returns 0 and reports the agent's
|
|
452
|
+
# real exit code in PIPE_AGENT_RC, which pipe_require_agent_ran checks.
|
|
421
453
|
local label="$1" skill="$2" tools="${3:-Agent,Read,Write,Edit,Glob,Grep,Bash}" model="${4:-}"
|
|
422
454
|
local omp_tools; omp_tools=$(pipe_translate_tools_to_omp "$tools")
|
|
423
455
|
# Bound the run below the job's own hard kill (see pipe_agent_max_time).
|
|
@@ -431,6 +463,7 @@ pipe_run_omp() {
|
|
|
431
463
|
pipe_require_harness omp
|
|
432
464
|
local stdin_file; stdin_file=$(mktemp)
|
|
433
465
|
cat > "$stdin_file" || true
|
|
466
|
+
PIPE_AGENT_RC=0
|
|
434
467
|
|
|
435
468
|
if [ "$(id -u)" -eq 0 ]; then
|
|
436
469
|
local runuser="pipelinebot"
|
|
@@ -465,7 +498,7 @@ pipe_run_omp() {
|
|
|
465
498
|
} > "$runner"
|
|
466
499
|
chmod +x "$runner"
|
|
467
500
|
chown "$runuser:$runuser" "$runner"
|
|
468
|
-
su -m "$runuser" -s /bin/bash "$runner" ||
|
|
501
|
+
su -m "$runuser" -s /bin/bash "$runner" || PIPE_AGENT_RC=$?
|
|
469
502
|
chown -R root:root "$PWD" 2>/dev/null || true
|
|
470
503
|
rm -f "$runner"
|
|
471
504
|
else
|
|
@@ -477,9 +510,11 @@ pipe_run_omp() {
|
|
|
477
510
|
else
|
|
478
511
|
capture_omp "$label" -- "${max_time_args[@]}" --yolo --no-session --no-title --tools "$omp_tools" -p "$skill" < "$stdin_file"
|
|
479
512
|
fi
|
|
480
|
-
) ||
|
|
513
|
+
) || PIPE_AGENT_RC=$?
|
|
481
514
|
fi
|
|
482
515
|
rm -f "$stdin_file"
|
|
516
|
+
[ "$PIPE_AGENT_RC" -eq 0 ] || pipe_log "agent exited with code $PIPE_AGENT_RC"
|
|
517
|
+
return 0
|
|
483
518
|
}
|
|
484
519
|
|
|
485
520
|
# --- Harness dispatch ---------------------------------------------------
|
|
@@ -41,6 +41,9 @@ echo "$NOTES" | jq -r --arg u "${PIPE_BOT_USER:-}" --arg m "$REVIEW_MARKER" \
|
|
|
41
41
|
# verifies, writes the result JSON, and the review-fix.env marker. On cap it
|
|
42
42
|
# runs the shared postmortem flow (writing postmortem.md + postmortem.env).
|
|
43
43
|
pipe_run_agent coder "/fix-review-findings" "Agent,Read,Write,Edit,Glob,Grep,Bash" "$PIPE_MODEL_CODE" < /dev/null
|
|
44
|
+
# A crashed agent writes no marker, which step 6 would read as "nothing changed"
|
|
45
|
+
# and step 7 would report as a completed fix run that had nothing to do.
|
|
46
|
+
pipe_require_agent_ran "" "The review-fix agent" || exit 1
|
|
44
47
|
|
|
45
48
|
# 6. Read the marker the skill wrote.
|
|
46
49
|
RF_ENV="$PIPE_CONTEXT_DIR/review-fix.env"
|
|
@@ -87,7 +87,14 @@ pipe_metric_event code-reviewer review_findings \
|
|
|
87
87
|
--argjson inc "$([ "${PIPE_IS_INCREMENTAL:-false}" = "true" ] && echo true || echo false)" \
|
|
88
88
|
'{findings_total: $t, status: $s, has_fixable_bugs: $b, is_incremental: $inc}')"
|
|
89
89
|
|
|
90
|
-
# 7.
|
|
90
|
+
# 7. Fail the job when no review was produced. The comment above already told
|
|
91
|
+
# the humans; this tells the pipeline. PIPE_NO_GATE does not apply: it turns
|
|
92
|
+
# off the verdict gate, and this is a broken run, not a verdict. Without it a
|
|
93
|
+
# review that never ran (crashed agent, missing ANTHROPIC_API_KEY) reads as a
|
|
94
|
+
# review that ran and found nothing, and the MR goes green unreviewed.
|
|
95
|
+
pipe_require_agent_ran "$PIPE_RESULT_REVIEW" "The review agent" || exit 1
|
|
96
|
+
|
|
97
|
+
# 8. Gate. review.env is exported so the fix job can read REVIEW_HAS_BUGS at
|
|
91
98
|
# runtime. On GitLab the job exits non-zero to block the pipeline. On GitHub
|
|
92
99
|
# the workflow step owns the gate (it reads the output first), so it sets
|
|
93
100
|
# PIPE_NO_GATE=1 and this script leaves the exit to the workflow.
|
|
@@ -27,6 +27,9 @@ COVERAGE_BEFORE=$(pipe_count_fix_commits "$PIPE_COMMIT_COVERAGE")
|
|
|
27
27
|
# test-writer, verifies, and writes fix-tests.env. On cap it runs the shared
|
|
28
28
|
# postmortem flow (writing postmortem.md + postmortem.env).
|
|
29
29
|
pipe_run_agent test-fix "/fix-tests" "Agent,Read,Write,Edit,Glob,Grep,Bash" "$PIPE_MODEL_CODE" < /dev/null
|
|
30
|
+
# A crashed agent writes no marker, which step 4 would read as FIX_BRANCH=none
|
|
31
|
+
# and report as a false-alarm trigger, hiding the failure behind a green job.
|
|
32
|
+
pipe_require_agent_ran "" "The test-fix agent" || exit 1
|
|
30
33
|
|
|
31
34
|
# 4. Read the marker the skill wrote.
|
|
32
35
|
FT_ENV="$PIPE_CONTEXT_DIR/fix-tests.env"
|