Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
36027bd
ci: add pilot Linux artifact workflow
theredspoon Apr 24, 2026
3d40671
test(e2e): unblock Live Canary auth lanes after engine-v2 contract ch…
ilblackdragon May 5, 2026
d4451df
docs: promote database and configuration pages from drafts to live
Apr 24, 2026
eaabb01
docs: fix broken links and add DATABASE_POOL_SIZE to database page
Apr 24, 2026
c8c8311
docs: fill gaps in database and onboard pages
Apr 24, 2026
0cde3a7
docs: warn about SQLite→Postgres migration incompatibility
Apr 24, 2026
be7c231
docs: fix DATABASE_POOL_SIZE default and add database link to quickstart
Apr 24, 2026
5d93264
docs: fix 10 wrong defaults and remove 6 phantom env vars
Apr 24, 2026
4ee917a
docs: mark superseded draft files
Apr 24, 2026
79491c8
docs: clarify configuration reference scope
serrrfirat May 5, 2026
074919b
docs: expand configuration variable reference
serrrfirat May 5, 2026
ca33ba8
Merge pull request #3258 from nearai/salvage/pr-2948-docs-navigation
serrrfirat May 5, 2026
e67945e
docs: salvage Docker Hub image name fix from #3217 (#3260)
serrrfirat May 5, 2026
72c9826
skills: salvage Linear credential and identity bootstrap fix from #29…
serrrfirat May 5, 2026
927dc21
test: salvage Admin and Responses API E2E coverage from #2174 (#3267)
serrrfirat May 5, 2026
836aebb
fix(ci): unblock coverage on main (#3268)
serrrfirat May 6, 2026
04bd4a8
ci(e2e): run full browser suite nightly (#3261)
serrrfirat May 6, 2026
ee5b430
ci: add deterministic nightly deep checks (#3262)
serrrfirat May 6, 2026
8afd552
ci: slim main merge queue checks (#3263)
serrrfirat May 6, 2026
c86f700
fix(e2e): stabilize coverage suite failures
serrrfirat May 6, 2026
bd165d8
Merge pull request #3291 from serrrfirat/fix/e2e-plan-mode-ci
serrrfirat May 6, 2026
cde13e5
ci: add nightly failure issue alerts (#3293)
serrrfirat May 6, 2026
dd77b31
fix(libsql): parse scientific notation cost aggregates (#3296) (#3297)
serrrfirat May 6, 2026
576eb3b
test(libsql): cover decimal parser error branch (#3304)
serrrfirat May 6, 2026
b0b8d87
test(db): serialize postgres migration fixup tests (#3307)
serrrfirat May 6, 2026
89c21aa
fix(ci): keep nightly e2e alert outside reusable workflow (#3312)
serrrfirat May 6, 2026
e8f68c9
feat: multi-tenant relay channel with per-user identity resolution (#…
PierreLeGuen May 6, 2026
f2a6859
fix(bridge): coerce engine action params per schema (#3132) (#3197)
ilblackdragon May 6, 2026
dbbc973
ci: build ironclaw docker image with staging tag from main branch (#3…
think-in-universe May 6, 2026
4ba943a
docs: refresh feature parity against OpenClaw 2026.3.11-2026.4.30 (#3…
ilblackdragon May 6, 2026
b8e6caa
fix(engine): inline gate await for Tier 0 + Tier 1 Approval gates (#3…
ilblackdragon May 7, 2026
6c9e2ca
ci: extend nightly e2e timeout (#3329)
serrrfirat May 7, 2026
5f4a4c7
ci: attribute nightly failures to PRs merged since last green (#3318)
zmanian May 7, 2026
7db0df6
test(reborn): add dedicated e2e gate (#3251)
serrrfirat May 7, 2026
fd590f1
test(e2e): address Gemini gateway smoke review (#3332)
serrrfirat May 7, 2026
80c20ed
fix(engine,web): suppress restart-recovery noise on Projects tab; ret…
ilblackdragon May 7, 2026
f948e11
feat: wechat channel (#1666)
hanakannzashi May 7, 2026
89443ac
fix(config): keep startup LLM fallback in-memory only (#3229) (#3324)
ilblackdragon May 7, 2026
487d181
fix(common): clarify crate-level doc wording (#3370)
nickpismenkov May 7, 2026
e79c25e
feat(common): align crate description with lib.rs doc wording (#3372)
nickpismenkov May 7, 2026
481a34a
fix(llm): route DeepSeek, Gemini, and OpenRouter through dedicated ri…
ilblackdragon May 7, 2026
2b9a56e
chore: release
ironclaw-ci[bot] May 7, 2026
9e69f22
chore(release): bump ironclaw to 0.28.0
nickpismenkov May 7, 2026
0ef6e69
Merge pull request #3376 from nearai/release-plz-2026-05-07T19-30-56Z
nickpismenkov May 7, 2026
4bd6c10
fix(web): bug bash — restart modal recovery, approval clarity, http d…
ilblackdragon May 7, 2026
3fab297
fix(bridge): bypass agent-loop mpsc for inline-await Approval gates (…
ilblackdragon May 8, 2026
762a8b3
Add WeChat registry artifact metadata (#3386)
hanakannzashi May 8, 2026
1ecb169
refactor(llm): extract multi-provider integration into ironclaw_llm c…
ilblackdragon May 8, 2026
37b62f8
fix(channels): activate WASM channels on headless servers (#3233)
ilblackdragon May 8, 2026
dc6b67c
fix(canary): seed github_token_scopes companion in auth-live-seeded (…
nickpismenkov May 8, 2026
875387f
fix: multi-tenant workspace memory isolation (#3374)
serrrfirat May 8, 2026
4696a0a
fix(missions): auto-resume paused missions after gate resolution (#31…
ilblackdragon May 8, 2026
26c8b67
fix(e2e): restore auth and approval coverage (#3430)
serrrfirat May 9, 2026
6e6eca7
test(e2e): avoid REPL auth retry race (#3437)
serrrfirat May 9, 2026
60eb74f
feat: add pairing_approve tool for Slack binding via chat (#3396)
PierreLeGuen May 11, 2026
21e27b2
fix(web): isolate cross-tenant SSE/WS status events and thread access…
ilblackdragon May 11, 2026
09d3ebb
fix(auth): tighten Telegram pairing UX and OAuth-failure recovery (#3…
ilblackdragon May 11, 2026
4d485e0
feat(common): describe paths and platform helpers in crate descriptio…
nickpismenkov May 11, 2026
1f4fa56
chore: release
ironclaw-ci[bot] May 11, 2026
11aa7e3
chore(release): bump ironclaw to 0.28.1
nickpismenkov May 11, 2026
183a80d
Merge pull request #3388 from nearai/release-plz-2026-05-08T06-56-36Z
nickpismenkov May 11, 2026
cfeae9e
refactor(llm): hide provider-specific auth, model fetch, and embeddin…
ilblackdragon May 11, 2026
0e3a2c7
Make Skills E2E lifecycle deterministic (#3309)
serrrfirat May 12, 2026
e34309b
test(e2e): unxfail two auth-matrix tests now that contracts match (#3…
ilblackdragon May 13, 2026
34eeeaf
fix(extensions): restore chat-driven tool_install + fix double-invoke…
ilblackdragon May 13, 2026
85ae2bc
chore: release
nickpismenkov May 15, 2026
faf2ed4
Merge pull request #3674 from nearai/release/ironclaw-0.28.2
nickpismenkov May 15, 2026
cab708e
feat(engine): IRONCLAW_DISABLE_CODEACT flag to disable v2 CodeAct (#3…
May 15, 2026
201e216
Fix markdown_to_mrkdwn to avoid converting emphasis inside generated …
ilblackdragon May 15, 2026
c93c455
feat(gateway): add logs download button (#3588)
serrrfirat May 16, 2026
e31f34c
feat(web): support externally-provided tools in Responses API (#3122)
ilblackdragon May 16, 2026
b921b42
docs(api): document the Responses API end-to-end (#3709)
ilblackdragon May 16, 2026
4fea8b3
chore(deps): bump deps to address security advisories (#3719)
ilblackdragon May 17, 2026
c159315
merge: pull upstream/main into origin/main
theredspoon May 18, 2026
2deef75
ci: add daily upstream sync workflow
theredspoon May 18, 2026
ac5384b
ci: hourly upstream sync with enjimi mirror push
theredspoon May 18, 2026
8f6c4f0
ci: mirror all pushes to enjimi/ironclaw
theredspoon May 18, 2026
e3e56dc
ci: scope enjimi mirror to main and pilot branch
theredspoon May 18, 2026
58c1b35
ci: debug enjimi mirror token
theredspoon May 18, 2026
edc47ca
fix(ci): disable checkout credential helper for enjimi push
theredspoon May 18, 2026
2c7963b
chore(ci): bump actions/checkout to v6
theredspoon May 18, 2026
22603d7
ci: scope sync and mirror workflows to theredspoon only
theredspoon May 18, 2026
83b4a55
chore: add .fork-only to guard upstream PRs
theredspoon May 18, 2026
32d0fda
chore: add .fork-only to its own exclusion list
theredspoon May 18, 2026
6fc4f33
feat(tui): Ctrl-S downloads logs from the Logs tab (#3658)
May 18, 2026
8a12959
fix(canary): accurate test counts, chat-install probe, strict xfails …
nickpismenkov May 19, 2026
f1a8664
refactor: extract embeddings into ironclaw_embeddings crate (#3739)
ilblackdragon May 19, 2026
d47dfa5
fix(web): restore NEAR AI API Key + Fetch Models in configure UI (#37…
italic-jinxin May 20, 2026
81be41c
ci: add /benchmark slash-command dispatcher (#3808)
pranavraja99 May 20, 2026
b825a6c
fix(ci): grant pull-requests:write for /benchmark reactions endpoint …
pranavraja99 May 21, 2026
030cfeb
feat(ci): post "started" comment with link to dispatcher run (#3836)
pranavraja99 May 21, 2026
a91426c
chore(deps): update wasmtime to clear cargo-deny advisory (#4028)
hanakannzashi May 25, 2026
2a95799
feat: wecom channel (#2394)
hanakannzashi May 25, 2026
f0abd23
chore: v0.29.0 release (#4077)
think-in-universe May 26, 2026
9df5e8d
chore: add WeCom release artifact (#4107)
hanakannzashi May 27, 2026
0a6c212
plumb temperature through Responses API (#3641)
May 28, 2026
27994a1
ci(nearai-bench): track nearai/benchmarks @main instead of pinning (#…
pranavraja99 May 28, 2026
f314390
ci(nearai-bench): grant id-token: write to unblock reusable workflow …
pranavraja99 May 29, 2026
749f584
ci(nearai-bench): scope id-token: write to the bench job (#4221)
pranavraja99 May 29, 2026
287df65
ci: avoid tag conflicts during upstream sync
theredspoon Jun 1, 2026
f833a63
ci: configure identity for upstream sync PRs
theredspoon Jun 1, 2026
4918e0a
Merge branch 'main' of https://github.com/nearai/ironclaw into sync/u…
Jun 1, 2026
999d916
sync: update Matrix pilot with nearai main
theredspoon Jun 2, 2026
530de12
fix: satisfy Matrix pilot CI gates
theredspoon Jun 2, 2026
fc25da6
Declare Matrix SDK git dependency version
theredspoon Jun 2, 2026
a93afc6
ci: mirror Matrix pilot to enjimi main
theredspoon Jun 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .fork-only
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Files that exist only on this fork and must not be pushed to upstream.
# Used by the global pre-push hook to block accidental inclusion in PRs.
.fork-only
.github/workflows/sync-upstream.yml
.github/workflows/mirror-to-enjimi.yml
323 changes: 323 additions & 0 deletions .github/scripts/nightly-alert-issue.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,323 @@
#!/usr/bin/env bash
set -euo pipefail

# Create, update, or close a GitHub issue for a scheduled nightly workflow.
# Required env:
# GH_TOKEN, REPO, ALERT_WORKFLOW_NAME, ALERT_ISSUE_TITLE, ALERT_RESULT
# Optional env:
# ALERT_RUN_ID, ALERT_RUN_URL, ALERT_SHA, MAX_EXCERPT_LINES

require_env() {
local name="$1"
if [[ -z "${!name:-}" ]]; then
echo "Required environment variable ${name} is not set" >&2
exit 2
fi
}

strip_ansi() {
# Keep this sed expression POSIX-ish for the GitHub ubuntu runner.
sed -E $'s/\x1B\[[0-9;?]*[ -/]*[@-~]//g'
}

truncate_lines() {
local max_chars="$1"
awk -v max_chars="$max_chars" '
length($0) > max_chars { print substr($0, 1, max_chars) "... [line truncated]"; next }
{ print }
'
}

truncate_file_chars() {
local input_file="$1"
local output_file="$2"
local max_chars="$3"
local label="${4:-content}"
awk -v max_chars="$max_chars" -v label="$label" '
BEGIN { used = 0 }
{
line = $0 "\n"
line_len = length(line)
if (used + line_len > max_chars) {
remaining = max_chars - used
if (remaining > 0) {
printf "%s", substr(line, 1, remaining)
}
printf "\n... [%s truncated to %s characters]\n", label, max_chars
exit
}
printf "%s", line
used += line_len
}
' "$input_file" > "$output_file"
}

extract_failure_excerpt() {
local log_file="$1"
local output_file="$2"
local max_lines="${3:-${MAX_EXCERPT_LINES:-220}}"
local max_line_chars="${MAX_EXCERPT_LINE_CHARS:-2000}"
local max_excerpt_chars="${MAX_EXCERPT_CHARS:-50000}"
local cleaned_log raw_excerpt line_limited_excerpt
cleaned_log="$(mktemp)"
raw_excerpt="$(mktemp)"
line_limited_excerpt="$(mktemp)"

if [[ ! -s "$log_file" ]]; then
echo "No failed-job logs were available from GitHub Actions." > "$output_file"
return 0
fi

strip_ansi < "$log_file" > "$cleaned_log"

# Prefer high-signal lines from pytest, Rust/cargo, GitHub Actions, runner
# infrastructure, and common timeout/disk failures. Keep the excerpt bounded so
# repeated nightly failures do not create unreadably large issue comments.
grep -nEi \
'(^|[[:space:]])(FAILED|ERROR|FAILURES|failures:|test result: FAILED|panicked at|thread .+ panicked|No space left|timed out|timeout|Process completed with exit code|::error|Error:|Traceback|AssertionError|short test summary info|cargo (test|nextest|insta)|pytest|failed to|could not|cannot|killed|segmentation fault|signal:)' \
"$cleaned_log" \
| head -n "$max_lines" \
> "$raw_excerpt" || true

if [[ ! -s "$raw_excerpt" ]]; then
{
echo "No high-signal failure lines matched; showing the last 120 failed-log lines instead."
echo
tail -n 120 "$cleaned_log"
} > "$raw_excerpt"
fi

truncate_lines "$max_line_chars" < "$raw_excerpt" > "$line_limited_excerpt"
truncate_file_chars "$line_limited_excerpt" "$output_file" "$max_excerpt_chars" "excerpt"

rm -f "$cleaned_log" "$raw_excerpt" "$line_limited_excerpt"
}

find_open_issue() {
local title="$1"
gh issue list \
--repo "$REPO" \
--state open \
--search "${title} in:title" \
--json number,title \
--jq 'map(select(.title == env.ALERT_ISSUE_TITLE))[0].number // empty'
}

# Collect PRs merged into the alert branch since the previous successful run of
# this workflow, so the failure issue can @-mention authors who landed in the
# blame window. All API calls are best-effort: if any step fails (no prior
# green run, missing GroOT pulls endpoint, transient API error) the function
# writes a one-line note to its output file and returns 0 so the rest of the
# alert body renders normally.
collect_merged_prs() {
local output_file="$1"
local branch="${ALERT_BRANCH:-${GITHUB_REF_NAME:-main}}"
local current_sha="${ALERT_SHA}"
local max_prs="${ALERT_MAX_MERGED_PRS:-30}"

: > "$output_file"

local last_good_sha
last_good_sha="$(
gh run list \
--repo "$REPO" \
--workflow "$ALERT_WORKFLOW_NAME" \
--branch "$branch" \
--status success \
--limit 1 \
--json headSha \
--jq '.[0].headSha // empty' \
2>/dev/null
)" || true

if [[ -z "$last_good_sha" || "$last_good_sha" == "$current_sha" ]]; then
echo "_No prior successful \`${ALERT_WORKFLOW_NAME}\` run on \`${branch}\` to attribute against._" > "$output_file"
return 0
fi

local commits
commits="$(
gh api "repos/${REPO}/compare/${last_good_sha}...${current_sha}" \
--jq '.commits[].sha' \
2>/dev/null
)" || true

if [[ -z "$commits" ]]; then
echo "_No new commits between \`${last_good_sha:0:7}\` (last green) and \`${current_sha:0:7}\` (this run)._" > "$output_file"
return 0
fi

local pr_rows
pr_rows="$(mktemp)"
while IFS= read -r sha; do
[[ -z "$sha" ]] && continue
gh api "repos/${REPO}/commits/${sha}/pulls" \
--jq '.[] | select(.merged_at != null) | "\(.number)\t\(.user.login)\t\(.title)"' \
2>/dev/null \
>> "$pr_rows" || true
done <<< "$commits"

if [[ ! -s "$pr_rows" ]]; then
{
echo "Commits since last green at \`${last_good_sha:0:7}\` (no associated merged PRs found):"
echo
while IFS= read -r sha; do
[[ -z "$sha" ]] && continue
echo "- \`${sha:0:7}\`"
done <<< "$commits"
} > "$output_file"
rm -f "$pr_rows"
return 0
fi

local total_prs
total_prs="$(sort -k1,1n "$pr_rows" | awk -F'\t' '!seen[$1]++' | wc -l | tr -d ' ')"
{
echo "PRs merged into \`${branch}\` between \`${last_good_sha:0:7}\` (last green) and \`${current_sha:0:7}\` (this run):"
echo
sort -k1,1n "$pr_rows" \
| awk -F'\t' '!seen[$1]++' \
| head -n "$max_prs" \
| while IFS=$'\t' read -r number author title; do
echo "- #${number} ${title} — @${author}"
done
if [[ "$total_prs" -gt "$max_prs" ]]; then
echo
echo "_Showing first ${max_prs} of ${total_prs} PRs in the window._"
fi
} > "$output_file"
rm -f "$pr_rows"
}

write_failure_body() {
local body_file="$1"
local jobs_file="$2"
local excerpt_file="$3"
local log_error_file="$4"
local merged_prs_file="${5:-}"

{
echo "❌ ${ALERT_WORKFLOW_NAME} scheduled run failed."
echo
echo "- Workflow: ${ALERT_WORKFLOW_NAME}"
echo "- Result: ${ALERT_RESULT}"
echo "- Run: ${ALERT_RUN_URL}"
echo "- Commit: ${ALERT_SHA}"
echo "- Attempt: ${GITHUB_RUN_ATTEMPT:-1}"
echo "- Reported at: $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
echo
echo "## Failed jobs"
if [[ -s "$jobs_file" ]]; then
cat "$jobs_file"
else
echo "No failed job metadata was available from the Actions API. Check the run link above."
fi
echo
if [[ -s "$log_error_file" ]]; then
echo "## Log retrieval notes"
echo
echo "The alert job could not retrieve full failed-job logs with \`gh run view --log-failed\`. The run link and failed job links above are still authoritative."
echo
echo '```text'
head -n 40 "$log_error_file" | sed 's/```/` ` `/g'
echo '```'
echo
fi
echo "## Failure excerpt"
echo
echo '```text'
sed 's/```/` ` `/g' "$excerpt_file"
echo '```'
echo
if [[ -n "$merged_prs_file" && -s "$merged_prs_file" ]]; then
echo "## Merged since last green"
echo
cat "$merged_prs_file"
echo
fi
echo "This issue is updated in place on repeated failures to avoid notification spam. If the next scheduled run passes, the nightly alert job will close this issue automatically."
} > "$body_file"
}

write_recovery_body() {
local body_file="$1"
{
echo "✅ ${ALERT_WORKFLOW_NAME} recovered on the latest scheduled run."
echo
echo "- Run: ${ALERT_RUN_URL}"
echo "- Commit: ${ALERT_SHA}"
echo "- Reported at: $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
} > "$body_file"
}

main() {
require_env GH_TOKEN
require_env REPO
require_env ALERT_WORKFLOW_NAME
require_env ALERT_ISSUE_TITLE
require_env ALERT_RESULT

export ALERT_ISSUE_TITLE

ALERT_RUN_ID="${ALERT_RUN_ID:-${GITHUB_RUN_ID:-}}"
ALERT_RUN_URL="${ALERT_RUN_URL:-${GITHUB_SERVER_URL:-https://github.com}/${GITHUB_REPOSITORY:-$REPO}/actions/runs/${ALERT_RUN_ID}}"
ALERT_SHA="${ALERT_SHA:-${GITHUB_SHA:-unknown}}"

if [[ -z "$ALERT_RUN_ID" ]]; then
echo "ALERT_RUN_ID or GITHUB_RUN_ID is required" >&2
exit 2
fi

local issue_number
issue_number="$(find_open_issue "$ALERT_ISSUE_TITLE")"

if [[ "$ALERT_RESULT" == "success" ]]; then
if [[ -n "$issue_number" ]]; then
local recovery_body
recovery_body="$(mktemp)"
write_recovery_body "$recovery_body"
gh issue close "$issue_number" --repo "$REPO" --comment "$(cat "$recovery_body")"
rm -f "$recovery_body"
else
echo "${ALERT_WORKFLOW_NAME} succeeded and no open alert issue exists."
fi
exit 0
fi

local tmp_dir log_file log_error failed_jobs excerpt body merged_prs
tmp_dir="$(mktemp -d)"
log_file="${tmp_dir}/failed.log"
log_error="${tmp_dir}/failed-log-error.txt"
failed_jobs="${tmp_dir}/failed-jobs.md"
excerpt="${tmp_dir}/excerpt.txt"
merged_prs="${tmp_dir}/merged-prs.md"
body="${tmp_dir}/issue.md"

if ! gh run view "$ALERT_RUN_ID" --repo "$REPO" --log-failed > "$log_file" 2> "$log_error"; then
echo "Warning: failed to retrieve failed-job logs for run ${ALERT_RUN_ID}" >&2
fi

gh api "repos/${REPO}/actions/runs/${ALERT_RUN_ID}/jobs?per_page=100" \
--jq '.jobs[] | select(.status == "completed" and .conclusion != "success" and .conclusion != "skipped") | "- \(.name) (`\(.conclusion // "unknown")`): \(.html_url)"' \
> "$failed_jobs" || true

collect_merged_prs "$merged_prs"

extract_failure_excerpt "$log_file" "$excerpt" "${MAX_EXCERPT_LINES:-220}"
write_failure_body "$body" "$failed_jobs" "$excerpt" "$log_error" "$merged_prs"
truncate_file_chars "$body" "${body}.bounded" "${MAX_ISSUE_BODY_CHARS:-60000}" "issue body"
mv "${body}.bounded" "$body"

if [[ -n "$issue_number" ]]; then
gh issue edit "$issue_number" --repo "$REPO" --body-file "$body"
echo "Updated existing nightly alert issue #${issue_number}."
else
gh issue create --repo "$REPO" --title "$ALERT_ISSUE_TITLE" --body-file "$body"
fi

rm -rf "$tmp_dir"
}

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
main "$@"
fi
Loading
Loading