Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
02fa404
fix: add musl targets for Linux installer fallback
Mar 12, 2026
bca8bbc
fix: update Cargo.lock and pin musl CI runners
Mar 13, 2026
8526cde
fix: restore libSQL vector search with dynamic dimensions (#1393)
ilblackdragon Mar 20, 2026
455f543
fix(routines): surface errors when sandbox unavailable for full_job r…
zmanian Mar 20, 2026
3a52334
fix: f32→f64 precision artifact in temperature causes provider 400 er…
ilblackdragon Mar 20, 2026
806d402
feat: chat onboarding and routine advisor (#927)
ilblackdragon Mar 20, 2026
31c3b5b
feat(agent): activate stuck_threshold for time-based stuck job detect…
zmanian Mar 20, 2026
ef3d769
fix(security): validate embedding base URLs to prevent SSRF (#1221)
zmanian Mar 20, 2026
b952d22
fix: prefer execution-local message routing metadata (#1449)
henrypark133 Mar 20, 2026
e82f4bd
fix: register sandbox jobs in ContextManager for query tool visibilit…
vnz Mar 20, 2026
c176261
fix: skip credential validation for Bedrock backend (#1011)
rajulbhatnagar Mar 20, 2026
1b97ef4
fix: resolve wasm broadcast merge conflicts with staging (#395) (#1460)
ilblackdragon Mar 20, 2026
cba1bc3
feat(web): add light theme with dark/light/system toggle (#1457)
ilblackdragon Mar 20, 2026
3da9810
feat(llm): Add OpenAI Codex (ChatGPT subscription) as LLM provider (#…
ilblackdragon Mar 20, 2026
ee6f5cd
Use live owner tool scope for autonomous routines and jobs (#1453)
henrypark133 Mar 20, 2026
d3b69e7
Fix CI approval flows and stale fixtures (#1478)
henrypark133 Mar 20, 2026
9603fef
fix(setup): remove redundant LLM config and API keys from bootstrap .…
ilblackdragon Mar 20, 2026
6d847c6
feat(webhooks): add public webhook trigger endpoint for routines (#736)
zmanian Mar 20, 2026
47ba486
docs: Expand AGENTS.md with coding agents guidance (#1392)
qstommyshu Mar 21, 2026
c6d4abd
fix(ci): serialize env-mutating OAuth wildcard tests with ENV_MUTEX (…
zmanian Mar 21, 2026
a4f6cda
fix(routines): add missing extension_manager field in trigger_manual …
ilblackdragon Mar 21, 2026
e6277a3
perf(safety): single-pass escape_xml_attr (#1028)
G7CNF Mar 21, 2026
0d1a5c2
fix(deps): patch rustls-webpki vulnerability (RUSTSEC-2026-0049)
ilblackdragon Mar 21, 2026
212d661
feat(workspace): layered memory with sensitivity-based privacy redire…
standardtoaster Mar 21, 2026
9964d5d
feat(web-search): include thumbnail URLs in search results (#1313)
jackdempsey Mar 21, 2026
1d6f7d5
fix: persist startup-loaded MCP clients in ExtensionManager (#1509)
ilblackdragon Mar 21, 2026
6232609
feat(llm): add GitHub Copilot as LLM provider (#1512)
ilblackdragon Mar 21, 2026
8ad7d78
fix: parameter coercion and validation for oneOf/anyOf/allOf schemas …
ilblackdragon Mar 21, 2026
9d53813
fix(oauth): reject malformed ic2.* states in decode_hosted_oauth_stat…
ilblackdragon Mar 21, 2026
b97d82d
feat(extensions): support text setup fields in web configure modal (#…
Mcxiaocaibug Mar 21, 2026
189fc03
Merge branch 'staging' into fix/musl-installer-targets
ilblackdragon Mar 21, 2026
07c338f
fix(safety): escape tool output XML content and remove misleading san…
zmanian Mar 22, 2026
0e5837b
Merge pull request #1013 from rajulbhatnagar/fix/musl-installer-targets
ilblackdragon Mar 22, 2026
89394eb
feat(cli): add `ironclaw hooks list` subcommand (#1023)
reidliu41 Mar 22, 2026
ccdea40
feat(agent): queue and merge messages during active turns (#1412)
ilblackdragon Mar 22, 2026
b58b421
feat(shell): add Low/Medium/High risk levels for graduated command ap…
nlok5923 Mar 22, 2026
8638895
feat(gemini_oauth): full Gemini CLI OAuth integration with Cloud Code…
Mffff4 Mar 22, 2026
a09c023
feat(ux): complete UX overhaul — design system, onboarding, web polis…
ilblackdragon Mar 22, 2026
1a62feb
perf(agent): avoid preview allocations for non-truncated strings (fix…
G7CNF Mar 22, 2026
fbce9a5
refactor(llm): move transcription module into src/llm/ (#1559)
ilblackdragon Mar 22, 2026
3aa36c8
fix(tests): eliminate env mutex poison cascade (#1558)
ilblackdragon Mar 22, 2026
969b559
fix(mcp): handle empty 202 notification acknowledgements (#1539)
G7CNF Mar 22, 2026
3e73dbe
perf(tools): remove unconditional params clone in shared execution (f…
G7CNF Mar 23, 2026
7034e91
fix: generate Mistral-compatible 9-char alphanumeric tool call IDs (#…
noverby Mar 23, 2026
abba083
docs(feishu): clarify webhook-only event subscription support (#1567)
G7CNF Mar 23, 2026
4d7501a
Fix owner-scoped message routing fallbacks (#1574)
henrypark133 Mar 23, 2026
8f6999a
docs: add gitcgr code graph badge (#1563)
vitali87 Mar 23, 2026
d9358b0
feat(workspace): multi-scope workspace reads (#1117)
standardtoaster Mar 23, 2026
acb5902
test: Google OAuth URL broken when initiated from Telegram channel (#…
nickpismenkov Mar 23, 2026
485d156
feat(cli): add ironclaw models subcommands (list/status/set/set-provi…
reidliu41 Mar 23, 2026
dea789c
Default new lightweight routines to tools-enabled (#1573)
henrypark133 Mar 23, 2026
ddf64e8
Merge pull request #1466 from nearai/staging-promote/3da9810e-2335168…
henrypark133 Mar 23, 2026
0194275
Merge pull request #1462 from nearai/staging-promote/cba1bc37-2333437…
henrypark133 Mar 23, 2026
bb57e36
Merge pull request #1459 from nearai/staging-promote/c1762616-2333296…
henrypark133 Mar 23, 2026
74b2b41
Merge pull request #1456 from nearai/staging-promote/b952d229-2333146…
henrypark133 Mar 23, 2026
98418b3
Merge pull request #1452 from nearai/staging-promote/806d4028-2333026…
henrypark133 Mar 23, 2026
fa51b9f
fix: post-merge review sweep — 8 fixes across security, perf, and cor…
ilblackdragon Mar 23, 2026
ae370d7
Merge pull request #1467 from nearai/staging-promote/ee6f5cd6-2335412…
henrypark133 Mar 24, 2026
b441ebe
feat: multi-tenant auth with per-user workspace isolation (#1118)
standardtoaster Mar 24, 2026
3fdb187
refactor(tools): auto-compact WASM tool schemas, add descriptions, im…
ilblackdragon Mar 24, 2026
5847479
fix(agent): persist /model selection to .env, TOML, and DB (#1581)
ilblackdragon Mar 24, 2026
fb35489
fix(tunnel): managed tunnels target wrong port and die from SIGPIPE (…
nearfamiliarcow Mar 24, 2026
01678be
fix(routines): normalize status display across web and CLI (#1469)
zmanian Mar 24, 2026
d3d517f
fix(agent): case-insensitive channel match and user_id filter for eve…
zmanian Mar 24, 2026
5901451
fix: remove stale stream_token gate from channel-relay activation (#1…
PierreLeGuen Mar 24, 2026
424b470
Merge pull request #1483 from nearai/staging-promote/d3b69e7b-2335966…
henrypark133 Mar 24, 2026
f3da30a
perf(agent): optimize approval thread resolution (UUID parsing + lock…
zmanian Mar 24, 2026
dcb2d89
Fix hosted OAuth refresh via proxy (#1602)
henrypark133 Mar 24, 2026
82822d7
fix: restore owner-scoped gateway startup (#1625)
henrypark133 Mar 24, 2026
6561517
feat(cli): show credential auth status in tool info (#1572)
ilblackdragon Mar 25, 2026
706c3a1
refactor: extract AppEvent to crates/ironclaw_common (#1615)
ilblackdragon Mar 25, 2026
6daa2f1
fix: ensure LLM calls always end with user message (closes #763) (#1259)
Jacob-Lasky Mar 25, 2026
67a025e
fix(deps): unblock promotion PR #1451 cargo-deny
serrrfirat Mar 25, 2026
41ed0a0
feat(agent): thread per-tool reasoning through provider, session, and…
ilblackdragon Mar 25, 2026
0341fcc
Fix REPL single-message hang and cap CI test duration (#1643)
henrypark133 Mar 25, 2026
c949521
Fix MCP lifecycle trace user scope (#1646)
henrypark133 Mar 25, 2026
ab0ad94
Normalize cron schedules on routine create (#1648)
henrypark133 Mar 25, 2026
86d1143
Fix libsql prompt scope regressions (#1651)
henrypark133 Mar 25, 2026
5a5ffe8
Merge pull request #1654 from nearai/staging-promote/86d11430-2356541…
henrypark133 Mar 25, 2026
c5dce27
Merge pull request #1649 from nearai/staging-promote/ab0ad948-2356332…
henrypark133 Mar 25, 2026
189fa35
Merge pull request #1647 from nearai/staging-promote/c949521d-2356210…
henrypark133 Mar 25, 2026
c98ec3f
Merge pull request #1645 from nearai/staging-promote/0341fcc9-2355827…
henrypark133 Mar 25, 2026
b8b88ab
Merge pull request #1642 from nearai/staging-promote/6daa2f15-2353819…
henrypark133 Mar 25, 2026
492d9d2
Merge pull request #1627 from nearai/staging-promote/82822d7b-2351653…
henrypark133 Mar 25, 2026
9fd5537
Merge pull request #1624 from nearai/staging-promote/59014516-2350537…
henrypark133 Mar 25, 2026
0145672
Merge pull request #1620 from nearai/staging-promote/d3d517fd-2349196…
henrypark133 Mar 25, 2026
c737fb0
Merge pull request #1616 from nearai/staging-promote/fb354895-2347784…
henrypark133 Mar 25, 2026
a23d87f
Merge pull request #1606 from nearai/staging-promote/fa51b9f5-2346874…
henrypark133 Mar 25, 2026
d4e1802
Merge pull request #1604 from nearai/staging-promote/dea789cc-2345569…
henrypark133 Mar 25, 2026
e15c50e
Merge pull request #1593 from nearai/staging-promote/485d1568-2343977…
henrypark133 Mar 25, 2026
ad20a5a
Merge pull request #1583 from nearai/staging-promote/d9358b0f-2342613…
henrypark133 Mar 25, 2026
1f8d901
Merge pull request #1576 from nearai/staging-promote/abba0831-2341593…
henrypark133 Mar 25, 2026
2f47c61
Merge pull request #1561 from nearai/staging-promote/fbce9a5f-2340388…
henrypark133 Mar 25, 2026
2f80b7b
Merge pull request #1560 from nearai/staging-promote/1a62febe-2339806…
henrypark133 Mar 25, 2026
a19deb6
Merge pull request #1556 from nearai/staging-promote/86388958-2339716…
henrypark133 Mar 25, 2026
16aaea8
Merge pull request #1555 from nearai/staging-promote/b58b4215-2339645…
henrypark133 Mar 25, 2026
cb01800
Merge pull request #1553 from nearai/staging-promote/89394ebd-2339576…
henrypark133 Mar 25, 2026
f9dfb74
Merge pull request #1552 from nearai/staging-promote/b97d82db-2339077…
henrypark133 Mar 25, 2026
3d43917
Merge pull request #1551 from nearai/staging-promote/9d538136-2338976…
henrypark133 Mar 25, 2026
5d714be
Merge pull request #1548 from nearai/staging-promote/8ad7d78a-2338760…
henrypark133 Mar 25, 2026
c0f33c3
Merge pull request #1522 from nearai/staging-promote/62326090-2337457…
henrypark133 Mar 25, 2026
2b4e881
Merge pull request #1517 from nearai/staging-promote/9964d5da-2337276…
henrypark133 Mar 25, 2026
4c5d961
Merge pull request #1515 from nearai/staging-promote/0d1a5c21-2337203…
henrypark133 Mar 25, 2026
8d63287
Merge pull request #1514 from nearai/staging-promote/e6277a39-2337126…
henrypark133 Mar 25, 2026
ea24d79
Merge pull request #1508 from nearai/staging-promote/6d847c60-2336610…
henrypark133 Mar 25, 2026
b400c2a
Merge pull request #1499 from nearai/staging-promote/9603fefd-2336443…
henrypark133 Mar 25, 2026
ef37d70
Merge pull request #1655 from nearai/codex/fix-staging-promotion-1451…
henrypark133 Mar 25, 2026
bb24952
Merge branch 'main' into staging-promote/455f543b-23329172268
henrypark133 Mar 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ DATABASE_POOL_SIZE=10

# LLM Provider
# LLM_BACKEND=nearai # default
# Possible values: nearai, ollama, openai_compatible, openai, anthropic, tinfoil
# Possible values: nearai, ollama, openai_compatible, openai, anthropic, github_copilot, tinfoil, openai_codex, gemini_oauth
# LLM_REQUEST_TIMEOUT_SECS=120 # Increase for local LLMs (Ollama, vLLM, LM Studio)

# === Anthropic Direct ===
Expand All @@ -24,14 +24,25 @@ DATABASE_POOL_SIZE=10
# LLM_USE_CODEX_AUTH=true
# CODEX_AUTH_PATH=~/.codex/auth.json

# === GitHub Copilot ===
# Uses the OAuth token from your Copilot IDE sign-in (for example
# ~/.config/github-copilot/apps.json on Linux/macOS), or run `ironclaw onboard`
# and choose the GitHub device login flow.
# LLM_BACKEND=github_copilot
# GITHUB_COPILOT_TOKEN=gho_...
# GITHUB_COPILOT_MODEL=gpt-4o
# IronClaw injects standard VS Code Copilot headers automatically.
# Optional advanced headers for custom overrides:
# GITHUB_COPILOT_EXTRA_HEADERS=Copilot-Integration-Id:vscode-chat

# === NEAR AI (Chat Completions API) ===
# Two auth modes:
# 1. Session token (default): Uses browser OAuth (GitHub/Google) on first run.
# Session token stored in ~/.ironclaw/session.json automatically.
# Base URL defaults to https://private.near.ai
# 2. API key: Set NEARAI_API_KEY to use API key auth from cloud.near.ai.
# Base URL defaults to https://cloud-api.near.ai
NEARAI_MODEL=zai-org/GLM-5-FP8
NEARAI_MODEL=Qwen/Qwen3.5-122B-A10B
NEARAI_BASE_URL=https://private.near.ai
NEARAI_AUTH_URL=https://private.near.ai
# NEARAI_SESSION_TOKEN=sess_... # hosting providers: set this
Expand Down Expand Up @@ -92,6 +103,30 @@ NEARAI_AUTH_URL=https://private.near.ai
# long = 1-hour TTL, 2.0× (200%) write surcharge
# ANTHROPIC_CACHE_RETENTION=short

# === OpenAI Codex (ChatGPT subscription, OAuth) ===
# LLM_BACKEND=openai_codex
# OPENAI_CODEX_MODEL=gpt-5.3-codex # default
# OPENAI_CODEX_CLIENT_ID=app_EMoamEEZ73f0CkXaXp7hrann # override (rare)
# OPENAI_CODEX_AUTH_URL=https://auth.openai.com # override (rare)
# OPENAI_CODEX_API_URL=https://chatgpt.com/backend-api/codex # override (rare)

# === Google Gemini (OAuth, Gemini CLI compatible) ===
# LLM_BACKEND=gemini_oauth
# GEMINI_MODEL=gemini-2.5-flash # default
# GEMINI_CREDENTIALS_PATH=~/.gemini/oauth_creds.json # default
# GEMINI_API_KEY=... # optional: use API key instead of OAuth
# GEMINI_API_KEY_AUTH_MECHANISM=query # "query" (default) or "header"
# GEMINI_SAFETY_BLOCK_NONE=true # disable safety filters (default: false)
# GEMINI_CLI_CUSTOM_HEADERS=Key:Value,Key2:Value2
# GEMINI_TOP_P=0.95
# GEMINI_TOP_K=40
# GEMINI_SEED=42
# GEMINI_PRESENCE_PENALTY=0.0
# GEMINI_FREQUENCY_PENALTY=0.0
# GEMINI_RESPONSE_MIME_TYPE=application/json
# GEMINI_RESPONSE_JSON_SCHEMA={"type":"object"}
# GEMINI_CACHED_CONTENT=cachedContents/abc123

# For full provider setup guide see docs/LLM_PROVIDERS.md

# Channel Configuration
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
- group: features
files: "tests/e2e/scenarios/test_skills.py tests/e2e/scenarios/test_tool_approval.py tests/e2e/scenarios/test_webhook.py"
- group: extensions
files: "tests/e2e/scenarios/test_extensions.py tests/e2e/scenarios/test_extension_oauth.py tests/e2e/scenarios/test_telegram_token_validation.py tests/e2e/scenarios/test_telegram_hot_activation.py tests/e2e/scenarios/test_wasm_lifecycle.py tests/e2e/scenarios/test_tool_execution.py tests/e2e/scenarios/test_pairing.py tests/e2e/scenarios/test_mcp_auth_flow.py tests/e2e/scenarios/test_oauth_credential_fallback.py tests/e2e/scenarios/test_routine_oauth_credential_injection.py"
files: "tests/e2e/scenarios/test_extensions.py tests/e2e/scenarios/test_extension_oauth.py tests/e2e/scenarios/test_oauth_url_parameters.py tests/e2e/scenarios/test_telegram_token_validation.py tests/e2e/scenarios/test_telegram_hot_activation.py tests/e2e/scenarios/test_wasm_lifecycle.py tests/e2e/scenarios/test_tool_execution.py tests/e2e/scenarios/test_pairing.py tests/e2e/scenarios/test_mcp_auth_flow.py tests/e2e/scenarios/test_oauth_credential_fallback.py tests/e2e/scenarios/test_routine_oauth_credential_injection.py"
- group: routines
files: "tests/e2e/scenarios/test_owner_scope.py tests/e2e/scenarios/test_routine_event_batch.py"
steps:
Expand Down
35 changes: 35 additions & 0 deletions .github/workflows/regression-test-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ jobs:
fi
# Whole-function context: detect edits inside existing test functions.
# Uses -W (whole function) which works when git recognises function boundaries.
if git diff "${BASE_REF}...${HEAD_REF}" -W -- '*.rs' | awk '
/^@@/ { if (has_test && has_add) { found=1; exit } has_test=0; has_add=0 }
/^ .*#\[test\]/ || /^ .*#\[tokio::test\]/ || /^ .*#\[cfg\(test\)\]/ || /^ .*mod tests/ { has_test=1 }
Expand All @@ -132,6 +133,40 @@ jobs:
exit 0
fi
# Line-level check: detect changes inside #[cfg(test)] mod blocks.
# git -W relies on function boundary detection which misses Rust mod blocks,
# so this fallback checks whether changed line numbers fall within test modules.
# We specifically match #[cfg(test)] that is followed by `mod` (same or next
# line) to avoid false positives from standalone #[cfg(test)] items like
# individual statics or functions.
CHANGED_RS=$(echo "$CHANGED_FILES" | grep '\.rs$' || true)
if [ -n "$CHANGED_RS" ]; then
while IFS= read -r rs_file; do
[ -f "$rs_file" ] || continue
# Find the line where #[cfg(test)] precedes a `mod` declaration.
# Handles both `#[cfg(test)] mod tests` (same line) and the two-line form.
TEST_MOD_START=$(awk '
/^[[:space:]]*#\[cfg\(test\)\].*mod / { print NR; exit }
/^[[:space:]]*#\[cfg\(test\)\][[:space:]]*$/ { pending=NR; next }
pending && /^[[:space:]]*mod / { print pending; exit }
{ pending=0 }
' "$rs_file")
[ -n "$TEST_MOD_START" ] || continue
# Get changed line numbers in this file from the diff hunk headers.
# Each @@ line looks like: @@ -old,count +new,count @@
while IFS= read -r hunk_line; do
line_no=$(echo "$hunk_line" | sed -E 's/^@@ -[0-9,]+ \+([0-9]+).*/\1/')
[ -n "$line_no" ] || continue
if [ "$line_no" -ge "$TEST_MOD_START" ]; then
echo "Test changes found: $rs_file has changes at line $line_no inside #[cfg(test)] mod block (starts at line $TEST_MOD_START)."
exit 0
fi
done < <(git diff "${BASE_REF}...${HEAD_REF}" -U0 -- "$rs_file" | grep -E '^@@')
done <<< "$CHANGED_RS"
fi
if grep -qE '^tests/' <<< "$CHANGED_FILES"; then
echo "Test file changes found under tests/."
exit 0
Expand Down
24 changes: 19 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ jobs:
tests:
name: Tests (${{ matrix.name }})
runs-on: ubuntu-latest
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -40,11 +41,14 @@ jobs:
- name: Build WASM channels (for integration tests)
run: ./scripts/build-wasm-extensions.sh --channels
- name: Run Tests
run: cargo test ${{ matrix.flags }} -- --nocapture
run: |
timeout --signal=INT --kill-after=30s 40m \
cargo test ${{ matrix.flags }} -- --nocapture

heavy-integration-tests:
name: Heavy Integration Tests
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout repository
uses: actions/checkout@v6
Expand All @@ -58,24 +62,31 @@ jobs:
- name: Build Telegram WASM channel
run: cargo build --manifest-path channels-src/telegram/Cargo.toml --target wasm32-wasip2 --release
- name: Run thread scheduling integration tests
run: cargo test --no-default-features --features libsql,integration --test e2e_thread_scheduling -- --nocapture
run: |
timeout --signal=INT --kill-after=30s 15m \
cargo test --no-default-features --features libsql,integration --test e2e_thread_scheduling -- --nocapture
- name: Run Telegram thread-scope regression test
run: cargo test --features integration --test telegram_auth_integration test_private_messages_use_chat_id_as_thread_scope -- --exact
run: |
timeout --signal=INT --kill-after=30s 10m \
cargo test --features integration --test telegram_auth_integration test_private_messages_use_chat_id_as_thread_scope -- --exact

telegram-tests:
name: Telegram Channel Tests
if: >
github.event_name != 'pull_request' ||
github.base_ref != 'staging'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Run Telegram Channel Tests
run: cargo test --manifest-path channels-src/telegram/Cargo.toml -- --nocapture
run: |
timeout --signal=INT --kill-after=30s 10m \
cargo test --manifest-path channels-src/telegram/Cargo.toml -- --nocapture

windows-build:
name: Windows Build (${{ matrix.name }})
Expand Down Expand Up @@ -110,6 +121,7 @@ jobs:
github.event_name != 'pull_request' ||
github.base_ref != 'staging'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v6
Expand All @@ -125,7 +137,9 @@ jobs:
- name: Build all WASM extensions against current WIT
run: ./scripts/build-wasm-extensions.sh
- name: Instantiation test (host linker compatibility)
run: cargo test --all-features wit_compat -- --nocapture
run: |
timeout --signal=INT --kill-after=30s 20m \
cargo test --all-features wit_compat -- --nocapture

bench-compile:
name: Benchmark Compilation
Expand Down
90 changes: 89 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,94 @@
# Agent Rules

## Feature Parity Update Policy
## Purpose and Precedence

- `AGENTS.md` is the quick-start contract for coding agents. It is not the full architecture spec.
- Read the relevant subsystem spec before changing a complex area. When a repo spec exists, treat it as authoritative.
Start with these deeper docs as needed:
- `CLAUDE.md`
- `src/agent/CLAUDE.md`
- `src/channels/web/CLAUDE.md`
- `src/db/CLAUDE.md`
- `src/llm/CLAUDE.md`
- `src/setup/README.md`
- `src/tools/README.md`
- `src/workspace/README.md`
- `src/NETWORK_SECURITY.md`
- `tests/e2e/CLAUDE.md`

## Architecture Mental Model

- Channels normalize external input into `IncomingMessage`; `ChannelManager` merges all active channel streams.
- `Agent` owns session/thread/turn handling, submission parsing, the LLM/tool loop, approvals, routines, and background runtime behavior.
- `AppBuilder` is the composition root that wires database, secrets, LLMs, tools, workspace, extensions, skills, hooks, and cost controls before the agent starts.
- The web gateway is a browser-facing API/UI layered on top of the same agent/session/tool systems, not a separate product path.

## Where to Work

- Agent/runtime behavior: `src/agent/`
- Web gateway/API/SSE/WebSocket: `src/channels/web/`
- Persistence and DB abstractions: `src/db/`
- Setup/onboarding/configuration flow: `src/setup/`
- LLM providers and routing: `src/llm/`
- Workspace, memory, embeddings, search: `src/workspace/`
- Extensions, tools, channels, MCP, WASM: `src/extensions/`, `src/tools/`, `src/channels/`

## Ownership and Composition Rules

- Keep `src/main.rs` and `src/app.rs` orchestration-focused. Do not move module-owned logic into entrypoints.
- Module-specific initialization should live in the owning module behind a public factory/helper, not be reimplemented ad hoc.
- Keep feature-flag branching inside the module that owns the abstraction whenever possible.
- Prefer extending existing traits and registries over hardcoding one-off integration paths.

## Repo-Wide Coding Rules

- Avoid `.unwrap()` and `.expect()` in production; prefer proper error handling. They are fine in tests, and in production only for truly infallible invariants (e.g., literals/regexes) with a safety comment.
- Keep clippy clean with zero warnings.
- Prefer `crate::` imports for cross-module references.
- Use strong types and enums over stringly-typed control flow when the shape is known.

## Database, Setup, and Config Rules

- New persistence behavior must support both PostgreSQL and libSQL.
- Add new DB operations to the shared DB trait first, then implement both backends.
- Treat bootstrap config, DB-backed settings, and encrypted secrets as distinct layers; do not collapse them casually.
- If onboarding or setup behavior changes, update `src/setup/README.md` in the same branch.
- Do not break config precedence, bootstrap env loading, DB-backed config reload, or post-secrets LLM re-resolution.

## Security and Runtime Invariants

- Review any change touching listeners, routes, auth, secrets, sandboxing, approvals, or outbound HTTP with a security mindset.
- Do not weaken bearer-token auth, webhook auth, CORS/origin checks, body limits, rate limits, allowlists, or secret-handling guarantees.
- Treat Docker containers and external services as untrusted.
- Session/thread/turn state matters. Submission parsing happens before normal chat handling.
- Skills are selected deterministically. Tool approval and auth flows are special paths and must not be mixed into normal chat history carelessly.
- Persistent memory is the workspace system, not just transcript storage; preserve file-like semantics, chunking/search behavior, and identity/system-prompt loading.

## Tools, Channels, and Extensions

- Use a built-in Rust tool for core internal capabilities tightly coupled to the runtime.
- Use WASM tools or WASM channels for sandboxed extensions and plugin-style integrations.
- Use MCP for external server integrations when the capability belongs outside the main binary.
- Preserve extension lifecycle expectations: install, authenticate/configure, activate, remove.

## Docs, Parity, and Testing

- If behavior changes, update the relevant docs/specs in the same branch.
- If you change implementation status for any feature tracked in `FEATURE_PARITY.md`, update that file in the same branch.
- Do not open a PR that changes feature behavior without checking `FEATURE_PARITY.md` for needed status updates (`❌`, `🚧`, `✅`, notes, and priorities).
- Add the narrowest tests that validate the change: unit tests for local logic, integration tests for runtime/DB/routing behavior, and E2E or trace coverage for gateway, approvals, extensions, or other user-visible flows.

## Risk and Change Discipline

- Keep changes scoped; avoid broad refactors unless the task truly requires them.
- Security, database schema, runtime, worker, CI, and secrets changes are high-risk. Call out rollback risks, compatibility concerns, and hidden side effects.
- Preserve existing defaults unless the task explicitly changes them.
- Avoid unrelated file churn and generated-file edits unless required.
- Respect a dirty worktree and never revert user changes you did not make.

## Before Finishing

- Confirm whether behavior changes require updates to `FEATURE_PARITY.md`, specs, API docs, or `CHANGELOG.md`.
- Run the most targeted tests/checks that cover the change.
- Re-check security-sensitive paths when touching auth, secrets, network listeners, sandboxing, or approvals.
- Keep the final diff scoped to the task.
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ src/
├── secrets/ # Secrets management (AES-256-GCM, OS keychain for master key)
├── profile.rs # Psychographic profile types, 9-dimension analysis framework
├── setup/ # 7-step onboarding wizard — see src/setup/README.md
├── skills/ # SKILL.md prompt extension system — see .claude/rules/skills.md
Expand Down
Loading
Loading