diff --git a/.claude/commands/add-sse-event.md b/.claude/commands/add-sse-event.md index 23f47a08..0df56a31 100644 --- a/.claude/commands/add-sse-event.md +++ b/.claude/commands/add-sse-event.md @@ -5,7 +5,7 @@ argument-hint: [description] model: opus --- -Add a new SSE event called `$ARGUMENTS` to the IronClaw web gateway. This involves changes across 5 files in a specific order. Follow each step exactly. +Add a new SSE event called `$ARGUMENTS` to the OptimClaw web gateway. This involves changes across 5 files in a specific order. Follow each step exactly. ## Step 1: Add `StatusUpdate` variant diff --git a/.claude/commands/add-tool.md b/.claude/commands/add-tool.md index 19dd77bb..9dcfb338 100644 --- a/.claude/commands/add-tool.md +++ b/.claude/commands/add-tool.md @@ -5,7 +5,7 @@ argument-hint: [description] model: opus --- -Scaffold a new tool called `$ARGUMENTS` for the IronClaw agent. First, determine the tool type and then follow the appropriate path. +Scaffold a new tool called `$ARGUMENTS` for the OptimClaw agent. First, determine the tool type and then follow the appropriate path. ## Step 0: Determine tool type @@ -43,7 +43,7 @@ Follow this exact pattern (adjust name and description): name = "-tool" version = "0.1.0" edition = "2021" -description = " tool for IronClaw (WASM component)" +description = " tool for OptimClaw (WASM component)" license = "MIT OR Apache-2.0" publish = false diff --git a/.claude/commands/fix-issue.md b/.claude/commands/fix-issue.md index a9519774..6ea60367 100644 --- a/.claude/commands/fix-issue.md +++ b/.claude/commands/fix-issue.md @@ -62,7 +62,7 @@ Enter planning mode to design the implementation. The plan MUST cover: - Happy path (expected input produces expected output) - Error paths (invalid input, missing data, permission denied) - Edge cases (empty collections, boundary values, concurrent access) -5. **IronClaw-specific concerns**: +5. **OptimClaw-specific concerns**: - If the change touches persistence, both database backends must be updated (`postgres.rs` and `libsql_backend.rs`) - New `Database` trait methods need implementations in both backends - No `.unwrap()` or `.expect()` in production code @@ -80,7 +80,7 @@ After the plan is approved: 1. Implement each change from the plan. 2. Write all planned tests. -3. Run IronClaw's full quality gate: +3. Run OptimClaw's full quality gate: - `cargo fmt` - `cargo clippy --all --benches --tests --examples --all-features` (zero warnings) - `cargo test --lib` (all tests pass) diff --git a/.claude/commands/pr-shepherd.md b/.claude/commands/pr-shepherd.md index c6dc87a1..e4a4f852 100644 --- a/.claude/commands/pr-shepherd.md +++ b/.claude/commands/pr-shepherd.md @@ -96,7 +96,7 @@ Wait for user confirmation (unless `--fix` flag set), then proceed to Phase 3. Read EVERY changed file in full (not just diff hunks). For PRs touching >20 files, prioritize: service logic > handlers > types > tests > docs. Batch reads in parallel via Agent tool. -### IronClaw-specific checks (always) +### OptimClaw-specific checks (always) - No `.unwrap()` or `.expect()` in production code - Prefer `crate::` for cross-module imports (`super::` OK in tests/intra-module) - Error types use `thiserror` @@ -167,7 +167,7 @@ gh pr checkout {number} 1. All approved review comment fixes (from Phase 2a) 2. All approved review findings (from Phase 2b) -Follow IronClaw conventions: +Follow OptimClaw conventions: - `thiserror` for errors - `crate::` imports - No `.unwrap()` in production @@ -180,7 +180,7 @@ After all fixes implemented, proceed to Phase 4. ## Phase 4: Quality Gate -Run the full IronClaw shipping checklist: +Run the full OptimClaw shipping checklist: ```bash cargo fmt diff --git a/.claude/commands/respond-pr.md b/.claude/commands/respond-pr.md index 1db91207..c43719f4 100644 --- a/.claude/commands/respond-pr.md +++ b/.claude/commands/respond-pr.md @@ -60,7 +60,7 @@ Wait for user confirmation before proceeding to implementation. After user confirms: 1. Implement each fix in the plan. -2. Run IronClaw's quality gate to verify nothing breaks: +2. Run OptimClaw's quality gate to verify nothing breaks: - `cargo fmt` - `cargo clippy --all --benches --tests --examples --all-features` - `cargo test --lib` @@ -77,5 +77,5 @@ For each comment addressed, reply on the PR with a short message stating what wa - Group duplicate comments (same issue reported by multiple bots) and reply to all of them. - Do not make changes beyond what the review comments ask for. Stay focused. - If a comment suggests a change you disagree with, present your reasoning to the user during the planning phase rather than silently ignoring it. -- Follow IronClaw conventions: no `.unwrap()` in production code, use `crate::` imports, `thiserror` errors. +- Follow OptimClaw conventions: no `.unwrap()` in production code, use `crate::` imports, `thiserror` errors. - If changes touch persistence, verify both database backends are updated. diff --git a/.claude/commands/review-crate.md b/.claude/commands/review-crate.md index 0d51c007..225e005c 100644 --- a/.claude/commands/review-crate.md +++ b/.claude/commands/review-crate.md @@ -1,5 +1,5 @@ --- -description: Deep audit of the IronClaw crate for vulnerabilities, bugs, unfinished work, inconsistencies, and oversights +description: Deep audit of the OptimClaw crate for vulnerabilities, bugs, unfinished work, inconsistencies, and oversights disable-model-invocation: true allowed-tools: Bash(cargo fmt:*), Bash(cargo clippy:*), Bash(cargo test:*), Bash(cargo audit:*), Bash(git diff:*), Bash(git log:*), Bash(git show:*), Bash(wc:*), Read, Grep, Glob, Task argument-hint: "[path/to/crate]" @@ -93,7 +93,7 @@ Search for `.unwrap()`, `.expect(`, `panic!`, `unreachable!` in non-test code. F - Is there a code path that reaches this with None/Err? - Should it be replaced with proper error handling (`?`, `.ok()`, `.unwrap_or_default()`)? -IronClaw convention: `.unwrap()` and `.expect()` are banned in production code. Any occurrence outside `#[cfg(test)]` blocks is a **High severity** finding. +OptimClaw convention: `.unwrap()` and `.expect()` are banned in production code. Any occurrence outside `#[cfg(test)]` blocks is a **High severity** finding. ### 5c. SQL and injection vectors @@ -102,7 +102,7 @@ Search for string formatting used in SQL queries, shell commands, or HTML: - String interpolation in query construction vs parameterized queries - User input flowing into file paths (`Path::new`, `std::fs::`) -IronClaw has two database backends (PostgreSQL and libSQL). Check both for injection vectors. +OptimClaw has two database backends (PostgreSQL and libSQL). Check both for injection vectors. ### 5d. Cryptographic issues @@ -125,7 +125,7 @@ If the crate uses crypto: - Are errors swallowed silently? (`let _ = ...`, `.ok()` discarding errors that matter) - Do error types carry enough context to debug in production? - Are there error type mismatches? (returning generic `anyhow::Error` where a typed error would prevent confusion) -- Is `thiserror` used consistently for error types (IronClaw convention)? +- Is `thiserror` used consistently for error types (OptimClaw convention)? ## Step 6: Check for inconsistencies @@ -156,7 +156,7 @@ Look for: ### 6e. Import style -IronClaw convention: use `crate::` imports, not `super::`. Flag any `super::` imports in non-test code. +OptimClaw convention: use `crate::` imports, not `super::`. Flag any `super::` imports in non-test code. ## Step 7: Inspect for change oversights @@ -172,7 +172,7 @@ IronClaw convention: use `crate::` imports, not `super::`. Flag any `super::` im - Are there `impl` blocks that look incomplete? - Are `Default` implementations sensible? -IronClaw key traits: `Database` (~60 methods), `Channel`, `Tool`, `LlmProvider`, `SuccessEvaluator`, `EmbeddingProvider`. If any new methods were added to `Database`, verify both `postgres.rs` and `libsql_backend.rs` implement them. +OptimClaw key traits: `Database` (~60 methods), `Channel`, `Tool`, `LlmProvider`, `SuccessEvaluator`, `EmbeddingProvider`. If any new methods were added to `Database`, verify both `postgres.rs` and `libsql_backend.rs` implement them. ### 7c. Test coverage gaps diff --git a/.claude/commands/review-pr.md b/.claude/commands/review-pr.md index 6794444f..61a30c03 100644 --- a/.claude/commands/review-pr.md +++ b/.claude/commands/review-pr.md @@ -49,9 +49,9 @@ If the PR touches more than 20 files, still read all of them, but process in thi Go through the changes with each of these lenses. For every finding, note the file, line range, severity, and a concrete description. -### IronClaw-specific checks +### OptimClaw-specific checks -In addition to the general lenses below, check IronClaw conventions (see CLAUDE.md): +In addition to the general lenses below, check OptimClaw conventions (see CLAUDE.md): - No `.unwrap()` or `.expect()` in production code (tests are fine) - Use `crate::` imports, not `super::` - Error types use `thiserror` in `error.rs` diff --git a/.claude/commands/ship.md b/.claude/commands/ship.md index 675d1507..1e3c6e5c 100644 --- a/.claude/commands/ship.md +++ b/.claude/commands/ship.md @@ -3,7 +3,7 @@ description: Run the full Rust quality gate (fmt, clippy, tests) before shipping allowed-tools: Bash(cargo fmt:*), Bash(cargo clippy:*), Bash(cargo test:*) --- -Run the IronClaw shipping checklist. This is the mandatory quality gate before any change is considered done. +Run the OptimClaw shipping checklist. This is the mandatory quality gate before any change is considered done. ## Steps diff --git a/.claude/commands/trace.md b/.claude/commands/trace.md index 8651bd59..67f78a2e 100644 --- a/.claude/commands/trace.md +++ b/.claude/commands/trace.md @@ -1,15 +1,15 @@ --- -description: Trace a data flow or bug through the IronClaw codebase end-to-end +description: Trace a data flow or bug through the OptimClaw codebase end-to-end allowed-tools: Read, Glob, Grep, Bash(cargo test:*) argument-hint: model: sonnet --- -Trace the flow of `$ARGUMENTS` through the IronClaw codebase. Your job is to map every file and function involved, identify where data transforms or could break, and report the full chain. +Trace the flow of `$ARGUMENTS` through the OptimClaw codebase. Your job is to map every file and function involved, identify where data transforms or could break, and report the full chain. ## Architecture Reference -IronClaw has three main data flow paths. Identify which one(s) are relevant and trace through them: +OptimClaw has three main data flow paths. Identify which one(s) are relevant and trace through them: ### Message Flow (user input to LLM response) ``` diff --git a/.claude/rules/skills.md b/.claude/rules/skills.md index ded26de9..a0b238f5 100644 --- a/.claude/rules/skills.md +++ b/.claude/rules/skills.md @@ -11,8 +11,8 @@ SKILL.md files extend the agent's prompt with domain-specific instructions. Each | Trust Level | Source | Tool Access | |-------------|--------|-------------| -| **Trusted** | User-placed in `~/.ironclaw/skills/` or workspace `skills/` | All tools available to the agent | -| **Installed** | Downloaded from ClawHub registry (`~/.ironclaw/installed_skills/`) | Read-only tools only (no shell, file write, HTTP) | +| **Trusted** | User-placed in `~/.optimclaw/skills/` or workspace `skills/` | All tools available to the agent | +| **Installed** | Downloaded from ClawHub registry (`~/.optimclaw/installed_skills/`) | Read-only tools only (no shell, file write, HTTP) | ## SKILL.md Format diff --git a/.claude/rules/tools.md b/.claude/rules/tools.md index a35d9e23..1180671c 100644 --- a/.claude/rules/tools.md +++ b/.claude/rules/tools.md @@ -7,7 +7,7 @@ paths: **Keep tool-specific logic out of the main agent codebase.** The main agent provides generic infrastructure; tools are self-contained units that declare requirements through `.capabilities.json` sidecar files (in dev mode: `tools-src//-tool.capabilities.json`). -Tools can be WASM (sandboxed, credential-injected, single binary) or MCP servers (ecosystem, any language, no sandbox). Both are first-class via `ironclaw tool install`. +Tools can be WASM (sandboxed, credential-injected, single binary) or MCP servers (ecosystem, any language, no sandbox). Both are first-class via `optimclaw tool install`. See `src/tools/README.md` for full architecture, adding new tools, auth JSON examples, and WASM vs MCP decision guide. diff --git a/.github/workflows/claude-review.yml b/.github/workflows/claude-review.yml index 26c15d89..235456a8 100644 --- a/.github/workflows/claude-review.yml +++ b/.github/workflows/claude-review.yml @@ -28,7 +28,7 @@ jobs: uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} - allowed_bots: "ironclaw-ci[bot]" + allowed_bots: "optimclaw-ci[bot]" claude_args: "--max-turns 50 --model claude-haiku-4-5-20251001 --allowedTools 'Read,Glob,Grep,Agent,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*),Bash(gh issue view:*),Bash(gh issue list:*),Bash(gh search:*),Bash(git blame:*),Bash(git log:*),Bash(git diff:*)'" prompt: | Code review this pull request. Follow these steps precisely: diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 2f885b16..8caed515 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -6,11 +6,11 @@ # What it does: # - Runs unit and integration tests with coverage instrumentation # - Runs E2E tests with coverage instrumentation -# - Uploads coverage reports to Codecov (https://codecov.io/gh/nearai/ironclaw) +# - Uploads coverage reports to Codecov (https://codecov.io/gh/nearai/optimclaw) # # Viewing coverage reports: # - PRs automatically get coverage comments showing changes in coverage -# - Visit https://codecov.io/gh/nearai/ironclaw for detailed coverage reports +# - Visit https://codecov.io/gh/nearai/optimclaw for detailed coverage reports # - Coverage reports are generated for three configurations: # 1. all-features: Full feature set # 2. default: Default features @@ -58,7 +58,7 @@ jobs: env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres - POSTGRES_DB: ironclaw_test + POSTGRES_DB: optimclaw_test ports: - 5432:5432 options: >- @@ -103,11 +103,11 @@ jobs: PGHOST: localhost PGUSER: postgres PGPASSWORD: postgres - PGDATABASE: ironclaw_test + PGDATABASE: optimclaw_test - name: Set DATABASE_URL for postgres configs if: matrix.has_postgres - run: echo "DATABASE_URL=postgres://postgres:postgres@localhost/ironclaw_test" >> "$GITHUB_ENV" + run: echo "DATABASE_URL=postgres://postgres:postgres@localhost/optimclaw_test" >> "$GITHUB_ENV" - name: Generate coverage run: cargo llvm-cov ${{ matrix.flags }} --workspace --lcov --output-path lcov.info @@ -176,7 +176,7 @@ jobs: run: | pytest tests/e2e/ -v --timeout=120 env: - RUST_LOG: ironclaw=info + RUST_LOG: optimclaw=info RUST_BACKTRACE: "1" - name: Verify profraw files exist diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index bc705df7..f595f9eb 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -14,7 +14,7 @@ on: jobs: # ── Step 1: compile once ────────────────────────────────────────────────── build: - name: Build ironclaw (libsql) + name: Build optimclaw (libsql) runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -35,8 +35,8 @@ jobs: - name: Upload binary uses: actions/upload-artifact@v4 with: - name: ironclaw-e2e-binary - path: target/debug/ironclaw + name: optimclaw-e2e-binary + path: target/debug/optimclaw retention-days: 1 # ── Step 2: run test slices in parallel ─────────────────────────────────── @@ -63,11 +63,11 @@ jobs: - name: Download binary uses: actions/download-artifact@v4 with: - name: ironclaw-e2e-binary + name: optimclaw-e2e-binary path: target/debug/ - name: Make binary executable - run: chmod +x target/debug/ironclaw + run: chmod +x target/debug/optimclaw - uses: actions/setup-python@v5 with: diff --git a/.github/workflows/regression-test-check.yml b/.github/workflows/regression-test-check.yml index 75b8eb55..ebaa1666 100644 --- a/.github/workflows/regression-test-check.yml +++ b/.github/workflows/regression-test-check.yml @@ -56,7 +56,7 @@ jobs: "src/agent/self_repair.rs" "src/agent/agentic_loop.rs" "src/tools/execute.rs" - "crates/ironclaw_safety/src/" + "crates/optimclaw_safety/src/" ) for pattern in "${HIGH_RISK_PATTERNS[@]}"; do diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c4a4f416..ad243dfc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -166,7 +166,7 @@ jobs: continue fi name=$(echo "$filename" | sed "s/^${kind}-//" | sed 's/-[0-9].*-wasm32-wasip2\.tar\.gz$//') - url="https://github.com/nearai/ironclaw/releases/download/${RELEASE_TAG}/${filename}" + url="https://github.com/nearai/optimclaw/releases/download/${RELEASE_TAG}/${filename}" manifest="registry/${kind}s/${name}.json" if [ -f "$manifest" ]; then @@ -496,7 +496,7 @@ jobs: continue fi name=$(echo "$filename" | sed "s/^${kind}-//" | sed 's/-[0-9].*-wasm32-wasip2\.tar\.gz$//') - url="https://github.com/nearai/ironclaw/releases/download/${RELEASE_TAG}/${filename}" + url="https://github.com/nearai/optimclaw/releases/download/${RELEASE_TAG}/${filename}" manifest="registry/${kind}s/${name}.json" if [ -f "$manifest" ]; then diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5d4eabc0..76388b75 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -165,7 +165,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v6 - name: Build Docker image - run: docker build -t ironclaw-test:ci . + run: docker build -t optimclaw-test:ci . version-check: name: Version Bump Check diff --git a/CHANGELOG.md b/CHANGELOG.md index 9acc56ad..397c4b41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,637 +7,637 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [0.22.0](https://github.com/nearai/ironclaw/compare/ironclaw-v0.21.0...ironclaw-v0.22.0) - 2026-03-25 +## [0.22.0](https://github.com/nearai/optimclaw/compare/optimclaw-v0.21.0...optimclaw-v0.22.0) - 2026-03-25 ### Added -- *(agent)* thread per-tool reasoning through provider, session, and all surfaces ([#1513](https://github.com/nearai/ironclaw/pull/1513)) -- *(cli)* show credential auth status in tool info ([#1572](https://github.com/nearai/ironclaw/pull/1572)) -- multi-tenant auth with per-user workspace isolation ([#1118](https://github.com/nearai/ironclaw/pull/1118)) -- *(cli)* add ironclaw models subcommands (list/status/set/set-provider) ([#1043](https://github.com/nearai/ironclaw/pull/1043)) -- *(workspace)* multi-scope workspace reads ([#1117](https://github.com/nearai/ironclaw/pull/1117)) -- *(ux)* complete UX overhaul — design system, onboarding, web polish ([#1277](https://github.com/nearai/ironclaw/pull/1277)) -- *(gemini_oauth)* full Gemini CLI OAuth integration with Cloud Code API ([#1356](https://github.com/nearai/ironclaw/pull/1356)) -- *(shell)* add Low/Medium/High risk levels for graduated command approval (closes #172) ([#368](https://github.com/nearai/ironclaw/pull/368)) -- *(agent)* queue and merge messages during active turns ([#1412](https://github.com/nearai/ironclaw/pull/1412)) -- *(cli)* add `ironclaw hooks list` subcommand ([#1023](https://github.com/nearai/ironclaw/pull/1023)) -- *(extensions)* support text setup fields in web configure modal ([#496](https://github.com/nearai/ironclaw/pull/496)) -- *(llm)* add GitHub Copilot as LLM provider ([#1512](https://github.com/nearai/ironclaw/pull/1512)) -- *(workspace)* layered memory with sensitivity-based privacy redirect ([#1112](https://github.com/nearai/ironclaw/pull/1112)) -- *(webhooks)* add public webhook trigger endpoint for routines ([#736](https://github.com/nearai/ironclaw/pull/736)) -- *(llm)* Add OpenAI Codex (ChatGPT subscription) as LLM provider ([#1461](https://github.com/nearai/ironclaw/pull/1461)) -- *(web)* add light theme with dark/light/system toggle ([#1457](https://github.com/nearai/ironclaw/pull/1457)) -- *(agent)* activate stuck_threshold for time-based stuck job detection ([#1234](https://github.com/nearai/ironclaw/pull/1234)) -- chat onboarding and routine advisor ([#927](https://github.com/nearai/ironclaw/pull/927)) +- *(agent)* thread per-tool reasoning through provider, session, and all surfaces ([#1513](https://github.com/nearai/optimclaw/pull/1513)) +- *(cli)* show credential auth status in tool info ([#1572](https://github.com/nearai/optimclaw/pull/1572)) +- multi-tenant auth with per-user workspace isolation ([#1118](https://github.com/nearai/optimclaw/pull/1118)) +- *(cli)* add optimclaw models subcommands (list/status/set/set-provider) ([#1043](https://github.com/nearai/optimclaw/pull/1043)) +- *(workspace)* multi-scope workspace reads ([#1117](https://github.com/nearai/optimclaw/pull/1117)) +- *(ux)* complete UX overhaul — design system, onboarding, web polish ([#1277](https://github.com/nearai/optimclaw/pull/1277)) +- *(gemini_oauth)* full Gemini CLI OAuth integration with Cloud Code API ([#1356](https://github.com/nearai/optimclaw/pull/1356)) +- *(shell)* add Low/Medium/High risk levels for graduated command approval (closes #172) ([#368](https://github.com/nearai/optimclaw/pull/368)) +- *(agent)* queue and merge messages during active turns ([#1412](https://github.com/nearai/optimclaw/pull/1412)) +- *(cli)* add `optimclaw hooks list` subcommand ([#1023](https://github.com/nearai/optimclaw/pull/1023)) +- *(extensions)* support text setup fields in web configure modal ([#496](https://github.com/nearai/optimclaw/pull/496)) +- *(llm)* add GitHub Copilot as LLM provider ([#1512](https://github.com/nearai/optimclaw/pull/1512)) +- *(workspace)* layered memory with sensitivity-based privacy redirect ([#1112](https://github.com/nearai/optimclaw/pull/1112)) +- *(webhooks)* add public webhook trigger endpoint for routines ([#736](https://github.com/nearai/optimclaw/pull/736)) +- *(llm)* Add OpenAI Codex (ChatGPT subscription) as LLM provider ([#1461](https://github.com/nearai/optimclaw/pull/1461)) +- *(web)* add light theme with dark/light/system toggle ([#1457](https://github.com/nearai/optimclaw/pull/1457)) +- *(agent)* activate stuck_threshold for time-based stuck job detection ([#1234](https://github.com/nearai/optimclaw/pull/1234)) +- chat onboarding and routine advisor ([#927](https://github.com/nearai/optimclaw/pull/927)) ### Fixed -- ensure LLM calls always end with user message (closes #763) ([#1259](https://github.com/nearai/ironclaw/pull/1259)) -- restore owner-scoped gateway startup ([#1625](https://github.com/nearai/ironclaw/pull/1625)) -- remove stale stream_token gate from channel-relay activation ([#1623](https://github.com/nearai/ironclaw/pull/1623)) -- *(agent)* case-insensitive channel match and user_id filter for event triggers ([#1211](https://github.com/nearai/ironclaw/pull/1211)) -- *(routines)* normalize status display across web and CLI ([#1469](https://github.com/nearai/ironclaw/pull/1469)) -- *(tunnel)* managed tunnels target wrong port and die from SIGPIPE ([#1093](https://github.com/nearai/ironclaw/pull/1093)) -- *(agent)* persist /model selection to .env, TOML, and DB ([#1581](https://github.com/nearai/ironclaw/pull/1581)) -- post-merge review sweep — 8 fixes across security, perf, and correctness ([#1550](https://github.com/nearai/ironclaw/pull/1550)) -- generate Mistral-compatible 9-char alphanumeric tool call IDs ([#1242](https://github.com/nearai/ironclaw/pull/1242)) -- *(mcp)* handle empty 202 notification acknowledgements ([#1539](https://github.com/nearai/ironclaw/pull/1539)) -- *(tests)* eliminate env mutex poison cascade ([#1558](https://github.com/nearai/ironclaw/pull/1558)) -- *(safety)* escape tool output XML content and remove misleading sanitized attr ([#1067](https://github.com/nearai/ironclaw/pull/1067)) -- *(oauth)* reject malformed ic2.* states in decode_hosted_oauth_state ([#1441](https://github.com/nearai/ironclaw/pull/1441)) ([#1454](https://github.com/nearai/ironclaw/pull/1454)) -- parameter coercion and validation for oneOf/anyOf/allOf schemas ([#1397](https://github.com/nearai/ironclaw/pull/1397)) -- persist startup-loaded MCP clients in ExtensionManager ([#1509](https://github.com/nearai/ironclaw/pull/1509)) +- ensure LLM calls always end with user message (closes #763) ([#1259](https://github.com/nearai/optimclaw/pull/1259)) +- restore owner-scoped gateway startup ([#1625](https://github.com/nearai/optimclaw/pull/1625)) +- remove stale stream_token gate from channel-relay activation ([#1623](https://github.com/nearai/optimclaw/pull/1623)) +- *(agent)* case-insensitive channel match and user_id filter for event triggers ([#1211](https://github.com/nearai/optimclaw/pull/1211)) +- *(routines)* normalize status display across web and CLI ([#1469](https://github.com/nearai/optimclaw/pull/1469)) +- *(tunnel)* managed tunnels target wrong port and die from SIGPIPE ([#1093](https://github.com/nearai/optimclaw/pull/1093)) +- *(agent)* persist /model selection to .env, TOML, and DB ([#1581](https://github.com/nearai/optimclaw/pull/1581)) +- post-merge review sweep — 8 fixes across security, perf, and correctness ([#1550](https://github.com/nearai/optimclaw/pull/1550)) +- generate Mistral-compatible 9-char alphanumeric tool call IDs ([#1242](https://github.com/nearai/optimclaw/pull/1242)) +- *(mcp)* handle empty 202 notification acknowledgements ([#1539](https://github.com/nearai/optimclaw/pull/1539)) +- *(tests)* eliminate env mutex poison cascade ([#1558](https://github.com/nearai/optimclaw/pull/1558)) +- *(safety)* escape tool output XML content and remove misleading sanitized attr ([#1067](https://github.com/nearai/optimclaw/pull/1067)) +- *(oauth)* reject malformed ic2.* states in decode_hosted_oauth_state ([#1441](https://github.com/nearai/optimclaw/pull/1441)) ([#1454](https://github.com/nearai/optimclaw/pull/1454)) +- parameter coercion and validation for oneOf/anyOf/allOf schemas ([#1397](https://github.com/nearai/optimclaw/pull/1397)) +- persist startup-loaded MCP clients in ExtensionManager ([#1509](https://github.com/nearai/optimclaw/pull/1509)) - *(deps)* patch rustls-webpki vulnerability (RUSTSEC-2026-0049) - *(routines)* add missing extension_manager field in trigger_manual EngineContext -- *(ci)* serialize env-mutating OAuth wildcard tests with ENV_MUTEX ([#1280](https://github.com/nearai/ironclaw/pull/1280)) ([#1468](https://github.com/nearai/ironclaw/pull/1468)) -- *(setup)* remove redundant LLM config and API keys from bootstrap .env ([#1448](https://github.com/nearai/ironclaw/pull/1448)) -- resolve wasm broadcast merge conflicts with staging ([#395](https://github.com/nearai/ironclaw/pull/395)) ([#1460](https://github.com/nearai/ironclaw/pull/1460)) -- skip credential validation for Bedrock backend ([#1011](https://github.com/nearai/ironclaw/pull/1011)) -- register sandbox jobs in ContextManager for query tool visibility ([#1426](https://github.com/nearai/ironclaw/pull/1426)) -- prefer execution-local message routing metadata ([#1449](https://github.com/nearai/ironclaw/pull/1449)) -- *(security)* validate embedding base URLs to prevent SSRF ([#1221](https://github.com/nearai/ironclaw/pull/1221)) -- f32→f64 precision artifact in temperature causes provider 400 errors ([#1450](https://github.com/nearai/ironclaw/pull/1450)) -- *(routines)* surface errors when sandbox unavailable for full_job routines ([#769](https://github.com/nearai/ironclaw/pull/769)) -- restore libSQL vector search with dynamic dimensions ([#1393](https://github.com/nearai/ironclaw/pull/1393)) -- staging CI triage — consolidate retry parsing, fix flaky tests, add docs ([#1427](https://github.com/nearai/ironclaw/pull/1427)) +- *(ci)* serialize env-mutating OAuth wildcard tests with ENV_MUTEX ([#1280](https://github.com/nearai/optimclaw/pull/1280)) ([#1468](https://github.com/nearai/optimclaw/pull/1468)) +- *(setup)* remove redundant LLM config and API keys from bootstrap .env ([#1448](https://github.com/nearai/optimclaw/pull/1448)) +- resolve wasm broadcast merge conflicts with staging ([#395](https://github.com/nearai/optimclaw/pull/395)) ([#1460](https://github.com/nearai/optimclaw/pull/1460)) +- skip credential validation for Bedrock backend ([#1011](https://github.com/nearai/optimclaw/pull/1011)) +- register sandbox jobs in ContextManager for query tool visibility ([#1426](https://github.com/nearai/optimclaw/pull/1426)) +- prefer execution-local message routing metadata ([#1449](https://github.com/nearai/optimclaw/pull/1449)) +- *(security)* validate embedding base URLs to prevent SSRF ([#1221](https://github.com/nearai/optimclaw/pull/1221)) +- f32→f64 precision artifact in temperature causes provider 400 errors ([#1450](https://github.com/nearai/optimclaw/pull/1450)) +- *(routines)* surface errors when sandbox unavailable for full_job routines ([#769](https://github.com/nearai/optimclaw/pull/769)) +- restore libSQL vector search with dynamic dimensions ([#1393](https://github.com/nearai/optimclaw/pull/1393)) +- staging CI triage — consolidate retry parsing, fix flaky tests, add docs ([#1427](https://github.com/nearai/optimclaw/pull/1427)) ### Other - Merge branch 'main' into staging-promote/455f543b-23329172268 - Merge pull request #1655 from nearai/codex/fix-staging-promotion-1451-version-bumps - Merge pull request #1499 from nearai/staging-promote/9603fefd-23364438978 -- Fix libsql prompt scope regressions ([#1651](https://github.com/nearai/ironclaw/pull/1651)) -- Normalize cron schedules on routine create ([#1648](https://github.com/nearai/ironclaw/pull/1648)) -- Fix MCP lifecycle trace user scope ([#1646](https://github.com/nearai/ironclaw/pull/1646)) -- Fix REPL single-message hang and cap CI test duration ([#1643](https://github.com/nearai/ironclaw/pull/1643)) -- extract AppEvent to crates/ironclaw_common ([#1615](https://github.com/nearai/ironclaw/pull/1615)) -- Fix hosted OAuth refresh via proxy ([#1602](https://github.com/nearai/ironclaw/pull/1602)) -- *(agent)* optimize approval thread resolution (UUID parsing + lock contention) ([#1592](https://github.com/nearai/ironclaw/pull/1592)) -- *(tools)* auto-compact WASM tool schemas, add descriptions, improve credential prompts ([#1525](https://github.com/nearai/ironclaw/pull/1525)) -- Default new lightweight routines to tools-enabled ([#1573](https://github.com/nearai/ironclaw/pull/1573)) -- Google OAuth URL broken when initiated from Telegram channel ([#1165](https://github.com/nearai/ironclaw/pull/1165)) -- add gitcgr code graph badge ([#1563](https://github.com/nearai/ironclaw/pull/1563)) -- Fix owner-scoped message routing fallbacks ([#1574](https://github.com/nearai/ironclaw/pull/1574)) -- *(tools)* remove unconditional params clone in shared execution (fix #893) ([#926](https://github.com/nearai/ironclaw/pull/926)) -- *(llm)* move transcription module into src/llm/ ([#1559](https://github.com/nearai/ironclaw/pull/1559)) -- *(agent)* avoid preview allocations for non-truncated strings (fix #894) ([#924](https://github.com/nearai/ironclaw/pull/924)) -- Expand AGENTS.md with coding agents guidance ([#1392](https://github.com/nearai/ironclaw/pull/1392)) -- Fix CI approval flows and stale fixtures ([#1478](https://github.com/nearai/ironclaw/pull/1478)) -- Use live owner tool scope for autonomous routines and jobs ([#1453](https://github.com/nearai/ironclaw/pull/1453)) -- use Arc in embedding cache to avoid clones on miss path ([#1438](https://github.com/nearai/ironclaw/pull/1438)) -- Add owner-scoped permissions for full-job routines ([#1440](https://github.com/nearai/ironclaw/pull/1440)) +- Fix libsql prompt scope regressions ([#1651](https://github.com/nearai/optimclaw/pull/1651)) +- Normalize cron schedules on routine create ([#1648](https://github.com/nearai/optimclaw/pull/1648)) +- Fix MCP lifecycle trace user scope ([#1646](https://github.com/nearai/optimclaw/pull/1646)) +- Fix REPL single-message hang and cap CI test duration ([#1643](https://github.com/nearai/optimclaw/pull/1643)) +- extract AppEvent to crates/optimclaw_common ([#1615](https://github.com/nearai/optimclaw/pull/1615)) +- Fix hosted OAuth refresh via proxy ([#1602](https://github.com/nearai/optimclaw/pull/1602)) +- *(agent)* optimize approval thread resolution (UUID parsing + lock contention) ([#1592](https://github.com/nearai/optimclaw/pull/1592)) +- *(tools)* auto-compact WASM tool schemas, add descriptions, improve credential prompts ([#1525](https://github.com/nearai/optimclaw/pull/1525)) +- Default new lightweight routines to tools-enabled ([#1573](https://github.com/nearai/optimclaw/pull/1573)) +- Google OAuth URL broken when initiated from Telegram channel ([#1165](https://github.com/nearai/optimclaw/pull/1165)) +- add gitcgr code graph badge ([#1563](https://github.com/nearai/optimclaw/pull/1563)) +- Fix owner-scoped message routing fallbacks ([#1574](https://github.com/nearai/optimclaw/pull/1574)) +- *(tools)* remove unconditional params clone in shared execution (fix #893) ([#926](https://github.com/nearai/optimclaw/pull/926)) +- *(llm)* move transcription module into src/llm/ ([#1559](https://github.com/nearai/optimclaw/pull/1559)) +- *(agent)* avoid preview allocations for non-truncated strings (fix #894) ([#924](https://github.com/nearai/optimclaw/pull/924)) +- Expand AGENTS.md with coding agents guidance ([#1392](https://github.com/nearai/optimclaw/pull/1392)) +- Fix CI approval flows and stale fixtures ([#1478](https://github.com/nearai/optimclaw/pull/1478)) +- Use live owner tool scope for autonomous routines and jobs ([#1453](https://github.com/nearai/optimclaw/pull/1453)) +- use Arc in embedding cache to avoid clones on miss path ([#1438](https://github.com/nearai/optimclaw/pull/1438)) +- Add owner-scoped permissions for full-job routines ([#1440](https://github.com/nearai/optimclaw/pull/1440)) -## [0.21.0](https://github.com/nearai/ironclaw/compare/v0.20.0...v0.21.0) - 2026-03-20 +## [0.21.0](https://github.com/nearai/optimclaw/compare/v0.20.0...v0.21.0) - 2026-03-20 ### Added -- structured fallback deliverables for failed/stuck jobs ([#236](https://github.com/nearai/ironclaw/pull/236)) -- LRU embedding cache for workspace search ([#1423](https://github.com/nearai/ironclaw/pull/1423)) -- receive relay events via webhook callbacks ([#1254](https://github.com/nearai/ironclaw/pull/1254)) +- structured fallback deliverables for failed/stuck jobs ([#236](https://github.com/nearai/optimclaw/pull/236)) +- LRU embedding cache for workspace search ([#1423](https://github.com/nearai/optimclaw/pull/1423)) +- receive relay events via webhook callbacks ([#1254](https://github.com/nearai/optimclaw/pull/1254)) ### Fixed - bump Feishu channel version for promotion -- *(approval)* make "always" auto-approve work for credentialed HTTP requests ([#1257](https://github.com/nearai/ironclaw/pull/1257)) -- skip NEAR AI session check when backend is not nearai ([#1413](https://github.com/nearai/ironclaw/pull/1413)) +- *(approval)* make "always" auto-approve work for credentialed HTTP requests ([#1257](https://github.com/nearai/optimclaw/pull/1257)) +- skip NEAR AI session check when backend is not nearai ([#1413](https://github.com/nearai/optimclaw/pull/1413)) ### Other -- Make hosted OAuth and MCP auth generic ([#1375](https://github.com/nearai/ironclaw/pull/1375)) +- Make hosted OAuth and MCP auth generic ([#1375](https://github.com/nearai/optimclaw/pull/1375)) -## [0.20.0](https://github.com/nearai/ironclaw/compare/v0.19.0...v0.20.0) - 2026-03-19 +## [0.20.0](https://github.com/nearai/optimclaw/compare/v0.19.0...v0.20.0) - 2026-03-19 ### Added -- *(self-repair)* wire stuck_threshold, store, and builder ([#712](https://github.com/nearai/ironclaw/pull/712)) -- *(testing)* add FaultInjector framework for StubLlm ([#1233](https://github.com/nearai/ironclaw/pull/1233)) -- *(gateway)* unified settings page with subtabs ([#1191](https://github.com/nearai/ironclaw/pull/1191)) -- upgrade MiniMax default model to M2.7 ([#1357](https://github.com/nearai/ironclaw/pull/1357)) +- *(self-repair)* wire stuck_threshold, store, and builder ([#712](https://github.com/nearai/optimclaw/pull/712)) +- *(testing)* add FaultInjector framework for StubLlm ([#1233](https://github.com/nearai/optimclaw/pull/1233)) +- *(gateway)* unified settings page with subtabs ([#1191](https://github.com/nearai/optimclaw/pull/1191)) +- upgrade MiniMax default model to M2.7 ([#1357](https://github.com/nearai/optimclaw/pull/1357)) ### Fixed -- navigate telegram E2E tests to channels subtab ([#1408](https://github.com/nearai/ironclaw/pull/1408)) -- add missing `builder` field and update E2E extensions tab navigation ([#1400](https://github.com/nearai/ironclaw/pull/1400)) -- remove debug_assert guards that panic on valid error paths ([#1385](https://github.com/nearai/ironclaw/pull/1385)) -- address valid review comments from PR #1359 ([#1380](https://github.com/nearai/ironclaw/pull/1380)) -- full_job routine runs stay running until linked job completion ([#1374](https://github.com/nearai/ironclaw/pull/1374)) -- full_job routine concurrency tracks linked job lifetime ([#1372](https://github.com/nearai/ironclaw/pull/1372)) -- remove -x from coverage pytest to prevent suite-blocking failures ([#1360](https://github.com/nearai/ironclaw/pull/1360)) -- add debug_assert invariant guards to critical code paths ([#1312](https://github.com/nearai/ironclaw/pull/1312)) -- *(mcp)* retry after missing session id errors ([#1355](https://github.com/nearai/ironclaw/pull/1355)) -- *(telegram)* preserve polling after secret-blocked updates ([#1353](https://github.com/nearai/ironclaw/pull/1353)) -- *(llm)* cap retry-after delays ([#1351](https://github.com/nearai/ironclaw/pull/1351)) -- *(setup)* remove nonexistent webhook secret command hint ([#1349](https://github.com/nearai/ironclaw/pull/1349)) -- Rate limiter returns retry after None instead of a duration ([#1269](https://github.com/nearai/ironclaw/pull/1269)) +- navigate telegram E2E tests to channels subtab ([#1408](https://github.com/nearai/optimclaw/pull/1408)) +- add missing `builder` field and update E2E extensions tab navigation ([#1400](https://github.com/nearai/optimclaw/pull/1400)) +- remove debug_assert guards that panic on valid error paths ([#1385](https://github.com/nearai/optimclaw/pull/1385)) +- address valid review comments from PR #1359 ([#1380](https://github.com/nearai/optimclaw/pull/1380)) +- full_job routine runs stay running until linked job completion ([#1374](https://github.com/nearai/optimclaw/pull/1374)) +- full_job routine concurrency tracks linked job lifetime ([#1372](https://github.com/nearai/optimclaw/pull/1372)) +- remove -x from coverage pytest to prevent suite-blocking failures ([#1360](https://github.com/nearai/optimclaw/pull/1360)) +- add debug_assert invariant guards to critical code paths ([#1312](https://github.com/nearai/optimclaw/pull/1312)) +- *(mcp)* retry after missing session id errors ([#1355](https://github.com/nearai/optimclaw/pull/1355)) +- *(telegram)* preserve polling after secret-blocked updates ([#1353](https://github.com/nearai/optimclaw/pull/1353)) +- *(llm)* cap retry-after delays ([#1351](https://github.com/nearai/optimclaw/pull/1351)) +- *(setup)* remove nonexistent webhook secret command hint ([#1349](https://github.com/nearai/optimclaw/pull/1349)) +- Rate limiter returns retry after None instead of a duration ([#1269](https://github.com/nearai/optimclaw/pull/1269)) ### Other -- bump telegram channel version to 0.2.5 ([#1410](https://github.com/nearai/ironclaw/pull/1410)) -- *(ci)* enforce test requirement for state machine and resilience changes ([#1230](https://github.com/nearai/ironclaw/pull/1230)) ([#1304](https://github.com/nearai/ironclaw/pull/1304)) -- Fix duplicate LLM responses for matched event routines ([#1275](https://github.com/nearai/ironclaw/pull/1275)) -- add Japanese README ([#1306](https://github.com/nearai/ironclaw/pull/1306)) -- *(ci)* add coverage gates via codecov.yml ([#1228](https://github.com/nearai/ironclaw/pull/1228)) ([#1291](https://github.com/nearai/ironclaw/pull/1291)) -- Redesign routine create requests for LLMs ([#1147](https://github.com/nearai/ironclaw/pull/1147)) +- bump telegram channel version to 0.2.5 ([#1410](https://github.com/nearai/optimclaw/pull/1410)) +- *(ci)* enforce test requirement for state machine and resilience changes ([#1230](https://github.com/nearai/optimclaw/pull/1230)) ([#1304](https://github.com/nearai/optimclaw/pull/1304)) +- Fix duplicate LLM responses for matched event routines ([#1275](https://github.com/nearai/optimclaw/pull/1275)) +- add Japanese README ([#1306](https://github.com/nearai/optimclaw/pull/1306)) +- *(ci)* add coverage gates via codecov.yml ([#1228](https://github.com/nearai/optimclaw/pull/1228)) ([#1291](https://github.com/nearai/optimclaw/pull/1291)) +- Redesign routine create requests for LLMs ([#1147](https://github.com/nearai/optimclaw/pull/1147)) -## [0.19.0](https://github.com/nearai/ironclaw/compare/v0.18.0...v0.19.0) - 2026-03-17 +## [0.19.0](https://github.com/nearai/optimclaw/compare/v0.18.0...v0.19.0) - 2026-03-17 ### Added -- verify telegram owner during hot activation ([#1157](https://github.com/nearai/ironclaw/pull/1157)) -- *(config)* unify config resolution with Settings fallback (Phase 2, #1119) ([#1203](https://github.com/nearai/ironclaw/pull/1203)) -- *(sandbox)* add retry logic for transient container failures ([#1232](https://github.com/nearai/ironclaw/pull/1232)) -- *(heartbeat)* fire_at time-of-day scheduling with IANA timezone ([#1029](https://github.com/nearai/ironclaw/pull/1029)) -- Reuse Codex CLI OAuth tokens for ChatGPT backend LLM calls ([#693](https://github.com/nearai/ironclaw/pull/693)) -- add pre-push git hook with delta lint mode ([#833](https://github.com/nearai/ironclaw/pull/833)) -- *(cli)* add `logs` command for gateway log access ([#1105](https://github.com/nearai/ironclaw/pull/1105)) -- add Feishu/Lark WASM channel plugin ([#1110](https://github.com/nearai/ironclaw/pull/1110)) -- add Criterion benchmarks for safety layer hot paths ([#836](https://github.com/nearai/ironclaw/pull/836)) -- *(routines)* human-readable cron schedule summaries in web UI ([#1154](https://github.com/nearai/ironclaw/pull/1154)) -- *(web)* add follow-up suggestion chips and ghost text ([#1156](https://github.com/nearai/ironclaw/pull/1156)) -- *(ci)* include commit history in staging promotion PRs ([#952](https://github.com/nearai/ironclaw/pull/952)) -- *(tools)* add reusable sensitive JSON redaction helper ([#457](https://github.com/nearai/ironclaw/pull/457)) -- configurable hybrid search fusion strategy ([#234](https://github.com/nearai/ironclaw/pull/234)) -- *(cli)* add cron subcommand for managing scheduled routines ([#1017](https://github.com/nearai/ironclaw/pull/1017)) -- adds context-llm tool support ([#616](https://github.com/nearai/ironclaw/pull/616)) -- *(web-chat)* add hover copy button for user/assistant messages ([#948](https://github.com/nearai/ironclaw/pull/948)) -- add Slack approval buttons for tool execution in DMs ([#796](https://github.com/nearai/ironclaw/pull/796)) -- enhance HTTP tool parameter parsing ([#911](https://github.com/nearai/ironclaw/pull/911)) -- *(routines)* enable tool access in lightweight routine execution ([#257](https://github.com/nearai/ironclaw/pull/257)) ([#730](https://github.com/nearai/ironclaw/pull/730)) -- add MiniMax as a built-in LLM provider ([#940](https://github.com/nearai/ironclaw/pull/940)) -- *(cli)* add `ironclaw channels list` subcommand ([#933](https://github.com/nearai/ironclaw/pull/933)) -- *(cli)* add `ironclaw skills list/search/info` subcommands ([#918](https://github.com/nearai/ironclaw/pull/918)) -- add cargo-deny for supply chain safety ([#834](https://github.com/nearai/ironclaw/pull/834)) -- *(setup)* display ASCII art banner during onboarding ([#851](https://github.com/nearai/ironclaw/pull/851)) -- *(extensions)* unify auth and configure into single entrypoint ([#677](https://github.com/nearai/ironclaw/pull/677)) -- *(i18n)* Add internationalization support with Chinese and English translations ([#929](https://github.com/nearai/ironclaw/pull/929)) -- Import OpenClaw memory, history and settings ([#903](https://github.com/nearai/ironclaw/pull/903)) +- verify telegram owner during hot activation ([#1157](https://github.com/nearai/optimclaw/pull/1157)) +- *(config)* unify config resolution with Settings fallback (Phase 2, #1119) ([#1203](https://github.com/nearai/optimclaw/pull/1203)) +- *(sandbox)* add retry logic for transient container failures ([#1232](https://github.com/nearai/optimclaw/pull/1232)) +- *(heartbeat)* fire_at time-of-day scheduling with IANA timezone ([#1029](https://github.com/nearai/optimclaw/pull/1029)) +- Reuse Codex CLI OAuth tokens for ChatGPT backend LLM calls ([#693](https://github.com/nearai/optimclaw/pull/693)) +- add pre-push git hook with delta lint mode ([#833](https://github.com/nearai/optimclaw/pull/833)) +- *(cli)* add `logs` command for gateway log access ([#1105](https://github.com/nearai/optimclaw/pull/1105)) +- add Feishu/Lark WASM channel plugin ([#1110](https://github.com/nearai/optimclaw/pull/1110)) +- add Criterion benchmarks for safety layer hot paths ([#836](https://github.com/nearai/optimclaw/pull/836)) +- *(routines)* human-readable cron schedule summaries in web UI ([#1154](https://github.com/nearai/optimclaw/pull/1154)) +- *(web)* add follow-up suggestion chips and ghost text ([#1156](https://github.com/nearai/optimclaw/pull/1156)) +- *(ci)* include commit history in staging promotion PRs ([#952](https://github.com/nearai/optimclaw/pull/952)) +- *(tools)* add reusable sensitive JSON redaction helper ([#457](https://github.com/nearai/optimclaw/pull/457)) +- configurable hybrid search fusion strategy ([#234](https://github.com/nearai/optimclaw/pull/234)) +- *(cli)* add cron subcommand for managing scheduled routines ([#1017](https://github.com/nearai/optimclaw/pull/1017)) +- adds context-llm tool support ([#616](https://github.com/nearai/optimclaw/pull/616)) +- *(web-chat)* add hover copy button for user/assistant messages ([#948](https://github.com/nearai/optimclaw/pull/948)) +- add Slack approval buttons for tool execution in DMs ([#796](https://github.com/nearai/optimclaw/pull/796)) +- enhance HTTP tool parameter parsing ([#911](https://github.com/nearai/optimclaw/pull/911)) +- *(routines)* enable tool access in lightweight routine execution ([#257](https://github.com/nearai/optimclaw/pull/257)) ([#730](https://github.com/nearai/optimclaw/pull/730)) +- add MiniMax as a built-in LLM provider ([#940](https://github.com/nearai/optimclaw/pull/940)) +- *(cli)* add `optimclaw channels list` subcommand ([#933](https://github.com/nearai/optimclaw/pull/933)) +- *(cli)* add `optimclaw skills list/search/info` subcommands ([#918](https://github.com/nearai/optimclaw/pull/918)) +- add cargo-deny for supply chain safety ([#834](https://github.com/nearai/optimclaw/pull/834)) +- *(setup)* display ASCII art banner during onboarding ([#851](https://github.com/nearai/optimclaw/pull/851)) +- *(extensions)* unify auth and configure into single entrypoint ([#677](https://github.com/nearai/optimclaw/pull/677)) +- *(i18n)* Add internationalization support with Chinese and English translations ([#929](https://github.com/nearai/optimclaw/pull/929)) +- Import OpenClaw memory, history and settings ([#903](https://github.com/nearai/optimclaw/pull/903)) ### Fixed -- jobs limit ([#1274](https://github.com/nearai/ironclaw/pull/1274)) -- misleading UI message ([#1265](https://github.com/nearai/ironclaw/pull/1265)) -- bump channel registry versions for promotion ([#1264](https://github.com/nearai/ironclaw/pull/1264)) -- cover staging CI all-features and routine batch regressions ([#1256](https://github.com/nearai/ironclaw/pull/1256)) +- jobs limit ([#1274](https://github.com/nearai/optimclaw/pull/1274)) +- misleading UI message ([#1265](https://github.com/nearai/optimclaw/pull/1265)) +- bump channel registry versions for promotion ([#1264](https://github.com/nearai/optimclaw/pull/1264)) +- cover staging CI all-features and routine batch regressions ([#1256](https://github.com/nearai/optimclaw/pull/1256)) - resolve merge conflict fallout and missing config fields -- web/CLI routine mutations do not refresh live event trigger cache ([#1255](https://github.com/nearai/ironclaw/pull/1255)) -- *(jobs)* make completed->completed transition idempotent to prevent race errors ([#1068](https://github.com/nearai/ironclaw/pull/1068)) -- *(llm)* persist refreshed Anthropic OAuth token after Keychain re-read ([#1213](https://github.com/nearai/ironclaw/pull/1213)) -- *(worker)* prevent orphaned tool_results and fix parallel merging ([#1069](https://github.com/nearai/ironclaw/pull/1069)) -- Telegram bot token validation fails intermittently (HTTP 404) ([#1166](https://github.com/nearai/ironclaw/pull/1166)) -- *(security)* prevent metadata spoofing of internal job monitor flag ([#1195](https://github.com/nearai/ironclaw/pull/1195)) -- *(security)* default webhook server to loopback when tunnel is configured ([#1194](https://github.com/nearai/ironclaw/pull/1194)) -- *(auth)* avoid false success and block chat during pending auth ([#1111](https://github.com/nearai/ironclaw/pull/1111)) -- *(config)* unify ChannelsConfig resolution to env > settings > default ([#1124](https://github.com/nearai/ironclaw/pull/1124)) -- *(web-chat)* normalize chat copy to plain text ([#1114](https://github.com/nearai/ironclaw/pull/1114)) -- *(skill)* treat empty url param as absent when installing skills ([#1128](https://github.com/nearai/ironclaw/pull/1128)) -- preserve AuthError type in oauth_http_client cache ([#1152](https://github.com/nearai/ironclaw/pull/1152)) -- *(web)* prevent Safari IME composition Enter from sending message ([#1140](https://github.com/nearai/ironclaw/pull/1140)) -- *(mcp)* handle 400 auth errors, clear auth mode after OAuth, trim tokens ([#1158](https://github.com/nearai/ironclaw/pull/1158)) -- eliminate panic paths in production code ([#1184](https://github.com/nearai/ironclaw/pull/1184)) -- N+1 query pattern in event trigger loop (routine_engine) ([#1163](https://github.com/nearai/ironclaw/pull/1163)) -- *(llm)* add stop_sequences parity for tool completions ([#1170](https://github.com/nearai/ironclaw/pull/1170)) -- *(channels)* use live owner binding during wasm hot activation ([#1171](https://github.com/nearai/ironclaw/pull/1171)) -- Non-transactional multi-step context updates between metadata/to… ([#1161](https://github.com/nearai/ironclaw/pull/1161)) -- *(webhook)* avoid lock-held awaits in server lifecycle paths ([#1168](https://github.com/nearai/ironclaw/pull/1168)) -- Google Sheets returns 403 PERMISSION_DENIED after completing OAuth ([#1164](https://github.com/nearai/ironclaw/pull/1164)) -- HTTP webhook secret transmitted in request body rather than via header, docs inconsistency and security concern ([#1162](https://github.com/nearai/ironclaw/pull/1162)) -- *(ci)* exclude ironclaw_safety from release automation ([#1146](https://github.com/nearai/ironclaw/pull/1146)) -- *(registry)* bump versions for github, web-search, and discord extensions ([#1106](https://github.com/nearai/ironclaw/pull/1106)) -- *(mcp)* address 14 audit findings across MCP module ([#1094](https://github.com/nearai/ironclaw/pull/1094)) -- *(http)* replace .expect() with match in webhook handler ([#1133](https://github.com/nearai/ironclaw/pull/1133)) -- *(time)* treat empty timezone string as absent ([#1127](https://github.com/nearai/ironclaw/pull/1127)) -- 5 critical/high-priority bugs (auth bypass, relay failures, unbounded recursion, context growth) ([#1083](https://github.com/nearai/ironclaw/pull/1083)) -- *(ci)* checkout promotion PR head for metadata refresh ([#1097](https://github.com/nearai/ironclaw/pull/1097)) -- *(ci)* add missing attachments field and crates/ dir to Dockerfiles ([#1100](https://github.com/nearai/ironclaw/pull/1100)) -- *(registry)* bump telegram channel version for capabilities change ([#1064](https://github.com/nearai/ironclaw/pull/1064)) -- *(ci)* repair staging promotion workflow behavior ([#1091](https://github.com/nearai/ironclaw/pull/1091)) -- *(wasm)* address #1086 review followups -- description hint and coercion safety ([#1092](https://github.com/nearai/ironclaw/pull/1092)) -- *(ci)* repair staging-ci workflow parsing ([#1090](https://github.com/nearai/ironclaw/pull/1090)) -- *(extensions)* fix lifecycle bugs + comprehensive E2E tests ([#1070](https://github.com/nearai/ironclaw/pull/1070)) -- add tool_info schema discovery for WASM tools ([#1086](https://github.com/nearai/ironclaw/pull/1086)) -- resolve bug_bash UX/logging issues (#1054 #1055 #1058) ([#1072](https://github.com/nearai/ironclaw/pull/1072)) -- *(http)* fail closed when webhook secret is missing at runtime ([#1075](https://github.com/nearai/ironclaw/pull/1075)) -- *(service)* set CLI_ENABLED=false in macOS launchd plist ([#1079](https://github.com/nearai/ironclaw/pull/1079)) -- relax approval requirements for low-risk tools ([#922](https://github.com/nearai/ironclaw/pull/922)) -- *(web)* make approval requests appear without page reload ([#996](https://github.com/nearai/ironclaw/pull/996)) ([#1073](https://github.com/nearai/ironclaw/pull/1073)) -- *(routines)* run cron checks immediately on ticker startup ([#1066](https://github.com/nearai/ironclaw/pull/1066)) -- *(web)* recompute cron next_fire_at when re-enabling routines ([#1080](https://github.com/nearai/ironclaw/pull/1080)) -- *(memory)* reject absolute filesystem paths with corrective routing ([#934](https://github.com/nearai/ironclaw/pull/934)) -- remove all inline event handlers for CSP script-src compliance ([#1063](https://github.com/nearai/ironclaw/pull/1063)) -- *(mcp)* include OAuth state parameter in authorization URLs ([#1049](https://github.com/nearai/ironclaw/pull/1049)) -- *(mcp)* open MCP OAuth in same browser as gateway ([#951](https://github.com/nearai/ironclaw/pull/951)) -- *(deploy)* harden production container and bootstrap security ([#1014](https://github.com/nearai/ironclaw/pull/1014)) -- release lock guards before awaiting channel send ([#869](https://github.com/nearai/ironclaw/pull/869)) ([#1003](https://github.com/nearai/ironclaw/pull/1003)) -- *(registry)* use versioned artifact URLs and checksums for all WASM manifests ([#1007](https://github.com/nearai/ironclaw/pull/1007)) -- *(setup)* preserve model selection on provider re-run ([#679](https://github.com/nearai/ironclaw/pull/679)) ([#987](https://github.com/nearai/ironclaw/pull/987)) -- *(mcp)* attach session manager for non-OAuth HTTP clients ([#793](https://github.com/nearai/ironclaw/pull/793)) ([#986](https://github.com/nearai/ironclaw/pull/986)) -- *(security)* migrate webhook auth to HMAC-SHA256 signature header ([#970](https://github.com/nearai/ironclaw/pull/970)) -- *(security)* make unsafe env::set_var calls safe with explicit invariants ([#968](https://github.com/nearai/ironclaw/pull/968)) -- *(security)* require explicit SANDBOX_ALLOW_FULL_ACCESS to enable FullAccess policy ([#967](https://github.com/nearai/ironclaw/pull/967)) -- *(security)* add Content-Security-Policy header to web gateway ([#966](https://github.com/nearai/ironclaw/pull/966)) -- *(test)* stabilize openai compat oversized-body regression ([#839](https://github.com/nearai/ironclaw/pull/839)) -- *(ci)* disambiguate WASM bundle filenames to prevent tool/channel collision ([#964](https://github.com/nearai/ironclaw/pull/964)) -- *(setup)* validate channel credentials during setup ([#684](https://github.com/nearai/ironclaw/pull/684)) -- drain tunnel pipes to prevent zombie process ([#735](https://github.com/nearai/ironclaw/pull/735)) -- *(mcp)* header safety validation and Authorization conflict bug from #704 ([#752](https://github.com/nearai/ironclaw/pull/752)) -- *(agent)* block thread_id-based context pollution across users ([#760](https://github.com/nearai/ironclaw/pull/760)) -- *(mcp)* stdio/unix transports skip initialize handshake ([#890](https://github.com/nearai/ironclaw/pull/890)) ([#935](https://github.com/nearai/ironclaw/pull/935)) -- *(setup)* drain residual events and filter key kind in onboard prompts ([#937](https://github.com/nearai/ironclaw/pull/937)) ([#949](https://github.com/nearai/ironclaw/pull/949)) -- *(security)* load WASM tool description and schema from capabilities.json ([#520](https://github.com/nearai/ironclaw/pull/520)) -- *(security)* resolve DNS once and reuse for SSRF validation to prevent rebinding ([#518](https://github.com/nearai/ironclaw/pull/518)) -- *(security)* replace regex HTML sanitizer with DOMPurify to prevent XSS ([#510](https://github.com/nearai/ironclaw/pull/510)) -- *(ci)* improve Claude Code review reliability ([#955](https://github.com/nearai/ironclaw/pull/955)) -- *(ci)* run gated test jobs during staging CI ([#956](https://github.com/nearai/ironclaw/pull/956)) -- *(ci)* prevent staging-ci tag failure and chained PR auto-close ([#900](https://github.com/nearai/ironclaw/pull/900)) -- *(ci)* WASM WIT compat sqlite3 duplicate symbol conflict ([#953](https://github.com/nearai/ironclaw/pull/953)) -- resolve deferred review items from PRs #883, #848, #788 ([#915](https://github.com/nearai/ironclaw/pull/915)) -- *(web)* improve UX readability and accessibility in chat UI ([#910](https://github.com/nearai/ironclaw/pull/910)) +- web/CLI routine mutations do not refresh live event trigger cache ([#1255](https://github.com/nearai/optimclaw/pull/1255)) +- *(jobs)* make completed->completed transition idempotent to prevent race errors ([#1068](https://github.com/nearai/optimclaw/pull/1068)) +- *(llm)* persist refreshed Anthropic OAuth token after Keychain re-read ([#1213](https://github.com/nearai/optimclaw/pull/1213)) +- *(worker)* prevent orphaned tool_results and fix parallel merging ([#1069](https://github.com/nearai/optimclaw/pull/1069)) +- Telegram bot token validation fails intermittently (HTTP 404) ([#1166](https://github.com/nearai/optimclaw/pull/1166)) +- *(security)* prevent metadata spoofing of internal job monitor flag ([#1195](https://github.com/nearai/optimclaw/pull/1195)) +- *(security)* default webhook server to loopback when tunnel is configured ([#1194](https://github.com/nearai/optimclaw/pull/1194)) +- *(auth)* avoid false success and block chat during pending auth ([#1111](https://github.com/nearai/optimclaw/pull/1111)) +- *(config)* unify ChannelsConfig resolution to env > settings > default ([#1124](https://github.com/nearai/optimclaw/pull/1124)) +- *(web-chat)* normalize chat copy to plain text ([#1114](https://github.com/nearai/optimclaw/pull/1114)) +- *(skill)* treat empty url param as absent when installing skills ([#1128](https://github.com/nearai/optimclaw/pull/1128)) +- preserve AuthError type in oauth_http_client cache ([#1152](https://github.com/nearai/optimclaw/pull/1152)) +- *(web)* prevent Safari IME composition Enter from sending message ([#1140](https://github.com/nearai/optimclaw/pull/1140)) +- *(mcp)* handle 400 auth errors, clear auth mode after OAuth, trim tokens ([#1158](https://github.com/nearai/optimclaw/pull/1158)) +- eliminate panic paths in production code ([#1184](https://github.com/nearai/optimclaw/pull/1184)) +- N+1 query pattern in event trigger loop (routine_engine) ([#1163](https://github.com/nearai/optimclaw/pull/1163)) +- *(llm)* add stop_sequences parity for tool completions ([#1170](https://github.com/nearai/optimclaw/pull/1170)) +- *(channels)* use live owner binding during wasm hot activation ([#1171](https://github.com/nearai/optimclaw/pull/1171)) +- Non-transactional multi-step context updates between metadata/to… ([#1161](https://github.com/nearai/optimclaw/pull/1161)) +- *(webhook)* avoid lock-held awaits in server lifecycle paths ([#1168](https://github.com/nearai/optimclaw/pull/1168)) +- Google Sheets returns 403 PERMISSION_DENIED after completing OAuth ([#1164](https://github.com/nearai/optimclaw/pull/1164)) +- HTTP webhook secret transmitted in request body rather than via header, docs inconsistency and security concern ([#1162](https://github.com/nearai/optimclaw/pull/1162)) +- *(ci)* exclude optimclaw_safety from release automation ([#1146](https://github.com/nearai/optimclaw/pull/1146)) +- *(registry)* bump versions for github, web-search, and discord extensions ([#1106](https://github.com/nearai/optimclaw/pull/1106)) +- *(mcp)* address 14 audit findings across MCP module ([#1094](https://github.com/nearai/optimclaw/pull/1094)) +- *(http)* replace .expect() with match in webhook handler ([#1133](https://github.com/nearai/optimclaw/pull/1133)) +- *(time)* treat empty timezone string as absent ([#1127](https://github.com/nearai/optimclaw/pull/1127)) +- 5 critical/high-priority bugs (auth bypass, relay failures, unbounded recursion, context growth) ([#1083](https://github.com/nearai/optimclaw/pull/1083)) +- *(ci)* checkout promotion PR head for metadata refresh ([#1097](https://github.com/nearai/optimclaw/pull/1097)) +- *(ci)* add missing attachments field and crates/ dir to Dockerfiles ([#1100](https://github.com/nearai/optimclaw/pull/1100)) +- *(registry)* bump telegram channel version for capabilities change ([#1064](https://github.com/nearai/optimclaw/pull/1064)) +- *(ci)* repair staging promotion workflow behavior ([#1091](https://github.com/nearai/optimclaw/pull/1091)) +- *(wasm)* address #1086 review followups -- description hint and coercion safety ([#1092](https://github.com/nearai/optimclaw/pull/1092)) +- *(ci)* repair staging-ci workflow parsing ([#1090](https://github.com/nearai/optimclaw/pull/1090)) +- *(extensions)* fix lifecycle bugs + comprehensive E2E tests ([#1070](https://github.com/nearai/optimclaw/pull/1070)) +- add tool_info schema discovery for WASM tools ([#1086](https://github.com/nearai/optimclaw/pull/1086)) +- resolve bug_bash UX/logging issues (#1054 #1055 #1058) ([#1072](https://github.com/nearai/optimclaw/pull/1072)) +- *(http)* fail closed when webhook secret is missing at runtime ([#1075](https://github.com/nearai/optimclaw/pull/1075)) +- *(service)* set CLI_ENABLED=false in macOS launchd plist ([#1079](https://github.com/nearai/optimclaw/pull/1079)) +- relax approval requirements for low-risk tools ([#922](https://github.com/nearai/optimclaw/pull/922)) +- *(web)* make approval requests appear without page reload ([#996](https://github.com/nearai/optimclaw/pull/996)) ([#1073](https://github.com/nearai/optimclaw/pull/1073)) +- *(routines)* run cron checks immediately on ticker startup ([#1066](https://github.com/nearai/optimclaw/pull/1066)) +- *(web)* recompute cron next_fire_at when re-enabling routines ([#1080](https://github.com/nearai/optimclaw/pull/1080)) +- *(memory)* reject absolute filesystem paths with corrective routing ([#934](https://github.com/nearai/optimclaw/pull/934)) +- remove all inline event handlers for CSP script-src compliance ([#1063](https://github.com/nearai/optimclaw/pull/1063)) +- *(mcp)* include OAuth state parameter in authorization URLs ([#1049](https://github.com/nearai/optimclaw/pull/1049)) +- *(mcp)* open MCP OAuth in same browser as gateway ([#951](https://github.com/nearai/optimclaw/pull/951)) +- *(deploy)* harden production container and bootstrap security ([#1014](https://github.com/nearai/optimclaw/pull/1014)) +- release lock guards before awaiting channel send ([#869](https://github.com/nearai/optimclaw/pull/869)) ([#1003](https://github.com/nearai/optimclaw/pull/1003)) +- *(registry)* use versioned artifact URLs and checksums for all WASM manifests ([#1007](https://github.com/nearai/optimclaw/pull/1007)) +- *(setup)* preserve model selection on provider re-run ([#679](https://github.com/nearai/optimclaw/pull/679)) ([#987](https://github.com/nearai/optimclaw/pull/987)) +- *(mcp)* attach session manager for non-OAuth HTTP clients ([#793](https://github.com/nearai/optimclaw/pull/793)) ([#986](https://github.com/nearai/optimclaw/pull/986)) +- *(security)* migrate webhook auth to HMAC-SHA256 signature header ([#970](https://github.com/nearai/optimclaw/pull/970)) +- *(security)* make unsafe env::set_var calls safe with explicit invariants ([#968](https://github.com/nearai/optimclaw/pull/968)) +- *(security)* require explicit SANDBOX_ALLOW_FULL_ACCESS to enable FullAccess policy ([#967](https://github.com/nearai/optimclaw/pull/967)) +- *(security)* add Content-Security-Policy header to web gateway ([#966](https://github.com/nearai/optimclaw/pull/966)) +- *(test)* stabilize openai compat oversized-body regression ([#839](https://github.com/nearai/optimclaw/pull/839)) +- *(ci)* disambiguate WASM bundle filenames to prevent tool/channel collision ([#964](https://github.com/nearai/optimclaw/pull/964)) +- *(setup)* validate channel credentials during setup ([#684](https://github.com/nearai/optimclaw/pull/684)) +- drain tunnel pipes to prevent zombie process ([#735](https://github.com/nearai/optimclaw/pull/735)) +- *(mcp)* header safety validation and Authorization conflict bug from #704 ([#752](https://github.com/nearai/optimclaw/pull/752)) +- *(agent)* block thread_id-based context pollution across users ([#760](https://github.com/nearai/optimclaw/pull/760)) +- *(mcp)* stdio/unix transports skip initialize handshake ([#890](https://github.com/nearai/optimclaw/pull/890)) ([#935](https://github.com/nearai/optimclaw/pull/935)) +- *(setup)* drain residual events and filter key kind in onboard prompts ([#937](https://github.com/nearai/optimclaw/pull/937)) ([#949](https://github.com/nearai/optimclaw/pull/949)) +- *(security)* load WASM tool description and schema from capabilities.json ([#520](https://github.com/nearai/optimclaw/pull/520)) +- *(security)* resolve DNS once and reuse for SSRF validation to prevent rebinding ([#518](https://github.com/nearai/optimclaw/pull/518)) +- *(security)* replace regex HTML sanitizer with DOMPurify to prevent XSS ([#510](https://github.com/nearai/optimclaw/pull/510)) +- *(ci)* improve Claude Code review reliability ([#955](https://github.com/nearai/optimclaw/pull/955)) +- *(ci)* run gated test jobs during staging CI ([#956](https://github.com/nearai/optimclaw/pull/956)) +- *(ci)* prevent staging-ci tag failure and chained PR auto-close ([#900](https://github.com/nearai/optimclaw/pull/900)) +- *(ci)* WASM WIT compat sqlite3 duplicate symbol conflict ([#953](https://github.com/nearai/optimclaw/pull/953)) +- resolve deferred review items from PRs #883, #848, #788 ([#915](https://github.com/nearai/optimclaw/pull/915)) +- *(web)* improve UX readability and accessibility in chat UI ([#910](https://github.com/nearai/optimclaw/pull/910)) ### Other -- Fix Telegram auto-verify flow and routing ([#1273](https://github.com/nearai/ironclaw/pull/1273)) -- *(e2e)* fix approval waiting regression coverage ([#1270](https://github.com/nearai/ironclaw/pull/1270)) -- isolate heavy integration tests ([#1266](https://github.com/nearai/ironclaw/pull/1266)) +- Fix Telegram auto-verify flow and routing ([#1273](https://github.com/nearai/optimclaw/pull/1273)) +- *(e2e)* fix approval waiting regression coverage ([#1270](https://github.com/nearai/optimclaw/pull/1270)) +- isolate heavy integration tests ([#1266](https://github.com/nearai/optimclaw/pull/1266)) - Merge branch 'main' into fix/resolve-conflicts -- Refactor owner scope across channels and fix default routing fallback ([#1151](https://github.com/nearai/ironclaw/pull/1151)) -- *(extensions)* document relay manager init order ([#928](https://github.com/nearai/ironclaw/pull/928)) -- *(setup)* extract init logic from wizard into owning modules ([#1210](https://github.com/nearai/ironclaw/pull/1210)) -- mention MiniMax as built-in provider in all READMEs ([#1209](https://github.com/nearai/ironclaw/pull/1209)) -- Fix schema-guided tool parameter coercion ([#1143](https://github.com/nearai/ironclaw/pull/1143)) -- Make no-panics CI check test-aware ([#1160](https://github.com/nearai/ironclaw/pull/1160)) -- *(mcp)* avoid reallocating SSE buffer on each chunk ([#1153](https://github.com/nearai/ironclaw/pull/1153)) -- *(routines)* avoid full message history clone each tool iteration ([#1172](https://github.com/nearai/ironclaw/pull/1172)) -- *(registry)* align manifest versions with published artifacts ([#1169](https://github.com/nearai/ironclaw/pull/1169)) -- remove __pycache__ from repo and add to .gitignore ([#1177](https://github.com/nearai/ironclaw/pull/1177)) -- *(registry)* move MCP servers from code to JSON manifests ([#1144](https://github.com/nearai/ironclaw/pull/1144)) -- improve routine schema guidance ([#1089](https://github.com/nearai/ironclaw/pull/1089)) -- add event-trigger routine e2e coverage ([#1088](https://github.com/nearai/ironclaw/pull/1088)) -- enforce no .unwrap(), .expect(), or assert!() in production code ([#1087](https://github.com/nearai/ironclaw/pull/1087)) -- periodic sync main into staging (resolved conflicts) ([#1098](https://github.com/nearai/ironclaw/pull/1098)) -- fix formatting in cli/mod.rs and mcp/auth.rs ([#1071](https://github.com/nearai/ironclaw/pull/1071)) -- Expose the shared agent session manager via AppComponents ([#532](https://github.com/nearai/ironclaw/pull/532)) -- *(agent)* remove unnecessary Worker re-export ([#923](https://github.com/nearai/ironclaw/pull/923)) -- Fix UTF-8 unsafe truncation in WASM emit_message ([#1015](https://github.com/nearai/ironclaw/pull/1015)) -- extract safety module into ironclaw_safety crate ([#1024](https://github.com/nearai/ironclaw/pull/1024)) -- Add Z.AI provider support for GLM-5 ([#938](https://github.com/nearai/ironclaw/pull/938)) -- *(html_to_markdown)* refresh golden files after renderer bump ([#1016](https://github.com/nearai/ironclaw/pull/1016)) -- Migrate GitHub webhook normalization into github tool ([#758](https://github.com/nearai/ironclaw/pull/758)) -- Fix systemctl unit ([#472](https://github.com/nearai/ironclaw/pull/472)) -- add Russian localization (README.ru.md) ([#850](https://github.com/nearai/ironclaw/pull/850)) -- Add generic host-verified /webhook/tools/{tool} ingress ([#757](https://github.com/nearai/ironclaw/pull/757)) +- Refactor owner scope across channels and fix default routing fallback ([#1151](https://github.com/nearai/optimclaw/pull/1151)) +- *(extensions)* document relay manager init order ([#928](https://github.com/nearai/optimclaw/pull/928)) +- *(setup)* extract init logic from wizard into owning modules ([#1210](https://github.com/nearai/optimclaw/pull/1210)) +- mention MiniMax as built-in provider in all READMEs ([#1209](https://github.com/nearai/optimclaw/pull/1209)) +- Fix schema-guided tool parameter coercion ([#1143](https://github.com/nearai/optimclaw/pull/1143)) +- Make no-panics CI check test-aware ([#1160](https://github.com/nearai/optimclaw/pull/1160)) +- *(mcp)* avoid reallocating SSE buffer on each chunk ([#1153](https://github.com/nearai/optimclaw/pull/1153)) +- *(routines)* avoid full message history clone each tool iteration ([#1172](https://github.com/nearai/optimclaw/pull/1172)) +- *(registry)* align manifest versions with published artifacts ([#1169](https://github.com/nearai/optimclaw/pull/1169)) +- remove __pycache__ from repo and add to .gitignore ([#1177](https://github.com/nearai/optimclaw/pull/1177)) +- *(registry)* move MCP servers from code to JSON manifests ([#1144](https://github.com/nearai/optimclaw/pull/1144)) +- improve routine schema guidance ([#1089](https://github.com/nearai/optimclaw/pull/1089)) +- add event-trigger routine e2e coverage ([#1088](https://github.com/nearai/optimclaw/pull/1088)) +- enforce no .unwrap(), .expect(), or assert!() in production code ([#1087](https://github.com/nearai/optimclaw/pull/1087)) +- periodic sync main into staging (resolved conflicts) ([#1098](https://github.com/nearai/optimclaw/pull/1098)) +- fix formatting in cli/mod.rs and mcp/auth.rs ([#1071](https://github.com/nearai/optimclaw/pull/1071)) +- Expose the shared agent session manager via AppComponents ([#532](https://github.com/nearai/optimclaw/pull/532)) +- *(agent)* remove unnecessary Worker re-export ([#923](https://github.com/nearai/optimclaw/pull/923)) +- Fix UTF-8 unsafe truncation in WASM emit_message ([#1015](https://github.com/nearai/optimclaw/pull/1015)) +- extract safety module into optimclaw_safety crate ([#1024](https://github.com/nearai/optimclaw/pull/1024)) +- Add Z.AI provider support for GLM-5 ([#938](https://github.com/nearai/optimclaw/pull/938)) +- *(html_to_markdown)* refresh golden files after renderer bump ([#1016](https://github.com/nearai/optimclaw/pull/1016)) +- Migrate GitHub webhook normalization into github tool ([#758](https://github.com/nearai/optimclaw/pull/758)) +- Fix systemctl unit ([#472](https://github.com/nearai/optimclaw/pull/472)) +- add Russian localization (README.ru.md) ([#850](https://github.com/nearai/optimclaw/pull/850)) +- Add generic host-verified /webhook/tools/{tool} ingress ([#757](https://github.com/nearai/optimclaw/pull/757)) -## [0.18.0](https://github.com/nearai/ironclaw/compare/v0.17.0...v0.18.0) - 2026-03-11 +## [0.18.0](https://github.com/nearai/optimclaw/compare/v0.17.0...v0.18.0) - 2026-03-11 ### Other - Merge pull request #907 from nearai/staging-promote/b0214fef-22930316561 -- promote staging to main (2026-03-10 15:19 UTC) ([#865](https://github.com/nearai/ironclaw/pull/865)) +- promote staging to main (2026-03-10 15:19 UTC) ([#865](https://github.com/nearai/optimclaw/pull/865)) - Merge pull request #830 from nearai/staging-promote/3a2989d0-22888378864 -- update WASM artifact SHA256 checksums [skip ci] ([#876](https://github.com/nearai/ironclaw/pull/876)) +- update WASM artifact SHA256 checksums [skip ci] ([#876](https://github.com/nearai/optimclaw/pull/876)) -## [0.17.0](https://github.com/nearai/ironclaw/compare/v0.16.1...v0.17.0) - 2026-03-10 +## [0.17.0](https://github.com/nearai/optimclaw/compare/v0.16.1...v0.17.0) - 2026-03-10 ### Added -- *(llm)* per-provider unsupported parameter filtering (#749, #728) ([#809](https://github.com/nearai/ironclaw/pull/809)) -- persist user_id in save_job and expose job_id on routine runs ([#709](https://github.com/nearai/ironclaw/pull/709)) -- *(ci)* chained promotion PRs with multi-agent Claude review ([#776](https://github.com/nearai/ironclaw/pull/776)) -- add background sandbox reaper for orphaned Docker containers ([#634](https://github.com/nearai/ironclaw/pull/634)) -- *(wasm)* lazy schema injection on WASM tool errors ([#638](https://github.com/nearai/ironclaw/pull/638)) -- add AWS Bedrock LLM provider via native Converse API ([#713](https://github.com/nearai/ironclaw/pull/713)) -- full image support across all channels ([#725](https://github.com/nearai/ironclaw/pull/725)) -- *(skills)* exclude_keywords veto in skill activation scoring ([#688](https://github.com/nearai/ironclaw/pull/688)) -- *(mcp)* transport abstraction, stdio/UDS transports, and OAuth fixes ([#721](https://github.com/nearai/ironclaw/pull/721)) -- add PID-based gateway lock to prevent multiple instances ([#717](https://github.com/nearai/ironclaw/pull/717)) -- configurable LLM request timeout via LLM_REQUEST_TIMEOUT_SECS ([#615](https://github.com/nearai/ironclaw/pull/615)) ([#630](https://github.com/nearai/ironclaw/pull/630)) -- *(timezone)* add timezone-aware session context ([#671](https://github.com/nearai/ironclaw/pull/671)) -- *(setup)* Anthropic OAuth onboarding with setup-token support ([#384](https://github.com/nearai/ironclaw/pull/384)) -- *(llm)* add Google Gemini, AWS Bedrock, io.net, Mistral, Yandex, and Cloudflare WS AI providers ([#676](https://github.com/nearai/ironclaw/pull/676)) -- unified thread model for web gateway ([#607](https://github.com/nearai/ironclaw/pull/607)) -- WASM channel attachments with LLM pipeline integration ([#596](https://github.com/nearai/ironclaw/pull/596)) -- enable Anthropic prompt caching via automatic cache_control injection ([#660](https://github.com/nearai/ironclaw/pull/660)) -- *(routines)* approval context for autonomous job execution ([#577](https://github.com/nearai/ironclaw/pull/577)) -- *(llm)* declarative provider registry ([#618](https://github.com/nearai/ironclaw/pull/618)) -- *(gateway)* show IronClaw version in status popover [skip-regression-check] ([#636](https://github.com/nearai/ironclaw/pull/636)) -- Wire memory hygiene retention policy into heartbeat loop ([#629](https://github.com/nearai/ironclaw/pull/629)) +- *(llm)* per-provider unsupported parameter filtering (#749, #728) ([#809](https://github.com/nearai/optimclaw/pull/809)) +- persist user_id in save_job and expose job_id on routine runs ([#709](https://github.com/nearai/optimclaw/pull/709)) +- *(ci)* chained promotion PRs with multi-agent Claude review ([#776](https://github.com/nearai/optimclaw/pull/776)) +- add background sandbox reaper for orphaned Docker containers ([#634](https://github.com/nearai/optimclaw/pull/634)) +- *(wasm)* lazy schema injection on WASM tool errors ([#638](https://github.com/nearai/optimclaw/pull/638)) +- add AWS Bedrock LLM provider via native Converse API ([#713](https://github.com/nearai/optimclaw/pull/713)) +- full image support across all channels ([#725](https://github.com/nearai/optimclaw/pull/725)) +- *(skills)* exclude_keywords veto in skill activation scoring ([#688](https://github.com/nearai/optimclaw/pull/688)) +- *(mcp)* transport abstraction, stdio/UDS transports, and OAuth fixes ([#721](https://github.com/nearai/optimclaw/pull/721)) +- add PID-based gateway lock to prevent multiple instances ([#717](https://github.com/nearai/optimclaw/pull/717)) +- configurable LLM request timeout via LLM_REQUEST_TIMEOUT_SECS ([#615](https://github.com/nearai/optimclaw/pull/615)) ([#630](https://github.com/nearai/optimclaw/pull/630)) +- *(timezone)* add timezone-aware session context ([#671](https://github.com/nearai/optimclaw/pull/671)) +- *(setup)* Anthropic OAuth onboarding with setup-token support ([#384](https://github.com/nearai/optimclaw/pull/384)) +- *(llm)* add Google Gemini, AWS Bedrock, io.net, Mistral, Yandex, and Cloudflare WS AI providers ([#676](https://github.com/nearai/optimclaw/pull/676)) +- unified thread model for web gateway ([#607](https://github.com/nearai/optimclaw/pull/607)) +- WASM channel attachments with LLM pipeline integration ([#596](https://github.com/nearai/optimclaw/pull/596)) +- enable Anthropic prompt caching via automatic cache_control injection ([#660](https://github.com/nearai/optimclaw/pull/660)) +- *(routines)* approval context for autonomous job execution ([#577](https://github.com/nearai/optimclaw/pull/577)) +- *(llm)* declarative provider registry ([#618](https://github.com/nearai/optimclaw/pull/618)) +- *(gateway)* show OptimClaw version in status popover [skip-regression-check] ([#636](https://github.com/nearai/optimclaw/pull/636)) +- Wire memory hygiene retention policy into heartbeat loop ([#629](https://github.com/nearai/optimclaw/pull/629)) ### Fixed -- *(ci)* run fmt + clippy on staging PRs, skip Windows clippy [skip-regression-check] ([#802](https://github.com/nearai/ironclaw/pull/802)) -- *(ci)* clean up staging pipeline — remove hacks, skip redundant checks [skip-regression-check] ([#794](https://github.com/nearai/ironclaw/pull/794)) -- *(ci)* secrets can't be used in step if conditions [skip-regression-check] ([#787](https://github.com/nearai/ironclaw/pull/787)) -- prevent irreversible context loss when compaction archive write fails ([#754](https://github.com/nearai/ironclaw/pull/754)) -- button styles ([#637](https://github.com/nearai/ironclaw/pull/637)) -- *(mcp)* JSON-RPC spec compliance — flexible id, correct notification format ([#685](https://github.com/nearai/ironclaw/pull/685)) -- preserve tool-call history across thread hydration ([#568](https://github.com/nearai/ironclaw/pull/568)) ([#670](https://github.com/nearai/ironclaw/pull/670)) -- CLI commands ignore runtime DATABASE_BACKEND when both features compiled ([#740](https://github.com/nearai/ironclaw/pull/740)) -- *(web)* prevent fetch error when hostname is an IP address in TEE check ([#672](https://github.com/nearai/ironclaw/pull/672)) -- add timezone conversion support to time tool ([#687](https://github.com/nearai/ironclaw/pull/687)) -- standardize libSQL timestamps as RFC 3339 UTC ([#683](https://github.com/nearai/ironclaw/pull/683)) -- *(docker)* bind postgres to localhost only ([#686](https://github.com/nearai/ironclaw/pull/686)) -- *(repl)* skip /quit on EOF when stdin is not a TTY ([#724](https://github.com/nearai/ironclaw/pull/724)) -- *(web)* prevent Enter key from sending message during IME composition ([#715](https://github.com/nearai/ironclaw/pull/715)) -- *(config)* init_secrets no longer overwrites entire config ([#726](https://github.com/nearai/ironclaw/pull/726)) -- *(cli)* status command ignores config.toml and settings.json ([#354](https://github.com/nearai/ironclaw/pull/354)) ([#734](https://github.com/nearai/ironclaw/pull/734)) -- *(setup)* preserve model name when re-running onboarding with same provider ([#600](https://github.com/nearai/ironclaw/pull/600)) ([#694](https://github.com/nearai/ironclaw/pull/694)) -- *(setup)* initialize secrets crypto for env-var security option ([#666](https://github.com/nearai/ironclaw/pull/666)) ([#706](https://github.com/nearai/ironclaw/pull/706)) -- persist /model selection across restarts ([#707](https://github.com/nearai/ironclaw/pull/707)) -- *(routines)* resolve message tool channel/target from per-job metadata ([#708](https://github.com/nearai/ironclaw/pull/708)) -- sanitize HTML error bodies from MCP servers to prevent web UI white screen ([#263](https://github.com/nearai/ironclaw/pull/263)) ([#656](https://github.com/nearai/ironclaw/pull/656)) -- prevent Instant duration overflow on Windows ([#657](https://github.com/nearai/ironclaw/pull/657)) ([#664](https://github.com/nearai/ironclaw/pull/664)) -- enable libsql remote + tls features for Turso cloud sync ([#587](https://github.com/nearai/ironclaw/pull/587)) -- *(tests)* replace hardcoded /tmp paths with tempdir + add 300 unit tests ([#659](https://github.com/nearai/ironclaw/pull/659)) -- *(llm)* nudge LLM when it expresses tool intent without calling tools ([#653](https://github.com/nearai/ironclaw/pull/653)) -- *(llm)* report zero cost for OpenRouter free-tier models ([#463](https://github.com/nearai/ironclaw/pull/463)) ([#613](https://github.com/nearai/ironclaw/pull/613)) -- reliable network tests and improved tool error messages ([#626](https://github.com/nearai/ironclaw/pull/626)) -- *(wasm)* use per-engine cache dirs on Windows to avoid file lock error ([#624](https://github.com/nearai/ironclaw/pull/624)) -- *(libsql)* support flexible embedding dimensions ([#534](https://github.com/nearai/ironclaw/pull/534)) +- *(ci)* run fmt + clippy on staging PRs, skip Windows clippy [skip-regression-check] ([#802](https://github.com/nearai/optimclaw/pull/802)) +- *(ci)* clean up staging pipeline — remove hacks, skip redundant checks [skip-regression-check] ([#794](https://github.com/nearai/optimclaw/pull/794)) +- *(ci)* secrets can't be used in step if conditions [skip-regression-check] ([#787](https://github.com/nearai/optimclaw/pull/787)) +- prevent irreversible context loss when compaction archive write fails ([#754](https://github.com/nearai/optimclaw/pull/754)) +- button styles ([#637](https://github.com/nearai/optimclaw/pull/637)) +- *(mcp)* JSON-RPC spec compliance — flexible id, correct notification format ([#685](https://github.com/nearai/optimclaw/pull/685)) +- preserve tool-call history across thread hydration ([#568](https://github.com/nearai/optimclaw/pull/568)) ([#670](https://github.com/nearai/optimclaw/pull/670)) +- CLI commands ignore runtime DATABASE_BACKEND when both features compiled ([#740](https://github.com/nearai/optimclaw/pull/740)) +- *(web)* prevent fetch error when hostname is an IP address in TEE check ([#672](https://github.com/nearai/optimclaw/pull/672)) +- add timezone conversion support to time tool ([#687](https://github.com/nearai/optimclaw/pull/687)) +- standardize libSQL timestamps as RFC 3339 UTC ([#683](https://github.com/nearai/optimclaw/pull/683)) +- *(docker)* bind postgres to localhost only ([#686](https://github.com/nearai/optimclaw/pull/686)) +- *(repl)* skip /quit on EOF when stdin is not a TTY ([#724](https://github.com/nearai/optimclaw/pull/724)) +- *(web)* prevent Enter key from sending message during IME composition ([#715](https://github.com/nearai/optimclaw/pull/715)) +- *(config)* init_secrets no longer overwrites entire config ([#726](https://github.com/nearai/optimclaw/pull/726)) +- *(cli)* status command ignores config.toml and settings.json ([#354](https://github.com/nearai/optimclaw/pull/354)) ([#734](https://github.com/nearai/optimclaw/pull/734)) +- *(setup)* preserve model name when re-running onboarding with same provider ([#600](https://github.com/nearai/optimclaw/pull/600)) ([#694](https://github.com/nearai/optimclaw/pull/694)) +- *(setup)* initialize secrets crypto for env-var security option ([#666](https://github.com/nearai/optimclaw/pull/666)) ([#706](https://github.com/nearai/optimclaw/pull/706)) +- persist /model selection across restarts ([#707](https://github.com/nearai/optimclaw/pull/707)) +- *(routines)* resolve message tool channel/target from per-job metadata ([#708](https://github.com/nearai/optimclaw/pull/708)) +- sanitize HTML error bodies from MCP servers to prevent web UI white screen ([#263](https://github.com/nearai/optimclaw/pull/263)) ([#656](https://github.com/nearai/optimclaw/pull/656)) +- prevent Instant duration overflow on Windows ([#657](https://github.com/nearai/optimclaw/pull/657)) ([#664](https://github.com/nearai/optimclaw/pull/664)) +- enable libsql remote + tls features for Turso cloud sync ([#587](https://github.com/nearai/optimclaw/pull/587)) +- *(tests)* replace hardcoded /tmp paths with tempdir + add 300 unit tests ([#659](https://github.com/nearai/optimclaw/pull/659)) +- *(llm)* nudge LLM when it expresses tool intent without calling tools ([#653](https://github.com/nearai/optimclaw/pull/653)) +- *(llm)* report zero cost for OpenRouter free-tier models ([#463](https://github.com/nearai/optimclaw/pull/463)) ([#613](https://github.com/nearai/optimclaw/pull/613)) +- reliable network tests and improved tool error messages ([#626](https://github.com/nearai/optimclaw/pull/626)) +- *(wasm)* use per-engine cache dirs on Windows to avoid file lock error ([#624](https://github.com/nearai/optimclaw/pull/624)) +- *(libsql)* support flexible embedding dimensions ([#534](https://github.com/nearai/optimclaw/pull/534)) ### Other -- Restructure CLAUDE.md into modular rules + add pr-shepherd command ([#750](https://github.com/nearai/ironclaw/pull/750)) -- make src/llm/ self-contained for crate extraction ([#767](https://github.com/nearai/ironclaw/pull/767)) -- add simplified Chinese (zh-CN) README translation ([#488](https://github.com/nearai/ironclaw/pull/488)) -- *(job)* cover job tool validation and state transitions ([#681](https://github.com/nearai/ironclaw/pull/681)) -- *(agent)* wire TestRig job tools through the scheduler ([#716](https://github.com/nearai/ironclaw/pull/716)) -- Fix single-message mode to exit after one turn when background channels are enabled ([#719](https://github.com/nearai/ironclaw/pull/719)) -- remove dead code ([#648](https://github.com/nearai/ironclaw/pull/648)) ([#703](https://github.com/nearai/ironclaw/pull/703)) -- add reviewer-feedback guardrails (CLAUDE.md, pre-commit hook, skill) ([#665](https://github.com/nearai/ironclaw/pull/665)) -- update WASM artifact SHA256 checksums [skip ci] ([#631](https://github.com/nearai/ironclaw/pull/631)) -- add explanatory comments to coverage workflow ([#610](https://github.com/nearai/ironclaw/pull/610)) -- build system prompt once per turn, skip tools on force-text ([#583](https://github.com/nearai/ironclaw/pull/583)) -- add comprehensive subdirectory CLAUDE.md files and update root ([#589](https://github.com/nearai/ironclaw/pull/589)) -- Improve test infrastructure: StubChannel, gateway helpers, security tests, search edge cases ([#623](https://github.com/nearai/ironclaw/pull/623)) -- *(workspace)* regression test for document_path in search results ([#509](https://github.com/nearai/ironclaw/pull/509)) +- Restructure CLAUDE.md into modular rules + add pr-shepherd command ([#750](https://github.com/nearai/optimclaw/pull/750)) +- make src/llm/ self-contained for crate extraction ([#767](https://github.com/nearai/optimclaw/pull/767)) +- add simplified Chinese (zh-CN) README translation ([#488](https://github.com/nearai/optimclaw/pull/488)) +- *(job)* cover job tool validation and state transitions ([#681](https://github.com/nearai/optimclaw/pull/681)) +- *(agent)* wire TestRig job tools through the scheduler ([#716](https://github.com/nearai/optimclaw/pull/716)) +- Fix single-message mode to exit after one turn when background channels are enabled ([#719](https://github.com/nearai/optimclaw/pull/719)) +- remove dead code ([#648](https://github.com/nearai/optimclaw/pull/648)) ([#703](https://github.com/nearai/optimclaw/pull/703)) +- add reviewer-feedback guardrails (CLAUDE.md, pre-commit hook, skill) ([#665](https://github.com/nearai/optimclaw/pull/665)) +- update WASM artifact SHA256 checksums [skip ci] ([#631](https://github.com/nearai/optimclaw/pull/631)) +- add explanatory comments to coverage workflow ([#610](https://github.com/nearai/optimclaw/pull/610)) +- build system prompt once per turn, skip tools on force-text ([#583](https://github.com/nearai/optimclaw/pull/583)) +- add comprehensive subdirectory CLAUDE.md files and update root ([#589](https://github.com/nearai/optimclaw/pull/589)) +- Improve test infrastructure: StubChannel, gateway helpers, security tests, search edge cases ([#623](https://github.com/nearai/optimclaw/pull/623)) +- *(workspace)* regression test for document_path in search results ([#509](https://github.com/nearai/optimclaw/pull/509)) ### Added - AWS Bedrock LLM provider via native Converse API with IAM and SSO auth support (feature-gated: `--features bedrock`) -## [0.16.1](https://github.com/nearai/ironclaw/compare/v0.16.0...v0.16.1) - 2026-03-06 +## [0.16.1](https://github.com/nearai/optimclaw/compare/v0.16.0...v0.16.1) - 2026-03-06 ### Fixed -- revert WASM artifact SHA256 checksums to null ([#627](https://github.com/nearai/ironclaw/pull/627)) +- revert WASM artifact SHA256 checksums to null ([#627](https://github.com/nearai/optimclaw/pull/627)) -## [0.16.0](https://github.com/nearai/ironclaw/compare/v0.15.0...v0.16.0) - 2026-03-06 +## [0.16.0](https://github.com/nearai/optimclaw/compare/v0.15.0...v0.16.0) - 2026-03-06 ### Added -- *(e2e)* extensions tab tests, CI parallelization, and 3 production bug fixes ([#584](https://github.com/nearai/ironclaw/pull/584)) -- WASM extension versioning with WIT compat checks ([#592](https://github.com/nearai/ironclaw/pull/592)) -- Add HMAC-SHA256 webhook signature validation for Slack ([#588](https://github.com/nearai/ironclaw/pull/588)) -- restart ([#531](https://github.com/nearai/ironclaw/pull/531)) -- merge http/web_fetch tools, add tool output stash for large responses ([#578](https://github.com/nearai/ironclaw/pull/578)) -- integrate 13-dimension complexity scorer into smart routing ([#529](https://github.com/nearai/ironclaw/pull/529)) +- *(e2e)* extensions tab tests, CI parallelization, and 3 production bug fixes ([#584](https://github.com/nearai/optimclaw/pull/584)) +- WASM extension versioning with WIT compat checks ([#592](https://github.com/nearai/optimclaw/pull/592)) +- Add HMAC-SHA256 webhook signature validation for Slack ([#588](https://github.com/nearai/optimclaw/pull/588)) +- restart ([#531](https://github.com/nearai/optimclaw/pull/531)) +- merge http/web_fetch tools, add tool output stash for large responses ([#578](https://github.com/nearai/optimclaw/pull/578)) +- integrate 13-dimension complexity scorer into smart routing ([#529](https://github.com/nearai/optimclaw/pull/529)) ### Fixed -- *(llm)* fix reasoning model response parsing bugs ([#564](https://github.com/nearai/ironclaw/pull/564)) ([#580](https://github.com/nearai/ironclaw/pull/580)) -- *(ci)* fix three coverage workflow failures ([#597](https://github.com/nearai/ironclaw/pull/597)) -- Telegram channel accepts group messages from all users if owner_… ([#590](https://github.com/nearai/ironclaw/pull/590)) -- *(ci)* anchor coverage/ gitignore rule to repo root ([#591](https://github.com/nearai/ironclaw/pull/591)) -- *(security)* use OsRng for all security-critical key and token generation ([#519](https://github.com/nearai/ironclaw/pull/519)) -- prevent concurrent memory hygiene passes and Windows file lock errors ([#535](https://github.com/nearai/ironclaw/pull/535)) -- sort tool_definitions() for deterministic LLM tool ordering ([#582](https://github.com/nearai/ironclaw/pull/582)) -- *(ci)* persist all cargo-llvm-cov env vars for E2E coverage ([#559](https://github.com/nearai/ironclaw/pull/559)) +- *(llm)* fix reasoning model response parsing bugs ([#564](https://github.com/nearai/optimclaw/pull/564)) ([#580](https://github.com/nearai/optimclaw/pull/580)) +- *(ci)* fix three coverage workflow failures ([#597](https://github.com/nearai/optimclaw/pull/597)) +- Telegram channel accepts group messages from all users if owner_… ([#590](https://github.com/nearai/optimclaw/pull/590)) +- *(ci)* anchor coverage/ gitignore rule to repo root ([#591](https://github.com/nearai/optimclaw/pull/591)) +- *(security)* use OsRng for all security-critical key and token generation ([#519](https://github.com/nearai/optimclaw/pull/519)) +- prevent concurrent memory hygiene passes and Windows file lock errors ([#535](https://github.com/nearai/optimclaw/pull/535)) +- sort tool_definitions() for deterministic LLM tool ordering ([#582](https://github.com/nearai/optimclaw/pull/582)) +- *(ci)* persist all cargo-llvm-cov env vars for E2E coverage ([#559](https://github.com/nearai/optimclaw/pull/559)) ### Other -- *(llm)* complete response cache — set_model invalidation, stats logging, sync mutex ([#290](https://github.com/nearai/ironclaw/pull/290)) -- add 29 E2E trace tests for issues #571-575 ([#593](https://github.com/nearai/ironclaw/pull/593)) -- add 26 tests for multi-thread safety, db CRUD, concurrency, errors ([#442](https://github.com/nearai/ironclaw/pull/442)) -- update WASM artifact SHA256 checksums [skip ci] ([#560](https://github.com/nearai/ironclaw/pull/560)) -- add WIT compatibility tests for WASM extensions ([#586](https://github.com/nearai/ironclaw/pull/586)) -- Trajectory benchmarks and e2e trace test rig ([#553](https://github.com/nearai/ironclaw/pull/553)) +- *(llm)* complete response cache — set_model invalidation, stats logging, sync mutex ([#290](https://github.com/nearai/optimclaw/pull/290)) +- add 29 E2E trace tests for issues #571-575 ([#593](https://github.com/nearai/optimclaw/pull/593)) +- add 26 tests for multi-thread safety, db CRUD, concurrency, errors ([#442](https://github.com/nearai/optimclaw/pull/442)) +- update WASM artifact SHA256 checksums [skip ci] ([#560](https://github.com/nearai/optimclaw/pull/560)) +- add WIT compatibility tests for WASM extensions ([#586](https://github.com/nearai/optimclaw/pull/586)) +- Trajectory benchmarks and e2e trace test rig ([#553](https://github.com/nearai/optimclaw/pull/553)) -## [0.15.0](https://github.com/nearai/ironclaw/compare/v0.14.0...v0.15.0) - 2026-03-04 +## [0.15.0](https://github.com/nearai/optimclaw/compare/v0.14.0...v0.15.0) - 2026-03-04 ### Added -- *(oauth)* route callbacks through web gateway for hosted instances ([#555](https://github.com/nearai/ironclaw/pull/555)) -- *(web)* show error details for failed tool calls ([#490](https://github.com/nearai/ironclaw/pull/490)) -- *(extensions)* improve auth UX and add load-time validation ([#536](https://github.com/nearai/ironclaw/pull/536)) -- add local-test skill and Dockerfile.test for web gateway testing ([#524](https://github.com/nearai/ironclaw/pull/524)) +- *(oauth)* route callbacks through web gateway for hosted instances ([#555](https://github.com/nearai/optimclaw/pull/555)) +- *(web)* show error details for failed tool calls ([#490](https://github.com/nearai/optimclaw/pull/490)) +- *(extensions)* improve auth UX and add load-time validation ([#536](https://github.com/nearai/optimclaw/pull/536)) +- add local-test skill and Dockerfile.test for web gateway testing ([#524](https://github.com/nearai/optimclaw/pull/524)) ### Fixed -- *(security)* restrict query-token auth to SSE endpoints only ([#528](https://github.com/nearai/ironclaw/pull/528)) -- *(ci)* flush profraw coverage data in E2E teardown ([#550](https://github.com/nearai/ironclaw/pull/550)) -- *(wasm)* coerce string parameters to schema-declared types ([#498](https://github.com/nearai/ironclaw/pull/498)) -- *(agent)* strip leaked [Called tool ...] text from responses ([#497](https://github.com/nearai/ironclaw/pull/497)) -- *(web)* reset job list UI on restart failure ([#499](https://github.com/nearai/ironclaw/pull/499)) -- *(security)* replace .unwrap() panics in pairing store with proper error handling ([#515](https://github.com/nearai/ironclaw/pull/515)) +- *(security)* restrict query-token auth to SSE endpoints only ([#528](https://github.com/nearai/optimclaw/pull/528)) +- *(ci)* flush profraw coverage data in E2E teardown ([#550](https://github.com/nearai/optimclaw/pull/550)) +- *(wasm)* coerce string parameters to schema-declared types ([#498](https://github.com/nearai/optimclaw/pull/498)) +- *(agent)* strip leaked [Called tool ...] text from responses ([#497](https://github.com/nearai/optimclaw/pull/497)) +- *(web)* reset job list UI on restart failure ([#499](https://github.com/nearai/optimclaw/pull/499)) +- *(security)* replace .unwrap() panics in pairing store with proper error handling ([#515](https://github.com/nearai/optimclaw/pull/515)) ### Other -- Fix UTF-8 unsafe truncation in sandbox log capture ([#359](https://github.com/nearai/ironclaw/pull/359)) -- enhance coverage with feature matrix, postgres, and E2E ([#523](https://github.com/nearai/ironclaw/pull/523)) +- Fix UTF-8 unsafe truncation in sandbox log capture ([#359](https://github.com/nearai/optimclaw/pull/359)) +- enhance coverage with feature matrix, postgres, and E2E ([#523](https://github.com/nearai/optimclaw/pull/523)) -## [0.14.0](https://github.com/nearai/ironclaw/compare/v0.13.1...v0.14.0) - 2026-03-04 +## [0.14.0](https://github.com/nearai/optimclaw/compare/v0.13.1...v0.14.0) - 2026-03-04 ### Added -- remove the okta tool ([#506](https://github.com/nearai/ironclaw/pull/506)) -- add OAuth support for WASM tools in web gateway ([#489](https://github.com/nearai/ironclaw/pull/489)) -- *(web)* fix jobs UI parity for non-sandbox mode ([#491](https://github.com/nearai/ironclaw/pull/491)) -- *(workspace)* add TOOLS.md, BOOTSTRAP.md, and disk-to-DB import ([#477](https://github.com/nearai/ironclaw/pull/477)) +- remove the okta tool ([#506](https://github.com/nearai/optimclaw/pull/506)) +- add OAuth support for WASM tools in web gateway ([#489](https://github.com/nearai/optimclaw/pull/489)) +- *(web)* fix jobs UI parity for non-sandbox mode ([#491](https://github.com/nearai/optimclaw/pull/491)) +- *(workspace)* add TOOLS.md, BOOTSTRAP.md, and disk-to-DB import ([#477](https://github.com/nearai/optimclaw/pull/477)) ### Fixed -- *(web)* mobile browser bar obscures chat input ([#508](https://github.com/nearai/ironclaw/pull/508)) -- *(web)* assign unique thread_id to manual routine triggers ([#500](https://github.com/nearai/ironclaw/pull/500)) -- *(web)* refresh routine UI after Run Now trigger ([#501](https://github.com/nearai/ironclaw/pull/501)) -- *(skills)* use slug for skill download URL from ClawHub ([#502](https://github.com/nearai/ironclaw/pull/502)) -- *(workspace)* thread document path through search results ([#503](https://github.com/nearai/ironclaw/pull/503)) -- *(workspace)* import custom templates before seeding defaults ([#505](https://github.com/nearai/ironclaw/pull/505)) -- use std::sync::RwLock in MessageTool to avoid runtime panic ([#411](https://github.com/nearai/ironclaw/pull/411)) -- wire secrets store into all WASM runtime activation paths ([#479](https://github.com/nearai/ironclaw/pull/479)) +- *(web)* mobile browser bar obscures chat input ([#508](https://github.com/nearai/optimclaw/pull/508)) +- *(web)* assign unique thread_id to manual routine triggers ([#500](https://github.com/nearai/optimclaw/pull/500)) +- *(web)* refresh routine UI after Run Now trigger ([#501](https://github.com/nearai/optimclaw/pull/501)) +- *(skills)* use slug for skill download URL from ClawHub ([#502](https://github.com/nearai/optimclaw/pull/502)) +- *(workspace)* thread document path through search results ([#503](https://github.com/nearai/optimclaw/pull/503)) +- *(workspace)* import custom templates before seeding defaults ([#505](https://github.com/nearai/optimclaw/pull/505)) +- use std::sync::RwLock in MessageTool to avoid runtime panic ([#411](https://github.com/nearai/optimclaw/pull/411)) +- wire secrets store into all WASM runtime activation paths ([#479](https://github.com/nearai/optimclaw/pull/479)) ### Other -- enforce regression tests for fix commits ([#517](https://github.com/nearai/ironclaw/pull/517)) -- add code coverage with cargo-llvm-cov and Codecov ([#511](https://github.com/nearai/ironclaw/pull/511)) -- Remove restart infrastructure, generalize WASM channel setup ([#493](https://github.com/nearai/ironclaw/pull/493)) +- enforce regression tests for fix commits ([#517](https://github.com/nearai/optimclaw/pull/517)) +- add code coverage with cargo-llvm-cov and Codecov ([#511](https://github.com/nearai/optimclaw/pull/511)) +- Remove restart infrastructure, generalize WASM channel setup ([#493](https://github.com/nearai/optimclaw/pull/493)) -## [0.13.1](https://github.com/nearai/ironclaw/compare/v0.13.0...v0.13.1) - 2026-03-02 +## [0.13.1](https://github.com/nearai/optimclaw/compare/v0.13.0...v0.13.1) - 2026-03-02 ### Added -- add Brave Web Search WASM tool ([#474](https://github.com/nearai/ironclaw/pull/474)) +- add Brave Web Search WASM tool ([#474](https://github.com/nearai/optimclaw/pull/474)) ### Fixed -- *(web)* auto-scroll and Enter key completion for slash command autocomplete ([#475](https://github.com/nearai/ironclaw/pull/475)) -- correct download URLs for telegram-mtproto and slack-tool extensions ([#470](https://github.com/nearai/ironclaw/pull/470)) +- *(web)* auto-scroll and Enter key completion for slash command autocomplete ([#475](https://github.com/nearai/optimclaw/pull/475)) +- correct download URLs for telegram-mtproto and slack-tool extensions ([#470](https://github.com/nearai/optimclaw/pull/470)) -## [0.13.0](https://github.com/nearai/ironclaw/compare/v0.12.0...v0.13.0) - 2026-03-02 +## [0.13.0](https://github.com/nearai/optimclaw/compare/v0.12.0...v0.13.0) - 2026-03-02 ### Added -- *(cli)* add tool setup command + GitHub setup schema ([#438](https://github.com/nearai/ironclaw/pull/438)) -- add web_fetch built-in tool ([#435](https://github.com/nearai/ironclaw/pull/435)) -- *(web)* DB-backed Jobs tab + scheduler-dispatched local jobs ([#436](https://github.com/nearai/ironclaw/pull/436)) -- *(extensions)* add OAuth setup UI for WASM tools + display name labels ([#437](https://github.com/nearai/ironclaw/pull/437)) -- *(bootstrap)* auto-detect libsql when ironclaw.db exists ([#399](https://github.com/nearai/ironclaw/pull/399)) -- *(web)* slash command autocomplete + /status /list + fix chat input locking ([#404](https://github.com/nearai/ironclaw/pull/404)) -- *(routines)* deliver notifications to all installed channels ([#398](https://github.com/nearai/ironclaw/pull/398)) -- *(web)* persist tool calls, restore approvals on thread switch, and UI fixes ([#382](https://github.com/nearai/ironclaw/pull/382)) -- add IRONCLAW_BASE_DIR env var with LazyLock caching ([#397](https://github.com/nearai/ironclaw/pull/397)) -- feat(signal) attachment upload + message tool ([#375](https://github.com/nearai/ironclaw/pull/375)) +- *(cli)* add tool setup command + GitHub setup schema ([#438](https://github.com/nearai/optimclaw/pull/438)) +- add web_fetch built-in tool ([#435](https://github.com/nearai/optimclaw/pull/435)) +- *(web)* DB-backed Jobs tab + scheduler-dispatched local jobs ([#436](https://github.com/nearai/optimclaw/pull/436)) +- *(extensions)* add OAuth setup UI for WASM tools + display name labels ([#437](https://github.com/nearai/optimclaw/pull/437)) +- *(bootstrap)* auto-detect libsql when optimclaw.db exists ([#399](https://github.com/nearai/optimclaw/pull/399)) +- *(web)* slash command autocomplete + /status /list + fix chat input locking ([#404](https://github.com/nearai/optimclaw/pull/404)) +- *(routines)* deliver notifications to all installed channels ([#398](https://github.com/nearai/optimclaw/pull/398)) +- *(web)* persist tool calls, restore approvals on thread switch, and UI fixes ([#382](https://github.com/nearai/optimclaw/pull/382)) +- add OPTIMCLAW_BASE_DIR env var with LazyLock caching ([#397](https://github.com/nearai/optimclaw/pull/397)) +- feat(signal) attachment upload + message tool ([#375](https://github.com/nearai/optimclaw/pull/375)) ### Fixed -- *(channels)* add host-based credential injection to WASM channel wrapper ([#421](https://github.com/nearai/ironclaw/pull/421)) -- pre-validate Cloudflare tunnel token by spawning cloudflared ([#446](https://github.com/nearai/ironclaw/pull/446)) -- batch of quick fixes (#417, #338, #330, #358, #419, #344) ([#428](https://github.com/nearai/ironclaw/pull/428)) -- persist channel activation state across restarts ([#432](https://github.com/nearai/ironclaw/pull/432)) -- init WASM runtime eagerly regardless of tools directory existence ([#401](https://github.com/nearai/ironclaw/pull/401)) -- add TLS support for PostgreSQL connections ([#363](https://github.com/nearai/ironclaw/pull/363)) ([#427](https://github.com/nearai/ironclaw/pull/427)) -- scan inbound messages for leaked secrets ([#433](https://github.com/nearai/ironclaw/pull/433)) -- use tailscale funnel --bg for proper tunnel setup ([#430](https://github.com/nearai/ironclaw/pull/430)) -- normalize secret names to lowercase for case-insensitive matching ([#413](https://github.com/nearai/ironclaw/pull/413)) ([#431](https://github.com/nearai/ironclaw/pull/431)) -- persist model name to .env so dotted names survive restart ([#426](https://github.com/nearai/ironclaw/pull/426)) -- *(setup)* check cloudflared binary and validate tunnel token ([#424](https://github.com/nearai/ironclaw/pull/424)) -- *(setup)* validate PostgreSQL version and pgvector availability before migrations ([#423](https://github.com/nearai/ironclaw/pull/423)) -- guard zsh compdef call to prevent error before compinit ([#422](https://github.com/nearai/ironclaw/pull/422)) -- *(telegram)* remove restart button, validate token on setup ([#434](https://github.com/nearai/ironclaw/pull/434)) -- web UI routines tab shows all routines regardless of creating channel ([#391](https://github.com/nearai/ironclaw/pull/391)) -- Discord Ed25519 signature verification and capabilities header alias ([#148](https://github.com/nearai/ironclaw/pull/148)) ([#372](https://github.com/nearai/ironclaw/pull/372)) -- prevent duplicate WASM channel activation on startup ([#390](https://github.com/nearai/ironclaw/pull/390)) +- *(channels)* add host-based credential injection to WASM channel wrapper ([#421](https://github.com/nearai/optimclaw/pull/421)) +- pre-validate Cloudflare tunnel token by spawning cloudflared ([#446](https://github.com/nearai/optimclaw/pull/446)) +- batch of quick fixes (#417, #338, #330, #358, #419, #344) ([#428](https://github.com/nearai/optimclaw/pull/428)) +- persist channel activation state across restarts ([#432](https://github.com/nearai/optimclaw/pull/432)) +- init WASM runtime eagerly regardless of tools directory existence ([#401](https://github.com/nearai/optimclaw/pull/401)) +- add TLS support for PostgreSQL connections ([#363](https://github.com/nearai/optimclaw/pull/363)) ([#427](https://github.com/nearai/optimclaw/pull/427)) +- scan inbound messages for leaked secrets ([#433](https://github.com/nearai/optimclaw/pull/433)) +- use tailscale funnel --bg for proper tunnel setup ([#430](https://github.com/nearai/optimclaw/pull/430)) +- normalize secret names to lowercase for case-insensitive matching ([#413](https://github.com/nearai/optimclaw/pull/413)) ([#431](https://github.com/nearai/optimclaw/pull/431)) +- persist model name to .env so dotted names survive restart ([#426](https://github.com/nearai/optimclaw/pull/426)) +- *(setup)* check cloudflared binary and validate tunnel token ([#424](https://github.com/nearai/optimclaw/pull/424)) +- *(setup)* validate PostgreSQL version and pgvector availability before migrations ([#423](https://github.com/nearai/optimclaw/pull/423)) +- guard zsh compdef call to prevent error before compinit ([#422](https://github.com/nearai/optimclaw/pull/422)) +- *(telegram)* remove restart button, validate token on setup ([#434](https://github.com/nearai/optimclaw/pull/434)) +- web UI routines tab shows all routines regardless of creating channel ([#391](https://github.com/nearai/optimclaw/pull/391)) +- Discord Ed25519 signature verification and capabilities header alias ([#148](https://github.com/nearai/optimclaw/pull/148)) ([#372](https://github.com/nearai/optimclaw/pull/372)) +- prevent duplicate WASM channel activation on startup ([#390](https://github.com/nearai/optimclaw/pull/390)) ### Other -- rename WasmBuildable::repo_url to source_dir ([#445](https://github.com/nearai/ironclaw/pull/445)) -- Improve --help: add detailed about/examples/color, snapshot test (clo… ([#371](https://github.com/nearai/ironclaw/pull/371)) -- Add automated QA: schema validator, CI matrix, Docker build, and P1 test coverage ([#353](https://github.com/nearai/ironclaw/pull/353)) +- rename WasmBuildable::repo_url to source_dir ([#445](https://github.com/nearai/optimclaw/pull/445)) +- Improve --help: add detailed about/examples/color, snapshot test (clo… ([#371](https://github.com/nearai/optimclaw/pull/371)) +- Add automated QA: schema validator, CI matrix, Docker build, and P1 test coverage ([#353](https://github.com/nearai/optimclaw/pull/353)) -## [0.12.0](https://github.com/nearai/ironclaw/compare/v0.11.1...v0.12.0) - 2026-02-26 +## [0.12.0](https://github.com/nearai/optimclaw/compare/v0.11.1...v0.12.0) - 2026-02-26 ### Added -- *(web)* improve WASM channel setup flow ([#380](https://github.com/nearai/ironclaw/pull/380)) -- *(web)* inline tool activity cards with auto-collapsing ([#376](https://github.com/nearai/ironclaw/pull/376)) -- *(web)* display logs newest-first in web gateway UI ([#369](https://github.com/nearai/ironclaw/pull/369)) -- *(signal)* tool approval workflow and status updates ([#350](https://github.com/nearai/ironclaw/pull/350)) -- add OpenRouter preset to setup wizard ([#270](https://github.com/nearai/ironclaw/pull/270)) -- *(channels)* add native Signal channel via signal-cli HTTP daemon ([#271](https://github.com/nearai/ironclaw/pull/271)) +- *(web)* improve WASM channel setup flow ([#380](https://github.com/nearai/optimclaw/pull/380)) +- *(web)* inline tool activity cards with auto-collapsing ([#376](https://github.com/nearai/optimclaw/pull/376)) +- *(web)* display logs newest-first in web gateway UI ([#369](https://github.com/nearai/optimclaw/pull/369)) +- *(signal)* tool approval workflow and status updates ([#350](https://github.com/nearai/optimclaw/pull/350)) +- add OpenRouter preset to setup wizard ([#270](https://github.com/nearai/optimclaw/pull/270)) +- *(channels)* add native Signal channel via signal-cli HTTP daemon ([#271](https://github.com/nearai/optimclaw/pull/271)) ### Fixed -- correct MCP registry URLs and remove non-existent Google endpoints ([#370](https://github.com/nearai/ironclaw/pull/370)) -- resolve_thread adopts existing session threads by UUID ([#377](https://github.com/nearai/ironclaw/pull/377)) -- resolve telegram/slack name collision between tool and channel registries ([#346](https://github.com/nearai/ironclaw/pull/346)) -- make onboarding installs prefer release artifacts with source fallback ([#323](https://github.com/nearai/ironclaw/pull/323)) -- copy missing files in Dockerfile to fix build ([#322](https://github.com/nearai/ironclaw/pull/322)) -- fall back to build-from-source when extension download fails ([#312](https://github.com/nearai/ironclaw/pull/312)) +- correct MCP registry URLs and remove non-existent Google endpoints ([#370](https://github.com/nearai/optimclaw/pull/370)) +- resolve_thread adopts existing session threads by UUID ([#377](https://github.com/nearai/optimclaw/pull/377)) +- resolve telegram/slack name collision between tool and channel registries ([#346](https://github.com/nearai/optimclaw/pull/346)) +- make onboarding installs prefer release artifacts with source fallback ([#323](https://github.com/nearai/optimclaw/pull/323)) +- copy missing files in Dockerfile to fix build ([#322](https://github.com/nearai/optimclaw/pull/322)) +- fall back to build-from-source when extension download fails ([#312](https://github.com/nearai/optimclaw/pull/312)) ### Other -- Add --version flag with clap built-in support and test ([#342](https://github.com/nearai/ironclaw/pull/342)) -- Update FEATURE_PARITY.md ([#337](https://github.com/nearai/ironclaw/pull/337)) -- add brew install ironclaw instructions ([#310](https://github.com/nearai/ironclaw/pull/310)) -- Fix skills system: enable by default, fix registry and install ([#300](https://github.com/nearai/ironclaw/pull/300)) +- Add --version flag with clap built-in support and test ([#342](https://github.com/nearai/optimclaw/pull/342)) +- Update FEATURE_PARITY.md ([#337](https://github.com/nearai/optimclaw/pull/337)) +- add brew install optimclaw instructions ([#310](https://github.com/nearai/optimclaw/pull/310)) +- Fix skills system: enable by default, fix registry and install ([#300](https://github.com/nearai/optimclaw/pull/300)) -## [0.11.1](https://github.com/nearai/ironclaw/compare/v0.11.0...v0.11.1) - 2026-02-23 +## [0.11.1](https://github.com/nearai/optimclaw/compare/v0.11.0...v0.11.1) - 2026-02-23 ### Other - Ignore out-of-date generated CI so custom release.yml jobs are allowed -## [0.11.0](https://github.com/nearai/ironclaw/compare/v0.10.0...v0.11.0) - 2026-02-23 +## [0.11.0](https://github.com/nearai/optimclaw/compare/v0.10.0...v0.11.0) - 2026-02-23 ### Fixed -- auto-compact and retry on ContextLengthExceeded ([#315](https://github.com/nearai/ironclaw/pull/315)) +- auto-compact and retry on ContextLengthExceeded ([#315](https://github.com/nearai/optimclaw/pull/315)) ### Other -- *(README)* Adding badges to readme ([#316](https://github.com/nearai/ironclaw/pull/316)) -- Feat/completion ([#240](https://github.com/nearai/ironclaw/pull/240)) +- *(README)* Adding badges to readme ([#316](https://github.com/nearai/optimclaw/pull/316)) +- Feat/completion ([#240](https://github.com/nearai/optimclaw/pull/240)) -## [0.10.0](https://github.com/nearai/ironclaw/compare/v0.9.0...v0.10.0) - 2026-02-22 +## [0.10.0](https://github.com/nearai/optimclaw/compare/v0.9.0...v0.10.0) - 2026-02-22 ### Added -- update dashboard favicon ([#309](https://github.com/nearai/ironclaw/pull/309)) -- add web UI test skill for Chrome extension ([#302](https://github.com/nearai/ironclaw/pull/302)) -- implement FullJob routine mode with scheduler dispatch ([#288](https://github.com/nearai/ironclaw/pull/288)) -- hot-activate WASM channels, channel-first prompts, unified artifact resolution ([#297](https://github.com/nearai/ironclaw/pull/297)) -- add pairing/permission system to all WASM channels and fix extension registry ([#286](https://github.com/nearai/ironclaw/pull/286)) -- group chat privacy, channel-aware prompts, and safety hardening ([#285](https://github.com/nearai/ironclaw/pull/285)) -- embedded registry catalog and WASM bundle install pipeline ([#283](https://github.com/nearai/ironclaw/pull/283)) -- show token usage and cost tracker in gateway status popover ([#284](https://github.com/nearai/ironclaw/pull/284)) -- support custom HTTP headers for OpenAI-compatible provider ([#269](https://github.com/nearai/ironclaw/pull/269)) -- add smart routing provider for cost-optimized model selection ([#281](https://github.com/nearai/ironclaw/pull/281)) +- update dashboard favicon ([#309](https://github.com/nearai/optimclaw/pull/309)) +- add web UI test skill for Chrome extension ([#302](https://github.com/nearai/optimclaw/pull/302)) +- implement FullJob routine mode with scheduler dispatch ([#288](https://github.com/nearai/optimclaw/pull/288)) +- hot-activate WASM channels, channel-first prompts, unified artifact resolution ([#297](https://github.com/nearai/optimclaw/pull/297)) +- add pairing/permission system to all WASM channels and fix extension registry ([#286](https://github.com/nearai/optimclaw/pull/286)) +- group chat privacy, channel-aware prompts, and safety hardening ([#285](https://github.com/nearai/optimclaw/pull/285)) +- embedded registry catalog and WASM bundle install pipeline ([#283](https://github.com/nearai/optimclaw/pull/283)) +- show token usage and cost tracker in gateway status popover ([#284](https://github.com/nearai/optimclaw/pull/284)) +- support custom HTTP headers for OpenAI-compatible provider ([#269](https://github.com/nearai/optimclaw/pull/269)) +- add smart routing provider for cost-optimized model selection ([#281](https://github.com/nearai/optimclaw/pull/281)) ### Fixed -- persist user message at turn start before agentic loop ([#305](https://github.com/nearai/ironclaw/pull/305)) -- block send until thread is selected ([#306](https://github.com/nearai/ironclaw/pull/306)) -- reload chat history on SSE reconnect ([#307](https://github.com/nearai/ironclaw/pull/307)) -- map Esc to interrupt and Ctrl+C to graceful quit ([#267](https://github.com/nearai/ironclaw/pull/267)) +- persist user message at turn start before agentic loop ([#305](https://github.com/nearai/optimclaw/pull/305)) +- block send until thread is selected ([#306](https://github.com/nearai/optimclaw/pull/306)) +- reload chat history on SSE reconnect ([#307](https://github.com/nearai/optimclaw/pull/307)) +- map Esc to interrupt and Ctrl+C to graceful quit ([#267](https://github.com/nearai/optimclaw/pull/267)) ### Other -- Fix tool schema OpenAI compatibility ([#301](https://github.com/nearai/ironclaw/pull/301)) -- simplify config resolution and consolidate main.rs init ([#287](https://github.com/nearai/ironclaw/pull/287)) +- Fix tool schema OpenAI compatibility ([#301](https://github.com/nearai/optimclaw/pull/301)) +- simplify config resolution and consolidate main.rs init ([#287](https://github.com/nearai/optimclaw/pull/287)) - Update image source in README.md - Add files via upload -- remove ExtensionSource::Bundled, use download-only install for WASM channels ([#293](https://github.com/nearai/ironclaw/pull/293)) -- allow OAuth callback to work on remote servers (fixes #186) ([#212](https://github.com/nearai/ironclaw/pull/212)) -- add rate limiting for built-in tools (closes #171) ([#276](https://github.com/nearai/ironclaw/pull/276)) -- add LLM providers guide (OpenRouter, Together AI, Fireworks, Ollama, vLLM) ([#193](https://github.com/nearai/ironclaw/pull/193)) -- Feat/html to markdown #106 ([#115](https://github.com/nearai/ironclaw/pull/115)) -- adopt agent-market design language for web UI ([#282](https://github.com/nearai/ironclaw/pull/282)) -- speed up startup from ~15s to ~2s ([#280](https://github.com/nearai/ironclaw/pull/280)) -- consolidate tool approval into single param-aware method ([#274](https://github.com/nearai/ironclaw/pull/274)) +- remove ExtensionSource::Bundled, use download-only install for WASM channels ([#293](https://github.com/nearai/optimclaw/pull/293)) +- allow OAuth callback to work on remote servers (fixes #186) ([#212](https://github.com/nearai/optimclaw/pull/212)) +- add rate limiting for built-in tools (closes #171) ([#276](https://github.com/nearai/optimclaw/pull/276)) +- add LLM providers guide (OpenRouter, Together AI, Fireworks, Ollama, vLLM) ([#193](https://github.com/nearai/optimclaw/pull/193)) +- Feat/html to markdown #106 ([#115](https://github.com/nearai/optimclaw/pull/115)) +- adopt agent-market design language for web UI ([#282](https://github.com/nearai/optimclaw/pull/282)) +- speed up startup from ~15s to ~2s ([#280](https://github.com/nearai/optimclaw/pull/280)) +- consolidate tool approval into single param-aware method ([#274](https://github.com/nearai/optimclaw/pull/274)) -## [0.9.0](https://github.com/nearai/ironclaw/compare/v0.8.0...v0.9.0) - 2026-02-21 +## [0.9.0](https://github.com/nearai/optimclaw/compare/v0.8.0...v0.9.0) - 2026-02-21 ### Added -- add TEE attestation shield to web gateway UI ([#275](https://github.com/nearai/ironclaw/pull/275)) -- configurable tool iterations, auto-approve, and policy fix ([#251](https://github.com/nearai/ironclaw/pull/251)) +- add TEE attestation shield to web gateway UI ([#275](https://github.com/nearai/optimclaw/pull/275)) +- configurable tool iterations, auto-approve, and policy fix ([#251](https://github.com/nearai/optimclaw/pull/251)) ### Fixed -- add X-Accel-Buffering header to SSE endpoints ([#277](https://github.com/nearai/ironclaw/pull/277)) +- add X-Accel-Buffering header to SSE endpoints ([#277](https://github.com/nearai/optimclaw/pull/277)) -## [0.8.0](https://github.com/nearai/ironclaw/compare/ironclaw-v0.7.0...ironclaw-v0.8.0) - 2026-02-20 +## [0.8.0](https://github.com/nearai/optimclaw/compare/optimclaw-v0.7.0...optimclaw-v0.8.0) - 2026-02-20 ### Added -- extension registry with metadata catalog and onboarding integration ([#238](https://github.com/nearai/ironclaw/pull/238)) -- *(models)* add GPT-5.3 Codex, full GPT-5.x family, Claude 4.x series, o4-mini ([#197](https://github.com/nearai/ironclaw/pull/197)) -- wire memory hygiene into the heartbeat loop ([#195](https://github.com/nearai/ironclaw/pull/195)) +- extension registry with metadata catalog and onboarding integration ([#238](https://github.com/nearai/optimclaw/pull/238)) +- *(models)* add GPT-5.3 Codex, full GPT-5.x family, Claude 4.x series, o4-mini ([#197](https://github.com/nearai/optimclaw/pull/197)) +- wire memory hygiene into the heartbeat loop ([#195](https://github.com/nearai/optimclaw/pull/195)) ### Fixed -- persist WASM channel workspace writes across callbacks ([#264](https://github.com/nearai/ironclaw/pull/264)) -- consolidate per-module ENV_MUTEX into crate-wide test lock ([#246](https://github.com/nearai/ironclaw/pull/246)) -- remove auto-proceed fake user message injection from agent loop ([#255](https://github.com/nearai/ironclaw/pull/255)) -- onboarding errors reset flow and remote server auth (#185, #186) ([#248](https://github.com/nearai/ironclaw/pull/248)) -- parallelize tool call execution via JoinSet ([#219](https://github.com/nearai/ironclaw/pull/219)) ([#252](https://github.com/nearai/ironclaw/pull/252)) -- prevent pipe deadlock in shell command execution ([#140](https://github.com/nearai/ironclaw/pull/140)) -- persist turns after approval and add agent-level tests ([#250](https://github.com/nearai/ironclaw/pull/250)) +- persist WASM channel workspace writes across callbacks ([#264](https://github.com/nearai/optimclaw/pull/264)) +- consolidate per-module ENV_MUTEX into crate-wide test lock ([#246](https://github.com/nearai/optimclaw/pull/246)) +- remove auto-proceed fake user message injection from agent loop ([#255](https://github.com/nearai/optimclaw/pull/255)) +- onboarding errors reset flow and remote server auth (#185, #186) ([#248](https://github.com/nearai/optimclaw/pull/248)) +- parallelize tool call execution via JoinSet ([#219](https://github.com/nearai/optimclaw/pull/219)) ([#252](https://github.com/nearai/optimclaw/pull/252)) +- prevent pipe deadlock in shell command execution ([#140](https://github.com/nearai/optimclaw/pull/140)) +- persist turns after approval and add agent-level tests ([#250](https://github.com/nearai/optimclaw/pull/250)) ### Other -- add automated PR labeling system ([#253](https://github.com/nearai/ironclaw/pull/253)) -- update CLAUDE.md for recently merged features ([#183](https://github.com/nearai/ironclaw/pull/183)) +- add automated PR labeling system ([#253](https://github.com/nearai/optimclaw/pull/253)) +- update CLAUDE.md for recently merged features ([#183](https://github.com/nearai/optimclaw/pull/183)) -## [0.7.0](https://github.com/nearai/ironclaw/compare/ironclaw-v0.6.0...ironclaw-v0.7.0) - 2026-02-19 +## [0.7.0](https://github.com/nearai/optimclaw/compare/optimclaw-v0.6.0...optimclaw-v0.7.0) - 2026-02-19 ### Added -- extend lifecycle hooks with declarative bundles ([#176](https://github.com/nearai/ironclaw/pull/176)) -- support per-request model override in /v1/chat/completions ([#103](https://github.com/nearai/ironclaw/pull/103)) +- extend lifecycle hooks with declarative bundles ([#176](https://github.com/nearai/optimclaw/pull/176)) +- support per-request model override in /v1/chat/completions ([#103](https://github.com/nearai/optimclaw/pull/103)) ### Fixed -- harden openai-compatible provider, approval replay, and embeddings defaults ([#237](https://github.com/nearai/ironclaw/pull/237)) -- Network Security Findings ([#201](https://github.com/nearai/ironclaw/pull/201)) +- harden openai-compatible provider, approval replay, and embeddings defaults ([#237](https://github.com/nearai/optimclaw/pull/237)) +- Network Security Findings ([#201](https://github.com/nearai/optimclaw/pull/201)) ### Added @@ -647,7 +647,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Changed default sandbox image to `ironclaw-worker:latest` in config/settings/sandbox defaults. +- Changed default sandbox image to `optimclaw-worker:latest` in config/settings/sandbox defaults. - Improved tool-message sanitization and provider compatibility handling across NEAR AI, rig adapter, and shared LLM provider code. ### Fixed @@ -656,80 +656,80 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed multi-tool approval resume flow by preserving and replaying deferred tool calls so all prior `tool_use` IDs receive matching `tool_result` messages. - Fixed REPL quit/exit handling to route shutdown through the agent loop for graceful termination. -## [0.6.0](https://github.com/nearai/ironclaw/compare/ironclaw-v0.5.0...ironclaw-v0.6.0) - 2026-02-19 +## [0.6.0](https://github.com/nearai/optimclaw/compare/optimclaw-v0.5.0...optimclaw-v0.6.0) - 2026-02-19 ### Added -- add issue triage skill ([#200](https://github.com/nearai/ironclaw/pull/200)) -- add PR triage dashboard skill ([#196](https://github.com/nearai/ironclaw/pull/196)) -- add OpenRouter usage examples ([#189](https://github.com/nearai/ironclaw/pull/189)) -- add Tinfoil private inference provider ([#62](https://github.com/nearai/ironclaw/pull/62)) -- shell env scrubbing and command injection detection ([#164](https://github.com/nearai/ironclaw/pull/164)) -- Add PR review tools, job monitor, and channel injection for E2E sandbox workflows ([#57](https://github.com/nearai/ironclaw/pull/57)) -- Secure prompt-based skills system (Phases 1-4) ([#51](https://github.com/nearai/ironclaw/pull/51)) -- Add benchmarking harness with spot suite ([#10](https://github.com/nearai/ironclaw/pull/10)) -- 10 infrastructure improvements from zeroclaw ([#126](https://github.com/nearai/ironclaw/pull/126)) +- add issue triage skill ([#200](https://github.com/nearai/optimclaw/pull/200)) +- add PR triage dashboard skill ([#196](https://github.com/nearai/optimclaw/pull/196)) +- add OpenRouter usage examples ([#189](https://github.com/nearai/optimclaw/pull/189)) +- add Tinfoil private inference provider ([#62](https://github.com/nearai/optimclaw/pull/62)) +- shell env scrubbing and command injection detection ([#164](https://github.com/nearai/optimclaw/pull/164)) +- Add PR review tools, job monitor, and channel injection for E2E sandbox workflows ([#57](https://github.com/nearai/optimclaw/pull/57)) +- Secure prompt-based skills system (Phases 1-4) ([#51](https://github.com/nearai/optimclaw/pull/51)) +- Add benchmarking harness with spot suite ([#10](https://github.com/nearai/optimclaw/pull/10)) +- 10 infrastructure improvements from zeroclaw ([#126](https://github.com/nearai/optimclaw/pull/126)) ### Fixed -- *(rig)* prevent OpenAI Responses API panic on tool call IDs ([#182](https://github.com/nearai/ironclaw/pull/182)) -- *(docs)* correct settings storage path in README ([#194](https://github.com/nearai/ironclaw/pull/194)) -- OpenAI tool calling — schema normalization, missing types, and Responses API panic ([#132](https://github.com/nearai/ironclaw/pull/132)) -- *(security)* prevent path traversal bypass in WASM HTTP allowlist ([#137](https://github.com/nearai/ironclaw/pull/137)) -- persist OpenAI-compatible provider and respect embeddings disable ([#177](https://github.com/nearai/ironclaw/pull/177)) -- remove .expect() calls in FailoverProvider::try_providers ([#156](https://github.com/nearai/ironclaw/pull/156)) -- sentinel value collision in FailoverProvider cooldown ([#125](https://github.com/nearai/ironclaw/pull/125)) ([#154](https://github.com/nearai/ironclaw/pull/154)) -- skills module audit cleanup ([#173](https://github.com/nearai/ironclaw/pull/173)) +- *(rig)* prevent OpenAI Responses API panic on tool call IDs ([#182](https://github.com/nearai/optimclaw/pull/182)) +- *(docs)* correct settings storage path in README ([#194](https://github.com/nearai/optimclaw/pull/194)) +- OpenAI tool calling — schema normalization, missing types, and Responses API panic ([#132](https://github.com/nearai/optimclaw/pull/132)) +- *(security)* prevent path traversal bypass in WASM HTTP allowlist ([#137](https://github.com/nearai/optimclaw/pull/137)) +- persist OpenAI-compatible provider and respect embeddings disable ([#177](https://github.com/nearai/optimclaw/pull/177)) +- remove .expect() calls in FailoverProvider::try_providers ([#156](https://github.com/nearai/optimclaw/pull/156)) +- sentinel value collision in FailoverProvider cooldown ([#125](https://github.com/nearai/optimclaw/pull/125)) ([#154](https://github.com/nearai/optimclaw/pull/154)) +- skills module audit cleanup ([#173](https://github.com/nearai/optimclaw/pull/173)) ### Other -- Fix division by zero panic in ValueEstimator::is_profitable ([#139](https://github.com/nearai/ironclaw/pull/139)) -- audit feature parity matrix against codebase and recent commits ([#202](https://github.com/nearai/ironclaw/pull/202)) -- architecture improvements for contributor velocity ([#198](https://github.com/nearai/ironclaw/pull/198)) +- Fix division by zero panic in ValueEstimator::is_profitable ([#139](https://github.com/nearai/optimclaw/pull/139)) +- audit feature parity matrix against codebase and recent commits ([#202](https://github.com/nearai/optimclaw/pull/202)) +- architecture improvements for contributor velocity ([#198](https://github.com/nearai/optimclaw/pull/198)) - fix rustfmt formatting from PR #137 -- add .env.example examples for Ollama and OpenAI-compatible ([#110](https://github.com/nearai/ironclaw/pull/110)) +- add .env.example examples for Ollama and OpenAI-compatible ([#110](https://github.com/nearai/optimclaw/pull/110)) -## [0.5.0](https://github.com/nearai/ironclaw/compare/v0.4.0...v0.5.0) - 2026-02-17 +## [0.5.0](https://github.com/nearai/optimclaw/compare/v0.4.0...v0.5.0) - 2026-02-17 ### Added -- add cooldown management to FailoverProvider ([#114](https://github.com/nearai/ironclaw/pull/114)) +- add cooldown management to FailoverProvider ([#114](https://github.com/nearai/optimclaw/pull/114)) -## [0.4.0](https://github.com/nearai/ironclaw/compare/v0.3.0...v0.4.0) - 2026-02-17 +## [0.4.0](https://github.com/nearai/optimclaw/compare/v0.3.0...v0.4.0) - 2026-02-17 ### Added -- move per-invocation approval check into Tool trait ([#119](https://github.com/nearai/ironclaw/pull/119)) -- add polished boot screen on CLI startup ([#118](https://github.com/nearai/ironclaw/pull/118)) -- Add lifecycle hooks system with 6 interception points ([#18](https://github.com/nearai/ironclaw/pull/18)) +- move per-invocation approval check into Tool trait ([#119](https://github.com/nearai/optimclaw/pull/119)) +- add polished boot screen on CLI startup ([#118](https://github.com/nearai/optimclaw/pull/118)) +- Add lifecycle hooks system with 6 interception points ([#18](https://github.com/nearai/optimclaw/pull/18)) ### Other -- remove accidentally committed .sidecar and .todos directories ([#123](https://github.com/nearai/ironclaw/pull/123)) +- remove accidentally committed .sidecar and .todos directories ([#123](https://github.com/nearai/optimclaw/pull/123)) -## [0.3.0](https://github.com/nearai/ironclaw/compare/v0.2.0...v0.3.0) - 2026-02-17 +## [0.3.0](https://github.com/nearai/optimclaw/compare/v0.2.0...v0.3.0) - 2026-02-17 ### Added -- direct api key and cheap model ([#116](https://github.com/nearai/ironclaw/pull/116)) +- direct api key and cheap model ([#116](https://github.com/nearai/optimclaw/pull/116)) -## [0.2.0](https://github.com/nearai/ironclaw/compare/v0.1.3...v0.2.0) - 2026-02-16 +## [0.2.0](https://github.com/nearai/optimclaw/compare/v0.1.3...v0.2.0) - 2026-02-16 ### Added -- mark Ollama + OpenAI-compatible as implemented ([#102](https://github.com/nearai/ironclaw/pull/102)) -- multi-provider inference + libSQL onboarding selection ([#92](https://github.com/nearai/ironclaw/pull/92)) -- add multi-provider LLM failover with retry backoff ([#28](https://github.com/nearai/ironclaw/pull/28)) -- add libSQL/Turso embedded database backend ([#47](https://github.com/nearai/ironclaw/pull/47)) -- Move debug log truncation from agent loop to REPL channel ([#65](https://github.com/nearai/ironclaw/pull/65)) +- mark Ollama + OpenAI-compatible as implemented ([#102](https://github.com/nearai/optimclaw/pull/102)) +- multi-provider inference + libSQL onboarding selection ([#92](https://github.com/nearai/optimclaw/pull/92)) +- add multi-provider LLM failover with retry backoff ([#28](https://github.com/nearai/optimclaw/pull/28)) +- add libSQL/Turso embedded database backend ([#47](https://github.com/nearai/optimclaw/pull/47)) +- Move debug log truncation from agent loop to REPL channel ([#65](https://github.com/nearai/optimclaw/pull/65)) ### Fixed -- shell destructive-command check bypassed by Value::Object arguments ([#72](https://github.com/nearai/ironclaw/pull/72)) -- propagate real tool_call_id instead of hardcoded placeholder ([#73](https://github.com/nearai/ironclaw/pull/73)) -- Fix wasm tool schemas and runtime ([#42](https://github.com/nearai/ironclaw/pull/42)) -- flatten tool messages for NEAR AI cloud-api compatibility ([#41](https://github.com/nearai/ironclaw/pull/41)) -- security hardening across all layers ([#35](https://github.com/nearai/ironclaw/pull/35)) +- shell destructive-command check bypassed by Value::Object arguments ([#72](https://github.com/nearai/optimclaw/pull/72)) +- propagate real tool_call_id instead of hardcoded placeholder ([#73](https://github.com/nearai/optimclaw/pull/73)) +- Fix wasm tool schemas and runtime ([#42](https://github.com/nearai/optimclaw/pull/42)) +- flatten tool messages for NEAR AI cloud-api compatibility ([#41](https://github.com/nearai/optimclaw/pull/41)) +- security hardening across all layers ([#35](https://github.com/nearai/optimclaw/pull/35)) ### Other @@ -737,57 +737,57 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Skip building binary artifacts on every PR - add module specification rules to CLAUDE.md - add setup/onboarding specification (src/setup/README.md) -- deduplicate tool code and remove dead stubs ([#98](https://github.com/nearai/ironclaw/pull/98)) -- Reformat architecture diagram in README ([#64](https://github.com/nearai/ironclaw/pull/64)) -- Add review discipline guidelines to CLAUDE.md ([#68](https://github.com/nearai/ironclaw/pull/68)) -- Bump MSRV to 1.92, add GCP deployment files ([#40](https://github.com/nearai/ironclaw/pull/40)) -- Add OpenAI-compatible HTTP API (/v1/chat/completions, /v1/models) ([#31](https://github.com/nearai/ironclaw/pull/31)) +- deduplicate tool code and remove dead stubs ([#98](https://github.com/nearai/optimclaw/pull/98)) +- Reformat architecture diagram in README ([#64](https://github.com/nearai/optimclaw/pull/64)) +- Add review discipline guidelines to CLAUDE.md ([#68](https://github.com/nearai/optimclaw/pull/68)) +- Bump MSRV to 1.92, add GCP deployment files ([#40](https://github.com/nearai/optimclaw/pull/40)) +- Add OpenAI-compatible HTTP API (/v1/chat/completions, /v1/models) ([#31](https://github.com/nearai/optimclaw/pull/31)) -## [0.1.3](https://github.com/nearai/ironclaw/compare/v0.1.2...v0.1.3) - 2026-02-12 +## [0.1.3](https://github.com/nearai/optimclaw/compare/v0.1.2...v0.1.3) - 2026-02-12 ### Other - Enabled builds caching during CI/CD - Disabled npm publishing as the name is already taken -## [0.1.2](https://github.com/nearai/ironclaw/compare/v0.1.1...v0.1.2) - 2026-02-12 +## [0.1.2](https://github.com/nearai/optimclaw/compare/v0.1.1...v0.1.2) - 2026-02-12 ### Other - Added Installation instructions for the pre-built binaries - Disabled Windows ARM64 builds as auto-updater [provided by cargo-dist] does not support this platform yet and it is not a common platform for us to support -## [0.1.1](https://github.com/nearai/ironclaw/compare/v0.1.0...v0.1.1) - 2026-02-12 +## [0.1.1](https://github.com/nearai/optimclaw/compare/v0.1.0...v0.1.1) - 2026-02-12 ### Other - Renamed the secrets in release-plz.yml to match the configuration - Make sure that the binaries release CD it kicking in after release-plz -## [0.1.0](https://github.com/nearai/ironclaw/releases/tag/v0.1.0) - 2026-02-12 +## [0.1.0](https://github.com/nearai/optimclaw/releases/tag/v0.1.0) - 2026-02-12 ### Added -- Add multi-provider LLM support via rig-core adapter ([#36](https://github.com/nearai/ironclaw/pull/36)) -- Sandbox jobs ([#4](https://github.com/nearai/ironclaw/pull/4)) -- Add Google Suite & Telegram WASM tools ([#9](https://github.com/nearai/ironclaw/pull/9)) -- Improve CLI ([#5](https://github.com/nearai/ironclaw/pull/5)) +- Add multi-provider LLM support via rig-core adapter ([#36](https://github.com/nearai/optimclaw/pull/36)) +- Sandbox jobs ([#4](https://github.com/nearai/optimclaw/pull/4)) +- Add Google Suite & Telegram WASM tools ([#9](https://github.com/nearai/optimclaw/pull/9)) +- Improve CLI ([#5](https://github.com/nearai/optimclaw/pull/5)) ### Fixed -- resolve runtime panic in Linux keychain integration ([#32](https://github.com/nearai/ironclaw/pull/32)) +- resolve runtime panic in Linux keychain integration ([#32](https://github.com/nearai/optimclaw/pull/32)) ### Other - Skip release-plz on forks - Upgraded release-plz CD pipeline -- Added CI/CD and release pipelines ([#45](https://github.com/nearai/ironclaw/pull/45)) -- DM pairing + Telegram channel improvements ([#17](https://github.com/nearai/ironclaw/pull/17)) -- Fixes build, adds missing sse event and correct command ([#11](https://github.com/nearai/ironclaw/pull/11)) -- Codex/feature parity pr hook ([#6](https://github.com/nearai/ironclaw/pull/6)) -- Add WebSocket gateway and control plane ([#8](https://github.com/nearai/ironclaw/pull/8)) -- select bundled Telegram channel and auto-install ([#3](https://github.com/nearai/ironclaw/pull/3)) +- Added CI/CD and release pipelines ([#45](https://github.com/nearai/optimclaw/pull/45)) +- DM pairing + Telegram channel improvements ([#17](https://github.com/nearai/optimclaw/pull/17)) +- Fixes build, adds missing sse event and correct command ([#11](https://github.com/nearai/optimclaw/pull/11)) +- Codex/feature parity pr hook ([#6](https://github.com/nearai/optimclaw/pull/6)) +- Add WebSocket gateway and control plane ([#8](https://github.com/nearai/optimclaw/pull/8)) +- select bundled Telegram channel and auto-install ([#3](https://github.com/nearai/optimclaw/pull/3)) - Adding skills for reusable work - Fix MCP tool calls, approval loop, shutdown, and improve web UI - Add auth mode, fix MCP token handling, and parallelize startup loading @@ -799,7 +799,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add proactivity features: memory CLI, session pruning, self-repair notifications, slash commands, status diagnostics, context warnings - Add hosted MCP server support with OAuth 2.1 and token refresh - Add interactive setup wizard and persistent settings -- Rebrand to IronClaw with security-first mission +- Rebrand to OptimClaw with security-first mission - Fix build_software tool stuck in planning mode loop - Enable sandbox by default - Fix Telegram Markdown formatting and clarify tool/memory distinctions @@ -840,7 +840,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix TuiChannel integration and enable in main.rs - Integrate Codex patterns: task scheduler, TUI, sessions, compaction - Adding LICENSE -- Add README with IronClaw branding +- Add README with OptimClaw branding - Add WASM sandbox secure API extension - Wire database Store into agent loop - Implementing WASM runtime diff --git a/CLAUDE.md b/CLAUDE.md index e2d84c1e..0401fc95 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,6 +1,6 @@ -# IronClaw Development Guide +# OptimClaw Development Guide -**IronClaw** is a secure personal AI assistant — user-first security, self-expanding tools, defense in depth, multi-channel access with proactive background execution. +**OptimClaw** is a secure personal AI assistant — user-first security, self-expanding tools, defense in depth, multi-channel access with proactive background execution. ## Build & Test @@ -9,7 +9,7 @@ cargo fmt # format cargo clippy --all --benches --tests --examples --all-features # lint (zero warnings) cargo test # unit tests cargo test --features integration # + PostgreSQL tests -RUST_LOG=ironclaw=debug cargo run # run with logging +RUST_LOG=optimclaw=debug cargo run # run with logging ``` E2E tests: see `tests/e2e/CLAUDE.md`. @@ -35,20 +35,20 @@ All I/O is async with tokio. Use `Arc` for shared state, `RwLock` for concurr ## Extracted Crates -Safety logic lives in `crates/ironclaw_safety/`. The `src/safety/mod.rs` shim re-exports everything for backward compatibility, but **new code should import from `ironclaw_safety` directly** (e.g. `use ironclaw_safety::SafetyLayer`). When touching a file that still uses `crate::safety::*`, migrate its imports to `ironclaw_safety::*`. +Safety logic lives in `crates/optimclaw_safety/`. The `src/safety/mod.rs` shim re-exports everything for backward compatibility, but **new code should import from `optimclaw_safety` directly** (e.g. `use optimclaw_safety::SafetyLayer`). When touching a file that still uses `crate::safety::*`, migrate its imports to `optimclaw_safety::*`. ## Project Structure ``` crates/ -└── ironclaw_safety/ # Extracted: prompt injection, validation, leak detection, policy +└── optimclaw_safety/ # Extracted: prompt injection, validation, leak detection, policy src/ ├── lib.rs # Library root, module declarations ├── main.rs # Entry point, CLI args, startup ├── app.rs # App startup orchestration (channel wiring, DB init) -├── bootstrap.rs # Base directory resolution (~/.ironclaw), early .env loading -├── settings.rs # User settings persistence (~/.ironclaw/settings.json) +├── bootstrap.rs # Base directory resolution (~/.optimclaw), early .env loading +├── settings.rs # User settings persistence (~/.optimclaw/settings.json) ├── service.rs # OS service management (launchd/systemd daemon install) ├── tracing_fmt.rs # Custom tracing formatter ├── util.rs # Shared utilities @@ -111,7 +111,7 @@ src/ │ ├── claude_bridge.rs # Claude Code bridge (spawns claude CLI) │ └── proxy_llm.rs # LlmProvider that proxies through orchestrator │ -├── safety/ # Re-export shim for crates/ironclaw_safety (see Extracted Crates) +├── safety/ # Re-export shim for crates/optimclaw_safety (see Extracted Crates) │ ├── llm/ # Multi-provider LLM integration — see src/llm/CLAUDE.md │ @@ -206,7 +206,7 @@ Pending -> InProgress -> Completed -> Submitted -> Accepted SKILL.md files extend the agent's prompt with domain-specific instructions. See `.claude/rules/skills.md` for full details. -- **Trust model**: Trusted (user-placed in `~/.ironclaw/skills/` or workspace `skills/`, full tool access) vs Installed (registry, read-only tools) +- **Trust model**: Trusted (user-placed in `~/.optimclaw/skills/` or workspace `skills/`, full tool access) vs Installed (registry, read-only tools) - **Selection pipeline**: gating (check bin/env/config requirements) -> scoring (keywords/patterns/tags) -> budget (fit within `SKILLS_MAX_TOKENS`) -> attenuation (trust-based tool ceiling) - **Skill tools**: `skill_list`, `skill_search`, `skill_install`, `skill_remove` @@ -228,9 +228,9 @@ Persistent memory with hybrid search (FTS + vector via RRF). Four tools: `memory ## Debugging ```bash -RUST_LOG=ironclaw=trace cargo run # verbose -RUST_LOG=ironclaw::agent=debug cargo run # agent module only -RUST_LOG=ironclaw=debug,tower_http=debug cargo run # + HTTP request logging +RUST_LOG=optimclaw=trace cargo run # verbose +RUST_LOG=optimclaw::agent=debug cargo run # agent module only +RUST_LOG=optimclaw=debug,tower_http=debug cargo run # + HTTP request logging ``` ## Current Limitations diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1c5c6d88..d34c4754 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,8 +3,8 @@ ## Getting Started ```bash -git clone https://github.com/nearai/ironclaw.git -cd ironclaw +git clone https://github.com/nearai/optimclaw.git +cd optimclaw ./scripts/dev-setup.sh ``` @@ -53,7 +53,7 @@ Select the appropriate track in the PR template based on what your changes touch ## Database Changes -IronClaw uses dual-backend persistence (PostgreSQL + libSQL). All new persistence features must support both backends. See `src/db/CLAUDE.md`. +OptimClaw uses dual-backend persistence (PostgreSQL + libSQL). All new persistence features must support both backends. See `src/db/CLAUDE.md`. ## Adding Dependencies diff --git a/COVERAGE_PLAN.md b/COVERAGE_PLAN.md index af5f872c..7247a8da 100644 --- a/COVERAGE_PLAN.md +++ b/COVERAGE_PLAN.md @@ -1,6 +1,6 @@ -# IronClaw Coverage Plan: 63.3% to 95% +# OptimClaw Coverage Plan: 63.3% to 95% -> Generated 2025-03-06 from [Codecov](https://app.codecov.io/gh/nearai/ironclaw/tree/main/src) +> Generated 2025-03-06 from [Codecov](https://app.codecov.io/gh/nearai/optimclaw/tree/main/src) ## Current State diff --git a/Cargo.toml b/Cargo.toml index fbd3d6ee..0493a1f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = [".", "crates/ironclaw_common", "crates/ironclaw_safety"] +members = [".", "crates/optimclaw_common", "crates/optimclaw_safety"] exclude = [ "channels-src/discord", "channels-src/telegram", @@ -15,19 +15,19 @@ exclude = [ "tools-src/slack", "tools-src/telegram", "fuzz", - "crates/ironclaw_safety/fuzz", + "crates/optimclaw_safety/fuzz", ] [package] -name = "ironclaw" +name = "optimclaw" version = "0.22.0" edition = "2024" rust-version = "1.92" description = "Secure personal AI assistant that protects your data and expands its capabilities on the fly" authors = ["NEAR AI "] license = "MIT OR Apache-2.0" -homepage = "https://github.com/nearai/ironclaw" -repository = "https://github.com/nearai/ironclaw" +homepage = "https://github.com/nearai/optimclaw" +repository = "https://github.com/nearai/optimclaw" [package.metadata.wix] upgrade-guid = "D0156E61-BA37-451E-8AB9-1A2ECCCFA48F" @@ -102,10 +102,10 @@ tower-http = { version = "0.6", features = ["trace", "cors", "set-header", "catc cron = "0.13" # Shared types -ironclaw_common = { path = "crates/ironclaw_common", version = "0.1.0" } +optimclaw_common = { path = "crates/optimclaw_common", version = "0.1.0" } # Safety/sanitization -ironclaw_safety = { path = "crates/ironclaw_safety", version = "0.2.0" } +optimclaw_safety = { path = "crates/optimclaw_safety", version = "0.2.0" } regex = "1" aho-corasick = "1" diff --git a/FEATURE_PARITY.md b/FEATURE_PARITY.md index ad2db551..cf3531eb 100644 --- a/FEATURE_PARITY.md +++ b/FEATURE_PARITY.md @@ -1,6 +1,6 @@ -# IronClaw ↔ OpenClaw Feature Parity Matrix +# OptimClaw ↔ OpenClaw Feature Parity Matrix -This document tracks feature parity between IronClaw (Rust implementation) and OpenClaw (TypeScript reference implementation). Use this to coordinate work across developers. +This document tracks feature parity between OptimClaw (Rust implementation) and OpenClaw (TypeScript reference implementation). Use this to coordinate work across developers. **Legend:** @@ -17,7 +17,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 1. Architecture -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| | Hub-and-spoke architecture | ✅ | ✅ | Web gateway as central hub | | WebSocket control plane | ✅ | ✅ | Gateway with WebSocket + SSE | @@ -32,7 +32,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 2. Gateway System -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| | Gateway control plane | ✅ | ✅ | Web gateway with 40+ API endpoints | | HTTP endpoints for Control UI | ✅ | ✅ | Web dashboard with chat, memory, jobs, logs, extensions | @@ -62,12 +62,12 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 3. Messaging Channels -| Channel | OpenClaw | IronClaw | Priority | Notes | +| Channel | OpenClaw | OptimClaw | Priority | Notes | |---------|----------|----------|----------|-------| | CLI/TUI | ✅ | ✅ | - | Ratatui-based TUI | | HTTP webhook | ✅ | ✅ | - | axum with secret validation | | REPL (simple) | ✅ | ✅ | - | For testing | -| WASM channels | ❌ | ✅ | - | IronClaw innovation; host resolves owner scope vs sender identity | +| WASM channels | ❌ | ✅ | - | OptimClaw innovation; host resolves owner scope vs sender identity | | WhatsApp | ✅ | ❌ | P1 | Baileys (Web), same-phone mode with echo detection | | Telegram | ✅ | ✅ | - | WASM channel(MTProto), DM pairing, caption, /start, bot_username, DM topics, setup-time owner auto-verification, owner-scoped persistence | | Discord | ✅ | ❌ | P2 | discord.js, thread parent binding inheritance | @@ -88,7 +88,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ### Telegram-Specific Features (since Feb 2025) -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| | Forum topic creation | ✅ | ❌ | Create topics in forum groups | | channel_post support | ✅ | ❌ | Bot-to-bot communication | @@ -100,7 +100,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ### Discord-Specific Features (since Feb 2025) -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| | Forwarded attachment downloads | ✅ | ❌ | Fetch media from forwarded messages | | Faster reaction state machine | ✅ | ❌ | Watchdog + debounce | @@ -108,7 +108,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ### Slack-Specific Features (since Feb 2025) -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| | Streaming draft replies | ✅ | ❌ | Partial replies via draft message updates | | Configurable stream modes | ✅ | ❌ | Per-channel stream behavior | @@ -117,23 +117,23 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ### Mattermost-Specific Features (since Mar 2026) -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| | Interactive buttons | ✅ | ❌ | Clickable message buttons with signed callback flow | | Interactive model picker | ✅ | ❌ | In-channel provider/model chooser | ### Feishu/Lark-Specific Features (since Mar 2026) -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| | Doc/table actions | ✅ | ❌ | `feishu_doc` supports tables, positional insert, color_text, image upload, and file upload | | Rich-text embedded media extraction | ✅ | ❌ | Pull video/media attachments from post messages | ### Channel Features -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| -| DM pairing codes | ✅ | ✅ | `ironclaw pairing list/approve`, host APIs | +| DM pairing codes | ✅ | ✅ | `optimclaw pairing list/approve`, host APIs | | Allowlist/blocklist | ✅ | 🚧 | `allow_from` + pairing store + hardened command/group allowlists | | Self-message bypass | ✅ | ❌ | Own messages skip pairing | | Mention-based activation | ✅ | ✅ | bot_username + respond_to_all_group_messages | @@ -151,7 +151,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 4. CLI Commands -| Command | OpenClaw | IronClaw | Priority | Notes | +| Command | OpenClaw | OptimClaw | Priority | Notes | |---------|----------|----------|----------|-------| | `run` (agent) | ✅ | ✅ | - | Default command | | `tool install/list/remove` | ✅ | ✅ | - | WASM tools | @@ -189,9 +189,9 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 5. Agent System -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| -| Pi agent runtime | ✅ | ➖ | IronClaw uses custom runtime | +| Pi agent runtime | ✅ | ➖ | OptimClaw uses custom runtime | | RPC-based execution | ✅ | ✅ | Orchestrator/worker pattern | | Multi-provider failover | ✅ | ✅ | `FailoverProvider` tries providers sequentially on retryable errors | | Per-sender sessions | ✅ | ✅ | | @@ -232,7 +232,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 6. Model & Provider Support -| Provider | OpenClaw | IronClaw | Priority | Notes | +| Provider | OpenClaw | OptimClaw | Priority | Notes | |----------|----------|----------|----------|-------| | NEAR AI | ✅ | ✅ | - | Primary provider | | Anthropic (Claude) | ✅ | 🚧 | - | Via NEAR AI proxy; Opus 4.5, Sonnet 4, Sonnet 4.6, adaptive thinking default | @@ -245,7 +245,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O | Cloudflare Workers AI | ✅ | ✅ | P3 | Via `cloudflare` adapter | | NVIDIA API | ✅ | ✅ | P3 | Via `nvidia` adapter and `providers.json` | | OpenRouter | ✅ | ✅ | - | Via OpenAI-compatible provider (RigAdapter) | -| Tinfoil | ❌ | ✅ | - | Private inference provider (IronClaw-only) | +| Tinfoil | ❌ | ✅ | - | Private inference provider (OptimClaw-only) | | OpenAI-compatible | ❌ | ✅ | - | Generic OpenAI-compatible endpoint (RigAdapter) | | GitHub Copilot | ✅ | ✅ | - | Dedicated provider with OAuth token exchange (`GithubCopilotProvider`) | | Ollama (local) | ✅ | ✅ | - | via `rig::providers::ollama` (full support) | @@ -257,7 +257,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ### Model Features -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| | Auto-discovery | ✅ | ❌ | | | Failover chains | ✅ | ✅ | `FailoverProvider` with configurable `fallback_model` | @@ -273,7 +273,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 7. Media Handling -| Feature | OpenClaw | IronClaw | Priority | Notes | +| Feature | OpenClaw | OptimClaw | Priority | Notes | |---------|----------|----------|----------|-------| | Image processing (Sharp) | ✅ | ❌ | P2 | Resize, format convert | | Configurable image resize dims | ✅ | ❌ | P2 | Per-agent dimension config | @@ -296,12 +296,12 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 8. Plugin & Extension System -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| | Dynamic loading | ✅ | ✅ | WASM modules | | Manifest validation | ✅ | ✅ | WASM metadata | | HTTP path registration | ✅ | ❌ | Plugin routes | -| Workspace-relative install | ✅ | ✅ | ~/.ironclaw/tools/ | +| Workspace-relative install | ✅ | ✅ | ~/.optimclaw/tools/ | | Channel plugins | ✅ | ✅ | WASM channels | | Auth plugins | ✅ | ❌ | | | Memory plugins | ✅ | ❌ | Custom backends + selectable memory slot | @@ -321,7 +321,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 9. Configuration System -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| | Primary config file | ✅ `~/.openclaw/openclaw.json` | ✅ `.env` | Different formats | | JSON5 support | ✅ | ❌ | Comments, trailing commas | @@ -330,7 +330,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O | Config validation/schema | ✅ | ✅ | Type-safe Config struct + `openclaw config validate` | | Hot-reload | ✅ | ❌ | | | Legacy migration | ✅ | ➖ | | -| State directory | ✅ `~/.openclaw-state/` | ✅ `~/.ironclaw/` | | +| State directory | ✅ `~/.openclaw-state/` | ✅ `~/.optimclaw/` | | | Credentials directory | ✅ | ✅ | Session files | | Full model compat fields in schema | ✅ | ❌ | pi-ai model compat exposed in config | @@ -340,7 +340,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 10. Memory & Knowledge System -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| | Vector memory | ✅ | ✅ | pgvector | | Session-based memory | ✅ | ✅ | | @@ -351,7 +351,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O | OpenAI embeddings | ✅ | ✅ | | | Gemini embeddings | ✅ | ❌ | | | Local embeddings | ✅ | ❌ | | -| SQLite-vec backend | ✅ | ❌ | IronClaw uses PostgreSQL | +| SQLite-vec backend | ✅ | ❌ | OptimClaw uses PostgreSQL | | LanceDB backend | ✅ | ❌ | Configurable auto-capture max length | | QMD backend | ✅ | ❌ | | | Atomic reindexing | ✅ | ✅ | | @@ -369,7 +369,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 11. Mobile Apps -| Feature | OpenClaw | IronClaw | Priority | Notes | +| Feature | OpenClaw | OptimClaw | Priority | Notes | |---------|----------|----------|----------|-------| | iOS app (SwiftUI) | ✅ | 🚫 | - | Out of scope initially | | Android app (Kotlin) | ✅ | 🚫 | - | Out of scope initially | @@ -390,7 +390,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 12. macOS App -| Feature | OpenClaw | IronClaw | Priority | Notes | +| Feature | OpenClaw | OptimClaw | Priority | Notes | |---------|----------|----------|----------|-------| | SwiftUI native app | ✅ | 🚫 | - | Out of scope | | Menu bar presence | ✅ | 🚫 | - | Animated menubar icon | @@ -411,7 +411,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 13. Web Interface -| Feature | OpenClaw | IronClaw | Priority | Notes | +| Feature | OpenClaw | OptimClaw | Priority | Notes | |---------|----------|----------|----------|-------| | Control UI Dashboard | ✅ | ✅ | - | Web gateway with chat, memory, jobs, logs, extensions | | Channel status view | ✅ | 🚧 | P2 | Gateway status widget, full channel view pending | @@ -431,7 +431,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 14. Automation -| Feature | OpenClaw | IronClaw | Priority | Notes | +| Feature | OpenClaw | OptimClaw | Priority | Notes | |---------|----------|----------|----------|-------| | Cron jobs | ✅ | ✅ | - | Routines with cron trigger | | Per-job model fallback override | ✅ | ❌ | P2 | `payload.fallbacks` overrides agent-level fallbacks | @@ -465,14 +465,14 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 15. Security Features -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| | Gateway token auth | ✅ | ✅ | Bearer token auth on web gateway | | Device pairing | ✅ | ❌ | | | Tailscale identity | ✅ | ❌ | | | Trusted-proxy auth | ✅ | ❌ | Header-based reverse proxy auth | | OAuth flows | ✅ | 🚧 | NEAR AI OAuth + Gemini OAuth (PKCE, S256) + hosted extension/MCP OAuth broker; external auth-proxy rollout still pending | -| DM pairing verification | ✅ | ✅ | ironclaw pairing approve, host APIs | +| DM pairing verification | ✅ | ✅ | optimclaw pairing approve, host APIs | | Allowlist/blocklist | ✅ | 🚧 | allow_from + pairing store | | Per-group tool policies | ✅ | ❌ | | | Exec approvals | ✅ | ✅ | TUI overlay | @@ -483,7 +483,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O | Loopback-first | ✅ | 🚧 | HTTP binds 0.0.0.0 | | Docker sandbox | ✅ | ✅ | Orchestrator/worker containers | | Podman support | ✅ | ❌ | Alternative to Docker | -| WASM sandbox | ❌ | ✅ | IronClaw innovation | +| WASM sandbox | ❌ | ✅ | OptimClaw innovation | | Sandbox env sanitization | ✅ | 🚧 | Shell tool scrubs env vars (secret detection); docker container env sanitization partial | | Tool policies | ✅ | ✅ | | | Elevated mode | ✅ | ❌ | | @@ -505,7 +505,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## 16. Development & Build System -| Feature | OpenClaw | IronClaw | Notes | +| Feature | OpenClaw | OptimClaw | Notes | |---------|----------|----------|-------| | Primary language | TypeScript | Rust | Different ecosystems | | Build tool | tsdown | cargo | | @@ -531,7 +531,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O - ✅ TUI channel with approval overlays - ✅ HTTP webhook channel -- ✅ DM pairing (ironclaw pairing list/approve, host APIs) +- ✅ DM pairing (optimclaw pairing list/approve, host APIs) - ✅ WASM tool sandbox - ✅ Workspace/memory with hybrid search + embeddings batching - ✅ Prompt injection defense @@ -605,7 +605,7 @@ This document tracks feature parity between IronClaw (Rust implementation) and O ## Deviations from OpenClaw -IronClaw intentionally differs from OpenClaw in these ways: +OptimClaw intentionally differs from OpenClaw in these ways: 1. **Rust vs TypeScript**: Native performance, memory safety, single binary distribution 2. **WASM sandbox vs Docker**: Lighter weight, faster startup, capability-based security @@ -613,7 +613,7 @@ IronClaw intentionally differs from OpenClaw in these ways: 4. **NEAR AI focus**: Primary provider with session-based auth 5. **No mobile/desktop apps**: Focus on server-side and CLI initially 6. **WASM channels**: Novel extension mechanism not in OpenClaw -7. **Tinfoil private inference**: IronClaw-only provider for private/encrypted inference +7. **Tinfoil private inference**: OptimClaw-only provider for private/encrypted inference 8. **GitHub WASM tool**: Native GitHub integration as WASM tool 9. **Prompt-based skills**: Different approach than OpenClaw capability bundles (trust gating, attenuation) diff --git a/README.ja.md b/README.ja.md index 887cf67e..e4534dea 100644 --- a/README.ja.md +++ b/README.ja.md @@ -1,8 +1,8 @@

- IronClaw + OptimClaw

-

IronClaw

+

OptimClaw

あなたの味方になる、安全なパーソナルAIアシスタント @@ -10,8 +10,8 @@

License: MIT OR Apache-2.0 - Telegram: @ironclawAI - Reddit: r/ironclawAI + Telegram: @optimclawAI + Reddit: r/optimclawAI

@@ -34,16 +34,16 @@ ## フィロソフィー -IronClawはシンプルな原則に基づいて構築されています:**あなたのAIアシスタントは、あなたのために働くべきであり、あなたに不利益をもたらすべきではありません。** +OptimClawはシンプルな原則に基づいて構築されています:**あなたのAIアシスタントは、あなたのために働くべきであり、あなたに不利益をもたらすべきではありません。** -AIシステムがデータの取り扱いについて不透明になり、企業の利益に沿って調整されることが増えている世界で、IronClawは異なるアプローチを取ります: +AIシステムがデータの取り扱いについて不透明になり、企業の利益に沿って調整されることが増えている世界で、OptimClawは異なるアプローチを取ります: - **あなたのデータはあなたのもの** - すべての情報はローカルに保存・暗号化され、あなたの管理下から離れることはありません - **設計段階からの透明性** - オープンソース、監査可能、隠れたテレメトリやデータ収集なし - **自己拡張する能力** - ベンダーのアップデートを待たずに、新しいツールをその場で構築 - **多層防御** - 複数のセキュリティレイヤーがプロンプトインジェクションやデータ流出から保護 -IronClawは、個人生活にも仕事にも本当に信頼できるAIアシスタントです。 +OptimClawは、個人生活にも仕事にも本当に信頼できるAIアシスタントです。 ## 機能 @@ -66,7 +66,7 @@ IronClawは、個人生活にも仕事にも本当に信頼できるAIアシス ### 自己拡張 -- **動的ツール構築** - 必要なものを説明すると、IronClawがWASMツールとして構築 +- **動的ツール構築** - 必要なものを説明すると、OptimClawがWASMツールとして構築 - **MCPプロトコル** - Model Context Protocolサーバーに接続して追加機能を利用 - **プラグインアーキテクチャ** - 再起動なしで新しいWASMツールやチャネルを追加 @@ -86,12 +86,12 @@ IronClawは、個人生活にも仕事にも本当に信頼できるAIアシス ## ダウンロードまたはビルド -最新のアップデートは[リリースページ](https://github.com/nearai/ironclaw/releases/)をご覧ください。 +最新のアップデートは[リリースページ](https://github.com/nearai/optimclaw/releases/)をご覧ください。

Windowsインストーラーでインストール(Windows) -[Windowsインストーラー](https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-x86_64-pc-windows-msvc.msi)をダウンロードして実行してください。 +[Windowsインストーラー](https://github.com/nearai/optimclaw/releases/latest/download/optimclaw-x86_64-pc-windows-msvc.msi)をダウンロードして実行してください。
@@ -99,7 +99,7 @@ IronClawは、個人生活にも仕事にも本当に信頼できるAIアシス PowerShellスクリプトでインストール(Windows) ```sh -irm https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-installer.ps1 | iex +irm https://github.com/nearai/optimclaw/releases/latest/download/optimclaw-installer.ps1 | iex ``` @@ -108,7 +108,7 @@ irm https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-install シェルスクリプトでインストール(macOS、Linux、Windows/WSL) ```sh -curl --proto '=https' --tlsv1.2 -LsSf https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-installer.sh | sh +curl --proto '=https' --tlsv1.2 -LsSf https://github.com/nearai/optimclaw/releases/latest/download/optimclaw-installer.sh | sh ``` @@ -116,7 +116,7 @@ curl --proto '=https' --tlsv1.2 -LsSf https://github.com/nearai/ironclaw/release Homebrewでインストール(macOS/Linux) ```sh -brew install ironclaw +brew install optimclaw ``` @@ -128,8 +128,8 @@ brew install ironclaw ```bash # リポジトリをクローン -git clone https://github.com/nearai/ironclaw.git -cd ironclaw +git clone https://github.com/nearai/optimclaw.git +cd optimclaw # ビルド cargo build --release @@ -146,25 +146,25 @@ cargo test ```bash # データベースを作成 -createdb ironclaw +createdb optimclaw # pgvectorを有効化 -psql ironclaw -c "CREATE EXTENSION IF NOT EXISTS vector;" +psql optimclaw -c "CREATE EXTENSION IF NOT EXISTS vector;" ``` ## 設定 -セットアップウィザードを実行してIronClawを設定します: +セットアップウィザードを実行してOptimClawを設定します: ```bash -ironclaw onboard +optimclaw onboard ``` -ウィザードは、データベース接続、NEAR AI認証(ブラウザOAuth経由)、シークレットの暗号化(システムキーチェーンを使用)を処理します。設定は接続されたデータベースに永続化されます。ブートストラップ変数(例:`DATABASE_URL`、`LLM_BACKEND`)は、データベース接続前に利用できるよう`~/.ironclaw/.env`に書き込まれます。 +ウィザードは、データベース接続、NEAR AI認証(ブラウザOAuth経由)、シークレットの暗号化(システムキーチェーンを使用)を処理します。設定は接続されたデータベースに永続化されます。ブートストラップ変数(例:`DATABASE_URL`、`LLM_BACKEND`)は、データベース接続前に利用できるよう`~/.optimclaw/.env`に書き込まれます。 ### 代替LLMプロバイダー -IronClawはデフォルトでNEAR AIを使用しますが、多くのLLMプロバイダーをすぐに利用できます。組み込みプロバイダーには**Anthropic**、**OpenAI**、**Google Gemini**、**MiniMax**、**Mistral**、**Ollama**(ローカル)が含まれます。**OpenRouter**(300以上のモデル)、**Together AI**、**Fireworks AI**、セルフホストサーバー(**vLLM**、**LiteLLM**)などのOpenAI互換サービスもサポートされています。 +OptimClawはデフォルトでNEAR AIを使用しますが、多くのLLMプロバイダーをすぐに利用できます。組み込みプロバイダーには**Anthropic**、**OpenAI**、**Google Gemini**、**MiniMax**、**Mistral**、**Ollama**(ローカル)が含まれます。**OpenRouter**(300以上のモデル)、**Together AI**、**Fireworks AI**、セルフホストサーバー(**vLLM**、**LiteLLM**)などのOpenAI互換サービスもサポートされています。 ウィザードでプロバイダーを選択するか、環境変数を直接設定してください: @@ -184,7 +184,7 @@ LLM_MODEL=anthropic/claude-sonnet-4 ## セキュリティ -IronClawは、データを保護し悪用を防ぐために多層防御を実装しています。 +OptimClawは、データを保護し悪用を防ぐために多層防御を実装しています。 ### WASMサンドボックス @@ -280,13 +280,13 @@ WASM ──► 許可リスト ──► リーク ──► 認証情報 ─ ```bash # 初回セットアップ(データベース、認証などを設定) -ironclaw onboard +optimclaw onboard # インタラクティブREPLを起動 cargo run # デバッグログ付き -RUST_LOG=ironclaw=debug cargo run +RUST_LOG=optimclaw=debug cargo run ``` ## 開発 @@ -299,7 +299,7 @@ cargo fmt cargo clippy --all --benches --tests --examples --all-features # テスト実行 -createdb ironclaw_test +createdb optimclaw_test cargo test # 特定のテストを実行 @@ -311,7 +311,7 @@ cargo test test_name ## OpenClawの系譜 -IronClawは[OpenClaw](https://github.com/openclaw/openclaw)にインスパイアされたRust再実装です。完全な対応表は[FEATURE_PARITY.md](FEATURE_PARITY.md)をご覧ください。 +OptimClawは[OpenClaw](https://github.com/openclaw/openclaw)にインスパイアされたRust再実装です。完全な対応表は[FEATURE_PARITY.md](FEATURE_PARITY.md)をご覧ください。 主な違い: diff --git a/README.md b/README.md index cb759236..a4882c49 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@

- IronClaw + OptimClaw

-

IronClaw

+

OptimClaw

Your secure personal AI assistant, always on your side @@ -10,10 +10,10 @@

License: MIT OR Apache-2.0 - Telegram: @ironclawAI - Reddit: r/ironclawAI - - gitcgr + Telegram: @optimclawAI + Reddit: r/optimclawAI + + gitcgr

@@ -37,16 +37,16 @@ ## Philosophy -IronClaw is built on a simple principle: **your AI assistant should work for you, not against you**. +OptimClaw is built on a simple principle: **your AI assistant should work for you, not against you**. -In a world where AI systems are increasingly opaque about data handling and aligned with corporate interests, IronClaw takes a different approach: +In a world where AI systems are increasingly opaque about data handling and aligned with corporate interests, OptimClaw takes a different approach: - **Your data stays yours** - All information is stored locally, encrypted, and never leaves your control - **Transparency by design** - Open source, auditable, no hidden telemetry or data harvesting - **Self-expanding capabilities** - Build new tools on the fly without waiting for vendor updates - **Defense in depth** - Multiple security layers protect against prompt injection and data exfiltration -IronClaw is the AI assistant you can actually trust with your personal and professional life. +OptimClaw is the AI assistant you can actually trust with your personal and professional life. ## Features @@ -69,7 +69,7 @@ IronClaw is the AI assistant you can actually trust with your personal and profe ### Self-Expanding -- **Dynamic Tool Building** - Describe what you need, and IronClaw builds it as a WASM tool +- **Dynamic Tool Building** - Describe what you need, and OptimClaw builds it as a WASM tool - **MCP Protocol** - Connect to Model Context Protocol servers for additional capabilities - **Plugin Architecture** - Drop in new WASM tools and channels without restarting @@ -89,12 +89,12 @@ IronClaw is the AI assistant you can actually trust with your personal and profe ## Download or Build -Visit [Releases page](https://github.com/nearai/ironclaw/releases/) to see the latest updates. +Visit [Releases page](https://github.com/nearai/optimclaw/releases/) to see the latest updates.
Install via Windows Installer (Windows) -Download the [Windows Installer](https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-x86_64-pc-windows-msvc.msi) and run it. +Download the [Windows Installer](https://github.com/nearai/optimclaw/releases/latest/download/optimclaw-x86_64-pc-windows-msvc.msi) and run it.
@@ -102,7 +102,7 @@ Download the [Windows Installer](https://github.com/nearai/ironclaw/releases/lat Install via powershell script (Windows) ```sh -irm https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-installer.ps1 | iex +irm https://github.com/nearai/optimclaw/releases/latest/download/optimclaw-installer.ps1 | iex ``` @@ -111,7 +111,7 @@ irm https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-install Install via shell script (macOS, Linux, Windows/WSL) ```sh -curl --proto '=https' --tlsv1.2 -LsSf https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-installer.sh | sh +curl --proto '=https' --tlsv1.2 -LsSf https://github.com/nearai/optimclaw/releases/latest/download/optimclaw-installer.sh | sh ``` @@ -119,7 +119,7 @@ curl --proto '=https' --tlsv1.2 -LsSf https://github.com/nearai/ironclaw/release Install via Homebrew (macOS/Linux) ```sh -brew install ironclaw +brew install optimclaw ``` @@ -131,8 +131,8 @@ Install it with `cargo`, just make sure you have [Rust](https://rustup.rs) insta ```bash # Clone the repository -git clone https://github.com/nearai/ironclaw.git -cd ironclaw +git clone https://github.com/nearai/optimclaw.git +cd optimclaw # Build cargo build --release @@ -149,28 +149,28 @@ For **full release** (after modifying channel sources), run `./scripts/build-all ```bash # Create database -createdb ironclaw +createdb optimclaw # Enable pgvector -psql ironclaw -c "CREATE EXTENSION IF NOT EXISTS vector;" +psql optimclaw -c "CREATE EXTENSION IF NOT EXISTS vector;" ``` ## Configuration -Run the setup wizard to configure IronClaw: +Run the setup wizard to configure OptimClaw: ```bash -ironclaw onboard +optimclaw onboard ``` The wizard handles database connection, NEAR AI authentication (via browser OAuth), and secrets encryption (using your system keychain). Settings are persisted in the connected database; bootstrap variables (e.g. `DATABASE_URL`, `LLM_BACKEND`) are -written to `~/.ironclaw/.env` so they are available before the database connects. +written to `~/.optimclaw/.env` so they are available before the database connects. ### Alternative LLM Providers -IronClaw defaults to NEAR AI but supports many LLM providers out of the box. +OptimClaw defaults to NEAR AI but supports many LLM providers out of the box. Built-in providers include **Anthropic**, **OpenAI**, **GitHub Copilot**, **Google Gemini**, **MiniMax**, **Mistral**, and **Ollama** (local). OpenAI-compatible services like **OpenRouter** (300+ models), **Together AI**, **Fireworks AI**, and self-hosted servers (**vLLM**, @@ -194,7 +194,7 @@ See [docs/LLM_PROVIDERS.md](docs/LLM_PROVIDERS.md) for a full provider guide. ## Security -IronClaw implements defense in depth to protect your data and prevent misuse. +OptimClaw implements defense in depth to protect your data and prevent misuse. ### WASM Sandbox @@ -287,13 +287,13 @@ External content passes through multiple security layers: ```bash # First-time setup (configures database, auth, etc.) -ironclaw onboard +optimclaw onboard # Start interactive REPL cargo run # With debug logging -RUST_LOG=ironclaw=debug cargo run +RUST_LOG=optimclaw=debug cargo run ``` ## Development @@ -306,7 +306,7 @@ cargo fmt cargo clippy --all --benches --tests --examples --all-features # Run tests -createdb ironclaw_test +createdb optimclaw_test cargo test # Run specific test @@ -318,7 +318,7 @@ cargo test test_name ## OpenClaw Heritage -IronClaw is a Rust reimplementation inspired by [OpenClaw](https://github.com/openclaw/openclaw). See [FEATURE_PARITY.md](FEATURE_PARITY.md) for the complete tracking matrix. +OptimClaw is a Rust reimplementation inspired by [OpenClaw](https://github.com/openclaw/openclaw). See [FEATURE_PARITY.md](FEATURE_PARITY.md) for the complete tracking matrix. Key differences: diff --git a/README.ru.md b/README.ru.md index 0546e7f4..e89eeede 100644 --- a/README.ru.md +++ b/README.ru.md @@ -1,8 +1,8 @@

- IronClaw + OptimClaw

-

IronClaw

+

OptimClaw

Ваш защищенный персональный AI-ассистент, всегда на вашей стороне @@ -10,8 +10,8 @@

Лицензия: MIT OR Apache-2.0 - Telegram: @ironclawAI - Reddit: r/ironclawAI + Telegram: @optimclawAI + Reddit: r/optimclawAI

@@ -34,16 +34,16 @@ ## Философия -IronClaw построен на простом принципе: **ваш AI-ассистент должен работать на вас, а не против вас**. +OptimClaw построен на простом принципе: **ваш AI-ассистент должен работать на вас, а не против вас**. -В мире, где системы ИИ становятся все более непрозрачными в вопросах обработки данных и ориентируются на корпоративные интересы, IronClaw выбирает другой путь: +В мире, где системы ИИ становятся все более непрозрачными в вопросах обработки данных и ориентируются на корпоративные интересы, OptimClaw выбирает другой путь: - **Ваши данные остаются вашими** — вся информация хранится локально, зашифрована и никогда не покидает ваш контроль. - **Прозрачность по умолчанию** — открытый исходный код, возможность аудита, отсутствие скрытой телеметрии или сбора данных. - **Саморасширяемые возможности** — создавайте новые инструменты «на лету», не дожидаясь обновлений от вендора. - **Глубокая защита** — несколько уровней безопасности защищают от инъекций промптов и утечки данных. -IronClaw — это AI-ассистент, которому вы действительно можете доверять в личной и профессиональной жизни. +OptimClaw — это AI-ассистент, которому вы действительно можете доверять в личной и профессиональной жизни. ## Возможности @@ -66,7 +66,7 @@ IronClaw — это AI-ассистент, которому вы действи ### Саморасширяемый -- **Динамическое создание инструментов** — опишите, что вам нужно, и IronClaw создаст это как инструмент WASM. +- **Динамическое создание инструментов** — опишите, что вам нужно, и OptimClaw создаст это как инструмент WASM. - **Протокол MCP** — подключайтесь к серверам Model Context Protocol для получения дополнительных возможностей. - **Плагинная архитектура** — добавляйте новые инструменты WASM и каналы без перезагрузки системы. @@ -86,12 +86,12 @@ IronClaw — это AI-ассистент, которому вы действи ## Загрузка и сборка -Посетите [страницу релизов](https://github.com/nearai/ironclaw/releases/), чтобы увидеть последние обновления. +Посетите [страницу релизов](https://github.com/nearai/optimclaw/releases/), чтобы увидеть последние обновления.

Установка через установщик Windows (Windows) -Загрузите [Windows Installer](https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-x86_64-pc-windows-msvc.msi) и запустите его. +Загрузите [Windows Installer](https://github.com/nearai/optimclaw/releases/latest/download/optimclaw-x86_64-pc-windows-msvc.msi) и запустите его.
@@ -99,7 +99,7 @@ IronClaw — это AI-ассистент, которому вы действи Установка через powershell-скрипт (Windows) ```sh -irm https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-installer.ps1 | iex +irm https://github.com/nearai/optimclaw/releases/latest/download/optimclaw-installer.ps1 | iex ``` @@ -108,7 +108,7 @@ irm https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-install Установка через shell-скрипт (macOS, Linux, Windows/WSL) ```sh -curl --proto '=https' --tlsv1.2 -LsSf https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-installer.sh | sh +curl --proto '=https' --tlsv1.2 -LsSf https://github.com/nearai/optimclaw/releases/latest/download/optimclaw-installer.sh | sh ``` @@ -116,7 +116,7 @@ curl --proto '=https' --tlsv1.2 -LsSf https://github.com/nearai/ironclaw/release Установка через Homebrew (macOS/Linux) ```sh -brew install ironclaw +brew install optimclaw ``` @@ -128,8 +128,8 @@ brew install ironclaw ```bash # Клонируйте репозиторий -git clone https://github.com/nearai/ironclaw.git -cd ironclaw +git clone https://github.com/nearai/optimclaw.git +cd optimclaw # Сборка cargo build --release @@ -146,25 +146,25 @@ cargo test ```bash # Создание базы данных -createdb ironclaw +createdb optimclaw # Включение pgvector -psql ironclaw -c "CREATE EXTENSION IF NOT EXISTS vector;" +psql optimclaw -c "CREATE EXTENSION IF NOT EXISTS vector;" ``` ## Конфигурация -Запустите мастер настройки для конфигурации IronClaw: +Запустите мастер настройки для конфигурации OptimClaw: ```bash -ironclaw onboard +optimclaw onboard ``` -Мастер настройки поможет установить соединение с базой данных, пройти аутентификацию NEAR AI (через браузер OAuth) и настроить шифрование секретов (используя системную связку ключей). Настройки сохраняются в базе данных; базовые переменные (например, `DATABASE_URL`, `LLM_BACKEND`) записываются в `~/.ironclaw/.env`, чтобы они были доступны до подключения к БД. +Мастер настройки поможет установить соединение с базой данных, пройти аутентификацию NEAR AI (через браузер OAuth) и настроить шифрование секретов (используя системную связку ключей). Настройки сохраняются в базе данных; базовые переменные (например, `DATABASE_URL`, `LLM_BACKEND`) записываются в `~/.optimclaw/.env`, чтобы они были доступны до подключения к БД. ### Альтернативные LLM-провайдеры -IronClaw по умолчанию использует NEAR AI, но поддерживает множество LLM-провайдеров из коробки. +OptimClaw по умолчанию использует NEAR AI, но поддерживает множество LLM-провайдеров из коробки. Встроенные провайдеры включают **Anthropic**, **OpenAI**, **Google Gemini**, **MiniMax**, **Mistral** и **Ollama** (локально). Также поддерживаются OpenAI-совместимые сервисы: **OpenRouter** (300+ моделей), **Together AI**, **Fireworks AI** и собственные серверы @@ -188,7 +188,7 @@ LLM_MODEL=anthropic/claude-sonnet-4 ## Безопасность -IronClaw реализует эшелонированную защиту для обеспечения безопасности ваших данных и предотвращения злоупотреблений. +OptimClaw реализует эшелонированную защиту для обеспечения безопасности ваших данных и предотвращения злоупотреблений. ### Песочница WASM @@ -282,13 +282,13 @@ WASM ──► Валидатор ──► Сканер ───► Инъек ```bash # Первоначальная настройка (БД, аутентификация и т.д.) -ironclaw onboard +optimclaw onboard # Запуск интерактивного REPL cargo run # С отладочными логами -RUST_LOG=ironclaw=debug cargo run +RUST_LOG=optimclaw=debug cargo run ``` ## Разработка @@ -301,7 +301,7 @@ cargo fmt cargo clippy --all --benches --tests --examples --all-features # Запуск тестов -createdb ironclaw_test +createdb optimclaw_test cargo test # Запуск конкретного теста @@ -313,7 +313,7 @@ cargo test название_теста ## Наследие OpenClaw -IronClaw — это реализация на Rust, вдохновленная проектом [OpenClaw](https://github.com/openclaw/openclaw). Полную матрицу соответствия функций можно найти в [FEATURE_PARITY.md](FEATURE_PARITY.md). +OptimClaw — это реализация на Rust, вдохновленная проектом [OpenClaw](https://github.com/openclaw/openclaw). Полную матрицу соответствия функций можно найти в [FEATURE_PARITY.md](FEATURE_PARITY.md). Ключевые отличия: diff --git a/README.zh-CN.md b/README.zh-CN.md index d818872a..0b971ef5 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,8 +1,8 @@

- IronClaw + OptimClaw

-

IronClaw

+

OptimClaw

安全可靠的个人 AI 助手,始终站在你这边 @@ -10,8 +10,8 @@

License: MIT OR Apache-2.0 - Telegram: @ironclawAI - Reddit: r/ironclawAI + Telegram: @optimclawAI + Reddit: r/optimclawAI

@@ -34,16 +34,16 @@ ## 设计理念 -IronClaw 基于一个简单的原则:**你的 AI 助手应该为你服务,而不是与你为敌。** +OptimClaw 基于一个简单的原则:**你的 AI 助手应该为你服务,而不是与你为敌。** -在 AI 系统对数据处理日益不透明、与企业利益捆绑的今天,IronClaw 选择了一条不同的路: +在 AI 系统对数据处理日益不透明、与企业利益捆绑的今天,OptimClaw 选择了一条不同的路: - **数据归你所有** — 所有信息存储在本地,加密保护,始终在你掌控之下 - **透明至上** — 完全开源,可审计,没有隐藏的遥测或数据收集 - **自主扩展** — 随时构建新工具,无需等待供应商更新 - **纵深防御** — 多层安全机制抵御提示注入和数据泄露 -IronClaw 是一个你真正可以信赖的 AI 助手,无论是个人生活还是工作。 +OptimClaw 是一个你真正可以信赖的 AI 助手,无论是个人生活还是工作。 ## 功能特性 @@ -66,7 +66,7 @@ IronClaw 是一个你真正可以信赖的 AI 助手,无论是个人生活还 ### 自主扩展 -- **动态工具构建** — 描述你的需求,IronClaw 会将其构建为 WASM 工具 +- **动态工具构建** — 描述你的需求,OptimClaw 会将其构建为 WASM 工具 - **MCP 协议** — 连接模型上下文协议(Model Context Protocol)服务器以获取额外能力 - **插件架构** — 无需重启即可加载新的 WASM 工具和渠道 @@ -86,12 +86,12 @@ IronClaw 是一个你真正可以信赖的 AI 助手,无论是个人生活还 ## 下载或编译 -访问 [Releases 页面](https://github.com/nearai/ironclaw/releases/) 查看最新版本。 +访问 [Releases 页面](https://github.com/nearai/optimclaw/releases/) 查看最新版本。

通过 Windows 安装程序安装 (Windows) -下载 [Windows 安装程序](https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-x86_64-pc-windows-msvc.msi) 并运行。 +下载 [Windows 安装程序](https://github.com/nearai/optimclaw/releases/latest/download/optimclaw-x86_64-pc-windows-msvc.msi) 并运行。
@@ -99,7 +99,7 @@ IronClaw 是一个你真正可以信赖的 AI 助手,无论是个人生活还 通过 PowerShell 脚本安装 (Windows) ```sh -irm https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-installer.ps1 | iex +irm https://github.com/nearai/optimclaw/releases/latest/download/optimclaw-installer.ps1 | iex ``` @@ -108,7 +108,7 @@ irm https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-install 通过 Shell 脚本安装 (macOS、Linux、Windows/WSL) ```sh -curl --proto '=https' --tlsv1.2 -LsSf https://github.com/nearai/ironclaw/releases/latest/download/ironclaw-installer.sh | sh +curl --proto '=https' --tlsv1.2 -LsSf https://github.com/nearai/optimclaw/releases/latest/download/optimclaw-installer.sh | sh ``` @@ -116,7 +116,7 @@ curl --proto '=https' --tlsv1.2 -LsSf https://github.com/nearai/ironclaw/release 通过 Homebrew 安装 (macOS/Linux) ```sh -brew install ironclaw +brew install optimclaw ``` @@ -128,8 +128,8 @@ brew install ironclaw ```bash # 克隆仓库 -git clone https://github.com/nearai/ironclaw.git -cd ironclaw +git clone https://github.com/nearai/optimclaw.git +cd optimclaw # 编译 cargo build --release @@ -146,25 +146,25 @@ cargo test ```bash # 创建数据库 -createdb ironclaw +createdb optimclaw # 启用 pgvector 扩展 -psql ironclaw -c "CREATE EXTENSION IF NOT EXISTS vector;" +psql optimclaw -c "CREATE EXTENSION IF NOT EXISTS vector;" ``` ## 配置 -运行设置向导来配置 IronClaw: +运行设置向导来配置 OptimClaw: ```bash -ironclaw onboard +optimclaw onboard ``` -向导将引导你完成数据库连接、NEAR AI 身份验证(通过浏览器 OAuth)和密钥加密(使用系统钥匙串)。设置会保存在数据库中;引导变量(如 `DATABASE_URL`、`LLM_BACKEND`)写入 `~/.ironclaw/.env`,以便在数据库连接前可用。 +向导将引导你完成数据库连接、NEAR AI 身份验证(通过浏览器 OAuth)和密钥加密(使用系统钥匙串)。设置会保存在数据库中;引导变量(如 `DATABASE_URL`、`LLM_BACKEND`)写入 `~/.optimclaw/.env`,以便在数据库连接前可用。 ### 替代 LLM 提供商 -IronClaw 默认使用 NEAR AI,但开箱即用地支持多种 LLM 提供商。 +OptimClaw 默认使用 NEAR AI,但开箱即用地支持多种 LLM 提供商。 内置提供商包括 **Anthropic**、**OpenAI**、**GitHub Copilot**、**Google Gemini**、**MiniMax**、**Mistral** 和 **Ollama**(本地部署)。同时也支持 OpenAI 兼容服务,如 **OpenRouter**(300+ 模型)、**Together AI**、**Fireworks AI** 以及自托管服务器(**vLLM**、**LiteLLM**)。 在向导中选择你的提供商,或直接设置环境变量: @@ -185,7 +185,7 @@ LLM_MODEL=anthropic/claude-sonnet-4 ## 安全机制 -IronClaw 实现了纵深防御策略来保护你的数据并防止滥用。 +OptimClaw 实现了纵深防御策略来保护你的数据并防止滥用。 ### WASM 沙箱 @@ -278,13 +278,13 @@ WASM ──► 白名单 ──► 泄露扫描 ──► 凭据 ──► 执 ```bash # 首次设置(配置数据库、认证等) -ironclaw onboard +optimclaw onboard # 启动交互式 REPL cargo run # 启用调试日志 -RUST_LOG=ironclaw=debug cargo run +RUST_LOG=optimclaw=debug cargo run ``` ## 开发 @@ -297,7 +297,7 @@ cargo fmt cargo clippy --all --benches --tests --examples --all-features # 运行测试 -createdb ironclaw_test +createdb optimclaw_test cargo test # 运行指定测试 @@ -309,7 +309,7 @@ cargo test test_name ## OpenClaw 传承 -IronClaw 是受 [OpenClaw](https://github.com/openclaw/openclaw) 启发的 Rust 重新实现。参见 [FEATURE_PARITY.md](FEATURE_PARITY.md) 了解完整的功能追踪矩阵。 +OptimClaw 是受 [OpenClaw](https://github.com/openclaw/openclaw) 启发的 Rust 重新实现。参见 [FEATURE_PARITY.md](FEATURE_PARITY.md) 了解完整的功能追踪矩阵。 主要差异: diff --git a/benches/safety_check.rs b/benches/safety_check.rs index 30a2d1ac..621ec1c5 100644 --- a/benches/safety_check.rs +++ b/benches/safety_check.rs @@ -1,5 +1,5 @@ use criterion::{Criterion, black_box, criterion_group, criterion_main}; -use ironclaw::safety::{LeakDetector, Sanitizer, Validator}; +use optimclaw::safety::{LeakDetector, Sanitizer, Validator}; fn bench_sanitizer(c: &mut Criterion) { let mut group = c.benchmark_group("sanitizer"); diff --git a/benches/safety_pipeline.rs b/benches/safety_pipeline.rs index 583985b7..42a237b5 100644 --- a/benches/safety_pipeline.rs +++ b/benches/safety_pipeline.rs @@ -1,6 +1,6 @@ use criterion::{Criterion, black_box, criterion_group, criterion_main}; -use ironclaw::config::SafetyConfig; -use ironclaw::safety::{SafetyLayer, Validator}; +use optimclaw::config::SafetyConfig; +use optimclaw::safety::{SafetyLayer, Validator}; fn bench_safety_layer_pipeline(c: &mut Criterion) { let mut group = c.benchmark_group("safety_pipeline"); diff --git a/channels-src/discord/Cargo.toml b/channels-src/discord/Cargo.toml index a2892494..925d20e9 100644 --- a/channels-src/discord/Cargo.toml +++ b/channels-src/discord/Cargo.toml @@ -2,7 +2,7 @@ name = "discord-channel" version = "0.2.0" edition = "2021" -description = "Discord channel for IronClaw" +description = "Discord channel for OptimClaw" license = "MIT OR Apache-2.0" publish = false diff --git a/channels-src/discord/README.md b/channels-src/discord/README.md index 333e7670..f426e468 100644 --- a/channels-src/discord/README.md +++ b/channels-src/discord/README.md @@ -1,4 +1,4 @@ -# Discord Channel for IronClaw +# Discord Channel for OptimClaw WASM channel for Discord integration - handle slash commands and button interactions via webhooks. @@ -13,12 +13,12 @@ WASM channel for Discord integration - handle slash commands and button interact 1. Create a Discord Application at 2. Create a Bot and get the token -3. Set up Interactions URL to point to your IronClaw instance +3. Set up Interactions URL to point to your OptimClaw instance 4. Copy the Application ID and Public Key -5. Store in IronClaw secrets: +5. Store in OptimClaw secrets: ```bash - ironclaw secret set discord_bot_token YOUR_BOT_TOKEN + optimclaw secret set discord_bot_token YOUR_BOT_TOKEN ``` **Note:** The `discord_bot_token` secret is used for Discord REST API calls. @@ -51,7 +51,7 @@ curl -X POST \ In your Discord app settings, set: -- Interactions Endpoint URL: `https://your-ironclaw.com/webhook/discord` +- Interactions Endpoint URL: `https://your-optimclaw.com/webhook/discord` ## Usage Examples @@ -127,7 +127,7 @@ To send embeds, include an `embeds` array in the `metadata_json` field of the ag ### "401 Unauthorized" -- Check that `discord_bot_token` is set correctly in IronClaw secrets. +- Check that `discord_bot_token` is set correctly in OptimClaw secrets. - Ensure the bot is added to the server. ### "Interaction Failed" diff --git a/channels-src/discord/src/lib.rs b/channels-src/discord/src/lib.rs index 249d1e5b..9e3c9a48 100644 --- a/channels-src/discord/src/lib.rs +++ b/channels-src/discord/src/lib.rs @@ -1,4 +1,4 @@ -//! Discord Gateway/Webhook channel for IronClaw. +//! Discord Gateway/Webhook channel for OptimClaw. //! //! This WASM component implements the channel interface for handling Discord //! interactions via webhooks and sending messages back to Discord. @@ -1171,7 +1171,7 @@ fn send_pairing_reply(ctx: &PairingReplyCtx, code: &str) -> Result<(), String> { ); let payload = serde_json::json!({ "content": format!( - "To pair with this bot, run: `ironclaw pairing approve discord {}`", + "To pair with this bot, run: `optimclaw pairing approve discord {}`", code ), "flags": 64 diff --git a/channels-src/feishu/Cargo.toml b/channels-src/feishu/Cargo.toml index 95762410..19526f9a 100644 --- a/channels-src/feishu/Cargo.toml +++ b/channels-src/feishu/Cargo.toml @@ -2,7 +2,7 @@ name = "feishu-channel" version = "0.1.0" edition = "2021" -description = "Feishu/Lark Bot channel for IronClaw" +description = "Feishu/Lark Bot channel for OptimClaw" license = "MIT OR Apache-2.0" [lib] diff --git a/channels-src/feishu/feishu.capabilities.json b/channels-src/feishu/feishu.capabilities.json index cf344d74..b3973f69 100644 --- a/channels-src/feishu/feishu.capabilities.json +++ b/channels-src/feishu/feishu.capabilities.json @@ -7,7 +7,7 @@ "auth": { "secret_name": "feishu_app_id", "display_name": "Feishu / Lark", - "instructions": "Create a bot at https://open.feishu.cn/app (Feishu) or https://open.larksuite.com/app (Lark). You need the App ID and App Secret. Note: IronClaw supports Event Subscription webhook delivery, but not Feishu's long-connection websocket mode.", + "instructions": "Create a bot at https://open.feishu.cn/app (Feishu) or https://open.larksuite.com/app (Lark). You need the App ID and App Secret. Note: OptimClaw supports Event Subscription webhook delivery, but not Feishu's long-connection websocket mode.", "setup_url": "https://open.feishu.cn/app", "token_hint": "App ID looks like cli_XXXX, App Secret is a long alphanumeric string", "env_var": "FEISHU_APP_ID" diff --git a/channels-src/feishu/src/lib.rs b/channels-src/feishu/src/lib.rs index 647f5fa5..8c839153 100644 --- a/channels-src/feishu/src/lib.rs +++ b/channels-src/feishu/src/lib.rs @@ -1,11 +1,11 @@ // Feishu API types have fields reserved for future use. #![allow(dead_code)] -//! Feishu/Lark Bot channel for IronClaw. +//! Feishu/Lark Bot channel for OptimClaw. //! //! This WASM component implements the channel interface for handling Feishu //! webhooks (Event Subscription v2.0) and sending messages back via the -//! Feishu/Lark Bot API. IronClaw currently does not connect to Feishu's +//! Feishu/Lark Bot API. OptimClaw currently does not connect to Feishu's //! long-connection websocket subscription mode; use Event Subscription //! webhooks for this channel. //! diff --git a/channels-src/slack/Cargo.toml b/channels-src/slack/Cargo.toml index e5445abb..7e9950ba 100644 --- a/channels-src/slack/Cargo.toml +++ b/channels-src/slack/Cargo.toml @@ -2,7 +2,7 @@ name = "slack-channel" version = "0.2.1" edition = "2021" -description = "Slack Events API channel for IronClaw" +description = "Slack Events API channel for OptimClaw" license = "MIT OR Apache-2.0" [lib] diff --git a/channels-src/slack/src/lib.rs b/channels-src/slack/src/lib.rs index 24f01df3..a6f3bab4 100644 --- a/channels-src/slack/src/lib.rs +++ b/channels-src/slack/src/lib.rs @@ -1,4 +1,4 @@ -//! Slack Events API channel for IronClaw. +//! Slack Events API channel for OptimClaw. //! //! This WASM component implements the channel interface for handling Slack //! webhooks and sending messages back to Slack. @@ -650,7 +650,7 @@ fn send_pairing_reply(channel_id: &str, code: &str) -> Result<(), String> { let payload = serde_json::json!({ "channel": channel_id, "text": format!( - "To pair with this bot, run: `ironclaw pairing approve slack {}`", + "To pair with this bot, run: `optimclaw pairing approve slack {}`", code ), }); diff --git a/channels-src/telegram/Cargo.toml b/channels-src/telegram/Cargo.toml index 182e5f5d..28eafcde 100644 --- a/channels-src/telegram/Cargo.toml +++ b/channels-src/telegram/Cargo.toml @@ -2,7 +2,7 @@ name = "telegram-channel" version = "0.2.1" edition = "2021" -description = "Telegram Bot API channel for IronClaw" +description = "Telegram Bot API channel for OptimClaw" license = "MIT OR Apache-2.0" [lib] diff --git a/channels-src/telegram/src/lib.rs b/channels-src/telegram/src/lib.rs index f34ed68a..4cb0079e 100644 --- a/channels-src/telegram/src/lib.rs +++ b/channels-src/telegram/src/lib.rs @@ -1,7 +1,7 @@ // Telegram API types have fields reserved for future use (entities, reply threading, etc.) #![allow(dead_code)] -//! Telegram Bot API channel for IronClaw. +//! Telegram Bot API channel for OptimClaw. //! //! This WASM component implements the channel interface for handling Telegram //! webhooks and sending messages back via the Bot API. @@ -1170,7 +1170,7 @@ fn send_photo( ); } - let boundary = format!("ironclaw-{}", channel_host::now_millis()); + let boundary = format!("optimclaw-{}", channel_host::now_millis()); let mut body = Vec::new(); write_multipart_field(&mut body, &boundary, "chat_id", &chat_id.to_string()); @@ -1235,7 +1235,7 @@ fn send_document( ) -> Result<(), String> { let message_thread_id = normalize_thread_id(message_thread_id); - let boundary = format!("ironclaw-{}", channel_host::now_millis()); + let boundary = format!("optimclaw-{}", channel_host::now_millis()); let mut body = Vec::new(); write_multipart_field(&mut body, &boundary, "chat_id", &chat_id.to_string()); @@ -1552,7 +1552,7 @@ fn send_pairing_reply(chat_id: i64, code: &str) -> Result<(), String> { send_message( chat_id, &format!( - "To pair with this bot, run: `ironclaw pairing approve telegram {}`", + "To pair with this bot, run: `optimclaw pairing approve telegram {}`", code ), None, diff --git a/channels-src/whatsapp/Cargo.toml b/channels-src/whatsapp/Cargo.toml index cf211e2e..ffbd62b1 100644 --- a/channels-src/whatsapp/Cargo.toml +++ b/channels-src/whatsapp/Cargo.toml @@ -2,7 +2,7 @@ name = "whatsapp-channel" version = "0.2.0" edition = "2021" -description = "WhatsApp Cloud API channel for IronClaw" +description = "WhatsApp Cloud API channel for OptimClaw" [lib] crate-type = ["cdylib"] diff --git a/channels-src/whatsapp/src/lib.rs b/channels-src/whatsapp/src/lib.rs index c69a9b9f..f5611d47 100644 --- a/channels-src/whatsapp/src/lib.rs +++ b/channels-src/whatsapp/src/lib.rs @@ -1,7 +1,7 @@ // WhatsApp API types have fields reserved for future use (contacts, statuses, etc.) #![allow(dead_code)] -//! WhatsApp Cloud API channel for IronClaw. +//! WhatsApp Cloud API channel for OptimClaw. //! //! This WASM component implements the channel interface for handling WhatsApp //! webhooks and sending messages back via the Cloud API. @@ -910,7 +910,7 @@ fn send_pairing_reply( "text": { "preview_url": false, "body": format!( - "To pair with this bot, run: ironclaw pairing approve whatsapp {}", + "To pair with this bot, run: optimclaw pairing approve whatsapp {}", code ) } diff --git a/clippy.toml b/clippy.toml index 9a039e91..9985e5eb 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1,6 +1,6 @@ # Complexity guardrails for AI-assisted development quality. # These thresholds prevent new violations while preserving existing code. -# See: https://github.com/nearai/ironclaw/issues/338 +# See: https://github.com/nearai/optimclaw/issues/338 cognitive-complexity-threshold = 15 # default: 25 (only active when lint is enabled) too-many-lines-threshold = 100 # default: 100 (only active when lint is enabled) diff --git a/crates/ironclaw_common/Cargo.toml b/crates/optimclaw_common/Cargo.toml similarity index 56% rename from crates/ironclaw_common/Cargo.toml rename to crates/optimclaw_common/Cargo.toml index 6e7db5a4..78b4ba79 100644 --- a/crates/ironclaw_common/Cargo.toml +++ b/crates/optimclaw_common/Cargo.toml @@ -1,13 +1,13 @@ [package] -name = "ironclaw_common" +name = "optimclaw_common" version = "0.1.0" edition = "2024" rust-version = "1.92" -description = "Shared types and utilities for the IronClaw workspace" +description = "Shared types and utilities for the OptimClaw workspace" authors = ["NEAR AI "] license = "MIT OR Apache-2.0" -homepage = "https://github.com/nearai/ironclaw" -repository = "https://github.com/nearai/ironclaw" +homepage = "https://github.com/nearai/optimclaw" +repository = "https://github.com/nearai/optimclaw" [package.metadata.dist] dist = false diff --git a/crates/ironclaw_common/src/event.rs b/crates/optimclaw_common/src/event.rs similarity index 100% rename from crates/ironclaw_common/src/event.rs rename to crates/optimclaw_common/src/event.rs diff --git a/crates/ironclaw_common/src/lib.rs b/crates/optimclaw_common/src/lib.rs similarity index 62% rename from crates/ironclaw_common/src/lib.rs rename to crates/optimclaw_common/src/lib.rs index f52dc0aa..a50a864b 100644 --- a/crates/ironclaw_common/src/lib.rs +++ b/crates/optimclaw_common/src/lib.rs @@ -1,4 +1,4 @@ -//! Shared types and utilities for the IronClaw workspace. +//! Shared types and utilities for the OptimClaw workspace. mod event; mod util; diff --git a/crates/ironclaw_common/src/util.rs b/crates/optimclaw_common/src/util.rs similarity index 100% rename from crates/ironclaw_common/src/util.rs rename to crates/optimclaw_common/src/util.rs diff --git a/crates/ironclaw_safety/Cargo.toml b/crates/optimclaw_safety/Cargo.toml similarity index 75% rename from crates/ironclaw_safety/Cargo.toml rename to crates/optimclaw_safety/Cargo.toml index 38b8718a..8456f257 100644 --- a/crates/ironclaw_safety/Cargo.toml +++ b/crates/optimclaw_safety/Cargo.toml @@ -1,13 +1,13 @@ [package] -name = "ironclaw_safety" +name = "optimclaw_safety" version = "0.2.0" edition = "2024" rust-version = "1.92" description = "Prompt injection defense, input validation, secret leak detection, and safety policy enforcement" authors = ["NEAR AI "] license = "MIT OR Apache-2.0" -homepage = "https://github.com/nearai/ironclaw" -repository = "https://github.com/nearai/ironclaw" +homepage = "https://github.com/nearai/optimclaw" +repository = "https://github.com/nearai/optimclaw" [package.metadata.dist] dist = false diff --git a/crates/ironclaw_safety/fuzz/Cargo.toml b/crates/optimclaw_safety/fuzz/Cargo.toml similarity index 91% rename from crates/ironclaw_safety/fuzz/Cargo.toml rename to crates/optimclaw_safety/fuzz/Cargo.toml index acd797f3..2f08bdb9 100644 --- a/crates/ironclaw_safety/fuzz/Cargo.toml +++ b/crates/optimclaw_safety/fuzz/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ironclaw-safety-fuzz" +name = "optimclaw-safety-fuzz" version = "0.0.0" publish = false edition = "2021" @@ -11,7 +11,7 @@ cargo-fuzz = true libfuzzer-sys = "0.4" serde_json = "1" -[dependencies.ironclaw_safety] +[dependencies.optimclaw_safety] path = ".." [[bin]] diff --git a/crates/ironclaw_safety/fuzz/README.md b/crates/optimclaw_safety/fuzz/README.md similarity index 87% rename from crates/ironclaw_safety/fuzz/README.md rename to crates/optimclaw_safety/fuzz/README.md index f256706a..293ac6b2 100644 --- a/crates/ironclaw_safety/fuzz/README.md +++ b/crates/optimclaw_safety/fuzz/README.md @@ -1,6 +1,6 @@ -# ironclaw_safety Fuzz Targets +# optimclaw_safety Fuzz Targets -Fuzz testing for the `ironclaw_safety` crate using [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz) (libFuzzer). +Fuzz testing for the `optimclaw_safety` crate using [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz) (libFuzzer). ## Targets @@ -22,7 +22,7 @@ rustup install nightly ## Running ```bash -cd crates/ironclaw_safety +cd crates/optimclaw_safety # Run a specific target (runs until stopped or crash found) cargo +nightly fuzz run fuzz_safety_sanitizer diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_config_env/all_attacks b/crates/optimclaw_safety/fuzz/corpus/fuzz_config_env/all_attacks similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_config_env/all_attacks rename to crates/optimclaw_safety/fuzz/corpus/fuzz_config_env/all_attacks diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_config_env/clean b/crates/optimclaw_safety/fuzz/corpus/fuzz_config_env/clean similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_config_env/clean rename to crates/optimclaw_safety/fuzz/corpus/fuzz_config_env/clean diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_config_env/injection_with_secret b/crates/optimclaw_safety/fuzz/corpus/fuzz_config_env/injection_with_secret similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_config_env/injection_with_secret rename to crates/optimclaw_safety/fuzz/corpus/fuzz_config_env/injection_with_secret diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/api_key_header b/crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/api_key_header similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/api_key_header rename to crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/api_key_header diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/array_headers b/crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/array_headers similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/array_headers rename to crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/array_headers diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/auth_header b/crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/auth_header similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/auth_header rename to crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/auth_header diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/bearer_value b/crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/bearer_value similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/bearer_value rename to crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/bearer_value diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/empty_object b/crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/empty_object similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/empty_object rename to crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/empty_object diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/invalid_url b/crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/invalid_url similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/invalid_url rename to crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/invalid_url diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/no_creds b/crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/no_creds similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/no_creds rename to crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/no_creds diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/not_json b/crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/not_json similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/not_json rename to crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/not_json diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/safe_headers b/crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/safe_headers similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/safe_headers rename to crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/safe_headers diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/url_access_token b/crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/url_access_token similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/url_access_token rename to crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/url_access_token diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/url_api_key b/crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/url_api_key similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/url_api_key rename to crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/url_api_key diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/url_userinfo b/crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/url_userinfo similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_credential_detect/url_userinfo rename to crates/optimclaw_safety/fuzz/corpus/fuzz_credential_detect/url_userinfo diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/anthropic_key b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/anthropic_key similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/anthropic_key rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/anthropic_key diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/aws_key b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/aws_key similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/aws_key rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/aws_key diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/bearer_token b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/bearer_token similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/bearer_token rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/bearer_token diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/clean_text b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/clean_text similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/clean_text rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/clean_text diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/github_pat b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/github_pat similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/github_pat rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/github_pat diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/github_token b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/github_token similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/github_token rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/github_token diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/hex_64 b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/hex_64 similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/hex_64 rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/hex_64 diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/multiple_secrets b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/multiple_secrets similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/multiple_secrets rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/multiple_secrets diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/near_miss_short b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/near_miss_short similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/near_miss_short rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/near_miss_short diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/openai_key b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/openai_key similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/openai_key rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/openai_key diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/pem_key b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/pem_key similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/pem_key rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/pem_key diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/sendgrid_key b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/sendgrid_key similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/sendgrid_key rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/sendgrid_key diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/slack_token b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/slack_token similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/slack_token rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/slack_token diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/ssh_key b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/ssh_key similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/ssh_key rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/ssh_key diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/stripe_key b/crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/stripe_key similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_leak_detector/stripe_key rename to crates/optimclaw_safety/fuzz/corpus/fuzz_leak_detector/stripe_key diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/base64_payload b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/base64_payload similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/base64_payload rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/base64_payload diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/clean_text b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/clean_text similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/clean_text rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/clean_text diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/eval_exec b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/eval_exec similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/eval_exec rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/eval_exec diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/ignore_previous b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/ignore_previous similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/ignore_previous rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/ignore_previous diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/inst_tokens b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/inst_tokens similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/inst_tokens rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/inst_tokens diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/markdown_code b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/markdown_code similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/markdown_code rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/markdown_code diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/mixed_case b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/mixed_case similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/mixed_case rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/mixed_case diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/null_bytes b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/null_bytes similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/null_bytes rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/null_bytes diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/role_markers b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/role_markers similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/role_markers rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/role_markers diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/special_tokens b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/special_tokens similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/special_tokens rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/special_tokens diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/system_injection b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/system_injection similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/system_injection rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/system_injection diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/unicode_mixed b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/unicode_mixed similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/unicode_mixed rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_sanitizer/unicode_mixed diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/empty b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/empty similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/empty rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/empty diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/excessive_whitespace b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/excessive_whitespace similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/excessive_whitespace rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/excessive_whitespace diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/json_array b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/json_array similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/json_array rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/json_array diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/json_deep b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/json_deep similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/json_deep rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/json_deep diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/json_nested b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/json_nested similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/json_nested rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/json_nested diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/long_input b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/long_input similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/long_input rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/long_input diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/normal_input b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/normal_input similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/normal_input rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/normal_input diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/null_bytes b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/null_bytes similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/null_bytes rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/null_bytes diff --git a/crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/repetition b/crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/repetition similarity index 100% rename from crates/ironclaw_safety/fuzz/corpus/fuzz_safety_validator/repetition rename to crates/optimclaw_safety/fuzz/corpus/fuzz_safety_validator/repetition diff --git a/crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_config_env.rs b/crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_config_env.rs similarity index 97% rename from crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_config_env.rs rename to crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_config_env.rs index e4f25087..4b3ecb92 100644 --- a/crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_config_env.rs +++ b/crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_config_env.rs @@ -1,5 +1,5 @@ #![no_main] -use ironclaw_safety::{LeakDetector, Sanitizer, Validator}; +use optimclaw_safety::{LeakDetector, Sanitizer, Validator}; use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { diff --git a/crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_credential_detect.rs b/crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_credential_detect.rs similarity index 87% rename from crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_credential_detect.rs rename to crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_credential_detect.rs index 32bcf97e..1dd32856 100644 --- a/crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_credential_detect.rs +++ b/crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_credential_detect.rs @@ -1,5 +1,5 @@ #![no_main] -use ironclaw_safety::params_contain_manual_credentials; +use optimclaw_safety::params_contain_manual_credentials; use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { diff --git a/crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_leak_detector.rs b/crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_leak_detector.rs similarity index 94% rename from crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_leak_detector.rs rename to crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_leak_detector.rs index 7f13ceed..96d03936 100644 --- a/crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_leak_detector.rs +++ b/crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_leak_detector.rs @@ -1,5 +1,5 @@ #![no_main] -use ironclaw_safety::LeakDetector; +use optimclaw_safety::LeakDetector; use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { diff --git a/crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_safety_sanitizer.rs b/crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_safety_sanitizer.rs similarity index 93% rename from crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_safety_sanitizer.rs rename to crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_safety_sanitizer.rs index f9046fa1..5ab9a878 100644 --- a/crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_safety_sanitizer.rs +++ b/crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_safety_sanitizer.rs @@ -1,5 +1,5 @@ #![no_main] -use ironclaw_safety::{Sanitizer, Severity}; +use optimclaw_safety::{Sanitizer, Severity}; use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { diff --git a/crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_safety_validator.rs b/crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_safety_validator.rs similarity index 94% rename from crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_safety_validator.rs rename to crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_safety_validator.rs index f6ee6fc2..90420d7a 100644 --- a/crates/ironclaw_safety/fuzz/fuzz_targets/fuzz_safety_validator.rs +++ b/crates/optimclaw_safety/fuzz/fuzz_targets/fuzz_safety_validator.rs @@ -1,5 +1,5 @@ #![no_main] -use ironclaw_safety::Validator; +use optimclaw_safety::Validator; use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { diff --git a/crates/ironclaw_safety/src/credential_detect.rs b/crates/optimclaw_safety/src/credential_detect.rs similarity index 99% rename from crates/ironclaw_safety/src/credential_detect.rs rename to crates/optimclaw_safety/src/credential_detect.rs index 518e6f34..a08993a0 100644 --- a/crates/ironclaw_safety/src/credential_detect.rs +++ b/crates/optimclaw_safety/src/credential_detect.rs @@ -381,7 +381,7 @@ mod tests { /// Adversarial tests for credential detection with Unicode, control chars, /// and case folding edge cases. - /// See . + /// See . mod adversarial { use super::*; diff --git a/crates/ironclaw_safety/src/leak_detector.rs b/crates/optimclaw_safety/src/leak_detector.rs similarity index 99% rename from crates/ironclaw_safety/src/leak_detector.rs rename to crates/optimclaw_safety/src/leak_detector.rs index fe1a5bdc..1bee1371 100644 --- a/crates/ironclaw_safety/src/leak_detector.rs +++ b/crates/optimclaw_safety/src/leak_detector.rs @@ -836,7 +836,7 @@ mod tests { } /// Adversarial tests for leak detector regex patterns and masking. - /// See . + /// See . mod adversarial { use crate::leak_detector::{LeakDetector, mask_secret}; diff --git a/crates/ironclaw_safety/src/lib.rs b/crates/optimclaw_safety/src/lib.rs similarity index 99% rename from crates/ironclaw_safety/src/lib.rs rename to crates/optimclaw_safety/src/lib.rs index 31fda95e..e3a49c60 100644 --- a/crates/ironclaw_safety/src/lib.rs +++ b/crates/optimclaw_safety/src/lib.rs @@ -147,7 +147,7 @@ impl SafetyLayer { pub fn scan_inbound_for_secrets(&self, input: &str) -> Option { let warning = "Your message appears to contain a secret (API key, token, or credential). \ For security, it was not sent to the AI. Please remove the secret and try again. \ - To store credentials, use the setup form or `ironclaw config set `."; + To store credentials, use the setup form or `optimclaw config set `."; match self.leak_detector.scan_and_clean(input) { Ok(cleaned) if cleaned != input => Some(warning.to_string()), Err(_) => Some(warning.to_string()), @@ -506,7 +506,7 @@ mod tests { } /// Adversarial tests for SafetyLayer truncation at multi-byte boundaries. - /// See . + /// See . mod adversarial { use super::*; diff --git a/crates/ironclaw_safety/src/policy.rs b/crates/optimclaw_safety/src/policy.rs similarity index 99% rename from crates/ironclaw_safety/src/policy.rs rename to crates/optimclaw_safety/src/policy.rs index d1784b98..2db0d3ea 100644 --- a/crates/ironclaw_safety/src/policy.rs +++ b/crates/optimclaw_safety/src/policy.rs @@ -302,7 +302,7 @@ mod tests { } /// Adversarial tests for policy regex patterns. - /// See . + /// See . mod adversarial { use super::*; diff --git a/crates/ironclaw_safety/src/sanitizer.rs b/crates/optimclaw_safety/src/sanitizer.rs similarity index 99% rename from crates/ironclaw_safety/src/sanitizer.rs rename to crates/optimclaw_safety/src/sanitizer.rs index 256e1f45..9151afa4 100644 --- a/crates/ironclaw_safety/src/sanitizer.rs +++ b/crates/optimclaw_safety/src/sanitizer.rs @@ -433,7 +433,7 @@ mod tests { } /// Adversarial tests for regex backtracking, Unicode edge cases, and - /// control character variants. See . + /// control character variants. See . mod adversarial { use super::*; diff --git a/crates/ironclaw_safety/src/validator.rs b/crates/optimclaw_safety/src/validator.rs similarity index 99% rename from crates/ironclaw_safety/src/validator.rs rename to crates/optimclaw_safety/src/validator.rs index 31e731c5..f5a5a8d8 100644 --- a/crates/ironclaw_safety/src/validator.rs +++ b/crates/optimclaw_safety/src/validator.rs @@ -471,7 +471,7 @@ mod tests { /// Adversarial tests for validator whitespace ratio, repetition detection, /// and Unicode edge cases. - /// See . + /// See . mod adversarial { use super::*; diff --git a/deploy/ironclaw.service b/deploy/optimclaw.service similarity index 100% rename from deploy/ironclaw.service rename to deploy/optimclaw.service diff --git a/docker-compose.yml b/docker-compose.yml index e3e6f578..4512a460 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,13 +5,13 @@ services: ports: - "127.0.0.1:5432:5432" environment: - POSTGRES_DB: ironclaw - POSTGRES_USER: ironclaw - POSTGRES_PASSWORD: ironclaw # dev-only, change for any non-local deployment + POSTGRES_DB: optimclaw + POSTGRES_USER: optimclaw + POSTGRES_PASSWORD: optimclaw # dev-only, change for any non-local deployment volumes: - pgdata:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -U ironclaw"] + test: ["CMD-SHELL", "pg_isready -U optimclaw"] interval: 5s timeout: 3s retries: 5 diff --git a/docs/BUILDING_CHANNELS.md b/docs/BUILDING_CHANNELS.md index 4fad5756..ada24c26 100644 --- a/docs/BUILDING_CHANNELS.md +++ b/docs/BUILDING_CHANNELS.md @@ -1,6 +1,6 @@ # Building WASM Channels -This guide covers how to build WASM channel modules for IronClaw. +This guide covers how to build WASM channel modules for OptimClaw. ## Overview @@ -19,7 +19,7 @@ channels/ # Or channels-src/ After building, deploy to: ``` -~/.ironclaw/channels/ +~/.optimclaw/channels/ ├── my-channel.wasm └── my-channel.capabilities.json ``` @@ -31,7 +31,7 @@ After building, deploy to: name = "my-channel" version = "0.1.0" edition = "2021" -description = "My messaging platform channel for IronClaw" +description = "My messaging platform channel for OptimClaw" [lib] crate-type = ["cdylib"] @@ -248,7 +248,7 @@ Create `my-channel.capabilities.json`: ### Supply Chain Security: No Committed Binaries -**Do not commit compiled WASM binaries.** They are a supply chain risk — the binary in a PR may not match the source. IronClaw builds channels from source: +**Do not commit compiled WASM binaries.** They are a supply chain risk — the binary in a PR may not match the source. OptimClaw builds channels from source: - `cargo build` automatically builds `telegram.wasm` via `build.rs` - The built binary is in `.gitignore` and is not committed @@ -270,12 +270,12 @@ rustup target add wasm32-wasip2 # Build Telegram channel ./channels-src/telegram/build.sh -# Install (or use ironclaw onboard to install bundled channel) -mkdir -p ~/.ironclaw/channels -cp channels-src/telegram/telegram.wasm channels-src/telegram/telegram.capabilities.json ~/.ironclaw/channels/ +# Install (or use optimclaw onboard to install bundled channel) +mkdir -p ~/.optimclaw/channels +cp channels-src/telegram/telegram.wasm channels-src/telegram/telegram.capabilities.json ~/.optimclaw/channels/ ``` -**Note**: The main IronClaw binary bundles `telegram.wasm` via `include_bytes!`. When modifying the Telegram channel source, run `./channels-src/telegram/build.sh` **before** building the main crate, so the updated WASM is included. +**Note**: The main OptimClaw binary bundles `telegram.wasm` via `include_bytes!`. When modifying the Telegram channel source, run `./channels-src/telegram/build.sh` **before** building the main crate, so the updated WASM is included. ### Other Channels @@ -284,9 +284,9 @@ cp channels-src/telegram/telegram.wasm channels-src/telegram/telegram.capabiliti cd channels-src/my-channel cargo build --release --target wasm32-wasip2 -# Deploy to ~/.ironclaw/channels/ -cp target/wasm32-wasip2/release/my_channel.wasm ~/.ironclaw/channels/my-channel.wasm -cp my-channel.capabilities.json ~/.ironclaw/channels/ +# Deploy to ~/.optimclaw/channels/ +cp target/wasm32-wasip2/release/my_channel.wasm ~/.optimclaw/channels/my-channel.wasm +cp my-channel.capabilities.json ~/.optimclaw/channels/ ``` ## Host Functions Available diff --git a/docs/LLM_PROVIDERS.md b/docs/LLM_PROVIDERS.md index 765ce8ea..0dc4a356 100644 --- a/docs/LLM_PROVIDERS.md +++ b/docs/LLM_PROVIDERS.md @@ -1,6 +1,6 @@ # LLM Provider Configuration -IronClaw defaults to NEAR AI for model access, but supports any OpenAI-compatible +OptimClaw defaults to NEAR AI for model access, but supports any OpenAI-compatible endpoint as well as Anthropic, Ollama, and Google Gemini directly. This guide covers the most common configurations. @@ -30,8 +30,8 @@ the most common configurations. ## NEAR AI (default) -No additional configuration required. On first run, `ironclaw onboard` opens a browser -for OAuth authentication. Credentials are saved to `~/.ironclaw/session.json`. +No additional configuration required. On first run, `optimclaw onboard` opens a browser +for OAuth authentication. Credentials are saved to `~/.optimclaw/session.json`. ```env NEARAI_MODEL=claude-3-5-sonnet-20241022 @@ -110,7 +110,7 @@ API (`generativelanguage.googleapis.com`). ## GitHub Copilot GitHub Copilot exposes chat endpoint at -`https://api.githubcopilot.com`. IronClaw uses that endpoint directly through the +`https://api.githubcopilot.com`. OptimClaw uses that endpoint directly through the built-in `github_copilot` provider. ```env @@ -121,14 +121,14 @@ GITHUB_COPILOT_MODEL=gpt-4o # GITHUB_COPILOT_EXTRA_HEADERS=Copilot-Integration-Id:vscode-chat ``` -`ironclaw onboard` can acquire this token for you using GitHub device login. If you +`optimclaw onboard` can acquire this token for you using GitHub device login. If you already signed into Copilot through VS Code or a JetBrains IDE, you can also reuse the `oauth_token` stored in `~/.config/github-copilot/apps.json`. If you prefer, `LLM_BACKEND=github-copilot` also works as an alias. -Popular models vary by subscription, but `gpt-4o` is a safe default. IronClaw keeps +Popular models vary by subscription, but `gpt-4o` is a safe default. OptimClaw keeps model entry manual for this provider because GitHub Copilot model listing may require -extra integration headers on some clients. IronClaw automatically injects the standard +extra integration headers on some clients. OptimClaw automatically injects the standard VS Code identity headers (`User-Agent`, `Editor-Version`, `Editor-Plugin-Version`, `Copilot-Integration-Id`) and lets you override them with `GITHUB_COPILOT_EXTRA_HEADERS`. @@ -313,7 +313,7 @@ LLM_MODEL=llama-3.2-3b-instruct-q4_K_M Instead of editing `.env` manually, run the onboarding wizard: ```bash -ironclaw onboard +optimclaw onboard ``` Select **"OpenAI-compatible"** for OpenRouter, Together AI, Fireworks, vLLM, LiteLLM, diff --git a/docs/TELEGRAM_SETUP.md b/docs/TELEGRAM_SETUP.md index f9ec24eb..6038d259 100644 --- a/docs/TELEGRAM_SETUP.md +++ b/docs/TELEGRAM_SETUP.md @@ -1,10 +1,10 @@ # Telegram Channel Setup -This guide covers configuring the Telegram channel for IronClaw, including DM pairing for access control. +This guide covers configuring the Telegram channel for OptimClaw, including DM pairing for access control. ## Overview -The Telegram channel lets you interact with IronClaw via Telegram DMs and groups. It supports: +The Telegram channel lets you interact with OptimClaw via Telegram DMs and groups. It supports: - **Webhook mode** (recommended): Instant delivery via tunnel - **Polling mode**: No tunnel required; ~30s delay @@ -13,7 +13,7 @@ The Telegram channel lets you interact with IronClaw via Telegram DMs and groups ## Prerequisites -- IronClaw installed and configured (`ironclaw onboard`) +- OptimClaw installed and configured (`optimclaw onboard`) - A Telegram bot token from [@BotFather](https://t.me/BotFather) ## Quick Start @@ -27,7 +27,7 @@ The Telegram channel lets you interact with IronClaw via Telegram DMs and groups ### 2. Configure via Setup Wizard ```bash -ironclaw onboard +optimclaw onboard ``` When prompted, enable the Telegram channel and paste your bot token. The wizard will: @@ -57,26 +57,26 @@ When an unknown user DMs your bot, they receive a pairing code. You must approve ### Flow 1. Unknown user sends a message to your bot -2. Bot replies: `To pair with this bot, run: ironclaw pairing approve telegram ABC12345` -3. You run: `ironclaw pairing approve telegram ABC12345` +2. Bot replies: `To pair with this bot, run: optimclaw pairing approve telegram ABC12345` +3. You run: `optimclaw pairing approve telegram ABC12345` 4. User is added to the allow list; future messages are delivered ### Commands ```bash # List pending pairing requests -ironclaw pairing list telegram +optimclaw pairing list telegram # List as JSON -ironclaw pairing list telegram --json +optimclaw pairing list telegram --json # Approve a user by code -ironclaw pairing approve telegram ABC12345 +optimclaw pairing approve telegram ABC12345 ``` ### Configuration -Edit `~/.ironclaw/channels/telegram.capabilities.json` (or the config injected by the host): +Edit `~/.optimclaw/channels/telegram.capabilities.json` (or the config injected by the host): | Option | Values | Default | Description | |--------|--------|---------|-------------| @@ -96,8 +96,8 @@ rustup target add wasm32-wasip2 ./channels-src/telegram/build.sh # Install -mkdir -p ~/.ironclaw/channels -cp channels-src/telegram/telegram.wasm channels-src/telegram/telegram.capabilities.json ~/.ironclaw/channels/ +mkdir -p ~/.optimclaw/channels +cp channels-src/telegram/telegram.wasm channels-src/telegram/telegram.capabilities.json ~/.optimclaw/channels/ ``` ## Secrets @@ -106,7 +106,7 @@ The channel expects a secret named `telegram_bot_token`. Configure via: - **Setup wizard**: Saves to encrypted secrets store - **Environment**: `TELEGRAM_BOT_TOKEN=your_token` -- **Secrets store**: `ironclaw` CLI (if available) +- **Secrets store**: `optimclaw` CLI (if available) ## Webhook Secret (Optional) @@ -126,10 +126,10 @@ For webhook validation, set `telegram_webhook_secret` in secrets. Telegram will ### Group mentions not working -- Set `bot_username` in config to your bot's username (e.g., `MyIronClawBot`) +- Set `bot_username` in config to your bot's username (e.g., `MyOptimClawBot`) - Ensure the message contains `@YourBot` or starts with `/` ### "Connection refused" when starting -- For webhook mode: Start your tunnel before `ironclaw run` +- For webhook mode: Start your tunnel before `optimclaw run` - For polling only: No tunnel needed; ignore tunnel-related warnings diff --git a/docs/USER_MANAGEMENT_API.md b/docs/USER_MANAGEMENT_API.md index 3767215d..e38d2215 100644 --- a/docs/USER_MANAGEMENT_API.md +++ b/docs/USER_MANAGEMENT_API.md @@ -1,6 +1,6 @@ # User Management API -DB-backed user management for multi-tenant IronClaw deployments. Covers admin user CRUD, per-user secrets provisioning, self-service profile, API token management, and usage reporting. +DB-backed user management for multi-tenant OptimClaw deployments. Covers admin user CRUD, per-user secrets provisioning, self-service profile, API token management, and usage reporting. ## Authentication @@ -211,7 +211,7 @@ Permanently delete a user and all associated data (tokens, jobs, conversations, ## Admin: Per-User Secrets -Provision secrets on behalf of individual users. The primary use case is an application backend (acting as admin) that configures per-user credentials so each user's IronClaw agent can call back to external services. +Provision secrets on behalf of individual users. The primary use case is an application backend (acting as admin) that configures per-user credentials so each user's OptimClaw agent can call back to external services. Secrets are encrypted at rest with AES-256-GCM using a per-secret HKDF-derived key. Plaintext values are **never returned** by any endpoint — they can only be used by the agent's tool system at runtime. @@ -260,17 +260,17 @@ Create or update a secret for the specified user. If a secret with the same name ```bash # Admin creates a user -curl -X POST https://ironclaw.example.com/api/admin/users \ +curl -X POST https://optimclaw.example.com/api/admin/users \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"display_name": "Alice", "role": "member"}' # Response includes: {"id": "alice-uuid", "token": "alice-bearer-token", ...} # Admin provisions a per-user callback secret -curl -X PUT https://ironclaw.example.com/api/admin/users/alice-uuid/secrets/app_callback_token \ +curl -X PUT https://optimclaw.example.com/api/admin/users/alice-uuid/secrets/app_callback_token \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"value": "per-user-jwt-for-alice", "provider": "my-app"}' -# Now Alice's IronClaw agent can use the "app_callback_token" secret +# Now Alice's OptimClaw agent can use the "app_callback_token" secret # when calling tools that need to authenticate back to the app backend. ``` diff --git a/docs/plans/2026-02-24-automated-qa.md b/docs/plans/2026-02-24-automated-qa.md index 5fb56d4b..19951448 100644 --- a/docs/plans/2026-02-24-automated-qa.md +++ b/docs/plans/2026-02-24-automated-qa.md @@ -1,4 +1,4 @@ -# Automated QA Plan for IronClaw +# Automated QA Plan for OptimClaw **Date:** 2026-02-24 **Status:** Draft @@ -8,7 +8,7 @@ ## Motivation -A review of all closed issues and merged bug-fix PRs reveals that most IronClaw bugs fall into a few recurring categories: +A review of all closed issues and merged bug-fix PRs reveals that most OptimClaw bugs fall into a few recurring categories: | Category | Examples | Root Cause | |----------|----------|------------| @@ -54,7 +54,7 @@ fn all_tool_schemas_are_openai_strict_valid() { } ``` -Add the same validation for WASM tools (loaded from `~/.ironclaw/tools/`) and MCP tools (mock a simple MCP manifest and validate the schema it produces). +Add the same validation for WASM tools (loaded from `~/.optimclaw/tools/`) and MCP tools (mock a simple MCP manifest and validate the schema it produces). **Files:** New `src/tools/schema_validator.rs` (validation logic), test in `tests/tool_schema_validation.rs` @@ -124,7 +124,7 @@ docker-build: steps: - uses: actions/checkout@v6 - name: Build Docker image - run: docker build -t ironclaw-test:ci . + run: docker build -t optimclaw-test:ci . ``` **Files:** Modify `.github/workflows/test.yml` @@ -318,7 +318,7 @@ async fn context_length_exceeded_triggers_compaction() { ## Tier 3: Computer-Use E2E Testing -**Cost:** High (requires Anthropic computer use API, headless browser, ironclaw running) +**Cost:** High (requires Anthropic computer use API, headless browser, optimclaw running) **Timeline:** ~2 weeks for infrastructure, then incremental scenario additions **Bugs this would have caught:** #307, #306, #263, all manual web-ui-test checklist items @@ -326,7 +326,7 @@ async fn context_length_exceeded_triggers_compaction() { ``` +------------------+ +-----------------+ +------------------+ -| Test Runner | | Headless | | IronClaw | +| Test Runner | | Headless | | OptimClaw | | (Python/TS) |---->| Chromium |---->| (cargo run) | | | | (Playwright) | | GATEWAY=true | | Orchestrates | | | | port 3001 | @@ -345,7 +345,7 @@ async fn context_length_exceeded_triggers_compaction() { **Components:** -1. **Test runner** -- Python or TypeScript script that orchestrates the flow. Starts ironclaw, waits for readiness, launches Playwright browser, runs scenarios. +1. **Test runner** -- Python or TypeScript script that orchestrates the flow. Starts optimclaw, waits for readiness, launches Playwright browser, runs scenarios. 2. **Playwright browser** -- Headless Chromium. Takes screenshots, executes click/type actions as directed by the computer use agent. Also provides DOM access for structural assertions (element exists, text content matches, no error toasts). @@ -362,7 +362,7 @@ async fn context_length_exceeded_triggers_compaction() { ``` tests/ e2e/ - conftest.py # pytest fixtures: start ironclaw, browser + conftest.py # pytest fixtures: start optimclaw, browser computer_use.py # Claude computer use client wrapper assertions.py # DOM + visual assertion helpers scenarios/ @@ -374,15 +374,15 @@ tests/ test_html_injection.py test_tool_approval.py screenshots/ # Reference screenshots (gitignored) - Dockerfile.test # Container for CI: ironclaw + chromium + Dockerfile.test # Container for CI: optimclaw + chromium ``` -**Fixture: start ironclaw** +**Fixture: start optimclaw** ```python @pytest.fixture(scope="session") -async def ironclaw_server(): - """Start ironclaw with gateway enabled, return base URL.""" +async def optimclaw_server(): + """Start optimclaw with gateway enabled, return base URL.""" env = { "CLI_ENABLED": "false", "GATEWAY_ENABLED": "true", @@ -409,12 +409,12 @@ async def ironclaw_server(): ```python @pytest.fixture -async def browser_agent(ironclaw_server): +async def browser_agent(optimclaw_server): """Playwright browser + Claude computer use agent.""" async with async_playwright() as p: browser = await p.chromium.launch(headless=True) page = await browser.new_page(viewport={"width": 1280, "height": 720}) - await page.goto(f"{ironclaw_server}/?token=test-token-e2e") + await page.goto(f"{optimclaw_server}/?token=test-token-e2e") agent = ComputerUseAgent(page) yield agent await browser.close() @@ -533,7 +533,7 @@ async def test_chat_sends_and_receives(browser_agent): #### Scenario 3: SSE Reconnect ```python -async def test_sse_reconnect_preserves_history(browser_agent, ironclaw_server): +async def test_sse_reconnect_preserves_history(browser_agent, optimclaw_server): """Bug: #307 (no re-sync on SSE reconnect after server restart)""" page = browser_agent.page @@ -546,7 +546,7 @@ async def test_sse_reconnect_preserves_history(browser_agent, ironclaw_server): # Step 2: Kill and restart the server # (test fixture provides a restart helper) - await restart_ironclaw(ironclaw_server) + await restart_optimclaw(optimclaw_server) # Step 3: Wait for reconnect await page.wait_for_selector(".connection-status.connected", timeout=30000) @@ -623,20 +623,20 @@ async def test_tool_approval_overlay(browser_agent): #### Scenario 7: Onboarding Wizard (Full Flow) ```python -async def test_onboarding_wizard_completes(tmp_ironclaw_home): +async def test_onboarding_wizard_completes(tmp_optimclaw_home): """Bugs: #187, #174, #129, #185 (wizard persistence and re-trigger)""" - # Start ironclaw with a fresh home directory (no prior config) + # Start optimclaw with a fresh home directory (no prior config) # The wizard runs in TUI mode, so we need a PTY or use the web wizard # if/when one exists. For now, test the CLI wizard via expect-style automation. proc = pexpect.spawn( "cargo run", - env={"IRONCLAW_HOME": str(tmp_ironclaw_home), **base_env}, + env={"OPTIMCLAW_HOME": str(tmp_optimclaw_home), **base_env}, timeout=60, ) # Step through wizard - proc.expect("Welcome to IronClaw") + proc.expect("Welcome to OptimClaw") proc.expect("LLM Backend") proc.sendline("1") # Select first option # ... continue through all 7 steps ... @@ -646,12 +646,12 @@ async def test_onboarding_wizard_completes(tmp_ironclaw_home): # Restart and verify wizard does NOT re-trigger proc2 = pexpect.spawn( "cargo run", - env={"IRONCLAW_HOME": str(tmp_ironclaw_home), **base_env}, + env={"OPTIMCLAW_HOME": str(tmp_optimclaw_home), **base_env}, timeout=30, ) - proc2.expect("Agent ironclaw ready") # Should skip wizard - # Must NOT see "Welcome to IronClaw" again - assert not proc2.match_any(["Welcome to IronClaw"], timeout=5) + proc2.expect("Agent optimclaw ready") # Should skip wizard + # Must NOT see "Welcome to OptimClaw" again + assert not proc2.match_any(["Welcome to OptimClaw"], timeout=5) proc2.close() ``` @@ -687,7 +687,7 @@ jobs: image: ollama/ollama:latest steps: - uses: actions/checkout@v6 - - name: Build ironclaw + - name: Build optimclaw run: cargo build --features libsql - name: Install Playwright run: pip install playwright pytest-playwright && playwright install chromium diff --git a/docs/plans/2026-02-24-e2e-infrastructure-design.md b/docs/plans/2026-02-24-e2e-infrastructure-design.md index 96810f98..cdfec83e 100644 --- a/docs/plans/2026-02-24-e2e-infrastructure-design.md +++ b/docs/plans/2026-02-24-e2e-infrastructure-design.md @@ -2,7 +2,7 @@ **Date:** 2026-02-24 **Status:** Approved -**Goal:** Deterministic browser-level E2E tests for the IronClaw web gateway using Python + Playwright, with a mock LLM backend for CI reliability. +**Goal:** Deterministic browser-level E2E tests for the OptimClaw web gateway using Python + Playwright, with a mock LLM backend for CI reliability. --- @@ -25,7 +25,7 @@ | +----------+-----------+ | | - mock_llm.py ironclaw binary + mock_llm.py optimclaw binary (canned responses) (cargo build --features libsql) 127.0.0.1:{port} 127.0.0.1:{port} | | @@ -39,12 +39,12 @@ **Flow:** 1. pytest session starts -2. Session-scoped fixture builds ironclaw binary (or reuses cached) +2. Session-scoped fixture builds optimclaw binary (or reuses cached) 3. Session-scoped fixture starts mock LLM on OS-assigned port -4. Session-scoped fixture starts ironclaw subprocess pointing to mock LLM, gateway on OS-assigned port, libSQL in-memory +4. Session-scoped fixture starts optimclaw subprocess pointing to mock LLM, gateway on OS-assigned port, libSQL in-memory 5. Function-scoped fixture launches Playwright browser, navigates to gateway with auth token 6. Each test uses Playwright locators + DOM assertions -7. Teardown kills ironclaw and mock LLM +7. Teardown kills optimclaw and mock LLM --- @@ -52,7 +52,7 @@ ``` tests/e2e/ - conftest.py # pytest fixtures: build binary, start ironclaw, mock LLM, browser + conftest.py # pytest fixtures: build binary, start optimclaw, mock LLM, browser mock_llm.py # OpenAI-compat HTTP server with canned responses helpers.py # Shared utilities (wait_for_ready, selectors) scenarios/ @@ -76,7 +76,7 @@ A minimal async HTTP server that speaks the OpenAI Chat Completions API. - Parses the `messages` array from the request body - Pattern-matches the last user message content to select a canned response - Returns a well-formed `ChatCompletionResponse` with `id`, `choices[0].message`, `usage` -- Supports `stream: true` by returning SSE chunks with `delta` objects (critical: IronClaw streams responses via SSE to the browser) +- Supports `stream: true` by returning SSE chunks with `delta` objects (critical: OptimClaw streams responses via SSE to the browser) **Canned response table:** @@ -109,8 +109,8 @@ data: [DONE] ### Session-scoped (run once per test session) -**`ironclaw_binary`** -- Checks if `./target/debug/ironclaw` exists +**`optimclaw_binary`** +- Checks if `./target/debug/optimclaw` exists - If missing or stale, runs `cargo build --no-default-features --features libsql` - Returns the binary path - Timeout: 300s (first build can be slow) @@ -122,8 +122,8 @@ data: [DONE] - Yields `(process, url)` - Kills process on teardown -**`ironclaw_server(ironclaw_binary, mock_llm_server)`** -- Starts the ironclaw binary with environment: +**`optimclaw_server(optimclaw_binary, mock_llm_server)`** +- Starts the optimclaw binary with environment: ``` GATEWAY_ENABLED=true @@ -143,14 +143,14 @@ ROUTINES_ENABLED=false HEARTBEAT_ENABLED=false ``` -- Parses actual gateway port from ironclaw stdout (`Gateway listening on 127.0.0.1:XXXX`) +- Parses actual gateway port from optimclaw stdout (`Gateway listening on 127.0.0.1:XXXX`) - Polls `GET /api/status` until ready (timeout 60s) - Yields the base URL (`http://127.0.0.1:{port}`) - Sends SIGTERM on teardown, SIGKILL after 5s grace ### Function-scoped (fresh per test) -**`page(ironclaw_server)`** +**`page(optimclaw_server)`** - Launches Playwright Chromium (headless) - Creates new browser context (isolated cookies/storage) - Creates new page with viewport 1280x720 @@ -248,7 +248,7 @@ test_skills_install_and_remove: ## Port Discovery -IronClaw logs `Gateway listening on 127.0.0.1:XXXX` at startup. The fixture reads stdout line-by-line until it finds this pattern, extracts the port. +OptimClaw logs `Gateway listening on 127.0.0.1:XXXX` at startup. The fixture reads stdout line-by-line until it finds this pattern, extracts the port. ```python async def wait_for_port(process, pattern=r"Gateway listening on .+:(\d+)", timeout=60): @@ -260,7 +260,7 @@ async def wait_for_port(process, pattern=r"Gateway listening on .+:(\d+)", timeo ) if match := re.search(pattern, line.decode()): return int(match.group(1)) - raise TimeoutError("ironclaw did not report listening port") + raise TimeoutError("optimclaw did not report listening port") ``` Same pattern for the mock LLM server. @@ -272,7 +272,7 @@ Same pattern for the mock LLM server. ```toml # tests/e2e/pyproject.toml [project] -name = "ironclaw-e2e" +name = "optimclaw-e2e" version = "0.1.0" requires-python = ">=3.11" dependencies = [ @@ -316,7 +316,7 @@ jobs: with: path: target key: e2e-${{ hashFiles('Cargo.lock') }} - - name: Build ironclaw + - name: Build optimclaw run: cargo build --no-default-features --features libsql - uses: actions/setup-python@v5 with: @@ -347,7 +347,7 @@ Not in initial scope. Design accommodates it via: ## Success Criteria -1. `pytest tests/e2e/ -v` passes locally with a pre-built ironclaw binary +1. `pytest tests/e2e/ -v` passes locally with a pre-built optimclaw binary 2. All 3 scenarios (connection, chat, skills) exercise real browser interactions 3. Mock LLM provides deterministic responses (no flaky tests from LLM randomness) 4. CI workflow runs on web gateway changes and weekly schedule diff --git a/docs/plans/2026-02-24-e2e-infrastructure.md b/docs/plans/2026-02-24-e2e-infrastructure.md index 1d773af1..4994ffd5 100644 --- a/docs/plans/2026-02-24-e2e-infrastructure.md +++ b/docs/plans/2026-02-24-e2e-infrastructure.md @@ -2,9 +2,9 @@ > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. -**Goal:** Build a Python + Playwright E2E testing framework that exercises the IronClaw web gateway through a real browser against the real binary with a mock LLM backend. +**Goal:** Build a Python + Playwright E2E testing framework that exercises the OptimClaw web gateway through a real browser against the real binary with a mock LLM backend. -**Architecture:** pytest session fixtures start a mock OpenAI-compat HTTP server and the ironclaw binary (libSQL in-memory, gateway enabled), then per-test Playwright browser instances navigate to the gateway and make DOM assertions. +**Architecture:** pytest session fixtures start a mock OpenAI-compat HTTP server and the optimclaw binary (libSQL in-memory, gateway enabled), then per-test Playwright browser instances navigate to the gateway and make DOM assertions. **Tech Stack:** Python 3.11+, pytest, pytest-asyncio, playwright, aiohttp @@ -22,7 +22,7 @@ ```toml [project] -name = "ironclaw-e2e" +name = "optimclaw-e2e" version = "0.1.0" requires-python = ">=3.11" dependencies = [ @@ -78,7 +78,7 @@ The server must: - Handle `POST /v1/chat/completions` with both streaming and non-streaming modes - Handle `GET /v1/models` for health checks - Pattern-match the last user message to select canned responses -- Support `stream: true` with proper SSE chunk format (critical for IronClaw's streaming) +- Support `stream: true` with proper SSE chunk format (critical for OptimClaw's streaming) ```python """Mock OpenAI-compatible LLM server for E2E tests.""" @@ -340,7 +340,7 @@ git commit -m "feat: E2E helpers with DOM selectors and port discovery" **Step 1: Write the fixtures** Key details from codebase research: -- IronClaw logs `Web UI: http://{host}:{port}/` to stdout (main.rs:508) using the config port, not the bound port. So we must use a fixed port, not port 0. +- OptimClaw logs `Web UI: http://{host}:{port}/` to stdout (main.rs:508) using the config port, not the bound port. So we must use a fixed port, not port 0. - Health endpoint: `GET /api/health` (public, no auth required) - Auth via `?token=` query parameter for the frontend auto-auth flow - The frontend hides `#auth-screen` when token is valid and SSE connects @@ -348,7 +348,7 @@ Key details from codebase research: ```python """pytest fixtures for E2E tests. -Session-scoped: build binary, start mock LLM, start ironclaw. +Session-scoped: build binary, start mock LLM, start optimclaw. Function-scoped: fresh Playwright browser page per test. """ @@ -372,11 +372,11 @@ GATEWAY_PORT = 18_200 @pytest.fixture(scope="session") -def ironclaw_binary(): - """Ensure ironclaw binary is built. Returns the binary path.""" - binary = ROOT / "target" / "debug" / "ironclaw" +def optimclaw_binary(): + """Ensure optimclaw binary is built. Returns the binary path.""" + binary = ROOT / "target" / "debug" / "optimclaw" if not binary.exists(): - print("Building ironclaw (this may take a while)...") + print("Building optimclaw (this may take a while)...") subprocess.run( ["cargo", "build", "--no-default-features", "--features", "libsql"], cwd=ROOT, @@ -418,11 +418,11 @@ async def mock_llm_server(): @pytest.fixture(scope="session") -async def ironclaw_server(ironclaw_binary, mock_llm_server): - """Start the ironclaw gateway. Yields the base URL.""" +async def optimclaw_server(optimclaw_binary, mock_llm_server): + """Start the optimclaw gateway. Yields the base URL.""" env = { **os.environ, - "RUST_LOG": "ironclaw=info", + "RUST_LOG": "optimclaw=info", "GATEWAY_ENABLED": "true", "GATEWAY_HOST": "127.0.0.1", "GATEWAY_PORT": str(GATEWAY_PORT), @@ -443,7 +443,7 @@ async def ironclaw_server(ironclaw_binary, mock_llm_server): "ONBOARD_COMPLETED": "true", } proc = await asyncio.create_subprocess_exec( - ironclaw_binary, + optimclaw_binary, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, env=env, @@ -461,7 +461,7 @@ async def ironclaw_server(ironclaw_binary, mock_llm_server): @pytest.fixture -async def page(ironclaw_server): +async def page(optimclaw_server): """Fresh Playwright browser page, navigated to the gateway with auth.""" from playwright.async_api import async_playwright @@ -469,7 +469,7 @@ async def page(ironclaw_server): browser = await p.chromium.launch(headless=True) context = await browser.new_context(viewport={"width": 1280, "height": 720}) pg = await context.new_page() - await pg.goto(f"{ironclaw_server}/?token={AUTH_TOKEN}") + await pg.goto(f"{optimclaw_server}/?token={AUTH_TOKEN}") # Wait for the app to initialize (auth screen hidden, SSE connected) await pg.wait_for_selector("#auth-screen", state="hidden", timeout=15000) yield pg @@ -481,7 +481,7 @@ async def page(ironclaw_server): ```bash git add tests/e2e/conftest.py -git commit -m "feat: E2E conftest with session fixtures for mock LLM and ironclaw" +git commit -m "feat: E2E conftest with session fixtures for mock LLM and optimclaw" ``` --- @@ -529,23 +529,23 @@ async def test_tab_navigation(page): await chat_input.wait_for(state="visible", timeout=5000) -async def test_auth_rejection(page, ironclaw_server): +async def test_auth_rejection(page, optimclaw_server): """Navigating without a token shows the auth screen.""" # Open a new page without the token new_page = await page.context.new_page() - await new_page.goto(ironclaw_server) + await new_page.goto(optimclaw_server) auth_screen = new_page.locator(SEL["auth_screen"]) await auth_screen.wait_for(state="visible", timeout=10000) await new_page.close() ``` -**Step 2: Verify test runs (may fail if ironclaw isn't built yet -- that's OK)** +**Step 2: Verify test runs (may fail if optimclaw isn't built yet -- that's OK)** ```bash cd tests/e2e && python -m pytest scenarios/test_connection.py -v --timeout=120 ``` -Expected: Tests pass if ironclaw is built, or skip/fail gracefully if not. +Expected: Tests pass if optimclaw is built, or skip/fail gracefully if not. **Step 3: Commit** @@ -789,7 +789,7 @@ jobs: ~/.cargo/registry key: e2e-${{ runner.os }}-${{ hashFiles('Cargo.lock') }} - - name: Build ironclaw (libsql) + - name: Build optimclaw (libsql) run: cargo build --no-default-features --features libsql - uses: actions/setup-python@v5 @@ -831,14 +831,14 @@ git commit -m "ci: add weekly E2E test workflow with Playwright" **Step 1: Write the README** ```markdown -# IronClaw E2E Tests +# OptimClaw E2E Tests -Browser-level end-to-end tests for the IronClaw web gateway using Python + Playwright. +Browser-level end-to-end tests for the OptimClaw web gateway using Python + Playwright. ## Prerequisites - Python 3.11+ -- Rust toolchain (for building ironclaw) +- Rust toolchain (for building optimclaw) - Chromium (installed via Playwright) ## Setup @@ -849,9 +849,9 @@ pip install -e . playwright install chromium ``` -## Build ironclaw +## Build optimclaw -The tests need the ironclaw binary built with libsql support: +The tests need the optimclaw binary built with libsql support: ```bash cargo build --no-default-features --features libsql @@ -874,7 +874,7 @@ HEADED=1 pytest tests/e2e/scenarios/test_connection.py -v Tests start two subprocesses: 1. **Mock LLM** (`mock_llm.py`) -- fake OpenAI-compat server with canned responses -2. **IronClaw** -- the real binary with gateway enabled, pointing to the mock LLM +2. **OptimClaw** -- the real binary with gateway enabled, pointing to the mock LLM Then Playwright drives a headless Chromium browser against the gateway, making DOM assertions. @@ -905,7 +905,7 @@ git commit -m "docs: E2E test README with setup and usage instructions" ### Task 10: Integration test -- run all scenarios end-to-end -**Step 1: Build ironclaw** +**Step 1: Build optimclaw** ```bash cargo build --no-default-features --features libsql diff --git a/docs/smart-routing-spec.md b/docs/smart-routing-spec.md index 7690a6ce..b87375be 100644 --- a/docs/smart-routing-spec.md +++ b/docs/smart-routing-spec.md @@ -1,4 +1,4 @@ -# Smart Model Routing for IronClaw +# Smart Model Routing for OptimClaw **Status:** Implemented **Author:** Microwave diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 7450d255..3f462579 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ironclaw-fuzz" +name = "optimclaw-fuzz" version = "0.0.0" publish = false edition = "2021" @@ -11,7 +11,7 @@ cargo-fuzz = true libfuzzer-sys = "0.4" serde_json = "1" -[dependencies.ironclaw] +[dependencies.optimclaw] path = ".." [[bin]] diff --git a/fuzz/README.md b/fuzz/README.md index 2e0e46da..18edc4fc 100644 --- a/fuzz/README.md +++ b/fuzz/README.md @@ -1,8 +1,8 @@ -# IronClaw Fuzz Targets +# OptimClaw Fuzz Targets -Fuzz testing for IronClaw code paths that depend on the full crate, using [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz) (libFuzzer). +Fuzz testing for OptimClaw code paths that depend on the full crate, using [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz) (libFuzzer). -> **Note:** Safety-specific fuzz targets (sanitizer, validator, leak detector, credential detect) have moved to `crates/ironclaw_safety/fuzz/`. See that directory's README for details. +> **Note:** Safety-specific fuzz targets (sanitizer, validator, leak detector, credential detect) have moved to `crates/optimclaw_safety/fuzz/`. See that directory's README for details. ## Targets @@ -32,6 +32,6 @@ cargo +nightly fuzz run fuzz_tool_params -- -max_total_time=300 1. Create `fuzz/fuzz_targets/fuzz_.rs` following the existing pattern 2. Add a `[[bin]]` entry in `fuzz/Cargo.toml` 3. Create `fuzz/corpus/fuzz_/` for seed inputs -4. Exercise real IronClaw code paths, not just generic serde +4. Exercise real OptimClaw code paths, not just generic serde -For safety-only targets, add them to `crates/ironclaw_safety/fuzz/` instead. +For safety-only targets, add them to `crates/optimclaw_safety/fuzz/` instead. diff --git a/fuzz/fuzz_targets/fuzz_tool_params.rs b/fuzz/fuzz_targets/fuzz_tool_params.rs index b8b5d63d..edc13ded 100644 --- a/fuzz/fuzz_targets/fuzz_tool_params.rs +++ b/fuzz/fuzz_targets/fuzz_tool_params.rs @@ -1,6 +1,6 @@ #![no_main] -use ironclaw::safety::Validator; -use ironclaw::tools::validate_tool_schema; +use optimclaw::safety::Validator; +use optimclaw::tools::validate_tool_schema; use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { diff --git a/ironclaw.bash b/optimclaw.bash similarity index 100% rename from ironclaw.bash rename to optimclaw.bash diff --git a/ironclaw.fish b/optimclaw.fish similarity index 100% rename from ironclaw.fish rename to optimclaw.fish diff --git a/ironclaw.png b/optimclaw.png similarity index 100% rename from ironclaw.png rename to optimclaw.png diff --git a/ironclaw.zsh b/optimclaw.zsh similarity index 100% rename from ironclaw.zsh rename to optimclaw.zsh diff --git a/registry/channels/discord.json b/registry/channels/discord.json index dc545d75..1da19d28 100644 --- a/registry/channels/discord.json +++ b/registry/channels/discord.json @@ -18,7 +18,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/v0.19.0/channel-discord-0.2.1-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/v0.19.0/channel-discord-0.2.1-wasm32-wasip2.tar.gz", "sha256": "6159cb54aa44a9d8219e29bf0aea9404213b20ff567506fe75f23d4698d6ec18" } }, diff --git a/registry/channels/feishu.json b/registry/channels/feishu.json index a7530943..089d2191 100644 --- a/registry/channels/feishu.json +++ b/registry/channels/feishu.json @@ -20,7 +20,7 @@ "artifacts": { "wasm32-wasip2": { "sha256": "a66ff0dafb67d2216d8161bb7e96e724a94acb0ab993b85d2782d30412f8fe94", - "url": "https://github.com/nearai/ironclaw/releases/download/ironclaw-v0.22.0/channel-feishu-0.1.3-wasm32-wasip2.tar.gz" + "url": "https://github.com/nearai/optimclaw/releases/download/optimclaw-v0.22.0/channel-feishu-0.1.3-wasm32-wasip2.tar.gz" } }, "auth_summary": { diff --git a/registry/channels/slack.json b/registry/channels/slack.json index e6d36604..4486c380 100644 --- a/registry/channels/slack.json +++ b/registry/channels/slack.json @@ -18,7 +18,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/v0.18.0/slack-0.2.1-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/v0.18.0/slack-0.2.1-wasm32-wasip2.tar.gz", "sha256": "d4667e35126986509d862bc3a0088777305d8f41c75de83c1e223b42312ede48" } }, diff --git a/registry/channels/telegram.json b/registry/channels/telegram.json index 52f66ce3..b6c9cc29 100644 --- a/registry/channels/telegram.json +++ b/registry/channels/telegram.json @@ -18,7 +18,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/v0.20.0/channel-telegram-0.2.5-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/v0.20.0/channel-telegram-0.2.5-wasm32-wasip2.tar.gz", "sha256": "1ef20a538f55b379e049356e4d6758006251846bc3365ceaa1c87eba8379a329" } }, diff --git a/registry/channels/whatsapp.json b/registry/channels/whatsapp.json index be3faf0d..2e952ebf 100644 --- a/registry/channels/whatsapp.json +++ b/registry/channels/whatsapp.json @@ -18,7 +18,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/v0.18.0/whatsapp-0.2.0-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/v0.18.0/whatsapp-0.2.0-wasm32-wasip2.tar.gz", "sha256": "feb9194719d9bed796b070ab4dc30348dbfb5d3dec56f9f21e02d14137abab01" } }, diff --git a/registry/tools/github.json b/registry/tools/github.json index bb351259..f4151820 100644 --- a/registry/tools/github.json +++ b/registry/tools/github.json @@ -19,7 +19,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/ironclaw-v0.22.0/tool-github-0.2.2-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/optimclaw-v0.22.0/tool-github-0.2.2-wasm32-wasip2.tar.gz", "sha256": "70b55af593193d8fa495c0f702ea23284d83a624124f8a5f7564916ec5032c3f" } }, diff --git a/registry/tools/gmail.json b/registry/tools/gmail.json index c4772129..edfdee74 100644 --- a/registry/tools/gmail.json +++ b/registry/tools/gmail.json @@ -18,7 +18,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/ironclaw-v0.22.0/tool-gmail-0.2.1-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/optimclaw-v0.22.0/tool-gmail-0.2.1-wasm32-wasip2.tar.gz", "sha256": "79025b40ee70ce1120acc4320bae50da095d7afb0ef67bd56d99b064b72ea779" } }, diff --git a/registry/tools/google-calendar.json b/registry/tools/google-calendar.json index 73065a67..29044a98 100644 --- a/registry/tools/google-calendar.json +++ b/registry/tools/google-calendar.json @@ -18,7 +18,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/ironclaw-v0.22.0/tool-google-calendar-0.2.1-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/optimclaw-v0.22.0/tool-google-calendar-0.2.1-wasm32-wasip2.tar.gz", "sha256": "86bcc075010b08f5ab2f98f504cec1c6c9e0ca144857d185cbecf72a11f504bf" } }, diff --git a/registry/tools/google-docs.json b/registry/tools/google-docs.json index 02cc94fe..38861e24 100644 --- a/registry/tools/google-docs.json +++ b/registry/tools/google-docs.json @@ -18,7 +18,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/ironclaw-v0.22.0/tool-google-docs-0.2.1-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/optimclaw-v0.22.0/tool-google-docs-0.2.1-wasm32-wasip2.tar.gz", "sha256": "39d476029764949498a53a6a223f9952b5f4df151be7b8b19bf3fe4d401a57cd" } }, diff --git a/registry/tools/google-drive.json b/registry/tools/google-drive.json index 719690f7..768d741a 100644 --- a/registry/tools/google-drive.json +++ b/registry/tools/google-drive.json @@ -18,7 +18,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/ironclaw-v0.22.0/tool-google-drive-0.2.1-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/optimclaw-v0.22.0/tool-google-drive-0.2.1-wasm32-wasip2.tar.gz", "sha256": "6e9a700fab93865c852af718666af64c5b534ad6a419fb4b736e07740188f494" } }, diff --git a/registry/tools/google-sheets.json b/registry/tools/google-sheets.json index 09aae574..b5fe8476 100644 --- a/registry/tools/google-sheets.json +++ b/registry/tools/google-sheets.json @@ -18,7 +18,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/ironclaw-v0.22.0/tool-google-sheets-0.2.1-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/optimclaw-v0.22.0/tool-google-sheets-0.2.1-wasm32-wasip2.tar.gz", "sha256": "1f8c381799a916be83263cac9d497d52946e21b1b588592a3a42ca94a73b7051" } }, diff --git a/registry/tools/google-slides.json b/registry/tools/google-slides.json index 64bc0e45..8863b3b2 100644 --- a/registry/tools/google-slides.json +++ b/registry/tools/google-slides.json @@ -17,7 +17,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/ironclaw-v0.22.0/tool-google-slides-0.2.1-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/optimclaw-v0.22.0/tool-google-slides-0.2.1-wasm32-wasip2.tar.gz", "sha256": "e2528be5da02f1b8cfc8ee9b0cdd849516c53d412e2f75c6175b3bded7f512cb" } }, diff --git a/registry/tools/llm-context.json b/registry/tools/llm-context.json index 422f2e18..c44e8b31 100644 --- a/registry/tools/llm-context.json +++ b/registry/tools/llm-context.json @@ -21,7 +21,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/ironclaw-v0.22.0/tool-llm-context-0.1.1-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/optimclaw-v0.22.0/tool-llm-context-0.1.1-wasm32-wasip2.tar.gz", "sha256": "9b19e2fd05dbbbe3c8bd55309a91db09124e8415eb0f767828b6e10b55771e63" } }, diff --git a/registry/tools/slack.json b/registry/tools/slack.json index 236062a4..c0f477ba 100644 --- a/registry/tools/slack.json +++ b/registry/tools/slack.json @@ -17,7 +17,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/ironclaw-v0.22.0/tool-slack-0.2.1-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/optimclaw-v0.22.0/tool-slack-0.2.1-wasm32-wasip2.tar.gz", "sha256": "927519e5b7734beeb022d3b8bbd152e0e6b9f67c9452a8ad47809d3c4221a137" } }, diff --git a/registry/tools/telegram.json b/registry/tools/telegram.json index e684ca94..8910b9bc 100644 --- a/registry/tools/telegram.json +++ b/registry/tools/telegram.json @@ -18,7 +18,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/ironclaw-v0.22.0/tool-telegram-0.2.1-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/optimclaw-v0.22.0/tool-telegram-0.2.1-wasm32-wasip2.tar.gz", "sha256": "1e57d0755fc9c7b3ec013d079f30168898b484a6919f9edd105f0cd80131c1cd" } }, diff --git a/registry/tools/web-search.json b/registry/tools/web-search.json index 014466af..7e49f885 100644 --- a/registry/tools/web-search.json +++ b/registry/tools/web-search.json @@ -18,7 +18,7 @@ }, "artifacts": { "wasm32-wasip2": { - "url": "https://github.com/nearai/ironclaw/releases/download/ironclaw-v0.22.0/tool-web-search-0.2.2-wasm32-wasip2.tar.gz", + "url": "https://github.com/nearai/optimclaw/releases/download/optimclaw-v0.22.0/tool-web-search-0.2.2-wasm32-wasip2.tar.gz", "sha256": "47382b50c1ea7525b20d59dc02fab04e336d018665826c2f24710bdf460779ae" } }, diff --git a/skills/local-test/SKILL.md b/skills/local-test/SKILL.md index 37224c5a..e9070468 100644 --- a/skills/local-test/SKILL.md +++ b/skills/local-test/SKILL.md @@ -1,7 +1,7 @@ --- name: local-test version: 0.1.0 -description: Build, run, and test IronClaw locally using Docker containers and Chrome MCP browser automation. +description: Build, run, and test OptimClaw locally using Docker containers and Chrome MCP browser automation. activation: keywords: - test locally @@ -22,20 +22,20 @@ activation: # Local Testing with Docker + Chrome MCP -Use this skill to build, run, and test IronClaw web gateway changes locally using `Dockerfile.test` and Chrome MCP browser automation tools. +Use this skill to build, run, and test OptimClaw web gateway changes locally using `Dockerfile.test` and Chrome MCP browser automation tools. ## Quick Start ```bash # Build the test image (libsql-only, no PostgreSQL needed) -docker build --platform linux/amd64 -f Dockerfile.test -t ironclaw-test . +docker build --platform linux/amd64 -f Dockerfile.test -t optimclaw-test . # Run on port 3003 (default) docker run --rm -p 3003:3003 \ -e ONBOARD_COMPLETED=true \ -e CLI_ENABLED=false \ -e NEARAI_API_KEY= \ - ironclaw-test + optimclaw-test # Open in browser # http://localhost:3003/?token=test @@ -46,7 +46,7 @@ docker run --rm -p 3003:3003 \ The test Dockerfile uses a two-stage build: Rust compilation with `--features libsql` (no PostgreSQL dependency), then a minimal Debian runtime image. ```bash -docker build --platform linux/amd64 -f Dockerfile.test -t ironclaw-test . +docker build --platform linux/amd64 -f Dockerfile.test -t optimclaw-test . ``` Build takes ~5-10 minutes on first run (cached subsequent builds are faster). The `--platform linux/amd64` flag avoids QEMU warnings on Apple Silicon but can be omitted if targeting native architecture. @@ -70,7 +70,7 @@ docker run --rm -p 3003:3003 \ -e ONBOARD_COMPLETED=true \ -e CLI_ENABLED=false \ -e NEARAI_API_KEY= \ - ironclaw-test + optimclaw-test ``` **NEAR AI (session token mode):** @@ -80,7 +80,7 @@ docker run --rm -p 3003:3003 \ -e CLI_ENABLED=false \ -e NEARAI_SESSION_TOKEN= \ -e NEARAI_BASE_URL=https://private.near.ai \ - ironclaw-test + optimclaw-test ``` **OpenAI:** @@ -90,7 +90,7 @@ docker run --rm -p 3003:3003 \ -e CLI_ENABLED=false \ -e LLM_BACKEND=openai \ -e OPENAI_API_KEY= \ - ironclaw-test + optimclaw-test ``` **Anthropic:** @@ -100,7 +100,7 @@ docker run --rm -p 3003:3003 \ -e CLI_ENABLED=false \ -e LLM_BACKEND=anthropic \ -e ANTHROPIC_API_KEY= \ - ironclaw-test + optimclaw-test ``` **Dummy run (no LLM, just test the UI loads):** @@ -109,7 +109,7 @@ docker run --rm -p 3003:3003 \ -e ONBOARD_COMPLETED=true \ -e CLI_ENABLED=false \ -e NEARAI_API_KEY=dummy \ - ironclaw-test + optimclaw-test ``` ### Common Overrides @@ -119,7 +119,7 @@ docker run --rm -p 3003:3003 \ | `GATEWAY_PORT` | Change the listen port | `3003` (default) | | `GATEWAY_AUTH_TOKEN` | Auth token for API | `test` (default) | | `NEARAI_MODEL` | Override LLM model | `claude-3-5-sonnet-20241022` | -| `RUST_LOG` | Logging verbosity | `ironclaw=debug` | +| `RUST_LOG` | Logging verbosity | `optimclaw=debug` | | `ROUTINES_ENABLED` | Enable routines | `true`/`false` | | `SKILLS_ENABLED` | Enable skills system | `true` (default) | @@ -128,8 +128,8 @@ docker run --rm -p 3003:3003 \ Run multiple containers on different host ports: ```bash -docker run --rm -d --name ic-test-a -p 3003:3003 -e ONBOARD_COMPLETED=true -e CLI_ENABLED=false -e NEARAI_API_KEY=dummy ironclaw-test -docker run --rm -d --name ic-test-b -p 3004:3003 -e ONBOARD_COMPLETED=true -e CLI_ENABLED=false -e NEARAI_API_KEY=dummy ironclaw-test +docker run --rm -d --name ic-test-a -p 3003:3003 -e ONBOARD_COMPLETED=true -e CLI_ENABLED=false -e NEARAI_API_KEY=dummy optimclaw-test +docker run --rm -d --name ic-test-b -p 3004:3003 -e ONBOARD_COMPLETED=true -e CLI_ENABLED=false -e NEARAI_API_KEY=dummy optimclaw-test ``` ## Chrome MCP Testing Workflow @@ -195,10 +195,10 @@ Click tabs, send messages, search skills — use `computer` tool with `action=cl docker stop ic-test-a # Stop all test containers -docker ps --filter ancestor=ironclaw-test -q | xargs -r docker stop +docker ps --filter ancestor=optimclaw-test -q | xargs -r docker stop # Remove the test image -docker rmi ironclaw-test +docker rmi optimclaw-test ``` ## Troubleshooting diff --git a/skills/ironclaw-workflow-orchestrator/SKILL.md b/skills/optimclaw-workflow-orchestrator/SKILL.md similarity index 90% rename from skills/ironclaw-workflow-orchestrator/SKILL.md rename to skills/optimclaw-workflow-orchestrator/SKILL.md index 6c38767f..4bb5cc60 100644 --- a/skills/ironclaw-workflow-orchestrator/SKILL.md +++ b/skills/optimclaw-workflow-orchestrator/SKILL.md @@ -1,9 +1,9 @@ --- -name: ironclaw-workflow-orchestrator -description: "Install and operate a full GitHub issue-to-merge workflow in IronClaw using event-driven and cron routines. Use when setting up or tuning autonomous project orchestration: issue intake, planning, maintainer feedback handling, branch/PR execution, CI/comment follow-up, batched staging review every 8 hours, and memory updates from merge outcomes." +name: optimclaw-workflow-orchestrator +description: "Install and operate a full GitHub issue-to-merge workflow in OptimClaw using event-driven and cron routines. Use when setting up or tuning autonomous project orchestration: issue intake, planning, maintainer feedback handling, branch/PR execution, CI/comment follow-up, batched staging review every 8 hours, and memory updates from merge outcomes." --- -# IronClaw Workflow Orchestrator +# OptimClaw Workflow Orchestrator ## Overview Use this skill to install and maintain a complete project workflow as routines, not core code changes. It maps GitHub webhook events plus scheduled checks into plan/update/implement/review/merge loops with explicit staging-batch analysis. diff --git a/skills/ironclaw-workflow-orchestrator/agents/openai.yaml b/skills/optimclaw-workflow-orchestrator/agents/openai.yaml similarity index 78% rename from skills/ironclaw-workflow-orchestrator/agents/openai.yaml rename to skills/optimclaw-workflow-orchestrator/agents/openai.yaml index 3febe0ff..74011dc0 100644 --- a/skills/ironclaw-workflow-orchestrator/agents/openai.yaml +++ b/skills/optimclaw-workflow-orchestrator/agents/openai.yaml @@ -1,4 +1,4 @@ interface: - display_name: "IronClaw Workflow Orchestrator" + display_name: "OptimClaw Workflow Orchestrator" short_description: "Install and run event-driven GitHub workflow routines" default_prompt: "Set up the full issue-to-merge workflow using routines and event triggers." diff --git a/skills/ironclaw-workflow-orchestrator/references/workflow-routines.md b/skills/optimclaw-workflow-orchestrator/references/workflow-routines.md similarity index 100% rename from skills/ironclaw-workflow-orchestrator/references/workflow-routines.md rename to skills/optimclaw-workflow-orchestrator/references/workflow-routines.md diff --git a/skills/review-checklist/SKILL.md b/skills/review-checklist/SKILL.md index feafd52f..d6d60f9a 100644 --- a/skills/review-checklist/SKILL.md +++ b/skills/review-checklist/SKILL.md @@ -18,7 +18,7 @@ activation: # Pre-Merge Review Checklist -Before merging, verify these items. They represent the most common issues caught by automated code reviewers (Copilot, Gemini) on IronClaw PRs. +Before merging, verify these items. They represent the most common issues caught by automated code reviewers (Copilot, Gemini) on OptimClaw PRs. ## Database Operations - [ ] Multi-step DB operations are wrapped in transactions (INSERT+INSERT, UPDATE+DELETE, read-modify-write) diff --git a/skills/web-ui-test/SKILL.md b/skills/web-ui-test/SKILL.md index 4ebde0e5..522eb6e2 100644 --- a/skills/web-ui-test/SKILL.md +++ b/skills/web-ui-test/SKILL.md @@ -1,7 +1,7 @@ --- name: web-ui-test version: 0.1.0 -description: Test the IronClaw web UI using the Claude for Chrome browser extension. +description: Test the OptimClaw web UI using the Claude for Chrome browser extension. activation: keywords: - test web ui @@ -19,11 +19,11 @@ activation: # Web UI Testing with Claude for Chrome -Use this skill when manually testing the IronClaw web gateway UI via the Claude for Chrome browser extension. +Use this skill when manually testing the OptimClaw web gateway UI via the Claude for Chrome browser extension. ## Prerequisites -- IronClaw must be running with `GATEWAY_ENABLED=true` +- OptimClaw must be running with `GATEWAY_ENABLED=true` - Note the gateway URL (default: `http://127.0.0.1:3000/`) and auth token - The Claude for Chrome extension must be installed and connected @@ -33,7 +33,7 @@ Use this skill when manually testing the IronClaw web gateway UI via the Claude CLI_ENABLED=false GATEWAY_AUTH_TOKEN= cargo run ``` -Wait for "Agent ironclaw ready and listening" in the logs before proceeding. +Wait for "Agent optimclaw ready and listening" in the logs before proceeding. ## Test Checklist @@ -94,7 +94,7 @@ Wait for "Agent ironclaw ready and listening" in the logs before proceeding. After testing, remove any test-installed skills: ```bash -rm -rf ~/.ironclaw/installed_skills/ +rm -rf ~/.optimclaw/installed_skills/ ``` Stop the server with Ctrl+C or by killing the process. diff --git a/src/NETWORK_SECURITY.md b/src/NETWORK_SECURITY.md index 94611a0f..117589e4 100644 --- a/src/NETWORK_SECURITY.md +++ b/src/NETWORK_SECURITY.md @@ -1,6 +1,6 @@ -# IronClaw Network Security Reference +# OptimClaw Network Security Reference -This document catalogs every network-facing surface in IronClaw, its authentication mechanism, bind address, security controls, and known findings. Use this as the authoritative reference during code reviews that touch network-facing code. +This document catalogs every network-facing surface in OptimClaw, its authentication mechanism, bind address, security controls, and known findings. Use this as the authoritative reference during code reviews that touch network-facing code. **Last updated:** 2026-02-18 @@ -8,7 +8,7 @@ This document catalogs every network-facing surface in IronClaw, its authenticat ## Threat Model -IronClaw operates across four trust boundaries: +OptimClaw operates across four trust boundaries: | Boundary | Trust Level | Examples | |----------|------------|---------| @@ -21,7 +21,7 @@ IronClaw operates across four trust boundaries: - The local machine is single-user. The web gateway and OAuth listener bind to loopback and do not defend against other local users. - Docker containers are adversarial. A compromised container should not be able to access other jobs, exfiltrate secrets, or reach the host network beyond the orchestrator API. -- Webhook senders must prove knowledge of the shared secret. The secret is never transmitted in the clear by IronClaw itself. +- Webhook senders must prove knowledge of the shared secret. The secret is never transmitted in the clear by OptimClaw itself. - MCP server URLs are operator-configured and treated as trusted destinations (see [MCP Client](#mcp-client)). --- @@ -272,7 +272,7 @@ Both IPv4 and IPv6 loopback addresses are security-equivalent — they are only ### Lifecycle -The listener is **ephemeral** — it is started only when an OAuth flow is initiated (e.g., `ironclaw tool auth `) and shut down after the callback is received or the timeout expires. +The listener is **ephemeral** — it is started only when an OAuth flow is initiated (e.g., `optimclaw tool auth `) and shut down after the callback is received or the timeout expires. ### Timeout @@ -290,7 +290,7 @@ The listener is **ephemeral** — it is started only when an OAuth flow is initi ### Built-in OAuth Credentials -Google OAuth client ID and secret are compiled into the binary (with compile-time override via `IRONCLAW_GOOGLE_CLIENT_ID` / `IRONCLAW_GOOGLE_CLIENT_SECRET`). As noted in the source, Google Desktop App client secrets are [not actually secret](https://developers.google.com/identity/protocols/oauth2/native-app) per Google's documentation. +Google OAuth client ID and secret are compiled into the binary (with compile-time override via `OPTIMCLAW_GOOGLE_CLIENT_ID` / `OPTIMCLAW_GOOGLE_CLIENT_SECRET`). As noted in the source, Google Desktop App client secrets are [not actually secret](https://developers.google.com/identity/protocols/oauth2/native-app) per Google's documentation. **Reference:** `src/cli/oauth_defaults.rs` — `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET` constants @@ -427,7 +427,7 @@ The `http` tool (`src/tools/builtin/http.rs`) has its own SSRF protections: MCP servers are external processes accessed via HTTP. The MCP client (`src/tools/mcp/client.rs`) uses `reqwest` with a 30-second timeout but has **no SSRF protections** — it connects to whatever URL is configured for the MCP server. -This is by design: MCP server URLs come from **operator-controlled configuration** (config files, environment variables, or the CLI `tool install` command), not from user input or LLM output. A compromised config file is outside IronClaw's threat model — it would imply the operator's machine is already compromised. +This is by design: MCP server URLs come from **operator-controlled configuration** (config files, environment variables, or the CLI `tool install` command), not from user input or LLM output. A compromised config file is outside OptimClaw's threat model — it would imply the operator's machine is already compromised. **Reference:** `src/tools/mcp/client.rs` — `reqwest::Client` builder diff --git a/src/agent/commands.rs b/src/agent/commands.rs index 643d8c7c..ba565218 100644 --- a/src/agent/commands.rs +++ b/src/agent/commands.rs @@ -625,11 +625,11 @@ impl Agent { )); } // Environment check: restart is only available in Docker containers - let in_docker = std::env::var("IRONCLAW_IN_DOCKER") + let in_docker = std::env::var("OPTIMCLAW_IN_DOCKER") .map(|v| v.to_lowercase() == "true") .unwrap_or(false); - tracing::debug!("[commands::restart] IRONCLAW_IN_DOCKER={}", in_docker); + tracing::debug!("[commands::restart] OPTIMCLAW_IN_DOCKER={}", in_docker); if !in_docker { tracing::warn!( @@ -637,7 +637,7 @@ impl Agent { ); return Ok(SubmissionResult::error( "Restart is not available in this environment. \ - The IRONCLAW_IN_DOCKER environment variable must be set to 'true' for Docker deployments." + The OPTIMCLAW_IN_DOCKER environment variable must be set to 'true' for Docker deployments." .to_string(), )); } @@ -976,7 +976,7 @@ impl Agent { let model_owned = model.to_string(); let backend = self.deps.llm_backend.clone(); if let Err(e) = tokio::task::spawn_blocking(move || { - // 2a. Update the backend-specific model env var in ~/.ironclaw/.env. + // 2a. Update the backend-specific model env var in ~/.optimclaw/.env. // // Env vars have the HIGHEST priority in LlmConfig::resolve_model() // (env var > TOML > DB > default). If the .env file has e.g. @@ -988,7 +988,7 @@ impl Agent { // Only update the .env file if the var is actually set there // (avoid injecting new vars the user never configured). - let env_path = crate::bootstrap::ironclaw_env_path(); + let env_path = crate::bootstrap::optimclaw_env_path(); let env_has_var = std::fs::read_to_string(&env_path) .ok() .is_some_and(|content| { diff --git a/src/agent/job_monitor.rs b/src/agent/job_monitor.rs index e102dfbf..70191e4d 100644 --- a/src/agent/job_monitor.rs +++ b/src/agent/job_monitor.rs @@ -22,7 +22,7 @@ use uuid::Uuid; use crate::channels::IncomingMessage; use crate::context::{ContextManager, JobState}; -use ironclaw_common::AppEvent; +use optimclaw_common::AppEvent; /// Route context for forwarding job monitor events back to the user's channel. #[derive(Debug, Clone)] diff --git a/src/agent/routine.rs b/src/agent/routine.rs index 5a57a8a6..ba0118d5 100644 --- a/src/agent/routine.rs +++ b/src/agent/routine.rs @@ -760,7 +760,7 @@ mod tests { #[test] fn test_system_event_trigger_roundtrip() { let mut filters = std::collections::HashMap::new(); - filters.insert("repo".to_string(), "nearai/ironclaw".to_string()); + filters.insert("repo".to_string(), "nearai/optimclaw".to_string()); filters.insert("action".to_string(), "opened".to_string()); let trigger = Trigger::SystemEvent { source: "github".to_string(), diff --git a/src/agent/routine_engine.rs b/src/agent/routine_engine.rs index 3687ebd4..bed64eba 100644 --- a/src/agent/routine_engine.rs +++ b/src/agent/routine_engine.rs @@ -39,7 +39,7 @@ use crate::tools::{ prepare_tool_params, }; use crate::workspace::Workspace; -use ironclaw_safety::SafetyLayer; +use optimclaw_safety::SafetyLayer; enum EventMatcher { Message { routine: Routine, regex: Regex }, diff --git a/src/agent/session.rs b/src/agent/session.rs index 6c873e46..613fc885 100644 --- a/src/agent/session.rs +++ b/src/agent/session.rs @@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize}; use uuid::Uuid; use crate::llm::{ChatMessage, ToolCall, generate_tool_call_id}; -use ironclaw_common::truncate_preview; +use optimclaw_common::truncate_preview; /// A session containing one or more threads. #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/src/agent/thread_ops.rs b/src/agent/thread_ops.rs index af0bd67f..a431036b 100644 --- a/src/agent/thread_ops.rs +++ b/src/agent/thread_ops.rs @@ -21,7 +21,7 @@ use crate::context::JobContext; use crate::error::Error; use crate::llm::{ChatMessage, ToolCall}; use crate::tools::redact_params; -use ironclaw_common::truncate_preview; +use optimclaw_common::truncate_preview; const FORGED_THREAD_ID_ERROR: &str = "Invalid or unauthorized thread ID."; diff --git a/src/app.rs b/src/app.rs index 94262c3a..1819568e 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,4 +1,4 @@ -//! Application builder for initializing core IronClaw components. +//! Application builder for initializing core OptimClaw components. //! //! Extracts the mechanical initialization phases from `main.rs` into a //! reusable builder so that: @@ -602,7 +602,7 @@ impl AppBuilder { { tracing::warn!( "MCP server '{}' requires authentication. \ - Run: ironclaw mcp auth {}", + Run: optimclaw mcp auth {}", server_name, server_name ); diff --git a/src/boot_screen.rs b/src/boot_screen.rs index c018abf6..54e0da31 100644 --- a/src/boot_screen.rs +++ b/src/boot_screen.rs @@ -3,7 +3,7 @@ //! Shows a compact ANSI-styled status panel with three tiers: //! - **Tier 1 (always):** Name + version, model + backend. //! - **Tier 2 (conditional):** Gateway URL, tunnel URL, non-default channels. -//! - **Tier 3 (removed):** Database, tool count, features → use `ironclaw status`. +//! - **Tier 3 (removed):** Database, tool count, features → use `optimclaw status`. use crate::cli::fmt; @@ -42,7 +42,7 @@ const KW: usize = 10; /// /// **Tier 1 (always):** Name + version, model + backend. /// **Tier 2 (conditional):** Gateway URL, tunnel URL, non-default channels. -/// **Tier 3 (removed):** Database, tool count, features — use `ironclaw status`. +/// **Tier 3 (removed):** Database, tool count, features — use `optimclaw status`. pub fn print_boot_screen(info: &BootInfo) { let border = format!(" {}", fmt::separator(58)); @@ -236,9 +236,9 @@ pub fn print_boot_screen(info: &BootInfo) { println!(" {}ready in {}{}", fmt::dim(), elapsed_str, fmt::reset()); } - // Hint to run `ironclaw status` for full details + // Hint to run `optimclaw status` for full details println!( - " {}Run `ironclaw status` for full system details.{}", + " {}Run `optimclaw status` for full system details.{}", fmt::hint(), fmt::reset() ); @@ -255,7 +255,7 @@ mod tests { fn test_print_boot_screen_full() { let info = BootInfo { version: "0.2.0".to_string(), - agent_name: "ironclaw".to_string(), + agent_name: "optimclaw".to_string(), llm_backend: "nearai".to_string(), llm_model: "claude-3-5-sonnet-20241022".to_string(), cheap_model: Some("gpt-4o-mini".to_string()), @@ -289,7 +289,7 @@ mod tests { fn test_print_boot_screen_minimal() { let info = BootInfo { version: "0.2.0".to_string(), - agent_name: "ironclaw".to_string(), + agent_name: "optimclaw".to_string(), llm_backend: "nearai".to_string(), llm_model: "gpt-4o".to_string(), cheap_model: None, diff --git a/src/bootstrap.rs b/src/bootstrap.rs index a5c8ffdb..2ade709b 100644 --- a/src/bootstrap.rs +++ b/src/bootstrap.rs @@ -1,33 +1,33 @@ -//! Bootstrap helpers for IronClaw. +//! Bootstrap helpers for OptimClaw. //! //! The only setting that truly needs disk persistence before the database is //! available is `DATABASE_URL` (chicken-and-egg: can't connect to DB without //! it). Everything else is auto-detected or read from env vars. //! -//! File: `~/.ironclaw/.env` (standard dotenvy format) +//! File: `~/.optimclaw/.env` (standard dotenvy format) use std::path::PathBuf; use std::sync::LazyLock; -const IRONCLAW_BASE_DIR_ENV: &str = "IRONCLAW_BASE_DIR"; +const OPTIMCLAW_BASE_DIR_ENV: &str = "OPTIMCLAW_BASE_DIR"; -/// Lazily computed IronClaw base directory, cached for the lifetime of the process. -static IRONCLAW_BASE_DIR: LazyLock = LazyLock::new(compute_ironclaw_base_dir); +/// Lazily computed OptimClaw base directory, cached for the lifetime of the process. +static OPTIMCLAW_BASE_DIR: LazyLock = LazyLock::new(compute_optimclaw_base_dir); -/// Compute the IronClaw base directory from environment. +/// Compute the OptimClaw base directory from environment. /// /// This is the underlying implementation used by both the public -/// `ironclaw_base_dir()` function (which caches the result) and tests +/// `optimclaw_base_dir()` function (which caches the result) and tests /// (which need to verify different configurations). -pub fn compute_ironclaw_base_dir() -> PathBuf { - std::env::var(IRONCLAW_BASE_DIR_ENV) +pub fn compute_optimclaw_base_dir() -> PathBuf { + std::env::var(OPTIMCLAW_BASE_DIR_ENV) .map(PathBuf::from) .map(|path| { if path.as_os_str().is_empty() { default_base_dir() } else if !path.is_absolute() { eprintln!( - "Warning: IRONCLAW_BASE_DIR is a relative path '{}', resolved against current directory", + "Warning: OPTIMCLAW_BASE_DIR is a relative path '{}', resolved against current directory", path.display() ); path @@ -38,64 +38,64 @@ pub fn compute_ironclaw_base_dir() -> PathBuf { .unwrap_or_else(|_| default_base_dir()) } -/// Get the default IronClaw base directory (~/.ironclaw). +/// Get the default OptimClaw base directory (~/.optimclaw). /// /// Logs a warning if the home directory cannot be determined and falls back to /// the current directory. fn default_base_dir() -> PathBuf { if let Some(home) = dirs::home_dir() { - home.join(".ironclaw") + home.join(".optimclaw") } else { eprintln!("Warning: Could not determine home directory, using current directory"); std::env::current_dir() .unwrap_or_else(|_| PathBuf::from("/tmp")) - .join(".ironclaw") + .join(".optimclaw") } } -/// Get the IronClaw base directory. +/// Get the OptimClaw base directory. /// -/// Override with `IRONCLAW_BASE_DIR` environment variable. -/// Defaults to `~/.ironclaw` (or `./.ironclaw` if home directory cannot be determined). +/// Override with `OPTIMCLAW_BASE_DIR` environment variable. +/// Defaults to `~/.optimclaw` (or `./.optimclaw` if home directory cannot be determined). /// /// Thread-safe: the value is computed once and cached in a `LazyLock`. /// /// # Environment Variable Behavior -/// - If `IRONCLAW_BASE_DIR` is set to a non-empty path, that path is used. -/// - If `IRONCLAW_BASE_DIR` is set to an empty string, it is treated as unset. -/// - If `IRONCLAW_BASE_DIR` contains null bytes, a warning is printed and the default is used. +/// - If `OPTIMCLAW_BASE_DIR` is set to a non-empty path, that path is used. +/// - If `OPTIMCLAW_BASE_DIR` is set to an empty string, it is treated as unset. +/// - If `OPTIMCLAW_BASE_DIR` contains null bytes, a warning is printed and the default is used. /// - If the home directory cannot be determined, a warning is printed and the current directory is used. /// /// # Returns /// A `PathBuf` pointing to the base directory. The path is not validated /// for existence. -pub fn ironclaw_base_dir() -> PathBuf { - IRONCLAW_BASE_DIR.clone() +pub fn optimclaw_base_dir() -> PathBuf { + OPTIMCLAW_BASE_DIR.clone() } -/// Path to the IronClaw-specific `.env` file: `~/.ironclaw/.env`. -pub fn ironclaw_env_path() -> PathBuf { - ironclaw_base_dir().join(".env") +/// Path to the OptimClaw-specific `.env` file: `~/.optimclaw/.env`. +pub fn optimclaw_env_path() -> PathBuf { + optimclaw_base_dir().join(".env") } -/// Load env vars from `~/.ironclaw/.env` (in addition to the standard `.env`). +/// Load env vars from `~/.optimclaw/.env` (in addition to the standard `.env`). /// /// Call this **after** `dotenvy::dotenv()` so that the standard `./.env` -/// takes priority over `~/.ironclaw/.env`. dotenvy never overwrites +/// takes priority over `~/.optimclaw/.env`. dotenvy never overwrites /// existing env vars, so the effective priority is: /// -/// explicit env vars > `./.env` > `~/.ironclaw/.env` > auto-detect +/// explicit env vars > `./.env` > `~/.optimclaw/.env` > auto-detect /// -/// If `~/.ironclaw/.env` doesn't exist but the legacy `bootstrap.json` does, +/// If `~/.optimclaw/.env` doesn't exist but the legacy `bootstrap.json` does, /// extracts `DATABASE_URL` from it and writes the `.env` file (one-time /// upgrade from the old config format). /// /// After loading the `.env` file, auto-detects the libsql backend: if -/// `DATABASE_BACKEND` is still unset and `~/.ironclaw/ironclaw.db` exists, +/// `DATABASE_BACKEND` is still unset and `~/.optimclaw/optimclaw.db` exists, /// defaults to `libsql` so cloud instances work out of the box without any /// manual configuration. -pub fn load_ironclaw_env() { - let path = ironclaw_env_path(); +pub fn load_optimclaw_env() { + let path = optimclaw_env_path(); if !path.exists() { // One-time upgrade: extract DATABASE_URL from legacy bootstrap.json @@ -109,18 +109,18 @@ pub fn load_ironclaw_env() { // Auto-detect libsql: if DATABASE_BACKEND is still unset after loading // all env files, and the local SQLite DB exists, default to libsql. // This avoids the chicken-and-egg problem on cloud instances where no - // DATABASE_URL is configured but ironclaw.db is already present. + // DATABASE_URL is configured but optimclaw.db is already present. if std::env::var("DATABASE_BACKEND").is_err() { let default_db = dirs::home_dir() .unwrap_or_default() - .join(".ironclaw") - .join("ironclaw.db"); + .join(".optimclaw") + .join("optimclaw.db"); if default_db.exists() { if tokio::runtime::Handle::try_current().is_ok() { // Tokio runtime is active (multi-threaded); std::env::set_var is UB here. // Fall back to the thread-safe runtime overlay so the value is always set. tracing::warn!( - "load_ironclaw_env called with active Tokio runtime; \ + "load_optimclaw_env called with active Tokio runtime; \ using runtime env overlay for DATABASE_BACKEND" ); crate::config::set_runtime_env("DATABASE_BACKEND", "libsql"); @@ -134,10 +134,10 @@ pub fn load_ironclaw_env() { /// If `bootstrap.json` exists, pull `database_url` out of it and write `.env`. fn migrate_bootstrap_json_to_env(env_path: &std::path::Path) { - let ironclaw_dir = env_path + let optimclaw_dir = env_path .parent() .unwrap_or_else(|| std::path::Path::new(".")); - let bootstrap_path = ironclaw_dir.join("bootstrap.json"); + let bootstrap_path = optimclaw_dir.join("bootstrap.json"); if !bootstrap_path.exists() { return; @@ -173,7 +173,7 @@ fn migrate_bootstrap_json_to_env(env_path: &std::path::Path) { } } -/// Write database bootstrap vars to `~/.ironclaw/.env`. +/// Write database bootstrap vars to `~/.optimclaw/.env`. /// /// These settings form the chicken-and-egg layer: they must be available /// from the filesystem (env vars) BEFORE any database connection, because @@ -184,7 +184,7 @@ fn migrate_bootstrap_json_to_env(env_path: &std::path::Path) { /// Values are double-quoted so that `#` (common in URL-encoded passwords) /// and other shell-special characters are preserved by dotenvy. pub fn save_bootstrap_env(vars: &[(&str, &str)]) -> std::io::Result<()> { - save_bootstrap_env_to(&ironclaw_env_path(), vars) + save_bootstrap_env_to(&optimclaw_env_path(), vars) } /// Write bootstrap vars to an arbitrary path (testable variant). @@ -207,13 +207,13 @@ pub fn save_bootstrap_env_to(path: &std::path::Path, vars: &[(&str, &str)]) -> s Ok(()) } -/// Update or add multiple variables in `~/.ironclaw/.env`, preserving existing content. +/// Update or add multiple variables in `~/.optimclaw/.env`, preserving existing content. /// /// Like `upsert_bootstrap_var` but batched — replaces lines for any key in `vars` /// and preserves all other existing lines. Use this instead of `save_bootstrap_env` /// when you want to update specific keys without destroying user-added variables. pub fn upsert_bootstrap_vars(vars: &[(&str, &str)]) -> std::io::Result<()> { - upsert_bootstrap_vars_to(&ironclaw_env_path(), vars) + upsert_bootstrap_vars_to(&optimclaw_env_path(), vars) } /// Update or add multiple variables at an arbitrary path (testable variant). @@ -259,14 +259,14 @@ pub fn upsert_bootstrap_vars_to( Ok(()) } -/// Update or add a single variable in `~/.ironclaw/.env`, preserving existing content. +/// Update or add a single variable in `~/.optimclaw/.env`, preserving existing content. /// /// Unlike `save_bootstrap_env` (which overwrites the entire file), this /// reads the current `.env`, replaces the line for `key` if it exists, /// or appends it otherwise. Use this when writing a single bootstrap var /// outside the wizard (which manages the full set via `save_bootstrap_env`). pub fn upsert_bootstrap_var(key: &str, value: &str) -> std::io::Result<()> { - upsert_bootstrap_var_to(&ironclaw_env_path(), key, value) + upsert_bootstrap_var_to(&optimclaw_env_path(), key, value) } /// Update or add a single variable at an arbitrary path (testable variant). @@ -325,7 +325,7 @@ fn restrict_file_permissions(_path: &std::path::Path) -> std::io::Result<()> { Ok(()) } -/// Write `DATABASE_URL` to `~/.ironclaw/.env`. +/// Write `DATABASE_URL` to `~/.optimclaw/.env`. /// /// Convenience wrapper around `save_bootstrap_env` for single-value migration /// paths. Prefer `save_bootstrap_env` for new code. @@ -333,7 +333,7 @@ pub fn save_database_url(url: &str) -> std::io::Result<()> { save_bootstrap_env(&[("DATABASE_URL", url)]) } -/// One-time migration of legacy `~/.ironclaw/settings.json` into the database. +/// One-time migration of legacy `~/.optimclaw/settings.json` into the database. /// /// Only runs when a `settings.json` exists on disk AND the DB has no settings /// yet. After the wizard writes directly to the DB, this path is only hit by @@ -344,8 +344,8 @@ pub async fn migrate_disk_to_db( store: &dyn crate::db::Database, user_id: &str, ) -> Result<(), MigrationError> { - let ironclaw_dir = ironclaw_base_dir(); - let legacy_settings_path = ironclaw_dir.join("settings.json"); + let optimclaw_dir = optimclaw_base_dir(); + let legacy_settings_path = optimclaw_dir.join("settings.json"); if !legacy_settings_path.exists() { tracing::debug!("No legacy settings.json found, skipping disk-to-DB migration"); @@ -378,15 +378,15 @@ pub async fn migrate_disk_to_db( tracing::info!("Migrated {} settings to database", db_map.len()); } - // 2. Write DATABASE_URL to ~/.ironclaw/.env + // 2. Write DATABASE_URL to ~/.optimclaw/.env if let Some(ref url) = settings.database_url { save_database_url(url) .map_err(|e| MigrationError::Io(format!("Failed to write .env: {}", e)))?; - tracing::info!("Wrote DATABASE_URL to {}", ironclaw_env_path().display()); + tracing::info!("Wrote DATABASE_URL to {}", optimclaw_env_path().display()); } // 3. Migrate mcp-servers.json if it exists - let mcp_path = ironclaw_dir.join("mcp-servers.json"); + let mcp_path = optimclaw_dir.join("mcp-servers.json"); if mcp_path.exists() { match std::fs::read_to_string(&mcp_path) { Ok(content) => match serde_json::from_str::(&content) { @@ -415,7 +415,7 @@ pub async fn migrate_disk_to_db( } // 4. Migrate session.json if it exists - let session_path = ironclaw_dir.join("session.json"); + let session_path = optimclaw_dir.join("session.json"); if session_path.exists() { match std::fs::read_to_string(&session_path) { Ok(content) => match serde_json::from_str::(&content) { @@ -447,7 +447,7 @@ pub async fn migrate_disk_to_db( rename_to_migrated(&legacy_settings_path); // 6. Clean up old bootstrap.json if it exists (superseded by .env) - let old_bootstrap = ironclaw_dir.join("bootstrap.json"); + let old_bootstrap = optimclaw_dir.join("bootstrap.json"); if old_bootstrap.exists() { rename_to_migrated(&old_bootstrap); tracing::info!("Renamed old bootstrap.json to .migrated"); @@ -477,12 +477,12 @@ pub enum MigrationError { // ── PID Lock ────────────────────────────────────────────────────────────── -/// Path to the PID lock file: `~/.ironclaw/ironclaw.pid`. +/// Path to the PID lock file: `~/.optimclaw/optimclaw.pid`. pub fn pid_lock_path() -> PathBuf { - ironclaw_base_dir().join("ironclaw.pid") + optimclaw_base_dir().join("optimclaw.pid") } -/// A PID-based lock that prevents multiple IronClaw instances from running +/// A PID-based lock that prevents multiple OptimClaw instances from running /// simultaneously. /// /// Uses `fs4::try_lock_exclusive()` for atomic locking (no TOCTOU race), @@ -499,7 +499,7 @@ pub struct PidLock { /// Errors from PID lock acquisition. #[derive(Debug, thiserror::Error)] pub enum PidLockError { - #[error("Another IronClaw instance is already running (PID {pid})")] + #[error("Another OptimClaw instance is already running (PID {pid})")] AlreadyRunning { pid: u32 }, #[error("Failed to acquire PID lock: {0}")] Io(#[from] std::io::Error), @@ -580,14 +580,14 @@ mod tests { let env_path = dir.path().join(".env"); // Write in the quoted format that save_database_url uses - let url = "postgres://localhost:5432/ironclaw_test"; + let url = "postgres://localhost:5432/optimclaw_test"; std::fs::write(&env_path, format!("DATABASE_URL=\"{}\"\n", url)).unwrap(); // Verify the content is a valid dotenv line (quoted) let content = std::fs::read_to_string(&env_path).unwrap(); assert_eq!( content, - "DATABASE_URL=\"postgres://localhost:5432/ironclaw_test\"\n" + "DATABASE_URL=\"postgres://localhost:5432/optimclaw_test\"\n" ); // Verify dotenvy can parse it (strips quotes automatically) @@ -607,7 +607,7 @@ mod tests { // URLs with # in the password are common (URL-encoded special chars). // Without quoting, dotenvy treats # as a comment delimiter. - let url = "postgres://user:p%23ss@localhost:5432/ironclaw"; + let url = "postgres://user:p%23ss@localhost:5432/optimclaw"; std::fs::write(&env_path, format!("DATABASE_URL=\"{}\"\n", url)).unwrap(); let parsed: Vec<(String, String)> = dotenvy::from_path_iter(&env_path) @@ -666,23 +666,23 @@ INJECTED="pwned"#; } #[test] - fn test_ironclaw_env_path() { - // Use compute_ironclaw_base_dir() directly to avoid LazyLock caching, + fn test_optimclaw_env_path() { + // Use compute_optimclaw_base_dir() directly to avoid LazyLock caching, // which can be poisoned by whichever test initializes it first. let _guard = lock_env(); - let old_val = std::env::var("IRONCLAW_BASE_DIR").ok(); + let old_val = std::env::var("OPTIMCLAW_BASE_DIR").ok(); // SAFETY: Under lock_env(), no concurrent env access. - unsafe { std::env::remove_var("IRONCLAW_BASE_DIR") }; + unsafe { std::env::remove_var("OPTIMCLAW_BASE_DIR") }; - let path = compute_ironclaw_base_dir().join(".env"); + let path = compute_optimclaw_base_dir().join(".env"); assert!( - path.ends_with(".ironclaw/.env"), - "expected path ending with .ironclaw/.env, got: {}", + path.ends_with(".optimclaw/.env"), + "expected path ending with .optimclaw/.env, got: {}", path.display() ); if let Some(val) = old_val { - unsafe { std::env::set_var("IRONCLAW_BASE_DIR", val) }; + unsafe { std::env::set_var("OPTIMCLAW_BASE_DIR", val) }; } } @@ -694,7 +694,7 @@ INJECTED="pwned"#; // Write a legacy bootstrap.json let bootstrap_json = serde_json::json!({ - "database_url": "postgres://localhost/ironclaw_upgrade", + "database_url": "postgres://localhost/optimclaw_upgrade", "database_pool_size": 5, "secrets_master_key_source": "keychain", "onboard_completed": true @@ -716,7 +716,7 @@ INJECTED="pwned"#; let content = std::fs::read_to_string(&env_path).unwrap(); assert_eq!( content, - "DATABASE_URL=\"postgres://localhost/ironclaw_upgrade\"\n" + "DATABASE_URL=\"postgres://localhost/optimclaw_upgrade\"\n" ); // bootstrap.json should be renamed to .migrated @@ -769,7 +769,7 @@ INJECTED="pwned"#; let vars = [ ("DATABASE_BACKEND", "libsql"), - ("LIBSQL_PATH", "/home/user/.ironclaw/ironclaw.db"), + ("LIBSQL_PATH", "/home/user/.optimclaw/optimclaw.db"), ]; // Write manually to the temp path (save_bootstrap_env uses the global path) @@ -793,7 +793,7 @@ INJECTED="pwned"#; parsed[1], ( "LIBSQL_PATH".to_string(), - "/home/user/.ironclaw/ironclaw.db".to_string() + "/home/user/.optimclaw/optimclaw.db".to_string() ) ); } @@ -855,7 +855,7 @@ INJECTED="pwned"#; unsafe { std::env::remove_var("DATABASE_BACKEND") }; let dir = tempdir().unwrap(); - let db_path = dir.path().join("ironclaw.db"); + let db_path = dir.path().join("optimclaw.db"); // No DB file — auto-detect guard should not trigger. assert!(!db_path.exists()); @@ -926,7 +926,7 @@ INJECTED="pwned"#; unsafe { std::env::set_var("DATABASE_BACKEND", "postgres") }; let dir = tempdir().unwrap(); - let db_path = dir.path().join("ironclaw.db"); + let db_path = dir.path().join("optimclaw.db"); std::fs::write(&db_path, "").unwrap(); // The guard: only sets libsql if DATABASE_BACKEND is NOT already set. @@ -1044,102 +1044,102 @@ INJECTED="pwned"#; } #[test] - fn test_ironclaw_base_dir_default() { + fn test_optimclaw_base_dir_default() { // This test must run first (or in isolation) before the LazyLock is initialized. - // It verifies that when IRONCLAW_BASE_DIR is not set, the default path is used. + // It verifies that when OPTIMCLAW_BASE_DIR is not set, the default path is used. let _guard = lock_env(); - let old_val = std::env::var("IRONCLAW_BASE_DIR").ok(); + let old_val = std::env::var("OPTIMCLAW_BASE_DIR").ok(); // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::remove_var("IRONCLAW_BASE_DIR") }; + unsafe { std::env::remove_var("OPTIMCLAW_BASE_DIR") }; // Force re-evaluation by calling the computation function directly - let path = compute_ironclaw_base_dir(); + let path = compute_optimclaw_base_dir(); let home = dirs::home_dir().unwrap_or_else(|| std::path::PathBuf::from(".")); - assert_eq!(path, home.join(".ironclaw")); + assert_eq!(path, home.join(".optimclaw")); if let Some(val) = old_val { // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::set_var("IRONCLAW_BASE_DIR", val) }; + unsafe { std::env::set_var("OPTIMCLAW_BASE_DIR", val) }; } } #[test] - fn test_ironclaw_base_dir_env_override() { - // This test verifies that when IRONCLAW_BASE_DIR is set, + fn test_optimclaw_base_dir_env_override() { + // This test verifies that when OPTIMCLAW_BASE_DIR is set, // the custom path is used. Must run before LazyLock is initialized. let _guard = lock_env(); - let old_val = std::env::var("IRONCLAW_BASE_DIR").ok(); + let old_val = std::env::var("OPTIMCLAW_BASE_DIR").ok(); // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::set_var("IRONCLAW_BASE_DIR", "/custom/ironclaw/path") }; + unsafe { std::env::set_var("OPTIMCLAW_BASE_DIR", "/custom/optimclaw/path") }; // Force re-evaluation by calling the computation function directly - let path = compute_ironclaw_base_dir(); - assert_eq!(path, std::path::PathBuf::from("/custom/ironclaw/path")); + let path = compute_optimclaw_base_dir(); + assert_eq!(path, std::path::PathBuf::from("/custom/optimclaw/path")); if let Some(val) = old_val { // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::set_var("IRONCLAW_BASE_DIR", val) }; + unsafe { std::env::set_var("OPTIMCLAW_BASE_DIR", val) }; } else { // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::remove_var("IRONCLAW_BASE_DIR") }; + unsafe { std::env::remove_var("OPTIMCLAW_BASE_DIR") }; } } #[test] fn test_compute_base_dir_env_path_join() { - // Verifies that ironclaw_env_path correctly joins .env to the base dir. - // Uses compute_ironclaw_base_dir directly to avoid LazyLock caching. + // Verifies that optimclaw_env_path correctly joins .env to the base dir. + // Uses compute_optimclaw_base_dir directly to avoid LazyLock caching. let _guard = lock_env(); - let old_val = std::env::var("IRONCLAW_BASE_DIR").ok(); + let old_val = std::env::var("OPTIMCLAW_BASE_DIR").ok(); // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::set_var("IRONCLAW_BASE_DIR", "/my/custom/dir") }; + unsafe { std::env::set_var("OPTIMCLAW_BASE_DIR", "/my/custom/dir") }; // Test the path construction logic directly - let base_path = compute_ironclaw_base_dir(); + let base_path = compute_optimclaw_base_dir(); let env_path = base_path.join(".env"); assert_eq!(env_path, std::path::PathBuf::from("/my/custom/dir/.env")); if let Some(val) = old_val { // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::set_var("IRONCLAW_BASE_DIR", val) }; + unsafe { std::env::set_var("OPTIMCLAW_BASE_DIR", val) }; } else { // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::remove_var("IRONCLAW_BASE_DIR") }; + unsafe { std::env::remove_var("OPTIMCLAW_BASE_DIR") }; } } #[test] - fn test_ironclaw_base_dir_empty_env() { - // Verifies that empty IRONCLAW_BASE_DIR falls back to default. + fn test_optimclaw_base_dir_empty_env() { + // Verifies that empty OPTIMCLAW_BASE_DIR falls back to default. let _guard = lock_env(); - let old_val = std::env::var("IRONCLAW_BASE_DIR").ok(); + let old_val = std::env::var("OPTIMCLAW_BASE_DIR").ok(); // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::set_var("IRONCLAW_BASE_DIR", "") }; + unsafe { std::env::set_var("OPTIMCLAW_BASE_DIR", "") }; // Force re-evaluation by calling the computation function directly - let path = compute_ironclaw_base_dir(); + let path = compute_optimclaw_base_dir(); let home = dirs::home_dir().unwrap_or_else(|| std::path::PathBuf::from(".")); - assert_eq!(path, home.join(".ironclaw")); + assert_eq!(path, home.join(".optimclaw")); if let Some(val) = old_val { // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::set_var("IRONCLAW_BASE_DIR", val) }; + unsafe { std::env::set_var("OPTIMCLAW_BASE_DIR", val) }; } else { // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::remove_var("IRONCLAW_BASE_DIR") }; + unsafe { std::env::remove_var("OPTIMCLAW_BASE_DIR") }; } } #[test] - fn test_ironclaw_base_dir_special_chars() { + fn test_optimclaw_base_dir_special_chars() { // Verifies that paths with special characters are handled correctly. let _guard = lock_env(); - let old_val = std::env::var("IRONCLAW_BASE_DIR").ok(); + let old_val = std::env::var("OPTIMCLAW_BASE_DIR").ok(); // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::set_var("IRONCLAW_BASE_DIR", "/tmp/test_with-special.chars") }; + unsafe { std::env::set_var("OPTIMCLAW_BASE_DIR", "/tmp/test_with-special.chars") }; // Force re-evaluation by calling the computation function directly - let path = compute_ironclaw_base_dir(); + let path = compute_optimclaw_base_dir(); assert_eq!( path, std::path::PathBuf::from("/tmp/test_with-special.chars") @@ -1147,10 +1147,10 @@ INJECTED="pwned"#; if let Some(val) = old_val { // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::set_var("IRONCLAW_BASE_DIR", val) }; + unsafe { std::env::set_var("OPTIMCLAW_BASE_DIR", val) }; } else { // SAFETY: ENV_MUTEX ensures single-threaded access to env vars in tests - unsafe { std::env::remove_var("IRONCLAW_BASE_DIR") }; + unsafe { std::env::remove_var("OPTIMCLAW_BASE_DIR") }; } } @@ -1159,7 +1159,7 @@ INJECTED="pwned"#; #[test] fn test_pid_lock_acquire_and_drop() { let dir = tempdir().unwrap(); - let pid_path = dir.path().join("ironclaw.pid"); + let pid_path = dir.path().join("optimclaw.pid"); // Acquire lock let lock = PidLock::acquire_at(pid_path.clone()).unwrap(); @@ -1177,7 +1177,7 @@ INJECTED="pwned"#; #[test] fn test_pid_lock_rejects_second_acquire() { let dir = tempdir().unwrap(); - let pid_path = dir.path().join("ironclaw.pid"); + let pid_path = dir.path().join("optimclaw.pid"); // First lock succeeds let _lock1 = PidLock::acquire_at(pid_path.clone()).unwrap(); @@ -1196,7 +1196,7 @@ INJECTED="pwned"#; #[test] fn test_pid_lock_reclaims_after_drop() { let dir = tempdir().unwrap(); - let pid_path = dir.path().join("ironclaw.pid"); + let pid_path = dir.path().join("optimclaw.pid"); // Acquire and release let lock = PidLock::acquire_at(pid_path.clone()).unwrap(); @@ -1210,7 +1210,7 @@ INJECTED="pwned"#; #[test] fn test_pid_lock_reclaims_stale_file_without_flock() { let dir = tempdir().unwrap(); - let pid_path = dir.path().join("ironclaw.pid"); + let pid_path = dir.path().join("optimclaw.pid"); // Write a stale PID file manually (no flock held) std::fs::write(&pid_path, "4294967294").unwrap(); @@ -1225,7 +1225,7 @@ INJECTED="pwned"#; #[test] fn test_pid_lock_handles_corrupt_pid_file() { let dir = tempdir().unwrap(); - let pid_path = dir.path().join("ironclaw.pid"); + let pid_path = dir.path().join("optimclaw.pid"); // Write garbage (no flock held) std::fs::write(&pid_path, "not-a-number").unwrap(); @@ -1238,7 +1238,7 @@ INJECTED="pwned"#; #[test] fn test_pid_lock_creates_parent_dirs() { let dir = tempdir().unwrap(); - let pid_path = dir.path().join("nested").join("deep").join("ironclaw.pid"); + let pid_path = dir.path().join("nested").join("deep").join("optimclaw.pid"); let lock = PidLock::acquire_at(pid_path.clone()).unwrap(); assert!(pid_path.exists()); @@ -1247,14 +1247,14 @@ INJECTED="pwned"#; #[test] fn test_pid_lock_child_helper_holds_lock() { - if std::env::var("IRONCLAW_PID_LOCK_CHILD").ok().as_deref() != Some("1") { + if std::env::var("OPTIMCLAW_PID_LOCK_CHILD").ok().as_deref() != Some("1") { return; } let pid_path = PathBuf::from( - std::env::var("IRONCLAW_PID_LOCK_PATH").expect("IRONCLAW_PID_LOCK_PATH missing"), + std::env::var("OPTIMCLAW_PID_LOCK_PATH").expect("OPTIMCLAW_PID_LOCK_PATH missing"), ); - let hold_ms = std::env::var("IRONCLAW_PID_LOCK_HOLD_MS") + let hold_ms = std::env::var("OPTIMCLAW_PID_LOCK_HOLD_MS") .ok() .and_then(|s| s.parse::().ok()) .unwrap_or(3000); @@ -1266,7 +1266,7 @@ INJECTED="pwned"#; #[test] fn test_pid_lock_rejects_lock_held_by_other_process() { let dir = tempdir().unwrap(); - let pid_path = dir.path().join("ironclaw.pid"); + let pid_path = dir.path().join("optimclaw.pid"); let current_exe = std::env::current_exe().unwrap(); let mut child = Command::new(current_exe) @@ -1276,9 +1276,9 @@ INJECTED="pwned"#; "--nocapture", "--test-threads=1", ]) - .env("IRONCLAW_PID_LOCK_CHILD", "1") - .env("IRONCLAW_PID_LOCK_PATH", pid_path.display().to_string()) - .env("IRONCLAW_PID_LOCK_HOLD_MS", "3000") + .env("OPTIMCLAW_PID_LOCK_CHILD", "1") + .env("OPTIMCLAW_PID_LOCK_PATH", pid_path.display().to_string()) + .env("OPTIMCLAW_PID_LOCK_HOLD_MS", "3000") .spawn() .unwrap(); diff --git a/src/channels/channel.rs b/src/channels/channel.rs index 784b6bcf..7cbd8979 100644 --- a/src/channels/channel.rs +++ b/src/channels/channel.rs @@ -73,7 +73,7 @@ pub struct IncomingMessage { /// configured owner is speaking; otherwise it can be a guest/sender-scoped /// identifier to preserve isolation. pub user_id: String, - /// Stable instance owner scope for this IronClaw deployment. + /// Stable instance owner scope for this OptimClaw deployment. pub owner_id: String, /// Channel-specific sender/actor identifier. pub sender_id: String, diff --git a/src/channels/relay/client.rs b/src/channels/relay/client.rs index 1bc60a56..061f70f7 100644 --- a/src/channels/relay/client.rs +++ b/src/channels/relay/client.rs @@ -119,7 +119,7 @@ impl RelayClient { /// Calls `GET /oauth/slack/auth` with `redirect(Policy::none())` and /// returns the `Location` header (Slack OAuth URL) without following it. /// Initiate Slack OAuth. Channel-relay derives all URLs from the trusted - /// instance_url in chat-api. IronClaw only passes an optional CSRF nonce + /// instance_url in chat-api. OptimClaw only passes an optional CSRF nonce /// for validating the callback — no URLs. pub async fn initiate_oauth(&self, state_nonce: Option<&str>) -> Result { let url = format!("{}/oauth/slack/auth", self.base_url); diff --git a/src/channels/relay/mod.rs b/src/channels/relay/mod.rs index 05f5870c..2251e007 100644 --- a/src/channels/relay/mod.rs +++ b/src/channels/relay/mod.rs @@ -2,7 +2,7 @@ //! (Slack) via the channel-relay service. //! //! The relay service handles OAuth, credential storage, and webhook ingestion. -//! IronClaw receives events via webhook callbacks and sends messages via the +//! OptimClaw receives events via webhook callbacks and sends messages via the //! relay's proxy API. pub mod channel; diff --git a/src/channels/repl.rs b/src/channels/repl.rs index 27b6ea40..9efc9ef1 100644 --- a/src/channels/repl.rs +++ b/src/channels/repl.rs @@ -39,7 +39,7 @@ use tokio::sync::mpsc; use tokio_stream::wrappers::ReceiverStream; use crate::agent::truncate_for_preview; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::channels::{Channel, IncomingMessage, MessageStream, OutgoingResponse, StatusUpdate}; use crate::cli::fmt; use crate::error::ChannelError; @@ -459,7 +459,7 @@ fn print_help() { let hi = fmt::hint(); println!(); - println!(" {h}IronClaw REPL{r}"); + println!(" {h}OptimClaw REPL{r}"); println!(); println!(" {h}Quick start{r}"); println!(" {c}/new{r} {hi}Start a new thread{r}"); @@ -479,9 +479,9 @@ fn print_help() { println!(); } -/// Get the history file path (~/.ironclaw/history). +/// Get the history file path (~/.optimclaw/history). fn history_path() -> std::path::PathBuf { - ironclaw_base_dir().join("history") + optimclaw_base_dir().join("history") } #[async_trait] @@ -553,7 +553,7 @@ impl Channel for ReplChannel { if !suppress_banner.load(Ordering::Relaxed) { println!( - "{}IronClaw{} /help for commands, /quit to exit", + "{}OptimClaw{} /help for commands, /quit to exit", fmt::bold(), fmt::reset() ); diff --git a/src/channels/signal.rs b/src/channels/signal.rs index 84afccd5..473f3bd6 100644 --- a/src/channels/signal.rs +++ b/src/channels/signal.rs @@ -17,7 +17,7 @@ use serde::Deserialize; use tokio::sync::RwLock; use uuid::Uuid; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::channels::{Channel, IncomingMessage, MessageStream, OutgoingResponse, StatusUpdate}; use crate::config::SignalConfig; use crate::error::ChannelError; @@ -203,7 +203,7 @@ impl SignalChannel { ); if result.created { let message = format!( - "To pair with this bot, run: `ironclaw pairing approve signal {}`", + "To pair with this bot, run: `optimclaw pairing approve signal {}`", result.code ); let http_url = self.config.http_url.clone(); @@ -555,10 +555,10 @@ impl SignalChannel { /// Uses the shared path validation logic from path_utils to ensure: /// - No path traversal attacks (../, URL-encoded, null bytes) /// - Paths are canonicalized and symlinks resolved - /// - All paths are within ~/.ironclaw/ sandbox + /// - All paths are within ~/.optimclaw/ sandbox fn validate_attachment_paths(paths: &[String]) -> Result<(), ChannelError> { // Get the sandbox base directory (same as MessageTool uses) - let base_dir = ironclaw_base_dir(); + let base_dir = optimclaw_base_dir(); for path in paths { crate::tools::builtin::path_utils::validate_path(path, Some(&base_dir)).map_err( @@ -2678,7 +2678,7 @@ mod tests { use std::fs; // Create test files in sandbox - let base_dir = crate::bootstrap::ironclaw_base_dir(); + let base_dir = crate::bootstrap::optimclaw_base_dir(); // Create sandbox directory if it doesn't exist (needed for CI) let _ = fs::create_dir_all(&base_dir); diff --git a/src/channels/wasm/bundled.rs b/src/channels/wasm/bundled.rs index 60fe8f4d..09e0a953 100644 --- a/src/channels/wasm/bundled.rs +++ b/src/channels/wasm/bundled.rs @@ -33,10 +33,10 @@ pub fn bundled_channel_names() -> Vec<&'static str> { /// Resolve the channels source directory. /// /// Checks (in order): -/// 1. `IRONCLAW_CHANNELS_SRC` env var +/// 1. `OPTIMCLAW_CHANNELS_SRC` env var /// 2. `/channels-src/` (dev builds) fn channels_src_dir() -> PathBuf { - if let Ok(dir) = std::env::var("IRONCLAW_CHANNELS_SRC") { + if let Ok(dir) = std::env::var("OPTIMCLAW_CHANNELS_SRC") { return PathBuf::from(dir); } PathBuf::from(CARGO_MANIFEST_DIR).join("channels-src") diff --git a/src/channels/wasm/loader.rs b/src/channels/wasm/loader.rs index 41ecfac1..bef007af 100644 --- a/src/channels/wasm/loader.rs +++ b/src/channels/wasm/loader.rs @@ -1,6 +1,6 @@ //! WASM channel loader for loading channels from files or directories. //! -//! Loads WASM channel modules from the filesystem (default: ~/.ironclaw/channels/). +//! Loads WASM channel modules from the filesystem (default: ~/.optimclaw/channels/). //! Each channel consists of: //! - `.wasm` - The compiled WASM component //! - `.capabilities.json` - Channel capabilities and configuration @@ -11,7 +11,7 @@ use std::sync::Arc; use tokio::fs; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::channels::wasm::capabilities::ChannelCapabilities; use crate::channels::wasm::error::WasmChannelError; use crate::channels::wasm::runtime::WasmChannelRuntime; @@ -416,10 +416,10 @@ pub struct DiscoveredChannel { /// Get the default channels directory path. /// -/// Returns ~/.ironclaw/channels/ +/// Returns ~/.optimclaw/channels/ #[allow(dead_code)] pub fn default_channels_dir() -> PathBuf { - ironclaw_base_dir().join("channels") + optimclaw_base_dir().join("channels") } #[cfg(test)] diff --git a/src/channels/wasm/mod.rs b/src/channels/wasm/mod.rs index 882709a9..8d4a7f7a 100644 --- a/src/channels/wasm/mod.rs +++ b/src/channels/wasm/mod.rs @@ -63,14 +63,14 @@ //! # Example Usage //! //! ```ignore -//! use ironclaw::channels::wasm::{WasmChannelLoader, WasmChannelRuntime}; +//! use optimclaw::channels::wasm::{WasmChannelLoader, WasmChannelRuntime}; //! //! // Create runtime (can share engine with tool runtime) //! let runtime = WasmChannelRuntime::new(config)?; //! //! // Load channels from directory //! let loader = WasmChannelLoader::new(runtime, pairing_store, settings_store, owner_scope_id); -//! let channels = loader.load_from_dir(Path::new("~/.ironclaw/channels/")).await?; +//! let channels = loader.load_from_dir(Path::new("~/.optimclaw/channels/")).await?; //! //! // Add to channel manager //! for channel in channels { diff --git a/src/channels/wasm/router.rs b/src/channels/wasm/router.rs index 510bc461..c69d47cd 100644 --- a/src/channels/wasm/router.rs +++ b/src/channels/wasm/router.rs @@ -620,7 +620,7 @@ async fn oauth_callback_handler( height: 100vh; margin: 0; background: #191919; color: white;\">\
\

Connected!

\ -

You can close this window and return to IronClaw.

\ +

You can close this window and return to OptimClaw.

\
" .to_string(), ), diff --git a/src/channels/wasm/wrapper.rs b/src/channels/wasm/wrapper.rs index a0f9689f..9966b68c 100644 --- a/src/channels/wasm/wrapper.rs +++ b/src/channels/wasm/wrapper.rs @@ -3276,16 +3276,16 @@ fn read_attachments(paths: &[String]) -> Result, St let mut total_bytes: u64 = 0; let tmp_base = std::path::Path::new("/tmp"); let home_base = dirs::home_dir() - .map(|h| h.join(".ironclaw")) + .map(|h| h.join(".optimclaw")) .unwrap_or_default(); for path in paths { - // Validate paths are under /tmp/ or ~/.ironclaw/ to prevent arbitrary file reads + // Validate paths are under /tmp/ or ~/.optimclaw/ to prevent arbitrary file reads let validated = crate::tools::builtin::path_utils::validate_path(path, Some(tmp_base)) .or_else(|_| crate::tools::builtin::path_utils::validate_path(path, Some(&home_base))); let validated = validated.map_err(|e| { format!( - "Invalid attachment path '{}': must be under /tmp/ or ~/.ironclaw/: {}", + "Invalid attachment path '{}': must be under /tmp/ or ~/.optimclaw/: {}", path, e ) })?; @@ -4778,7 +4778,7 @@ mod tests { ); assert_eq!(mime_from_extension("noext"), "application/octet-stream"); assert_eq!( - mime_from_extension("/home/user/.ironclaw/screenshot.png"), + mime_from_extension("/home/user/.optimclaw/screenshot.png"), "image/png" ); } diff --git a/src/channels/web/handlers/secrets.rs b/src/channels/web/handlers/secrets.rs index f8bfe5e4..ffb37f3e 100644 --- a/src/channels/web/handlers/secrets.rs +++ b/src/channels/web/handlers/secrets.rs @@ -1,7 +1,7 @@ //! Admin secrets provisioning handlers. //! //! Allows an admin (typically an application backend) to create, list, and -//! delete secrets on behalf of individual users so their IronClaw agent can +//! delete secrets on behalf of individual users so their OptimClaw agent can //! call back to external services with per-user credentials. use std::sync::Arc; diff --git a/src/channels/web/handlers/static_files.rs b/src/channels/web/handlers/static_files.rs index effc7037..d6379a36 100644 --- a/src/channels/web/handlers/static_files.rs +++ b/src/channels/web/handlers/static_files.rs @@ -6,7 +6,7 @@ use axum::{ response::{Html, IntoResponse}, }; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::channels::web::auth::AuthenticatedUser; use crate::channels::web::types::*; @@ -61,7 +61,7 @@ pub async fn project_file_handler( serve_project_file(&project_id, &path).await } -/// Shared logic: resolve the file inside `~/.ironclaw/projects/{project_id}/`, +/// Shared logic: resolve the file inside `~/.optimclaw/projects/{project_id}/`, /// guard against path traversal, and stream the content with the right MIME type. async fn serve_project_file(project_id: &str, path: &str) -> axum::response::Response { // Reject project_id values that could escape the projects directory. @@ -73,7 +73,7 @@ async fn serve_project_file(project_id: &str, path: &str) -> axum::response::Res return (StatusCode::BAD_REQUEST, "Invalid project ID").into_response(); } - let base = ironclaw_base_dir().join("projects").join(project_id); + let base = optimclaw_base_dir().join("projects").join(project_id); let file_path = base.join(path); diff --git a/src/channels/web/handlers/webhooks.rs b/src/channels/web/handlers/webhooks.rs index b8d4fd8d..332aeded 100644 --- a/src/channels/web/handlers/webhooks.rs +++ b/src/channels/web/handlers/webhooks.rs @@ -34,7 +34,7 @@ fn validate_webhook_secret( return Err(( StatusCode::FORBIDDEN, "Webhook secret not configured for this routine. \ - Set a secret with: ironclaw routine update --webhook-secret " + Set a secret with: optimclaw routine update --webhook-secret " .to_string(), )); } diff --git a/src/channels/web/log_layer.rs b/src/channels/web/log_layer.rs index b599ab09..e15526e0 100644 --- a/src/channels/web/log_layer.rs +++ b/src/channels/web/log_layer.rs @@ -110,7 +110,7 @@ impl Default for LogBroadcaster { /// Handle for changing the tracing `EnvFilter` at runtime. /// /// Wraps a `reload::Handle` so the gateway can switch between log levels -/// (e.g. `ironclaw=debug`) without restarting the process. +/// (e.g. `optimclaw=debug`) without restarting the process. pub struct LogLevelHandle { handle: reload::Handle, current_level: Mutex, @@ -130,7 +130,7 @@ impl LogLevelHandle { } } - /// Change the `ironclaw=` directive at runtime. + /// Change the `optimclaw=` directive at runtime. /// /// `level` must be one of: trace, debug, info, warn, error. pub fn set_level(&self, level: &str) -> Result<(), String> { @@ -145,9 +145,9 @@ impl LogLevelHandle { } let filter_str = if self.base_filter.is_empty() { - format!("ironclaw={}", level) + format!("optimclaw={}", level) } else { - format!("ironclaw={},{}", level, self.base_filter) + format!("optimclaw={},{}", level, self.base_filter) }; let new_filter = EnvFilter::new(&filter_str); @@ -161,7 +161,7 @@ impl LogLevelHandle { Ok(()) } - /// Returns the current ironclaw log level (e.g. "info", "debug"). + /// Returns the current optimclaw log level (e.g. "info", "debug"). pub fn current_level(&self) -> String { self.current_level .lock() @@ -176,17 +176,17 @@ impl LogLevelHandle { /// The fmt layer and `WebLogLayer` are attached alongside the reloadable filter. pub fn init_tracing(log_broadcaster: Arc) -> Arc { let raw_filter = - std::env::var("RUST_LOG").unwrap_or_else(|_| "ironclaw=info,tower_http=warn".to_string()); + std::env::var("RUST_LOG").unwrap_or_else(|_| "optimclaw=info,tower_http=warn".to_string()); - // Split into the ironclaw directive and "everything else" (base_filter). - let mut ironclaw_level = String::from("info"); + // Split into the optimclaw directive and "everything else" (base_filter). + let mut optimclaw_level = String::from("info"); let mut base_parts: Vec<&str> = Vec::new(); for part in raw_filter.split(',') { let trimmed = part.trim(); - if trimmed.starts_with("ironclaw=") { - if let Some(lvl) = trimmed.strip_prefix("ironclaw=") { - ironclaw_level = lvl.to_string(); + if trimmed.starts_with("optimclaw=") { + if let Some(lvl) = trimmed.strip_prefix("optimclaw=") { + optimclaw_level = lvl.to_string(); } } else if !trimmed.is_empty() { base_parts.push(trimmed); @@ -199,7 +199,7 @@ pub fn init_tracing(log_broadcaster: Arc) -> Arc let handle = Arc::new(LogLevelHandle::new( reload_handle, - ironclaw_level, + optimclaw_level, base_filter, )); @@ -220,7 +220,7 @@ pub fn init_tracing(log_broadcaster: Arc) -> Arc /// fields from a tracing event. /// /// The terminal formatter shows something like: -/// INFO ironclaw::agent: Request completed url="http://..." status=200 +/// INFO optimclaw::agent: Request completed url="http://..." status=200 /// /// We replicate that by capturing both the message and the extra fields. struct MessageVisitor { @@ -336,7 +336,7 @@ mod tests { broadcaster.send(LogEntry { level: "WARN".to_string(), - target: "ironclaw::test".to_string(), + target: "optimclaw::test".to_string(), message: "test warning".to_string(), timestamp: "2024-01-01T00:00:00.000Z".to_string(), }); @@ -350,7 +350,7 @@ mod tests { fn test_log_entry_serialization() { let entry = LogEntry { level: "ERROR".to_string(), - target: "ironclaw::agent".to_string(), + target: "optimclaw::agent".to_string(), message: "something broke".to_string(), timestamp: "2024-01-01T00:00:00.000Z".to_string(), }; diff --git a/src/channels/web/mod.rs b/src/channels/web/mod.rs index 77968223..d31058fe 100644 --- a/src/channels/web/mod.rs +++ b/src/channels/web/mod.rs @@ -1,4 +1,4 @@ -//! Web gateway channel for browser-based access to IronClaw. +//! Web gateway channel for browser-based access to OptimClaw. //! //! Provides a single-page web UI with: //! - Chat with the agent (via REST + SSE) diff --git a/src/channels/web/openai_compat.rs b/src/channels/web/openai_compat.rs index 0c0f1a9e..89e574c7 100644 --- a/src/channels/web/openai_compat.rs +++ b/src/channels/web/openai_compat.rs @@ -1,7 +1,7 @@ //! OpenAI-compatible HTTP API (`/v1/chat/completions`, `/v1/models`). //! //! This module provides a direct LLM proxy through the web gateway so any -//! standard OpenAI client library can use IronClaw as a backend by simply +//! standard OpenAI client library can use OptimClaw as a backend by simply //! changing the `base_url`. use std::sync::Arc; @@ -712,7 +712,7 @@ async fn handle_streaming( let sse = Sse::new(stream).keep_alive(KeepAlive::new().text("")); let mut response = sse.into_response(); response.headers_mut().insert( - "x-ironclaw-streaming", + "x-optimclaw-streaming", HeaderValue::from_static("simulated"), ); Ok(response) @@ -824,7 +824,7 @@ pub async fn models_handler( "id": name, "object": "model", "created": created, - "owned_by": "ironclaw" + "owned_by": "optimclaw" }) }) .collect(), @@ -834,7 +834,7 @@ pub async fn models_handler( "id": model_name, "object": "model", "created": created, - "owned_by": "ironclaw" + "owned_by": "optimclaw" })] } Err(e) => return Err(map_llm_error(e)), diff --git a/src/channels/web/server.rs b/src/channels/web/server.rs index 8c9ecdde..766044f8 100644 --- a/src/channels/web/server.rs +++ b/src/channels/web/server.rs @@ -27,7 +27,7 @@ use tower_http::set_header::SetResponseHeaderLayer; use uuid::Uuid; use crate::agent::SessionManager; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::channels::IncomingMessage; use crate::channels::relay::DEFAULT_RELAY_NAME; use crate::channels::web::auth::{ @@ -838,7 +838,7 @@ fn oauth_error_page(label: &str) -> axum::response::Response { /// redirect the user's browser here. The `state` query parameter correlates /// the callback with a pending OAuth flow registered by `start_wasm_oauth()`. /// -/// Used on hosted instances where `IRONCLAW_OAUTH_CALLBACK_URL` points to +/// Used on hosted instances where `OPTIMCLAW_OAUTH_CALLBACK_URL` points to /// the gateway (e.g., `https://kind-deer.agent1.near.ai/oauth/callback`). /// Local/desktop mode continues to use the TCP listener on port 9876. async fn oauth_callback_handler( @@ -859,14 +859,14 @@ async fn oauth_callback_handler( let state_param = match params.get("state") { Some(s) if !s.is_empty() => s.clone(), _ => { - return oauth_error_page("IronClaw"); + return oauth_error_page("OptimClaw"); } }; let code = match params.get("code") { Some(c) if !c.is_empty() => c.clone(), _ => { - return oauth_error_page("IronClaw"); + return oauth_error_page("OptimClaw"); } }; @@ -874,7 +874,7 @@ async fn oauth_callback_handler( let ext_mgr = match state.extension_manager.as_ref() { Some(mgr) => mgr, None => { - return oauth_error_page("IronClaw"); + return oauth_error_page("OptimClaw"); } }; @@ -888,7 +888,7 @@ async fn oauth_callback_handler( "OAuth callback received with malformed state" ); clear_auth_mode(&state, &state.owner_id).await; - return oauth_error_page("IronClaw"); + return oauth_error_page("OptimClaw"); } }; let lookup_key = decoded_state.flow_id.clone(); @@ -909,7 +909,7 @@ async fn oauth_callback_handler( lookup_key = %redacted_lookup_key, "OAuth callback received with unknown or expired state" ); - return oauth_error_page("IronClaw"); + return oauth_error_page("OptimClaw"); } }; @@ -1338,7 +1338,7 @@ async fn slack_relay_oauth_callback_handler( axum::response::Html( "\

Slack Connected!

\ -

You can close this tab and return to IronClaw.

\ +

You can close this tab and return to OptimClaw.

\ \ " .to_string(), @@ -2235,7 +2235,7 @@ async fn extensions_install_handler( crate::extensions::ExtensionSource::WasmBuildable { .. } => { format!( "'{}' requires building from source. \ - Run `ironclaw registry install {}` from the CLI.", + Run `optimclaw registry install {}` from the CLI.", req.name, req.name ) } @@ -2442,7 +2442,7 @@ async fn verify_project_ownership(state: &GatewayState, project_id: &str, user_i } } -/// Shared logic: resolve the file inside `~/.ironclaw/projects/{project_id}/`, +/// Shared logic: resolve the file inside `~/.optimclaw/projects/{project_id}/`, /// guard against path traversal, and stream the content with the right MIME type. async fn serve_project_file(project_id: &str, path: &str) -> axum::response::Response { // Reject project_id values that could escape the projects directory. @@ -2454,7 +2454,7 @@ async fn serve_project_file(project_id: &str, path: &str) -> axum::response::Res return (StatusCode::BAD_REQUEST, "Invalid project ID").into_response(); } - let base = ironclaw_base_dir().join("projects").join(project_id); + let base = optimclaw_base_dir().join("projects").join(project_id); let file_path = base.join(path); @@ -2901,7 +2901,7 @@ async fn gateway_status_handler( (None, None, None) }; - let restart_enabled = std::env::var("IRONCLAW_IN_DOCKER") + let restart_enabled = std::env::var("OPTIMCLAW_IN_DOCKER") .map(|v| v.to_lowercase() == "true") .unwrap_or(false); @@ -4065,8 +4065,8 @@ mod tests { // sees a stable proxy URL/token configuration throughout the test. let _env_guard = crate::config::helpers::lock_env(); let _exchange_url_guard = - set_env_var("IRONCLAW_OAUTH_EXCHANGE_URL", Some(&proxy.base_url())); - let _proxy_auth_guard = set_env_var("IRONCLAW_OAUTH_PROXY_AUTH_TOKEN", None); + set_env_var("OPTIMCLAW_OAUTH_EXCHANGE_URL", Some(&proxy.base_url())); + let _proxy_auth_guard = set_env_var("OPTIMCLAW_OAUTH_PROXY_AUTH_TOKEN", None); let _gateway_token_guard = set_env_var("GATEWAY_AUTH_TOKEN", Some("gateway-test-token")); let secrets = test_secrets_store(); @@ -4162,9 +4162,9 @@ mod tests { // sees a stable proxy URL/token configuration throughout the test. let _env_guard = crate::config::helpers::lock_env(); let _exchange_url_guard = - set_env_var("IRONCLAW_OAUTH_EXCHANGE_URL", Some(&proxy.base_url())); + set_env_var("OPTIMCLAW_OAUTH_EXCHANGE_URL", Some(&proxy.base_url())); let _proxy_auth_guard = set_env_var( - "IRONCLAW_OAUTH_PROXY_AUTH_TOKEN", + "OPTIMCLAW_OAUTH_PROXY_AUTH_TOKEN", Some("shared-oauth-proxy-secret"), ); let _gateway_token_guard = set_env_var("GATEWAY_AUTH_TOKEN", None); diff --git a/src/channels/web/types.rs b/src/channels/web/types.rs index 9ecece57..0c045108 100644 --- a/src/channels/web/types.rs +++ b/src/channels/web/types.rs @@ -120,9 +120,9 @@ pub struct ApprovalRequest { pub thread_id: Option, } -// --- App Event (re-exported from ironclaw_common) --- +// --- App Event (re-exported from optimclaw_common) --- -pub use ironclaw_common::{AppEvent, ToolDecisionDto}; +pub use optimclaw_common::{AppEvent, ToolDecisionDto}; // --- Memory --- diff --git a/src/channels/web/util.rs b/src/channels/web/util.rs index 1ee8e229..47fc20ae 100644 --- a/src/channels/web/util.rs +++ b/src/channels/web/util.rs @@ -2,11 +2,11 @@ use crate::channels::web::types::{ToolCallInfo, TurnInfo}; -pub use ironclaw_common::truncate_preview; +pub use optimclaw_common::truncate_preview; /// Convert stored tool errors into plain text suitable for UI display. pub fn tool_error_for_display(error: &str) -> String { - ironclaw_safety::SafetyLayer::unwrap_tool_output(error).unwrap_or_else(|| error.to_string()) + optimclaw_safety::SafetyLayer::unwrap_tool_output(error).unwrap_or_else(|| error.to_string()) } /// Parse tool call summary JSON objects into `ToolCallInfo` structs. diff --git a/src/cli/channels.rs b/src/cli/channels.rs index 0c1eff32..297a8287 100644 --- a/src/cli/channels.rs +++ b/src/cli/channels.rs @@ -13,7 +13,7 @@ //! Until `resolve()` falls back to settings (or the CLI writes `.env`), //! an `enable`/`disable` command would silently fail to take effect. //! -//! `status` (runtime health) requires connecting to a running IronClaw instance +//! `status` (runtime health) requires connecting to a running OptimClaw instance //! via IPC or HTTP, which does not exist yet as a CLI control plane. use std::path::Path; @@ -211,7 +211,7 @@ async fn cmd_list( println!("Use --verbose for details."); println!(); println!("Note: enable/disable not yet available. Channel configuration is"); - println!("managed via environment variables. See 'ironclaw onboard --channels-only'."); + println!("managed via environment variables. See 'optimclaw onboard --channels-only'."); } Ok(()) diff --git a/src/cli/completion.rs b/src/cli/completion.rs index 7d41ce16..1bf94a1f 100644 --- a/src/cli/completion.rs +++ b/src/cli/completion.rs @@ -2,7 +2,7 @@ use clap::{CommandFactory, Parser}; use clap_complete::{Shell, generate}; use std::io::{self, Write}; -/// Generate shell completion scripts for ironclaw +/// Generate shell completion scripts for optimclaw #[derive(Parser, Debug)] pub struct Completion { /// The shell to generate completions for @@ -17,7 +17,7 @@ impl Completion { if self.shell == Shell::Zsh { // Generate to buffer so we can patch the compdef call. - // clap_complete emits bare `compdef _ironclaw ironclaw` which + // clap_complete emits bare `compdef _optimclaw optimclaw` which // errors if sourced before compinit. Guard it so the script // works in all sourcing contexts. let mut buf = Vec::new(); diff --git a/src/cli/config.rs b/src/cli/config.rs index fc1312f6..1ff6584c 100644 --- a/src/cli/config.rs +++ b/src/cli/config.rs @@ -13,7 +13,7 @@ use crate::settings::Settings; pub enum ConfigCommand { /// Generate a default config.toml file Init { - /// Output path (default: ~/.ironclaw/config.toml) + /// Output path (default: ~/.optimclaw/config.toml) #[arg(short, long)] output: Option, @@ -239,14 +239,14 @@ fn show_path(has_db: bool) -> anyhow::Result<()> { } println!( "Env config: {}", - crate::bootstrap::ironclaw_env_path().display() + crate::bootstrap::optimclaw_env_path().display() ); let toml_path = Settings::default_toml_path(); let toml_status = if toml_path.exists() { "found" } else { - "not found (run `ironclaw config init` to create)" + "not found (run `optimclaw config init` to create)" }; println!( "TOML config: {} ({})", @@ -282,7 +282,7 @@ mod tests { // Reset to default settings.reset("agent.name").unwrap(); - assert_eq!(settings.agent.name, "ironclaw"); + assert_eq!(settings.agent.name, "optimclaw"); } #[tokio::test] diff --git a/src/cli/doctor.rs b/src/cli/doctor.rs index 023ac4e1..9a707eb8 100644 --- a/src/cli/doctor.rs +++ b/src/cli/doctor.rs @@ -1,4 +1,4 @@ -//! `ironclaw doctor` - active health diagnostics. +//! `optimclaw doctor` - active health diagnostics. //! //! Probes external dependencies and validates configuration to surface //! problems before they bite during normal operation. Each check reports @@ -6,14 +6,14 @@ use std::path::PathBuf; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::cli::fmt; use crate::settings::Settings; /// Run all diagnostic checks and print results. pub async fn run_doctor_command() -> anyhow::Result<()> { println!(); - println!(" {}IronClaw Doctor{}", fmt::bold(), fmt::reset()); + println!(" {}OptimClaw Doctor{}", fmt::bold(), fmt::reset()); let mut passed = 0u32; let mut failed = 0u32; @@ -274,7 +274,7 @@ async fn check_nearai_session(settings: &Settings) -> CheckResult { return CheckResult::Pass("API key configured".into()); } return CheckResult::Fail(format!( - "session file not found at {}. Run `ironclaw onboard`", + "session file not found at {}. Run `optimclaw onboard`", session_path.display() )); } @@ -376,7 +376,7 @@ async fn try_pg_connect() -> Result<(), String> { // ── Workspace directory ───────────────────────────────────── fn check_workspace_dir() -> CheckResult { - let dir = ironclaw_base_dir(); + let dir = optimclaw_base_dir(); if dir.exists() { if dir.is_dir() { @@ -419,7 +419,7 @@ fn check_embeddings(settings: &Settings) -> CheckResult { )) } else { let hint = match config.provider.as_str() { - "nearai" => "run `ironclaw onboard` to create a session", + "nearai" => "run `optimclaw onboard` to create a session", _ => "set OPENAI_API_KEY", }; CheckResult::Fail(format!( @@ -523,8 +523,8 @@ async fn check_mcp_config() -> CheckResult { // ── Skills ────────────────────────────────────────────────── async fn check_skills() -> CheckResult { - let user_dir = ironclaw_base_dir().join("skills"); - let installed_dir = ironclaw_base_dir().join("installed_skills"); + let user_dir = optimclaw_base_dir().join("skills"); + let installed_dir = optimclaw_base_dir().join("installed_skills"); let mut registry = crate::skills::SkillRegistry::new(user_dir.clone()); registry = registry.with_installed_dir(installed_dir); @@ -557,7 +557,7 @@ fn check_secrets(settings: &Settings) -> CheckResult { } } crate::settings::KeySource::None => { - CheckResult::Skip("secrets not configured (run `ironclaw onboard`)".into()) + CheckResult::Skip("secrets not configured (run `optimclaw onboard`)".into()) } } } @@ -567,21 +567,21 @@ fn check_secrets(settings: &Settings) -> CheckResult { fn check_service_installed() -> CheckResult { if cfg!(target_os = "macos") { let plist = - dirs::home_dir().map(|h| h.join("Library/LaunchAgents/com.ironclaw.daemon.plist")); + dirs::home_dir().map(|h| h.join("Library/LaunchAgents/com.optimclaw.daemon.plist")); match plist { Some(path) if path.exists() => { CheckResult::Pass(format!("launchd plist installed ({})", path.display())) } - Some(_) => CheckResult::Skip("not installed (run `ironclaw service install`)".into()), + Some(_) => CheckResult::Skip("not installed (run `optimclaw service install`)".into()), None => CheckResult::Skip("cannot determine home directory".into()), } } else if cfg!(target_os = "linux") { - let unit = dirs::home_dir().map(|h| h.join(".config/systemd/user/ironclaw.service")); + let unit = dirs::home_dir().map(|h| h.join(".config/systemd/user/optimclaw.service")); match unit { Some(path) if path.exists() => { CheckResult::Pass(format!("systemd unit installed ({})", path.display())) } - Some(_) => CheckResult::Skip("not installed (run `ironclaw service install`)".into()), + Some(_) => CheckResult::Skip("not installed (run `optimclaw service install`)".into()), None => CheckResult::Skip("cannot determine home directory".into()), } } else { @@ -651,7 +651,7 @@ mod tests { #[test] fn check_binary_skips_nonexistent() { - match check_binary("__ironclaw_nonexistent_binary__", &["--version"]) { + match check_binary("__optimclaw_nonexistent_binary__", &["--version"]) { CheckResult::Skip(_) => {} other => panic!( "expected Skip for nonexistent binary, got: {}", diff --git a/src/cli/hooks.rs b/src/cli/hooks.rs index b2dd4af1..a024712a 100644 --- a/src/cli/hooks.rs +++ b/src/cli/hooks.rs @@ -99,7 +99,7 @@ async fn discover_hooks(config: &crate::config::Config) -> Vec { /// /// Uses the same flat-file layout as the real WASM loaders: /// ```text -/// ~/.ironclaw/tools/ +/// ~/.optimclaw/tools/ /// ├── slack.wasm /// ├── slack.capabilities.json <- hooks section parsed here /// ├── github.wasm diff --git a/src/cli/import.rs b/src/cli/import.rs index 14e3dc03..a36225d4 100644 --- a/src/cli/import.rs +++ b/src/cli/import.rs @@ -103,7 +103,7 @@ async fn run_import_openclaw( } Err(_) => { return Err(anyhow::anyhow!( - "No secrets master key found. Set SECRETS_MASTER_KEY env var or run 'ironclaw onboard' first." + "No secrets master key found. Set SECRETS_MASTER_KEY env var or run 'optimclaw onboard' first." )); } } diff --git a/src/cli/logs.rs b/src/cli/logs.rs index 651bf891..61dda3b5 100644 --- a/src/cli/logs.rs +++ b/src/cli/logs.rs @@ -1,7 +1,7 @@ //! CLI command for viewing and managing gateway logs. //! //! Provides access to gateway logs through three mechanisms: -//! - Reading the gateway log file (`~/.ironclaw/gateway.log`) +//! - Reading the gateway log file (`~/.optimclaw/gateway.log`) //! - Streaming live logs via the gateway's SSE endpoint (`/api/logs/events`) //! - Getting/setting the runtime log level via `/api/logs/level` @@ -14,7 +14,7 @@ use clap::Args; #[derive(Args, Debug, Clone)] #[command( about = "View and manage gateway logs", - long_about = "Tail gateway logs, stream live output, or adjust log level.\nExamples:\n ironclaw logs # Show last 200 lines\n ironclaw logs --follow # Stream live logs via SSE\n ironclaw logs --limit 50 --json # Last 50 lines as JSON\n ironclaw logs --level # Show current log level\n ironclaw logs --level debug # Set log level to debug" + long_about = "Tail gateway logs, stream live output, or adjust log level.\nExamples:\n optimclaw logs # Show last 200 lines\n optimclaw logs --follow # Stream live logs via SSE\n optimclaw logs --limit 50 --json # Last 50 lines as JSON\n optimclaw logs --level # Show current log level\n optimclaw logs --level debug # Set log level to debug" )] pub struct LogsCommand { /// Stream live logs from the running gateway via SSE. @@ -84,18 +84,18 @@ pub async fn run_logs_command(cmd: LogsCommand, config_path: Option<&Path>) -> a // ── Show log file ──────────────────────────────────────────────────────── -/// Read the last N lines from `~/.ironclaw/gateway.log`. +/// Read the last N lines from `~/.optimclaw/gateway.log`. /// /// Uses a reverse-scan strategy: seeks to the end of the file and reads /// backwards in chunks to find the last `limit` newlines, so memory usage /// is proportional to the output size, not the file size. fn cmd_show(cmd: &LogsCommand) -> anyhow::Result<()> { - let log_path = crate::bootstrap::ironclaw_base_dir().join("gateway.log"); + let log_path = crate::bootstrap::optimclaw_base_dir().join("gateway.log"); if !log_path.exists() { anyhow::bail!( "No gateway log file found at {}.\n\ The log file is created when the gateway runs in background mode \ - (e.g. `ironclaw gateway start`).", + (e.g. `optimclaw gateway start`).", log_path.display() ); } @@ -197,7 +197,7 @@ async fn cmd_follow(cmd: &LogsCommand, params: &GatewayParams) -> anyhow::Result .map_err(|e| { anyhow::anyhow!( "Failed to connect to gateway at {url}: {e}\n\ - Is the gateway running? Try `ironclaw gateway status`." + Is the gateway running? Try `optimclaw gateway status`." ) })?; @@ -264,7 +264,7 @@ async fn cmd_get_level(cmd: &LogsCommand, params: &GatewayParams) -> anyhow::Res .map_err(|e| { anyhow::anyhow!( "Failed to connect to gateway at {url}: {e}\n\ - Is the gateway running? Try `ironclaw gateway status`." + Is the gateway running? Try `optimclaw gateway status`." ) })?; @@ -330,7 +330,7 @@ async fn cmd_set_level( .map_err(|e| { anyhow::anyhow!( "Failed to connect to gateway at {url}: {e}\n\ - Is the gateway running? Try `ironclaw gateway status`." + Is the gateway running? Try `optimclaw gateway status`." ) })?; @@ -412,7 +412,7 @@ async fn resolve_gateway_params( /// propagated — the user asked for a specific file and deserves a clear /// failure when it is missing, unreadable, or malformed. When no path /// was given we fall back to env-only resolution and silently return -/// `None` on failure so that `ironclaw logs` works without any config. +/// `None` on failure so that `optimclaw logs` works without any config. async fn load_gateway_config( config_path: Option<&Path>, ) -> anyhow::Result> { @@ -512,7 +512,7 @@ mod tests { fn test_print_log_entry_json() { let entry = serde_json::json!({ "level": "INFO", - "target": "ironclaw::agent", + "target": "optimclaw::agent", "message": "test message", "timestamp": "2024-01-15T10:30:00.000Z" }); diff --git a/src/cli/mcp.rs b/src/cli/mcp.rs index 2293a6d6..9257cb4f 100644 --- a/src/cli/mcp.rs +++ b/src/cli/mcp.rs @@ -271,7 +271,7 @@ async fn add_server(args: McpAddArgs) -> anyhow::Result<()> { if requires_auth { println!(); - println!(" Run 'ironclaw mcp auth {}' to authenticate.", name); + println!(" Run 'optimclaw mcp auth {}' to authenticate.", name); } println!(); @@ -305,7 +305,7 @@ async fn list_servers(verbose: bool) -> anyhow::Result<()> { println!(" No MCP servers configured."); println!(); println!(" Add a server with:"); - println!(" ironclaw mcp add [--client-id ]"); + println!(" optimclaw mcp add [--client-id ]"); println!(); return Ok(()); } @@ -455,9 +455,9 @@ async fn auth_server(name: String, user_id: String) -> anyhow::Result<()> { println!(" The server may require a different authentication method,"); println!(" or you may need to configure OAuth manually:"); println!(); - println!(" ironclaw mcp remove {}", name); + println!(" optimclaw mcp remove {}", name); println!( - " ironclaw mcp add {} {} --client-id YOUR_CLIENT_ID", + " optimclaw mcp add {} {} --client-id YOUR_CLIENT_ID", name, server.url ); println!(); @@ -500,7 +500,7 @@ async fn test_server(name: String, user_id: String) -> anyhow::Result<()> { // OAuth configured but no tokens - need to authenticate println!(); println!( - " ✗ Not authenticated. Run 'ironclaw mcp auth {}' first.", + " ✗ Not authenticated. Run 'optimclaw mcp auth {}' first.", name ); println!(); @@ -561,12 +561,12 @@ async fn test_server(name: String, user_id: String) -> anyhow::Result<()> { println!( " ✗ Authentication failed (token may be expired). Try re-authenticating:" ); - println!(" ironclaw mcp auth {}", name); + println!(" optimclaw mcp auth {}", name); } else { // No tokens - server requires auth println!(" ✗ Server requires authentication."); println!(); - println!(" Run 'ironclaw mcp auth {}' to authenticate.", name); + println!(" Run 'optimclaw mcp auth {}' to authenticate.", name); } } else { println!(" ✗ Connection failed: {}", e); diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 5da12e0b..4570b584 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -60,12 +60,12 @@ use std::sync::Arc; use clap::{ColorChoice, Parser, Subcommand}; #[derive(Parser, Debug)] -#[command(name = "ironclaw")] +#[command(name = "optimclaw")] #[command( about = "Secure personal AI assistant that protects your data and expands its capabilities" )] #[command( - long_about = "IronClaw is a secure AI assistant. Use 'ironclaw --help' for details.\nExamples:\n ironclaw run # Start the agent\n ironclaw config list # List configs" + long_about = "OptimClaw is a secure AI assistant. Use 'optimclaw --help' for details.\nExamples:\n optimclaw run # Start the agent\n optimclaw config list # List configs" )] #[command(version)] #[command(color = ColorChoice::Auto)] // Enable auto-color for help (if the terminal supports it) @@ -99,14 +99,14 @@ pub enum Command { /// Run the agent (default if no subcommand given) #[command( about = "Run the AI agent", - long_about = "Starts the IronClaw agent in default mode.\nExample: ironclaw run" + long_about = "Starts the OptimClaw agent in default mode.\nExample: optimclaw run" )] Run, /// Interactive onboarding wizard #[command( about = "Run interactive setup wizard", - long_about = "Guides through initial configuration.\nExamples:\n ironclaw onboard --skip-auth # Skip auth step\n ironclaw onboard --channels-only # Reconfigure channels\n ironclaw onboard --provider-only # Change LLM provider and model" + long_about = "Guides through initial configuration.\nExamples:\n optimclaw onboard --skip-auth # Skip auth step\n optimclaw onboard --channels-only # Reconfigure channels\n optimclaw onboard --provider-only # Change LLM provider and model" )] Onboard { /// Skip authentication (use existing session) @@ -134,7 +134,7 @@ pub enum Command { #[command( subcommand, about = "Manage app configs", - long_about = "Commands for listing, getting, and setting configurations.\nExample: ironclaw config list" + long_about = "Commands for listing, getting, and setting configurations.\nExample: optimclaw config list" )] Config(ConfigCommand), @@ -142,7 +142,7 @@ pub enum Command { #[command( subcommand, about = "Manage WASM tools", - long_about = "Install, list, or remove WASM-based tools.\nExample: ironclaw tool install mytool.wasm" + long_about = "Install, list, or remove WASM-based tools.\nExample: optimclaw tool install mytool.wasm" )] Tool(ToolCommand), @@ -150,7 +150,7 @@ pub enum Command { #[command( subcommand, about = "Browse/install extensions", - long_about = "Interact with extension registry.\nExample: ironclaw registry list" + long_about = "Interact with extension registry.\nExample: optimclaw registry list" )] Registry(RegistryCommand), @@ -158,7 +158,7 @@ pub enum Command { #[command( subcommand, about = "Manage channels", - long_about = "List configured messaging channels.\nExamples:\n ironclaw channels list\n ironclaw channels list --verbose\n ironclaw channels list --json" + long_about = "List configured messaging channels.\nExamples:\n optimclaw channels list\n optimclaw channels list --verbose\n optimclaw channels list --json" )] Channels(ChannelsCommand), @@ -167,7 +167,7 @@ pub enum Command { subcommand, alias = "cron", about = "Manage routines", - long_about = "List, create, edit, enable/disable, delete, and view history of routines.\nExamples:\n ironclaw routines list\n ironclaw routines create --name daily-digest --schedule '0 0 9 * * *' --prompt 'Summarize today'" + long_about = "List, create, edit, enable/disable, delete, and view history of routines.\nExamples:\n optimclaw routines list\n optimclaw routines create --name daily-digest --schedule '0 0 9 * * *' --prompt 'Summarize today'" )] Routines(RoutinesCommand), @@ -175,7 +175,7 @@ pub enum Command { #[command( subcommand, about = "Manage MCP servers", - long_about = "Add, auth, list, or test MCP servers.\nExample: ironclaw mcp add notion https://mcp.notion.com" + long_about = "Add, auth, list, or test MCP servers.\nExample: optimclaw mcp add notion https://mcp.notion.com" )] Mcp(Box), @@ -183,7 +183,7 @@ pub enum Command { #[command( subcommand, about = "Manage workspace memory", - long_about = "Search, read, or write to memory.\nExample: ironclaw memory search 'query'" + long_about = "Search, read, or write to memory.\nExample: optimclaw memory search 'query'" )] Memory(MemoryCommand), @@ -191,7 +191,7 @@ pub enum Command { #[command( subcommand, about = "Manage DM pairing", - long_about = "Approve or manage pairing requests.\nExamples:\n ironclaw pairing list telegram\n ironclaw pairing approve telegram ABC12345" + long_about = "Approve or manage pairing requests.\nExamples:\n optimclaw pairing list telegram\n optimclaw pairing approve telegram ABC12345" )] Pairing(PairingCommand), @@ -199,7 +199,7 @@ pub enum Command { #[command( subcommand, about = "Manage OS service", - long_about = "Install, start, or stop service.\nExample: ironclaw service install" + long_about = "Install, start, or stop service.\nExample: optimclaw service install" )] Service(ServiceCommand), @@ -207,7 +207,7 @@ pub enum Command { #[command( subcommand, about = "Manage skills", - long_about = "List, search, and inspect SKILL.md-based skills.\nExamples:\n ironclaw skills list\n ironclaw skills search 'writing'\n ironclaw skills info my-skill" + long_about = "List, search, and inspect SKILL.md-based skills.\nExamples:\n optimclaw skills list\n optimclaw skills search 'writing'\n optimclaw skills info my-skill" )] Skills(SkillsCommand), @@ -215,7 +215,7 @@ pub enum Command { #[command( subcommand, about = "Manage lifecycle hooks", - long_about = "List and inspect lifecycle hooks (bundled, plugin, workspace).\nExamples:\n ironclaw hooks list\n ironclaw hooks list --verbose\n ironclaw hooks list --json" + long_about = "List and inspect lifecycle hooks (bundled, plugin, workspace).\nExamples:\n optimclaw hooks list\n optimclaw hooks list --verbose\n optimclaw hooks list --json" )] Hooks(HooksCommand), @@ -223,35 +223,35 @@ pub enum Command { #[command( subcommand, about = "Manage LLM providers and models", - long_about = "List providers, view current configuration, and set active provider/model.\nExamples:\n ironclaw models list\n ironclaw models list openai --verbose\n ironclaw models status\n ironclaw models set gpt-4o\n ironclaw models set-provider anthropic --model claude-sonnet-4-6-20250514" + long_about = "List providers, view current configuration, and set active provider/model.\nExamples:\n optimclaw models list\n optimclaw models list openai --verbose\n optimclaw models status\n optimclaw models set gpt-4o\n optimclaw models set-provider anthropic --model claude-sonnet-4-6-20250514" )] Models(ModelsCommand), /// Probe external dependencies and validate configuration #[command( about = "Run diagnostics", - long_about = "Checks dependencies and config validity.\nExample: ironclaw doctor" + long_about = "Checks dependencies and config validity.\nExample: optimclaw doctor" )] Doctor, /// View and manage gateway logs #[command( about = "View and manage gateway logs", - long_about = "Tail gateway logs, stream live output, or adjust log level.\nExamples:\n ironclaw logs # Show last 200 lines from gateway.log\n ironclaw logs --follow # Stream live logs via SSE\n ironclaw logs --level # Show current log level\n ironclaw logs --level debug # Set log level to debug" + long_about = "Tail gateway logs, stream live output, or adjust log level.\nExamples:\n optimclaw logs # Show last 200 lines from gateway.log\n optimclaw logs --follow # Stream live logs via SSE\n optimclaw logs --level # Show current log level\n optimclaw logs --level debug # Set log level to debug" )] Logs(LogsCommand), /// Show system health and diagnostics #[command( about = "Show system status", - long_about = "Displays health and diagnostics info.\nExample: ironclaw status" + long_about = "Displays health and diagnostics info.\nExample: optimclaw status" )] Status, /// Generate shell completion scripts #[command( about = "Generate completions", - long_about = "Generates shell completion scripts.\nExample: ironclaw completion --shell bash > ironclaw.bash" + long_about = "Generates shell completion scripts.\nExample: optimclaw completion --shell bash > optimclaw.bash" )] Completion(Completion), @@ -260,14 +260,14 @@ pub enum Command { #[command( subcommand, about = "Import from other AI systems", - long_about = "Migrate data from other AI assistants like OpenClaw.\nExample: ironclaw import openclaw" + long_about = "Migrate data from other AI assistants like OpenClaw.\nExample: optimclaw import openclaw" )] Import(ImportCommand), /// Authenticate with a provider (re-login) #[command( about = "Authenticate with a provider", - long_about = "Re-authenticate with an LLM provider.\nExample: ironclaw login --openai-codex" + long_about = "Re-authenticate with an LLM provider.\nExample: optimclaw login --openai-codex" )] Login { /// Authenticate with OpenAI Codex (ChatGPT subscription) @@ -330,7 +330,7 @@ pub async fn init_secrets_store() let config = crate::config::Config::from_env().await?; let master_key = config.secrets.master_key().ok_or_else(|| { anyhow::anyhow!( - "SECRETS_MASTER_KEY not set. Run 'ironclaw onboard' first or set it in .env" + "SECRETS_MASTER_KEY not set. Run 'optimclaw onboard' first or set it in .env" ) })?; @@ -352,7 +352,7 @@ pub async fn run_routines_cli( .await .map_err(|e| anyhow::anyhow!("{e:#}"))?; - let user_id = std::env::var("IRONCLAW_OWNER_ID").unwrap_or_else(|_| "default".to_string()); + let user_id = std::env::var("OPTIMCLAW_OWNER_ID").unwrap_or_else(|_| "default".to_string()); run_routines_command(routines_cmd.clone(), db, &user_id).await } diff --git a/src/cli/models.rs b/src/cli/models.rs index e24c324a..f6d9e18a 100644 --- a/src/cli/models.rs +++ b/src/cli/models.rs @@ -2,7 +2,7 @@ //! //! Provides subcommands for listing providers, viewing current model //! configuration, and setting the active provider/model. Settings are -//! persisted to both `config.toml` and `~/.ironclaw/.env` so changes +//! persisted to both `config.toml` and `~/.optimclaw/.env` so changes //! take effect immediately (no DB connection required). use clap::Subcommand; @@ -147,7 +147,7 @@ fn save_settings(settings: &Settings, config_path: Option<&Path>) -> anyhow::Res } fn config_toml_path() -> std::path::PathBuf { - crate::bootstrap::ironclaw_base_dir().join("config.toml") + crate::bootstrap::optimclaw_base_dir().join("config.toml") } /// Try to fetch the live model list from a provider. @@ -228,7 +228,7 @@ fn print_model_list(models: &Option>, active_model: Option<&String>) } } -/// Also update `~/.ironclaw/.env` so changes take effect immediately. +/// Also update `~/.optimclaw/.env` so changes take effect immediately. /// /// Skipped when `config_path` is `Some` (custom `--config`), because the user /// is explicitly targeting a different config file and we must not pollute the @@ -818,7 +818,7 @@ mod tests { // With a custom config path, sync_to_dotenv should be a no-op // (it returns early when config_path is Some). // We verify by checking that cmd_set_provider succeeds without - // trying to write to the default ~/.ironclaw/.env. + // trying to write to the default ~/.optimclaw/.env. cmd_set_provider("groq", None, Some(&toml_path)).expect("set provider with custom config"); let settings = Settings::load_toml(&toml_path) diff --git a/src/cli/oauth_defaults.rs b/src/cli/oauth_defaults.rs index 5628f3d6..1322c00f 100644 --- a/src/cli/oauth_defaults.rs +++ b/src/cli/oauth_defaults.rs @@ -31,11 +31,11 @@ pub struct OAuthCredentials { /// Google OAuth "Desktop App" credentials, shared across all Google tools. /// Compile-time env vars override the hardcoded defaults below. -const GOOGLE_CLIENT_ID: &str = match option_env!("IRONCLAW_GOOGLE_CLIENT_ID") { +const GOOGLE_CLIENT_ID: &str = match option_env!("OPTIMCLAW_GOOGLE_CLIENT_ID") { Some(v) => v, None => "564604149681-efo25d43rs85v0tibdepsmdv5dsrhhr0.apps.googleusercontent.com", }; -const GOOGLE_CLIENT_SECRET: &str = match option_env!("IRONCLAW_GOOGLE_CLIENT_SECRET") { +const GOOGLE_CLIENT_SECRET: &str = match option_env!("OPTIMCLAW_GOOGLE_CLIENT_SECRET") { Some(v) => v, None => "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", }; @@ -57,14 +57,14 @@ pub fn builtin_credentials(secret_name: &str) -> Option { /// Returns the compile-time override env var name, if this provider supports one. pub fn builtin_client_id_override_env(secret_name: &str) -> Option<&'static str> { match secret_name { - "google_oauth_token" => Some("IRONCLAW_GOOGLE_CLIENT_ID"), + "google_oauth_token" => Some("OPTIMCLAW_GOOGLE_CLIENT_ID"), _ => None, } } /// Suppress the baked-in desktop OAuth client secret when a hosted proxy is configured. /// -/// In hosted deployments, IronClaw may resolve the platform Google client ID from +/// In hosted deployments, OptimClaw may resolve the platform Google client ID from /// environment variables while still falling back to the baked-in desktop secret. /// That client_id/client_secret mismatch breaks Google token exchange and refresh. /// @@ -514,11 +514,11 @@ pub fn new_pending_oauth_registry() -> PendingOAuthRegistry { /// Returns `true` if OAuth callbacks should be routed through the web gateway /// instead of the local TCP listener. /// -/// This is the case when `IRONCLAW_OAUTH_CALLBACK_URL` is set to a non-loopback +/// This is the case when `OPTIMCLAW_OAUTH_CALLBACK_URL` is set to a non-loopback /// URL, meaning the user's browser will redirect to a hosted gateway rather than /// localhost. pub fn use_gateway_callback() -> bool { - crate::config::helpers::env_or_override("IRONCLAW_OAUTH_CALLBACK_URL") + crate::config::helpers::env_or_override("OPTIMCLAW_OAUTH_CALLBACK_URL") .map(|raw| { url::Url::parse(&raw) .ok() @@ -531,7 +531,7 @@ pub fn use_gateway_callback() -> bool { /// Returns the configured OAuth token-exchange proxy URL, if any. pub fn exchange_proxy_url() -> Option { - crate::config::helpers::env_or_override("IRONCLAW_OAUTH_EXCHANGE_URL") + crate::config::helpers::env_or_override("OPTIMCLAW_OAUTH_EXCHANGE_URL") .map(|url| url.trim().to_string()) .filter(|url| !url.is_empty()) } @@ -539,7 +539,7 @@ pub fn exchange_proxy_url() -> Option { /// Returns the configured OAuth proxy auth token, if any. /// /// New hosted infra can inject a dedicated shared proxy secret via -/// `IRONCLAW_OAUTH_PROXY_AUTH_TOKEN`. Existing hosted instances continue to +/// `OPTIMCLAW_OAUTH_PROXY_AUTH_TOKEN`. Existing hosted instances continue to /// work by falling back to `GATEWAY_AUTH_TOKEN`. pub fn oauth_proxy_auth_token() -> Option { fn normalized_env_value(key: &str) -> Option { @@ -548,7 +548,7 @@ pub fn oauth_proxy_auth_token() -> Option { .filter(|value| !value.is_empty()) } - normalized_env_value("IRONCLAW_OAUTH_PROXY_AUTH_TOKEN") + normalized_env_value("OPTIMCLAW_OAUTH_PROXY_AUTH_TOKEN") .or_else(|| normalized_env_value("GATEWAY_AUTH_TOKEN")) } @@ -621,7 +621,7 @@ struct HostedOAuthStatePayload { } fn current_instance_name() -> Option { - crate::config::helpers::env_or_override("IRONCLAW_INSTANCE_NAME") + crate::config::helpers::env_or_override("OPTIMCLAW_INSTANCE_NAME") .or_else(|| crate::config::helpers::env_or_override("OPENCLAW_INSTANCE_NAME")) .filter(|v| !v.is_empty()) } @@ -634,7 +634,7 @@ fn hosted_state_checksum(payload_bytes: &[u8]) -> String { /// Build a versioned hosted OAuth state envelope. /// /// The encoded value is opaque to providers and can be decoded by both -/// IronClaw and the external auth proxy for routing and callback lookup. +/// OptimClaw and the external auth proxy for routing and callback lookup. pub fn encode_hosted_oauth_state(flow_id: &str, instance_name: Option<&str>) -> String { let payload = HostedOAuthStatePayload { flow_id: flow_id.to_string(), @@ -1351,11 +1351,11 @@ mod tests { fn test_callback_host_env_override() { let _guard = lock_env(); let original_host = std::env::var("OAUTH_CALLBACK_HOST").ok(); - let original_url = std::env::var("IRONCLAW_OAUTH_CALLBACK_URL").ok(); + let original_url = std::env::var("OPTIMCLAW_OAUTH_CALLBACK_URL").ok(); // SAFETY: Under ENV_MUTEX, no concurrent env access. unsafe { std::env::set_var("OAUTH_CALLBACK_HOST", "203.0.113.10"); - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); } assert_eq!(callback_host(), "203.0.113.10"); // callback_url() fallback should incorporate the custom host @@ -1369,7 +1369,7 @@ mod tests { std::env::remove_var("OAUTH_CALLBACK_HOST"); } if let Some(val) = original_url { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", val); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", val); } } } @@ -1378,11 +1378,11 @@ mod tests { fn test_callback_url_default() { let _guard = lock_env(); // Clear both env vars to test default behavior - let original_url = std::env::var("IRONCLAW_OAUTH_CALLBACK_URL").ok(); + let original_url = std::env::var("OPTIMCLAW_OAUTH_CALLBACK_URL").ok(); let original_host = std::env::var("OAUTH_CALLBACK_HOST").ok(); // SAFETY: Under ENV_MUTEX, no concurrent env access. unsafe { - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); std::env::remove_var("OAUTH_CALLBACK_HOST"); } let url = callback_url(); @@ -1390,7 +1390,7 @@ mod tests { // Restore unsafe { if let Some(val) = original_url { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", val); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", val); } if let Some(val) = original_host { std::env::set_var("OAUTH_CALLBACK_HOST", val); @@ -1401,11 +1401,11 @@ mod tests { #[test] fn test_callback_url_env_override() { let _guard = lock_env(); - let original = std::env::var("IRONCLAW_OAUTH_CALLBACK_URL").ok(); + let original = std::env::var("OPTIMCLAW_OAUTH_CALLBACK_URL").ok(); // SAFETY: Under ENV_MUTEX, no concurrent env access. unsafe { std::env::set_var( - "IRONCLAW_OAUTH_CALLBACK_URL", + "OPTIMCLAW_OAUTH_CALLBACK_URL", "https://myserver.example.com:9876", ); } @@ -1414,9 +1414,9 @@ mod tests { // Restore unsafe { if let Some(val) = original { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", val); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", val); } else { - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); } } } @@ -1440,7 +1440,7 @@ mod tests { let html = landing_html("Google", true); assert!(html.contains("Google Connected")); assert!(html.contains("charset")); - assert!(html.contains("IronClaw")); + assert!(html.contains("OptimClaw")); assert!(html.contains("#22c55e")); // green accent assert!(!html.contains("Failed")); } @@ -1457,7 +1457,7 @@ mod tests { let html = landing_html("Notion", false); assert!(html.contains("Authorization Failed")); assert!(html.contains("charset")); - assert!(html.contains("IronClaw")); + assert!(html.contains("OptimClaw")); assert!(html.contains("#ef4444")); // red accent assert!(!html.contains("Connected")); } @@ -1566,15 +1566,15 @@ mod tests { #[test] fn test_use_gateway_callback_false_by_default() { let _guard = lock_env(); - let original = std::env::var("IRONCLAW_OAUTH_CALLBACK_URL").ok(); + let original = std::env::var("OPTIMCLAW_OAUTH_CALLBACK_URL").ok(); // SAFETY: Under ENV_MUTEX, no concurrent env access. unsafe { - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); } assert!(!crate::cli::oauth_defaults::use_gateway_callback()); unsafe { if let Some(val) = original { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", val); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", val); } } } @@ -1582,20 +1582,20 @@ mod tests { #[test] fn test_use_gateway_callback_true_for_hosted() { let _guard = lock_env(); - let original = std::env::var("IRONCLAW_OAUTH_CALLBACK_URL").ok(); + let original = std::env::var("OPTIMCLAW_OAUTH_CALLBACK_URL").ok(); // SAFETY: Under ENV_MUTEX, no concurrent env access. unsafe { std::env::set_var( - "IRONCLAW_OAUTH_CALLBACK_URL", + "OPTIMCLAW_OAUTH_CALLBACK_URL", "https://kind-deer.agent1.near.ai", ); } assert!(crate::cli::oauth_defaults::use_gateway_callback()); unsafe { if let Some(val) = original { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", val); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", val); } else { - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); } } } @@ -1603,17 +1603,17 @@ mod tests { #[test] fn test_use_gateway_callback_false_for_localhost() { let _guard = lock_env(); - let original = std::env::var("IRONCLAW_OAUTH_CALLBACK_URL").ok(); + let original = std::env::var("OPTIMCLAW_OAUTH_CALLBACK_URL").ok(); // SAFETY: Under ENV_MUTEX, no concurrent env access. unsafe { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", "http://127.0.0.1:3001"); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", "http://127.0.0.1:3001"); } assert!(!crate::cli::oauth_defaults::use_gateway_callback()); unsafe { if let Some(val) = original { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", val); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", val); } else { - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); } } } @@ -1621,17 +1621,17 @@ mod tests { #[test] fn test_use_gateway_callback_false_for_empty() { let _guard = lock_env(); - let original = std::env::var("IRONCLAW_OAUTH_CALLBACK_URL").ok(); + let original = std::env::var("OPTIMCLAW_OAUTH_CALLBACK_URL").ok(); // SAFETY: Under ENV_MUTEX, no concurrent env access. unsafe { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", ""); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", ""); } assert!(!crate::cli::oauth_defaults::use_gateway_callback()); unsafe { if let Some(val) = original { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", val); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", val); } else { - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); } } } @@ -1641,10 +1641,10 @@ mod tests { use crate::cli::oauth_defaults::{build_platform_state, decode_hosted_oauth_state}; let _guard = lock_env(); - let original = std::env::var("IRONCLAW_INSTANCE_NAME").ok(); + let original = std::env::var("OPTIMCLAW_INSTANCE_NAME").ok(); // SAFETY: Under ENV_MUTEX, no concurrent env access. unsafe { - std::env::set_var("IRONCLAW_INSTANCE_NAME", "kind-deer"); + std::env::set_var("OPTIMCLAW_INSTANCE_NAME", "kind-deer"); } let encoded = build_platform_state("abc123"); let decoded = decode_hosted_oauth_state(&encoded).expect("decode hosted state"); @@ -1653,9 +1653,9 @@ mod tests { assert!(!decoded.is_legacy); unsafe { if let Some(val) = original { - std::env::set_var("IRONCLAW_INSTANCE_NAME", val); + std::env::set_var("OPTIMCLAW_INSTANCE_NAME", val); } else { - std::env::remove_var("IRONCLAW_INSTANCE_NAME"); + std::env::remove_var("OPTIMCLAW_INSTANCE_NAME"); } } } @@ -1665,11 +1665,11 @@ mod tests { use crate::cli::oauth_defaults::{build_platform_state, decode_hosted_oauth_state}; let _guard = lock_env(); - let original = std::env::var("IRONCLAW_INSTANCE_NAME").ok(); + let original = std::env::var("OPTIMCLAW_INSTANCE_NAME").ok(); let original_oc = std::env::var("OPENCLAW_INSTANCE_NAME").ok(); // SAFETY: Under ENV_MUTEX, no concurrent env access. unsafe { - std::env::remove_var("IRONCLAW_INSTANCE_NAME"); + std::env::remove_var("OPTIMCLAW_INSTANCE_NAME"); std::env::remove_var("OPENCLAW_INSTANCE_NAME"); } let encoded = build_platform_state("abc123"); @@ -1679,7 +1679,7 @@ mod tests { assert!(!decoded.is_legacy); unsafe { if let Some(val) = original { - std::env::set_var("IRONCLAW_INSTANCE_NAME", val); + std::env::set_var("OPTIMCLAW_INSTANCE_NAME", val); } if let Some(val) = original_oc { std::env::set_var("OPENCLAW_INSTANCE_NAME", val); @@ -1692,11 +1692,11 @@ mod tests { use crate::cli::oauth_defaults::{build_platform_state, decode_hosted_oauth_state}; let _guard = lock_env(); - let original_ic = std::env::var("IRONCLAW_INSTANCE_NAME").ok(); + let original_ic = std::env::var("OPTIMCLAW_INSTANCE_NAME").ok(); let original_oc = std::env::var("OPENCLAW_INSTANCE_NAME").ok(); // SAFETY: Under ENV_MUTEX, no concurrent env access. unsafe { - std::env::remove_var("IRONCLAW_INSTANCE_NAME"); + std::env::remove_var("OPTIMCLAW_INSTANCE_NAME"); std::env::set_var("OPENCLAW_INSTANCE_NAME", "quiet-lion"); } let encoded = build_platform_state("xyz789"); @@ -1706,7 +1706,7 @@ mod tests { assert!(!decoded.is_legacy); unsafe { if let Some(val) = original_ic { - std::env::set_var("IRONCLAW_INSTANCE_NAME", val); + std::env::set_var("OPTIMCLAW_INSTANCE_NAME", val); } if let Some(val) = original_oc { std::env::set_var("OPENCLAW_INSTANCE_NAME", val); @@ -1720,7 +1720,7 @@ mod tests { fn test_oauth_proxy_auth_token_prefers_dedicated_env() { let _guard = lock_env(); let _proxy_guard = set_env_var( - "IRONCLAW_OAUTH_PROXY_AUTH_TOKEN", + "OPTIMCLAW_OAUTH_PROXY_AUTH_TOKEN", Some("shared-proxy-secret"), ); let _gateway_guard = set_env_var("GATEWAY_AUTH_TOKEN", Some("gateway-token")); @@ -1734,7 +1734,7 @@ mod tests { #[test] fn test_oauth_proxy_auth_token_falls_back_to_gateway_token() { let _guard = lock_env(); - let _proxy_guard = set_env_var("IRONCLAW_OAUTH_PROXY_AUTH_TOKEN", None); + let _proxy_guard = set_env_var("OPTIMCLAW_OAUTH_PROXY_AUTH_TOKEN", None); let _gateway_guard = set_env_var("GATEWAY_AUTH_TOKEN", Some("gateway-token")); assert_eq!( @@ -1746,7 +1746,7 @@ mod tests { #[test] fn test_oauth_proxy_auth_token_whitespace_dedicated_env_falls_back_to_gateway_token() { let _guard = lock_env(); - let _proxy_guard = set_env_var("IRONCLAW_OAUTH_PROXY_AUTH_TOKEN", Some(" ")); + let _proxy_guard = set_env_var("OPTIMCLAW_OAUTH_PROXY_AUTH_TOKEN", Some(" ")); let _gateway_guard = set_env_var("GATEWAY_AUTH_TOKEN", Some("gateway-token")); assert_eq!( @@ -1758,7 +1758,7 @@ mod tests { #[test] fn test_oauth_proxy_auth_token_returns_none_when_unset() { let _guard = lock_env(); - let _proxy_guard = set_env_var("IRONCLAW_OAUTH_PROXY_AUTH_TOKEN", None); + let _proxy_guard = set_env_var("OPTIMCLAW_OAUTH_PROXY_AUTH_TOKEN", None); let _gateway_guard = set_env_var("GATEWAY_AUTH_TOKEN", None); assert_eq!(crate::cli::oauth_defaults::oauth_proxy_auth_token(), None); diff --git a/src/cli/registry.rs b/src/cli/registry.rs index a2fa8b02..75b9276f 100644 --- a/src/cli/registry.rs +++ b/src/cli/registry.rs @@ -144,7 +144,7 @@ fn cmd_list( let bundle_names = catalog.bundle_names(); if !bundle_names.is_empty() { println!("\nBundles available: {}", bundle_names.join(", ")); - println!("Use `ironclaw registry info ` for details."); + println!("Use `optimclaw registry info ` for details."); } Ok(()) @@ -304,7 +304,7 @@ async fn cmd_install( && auth.method.as_deref() != Some("none") { println!( - "\nNext step: authenticate with `ironclaw tool auth {}`", + "\nNext step: authenticate with `optimclaw tool auth {}`", manifest.name ); if let Some(url) = &auth.setup_url { diff --git a/src/cli/routines.rs b/src/cli/routines.rs index 287663f6..2a74a89c 100644 --- a/src/cli/routines.rs +++ b/src/cli/routines.rs @@ -1,4 +1,4 @@ -//! `ironclaw routines` — manage scheduled routines from the CLI. +//! `optimclaw routines` — manage scheduled routines from the CLI. //! //! Provides subcommands for listing, creating, editing, enabling/disabling, //! deleting, and viewing run history of routines without starting the full agent. diff --git a/src/cli/service.rs b/src/cli/service.rs index 100f472f..6c7ce62f 100644 --- a/src/cli/service.rs +++ b/src/cli/service.rs @@ -1,4 +1,4 @@ -//! CLI subcommand definitions for `ironclaw service`. +//! CLI subcommand definitions for `optimclaw service`. use clap::Subcommand; diff --git a/src/cli/skills.rs b/src/cli/skills.rs index 1f3cc46b..f3c8c501 100644 --- a/src/cli/skills.rs +++ b/src/cli/skills.rs @@ -121,7 +121,7 @@ async fn cmd_list(config: &SkillsConfig, verbose: bool, json: bool) -> anyhow::R println!(" User: {}", config.local_dir.display()); println!(" Installed: {}", config.installed_dir.display()); println!(); - println!("Use 'ironclaw skills search ' to find skills on ClawHub."); + println!("Use 'optimclaw skills search ' to find skills on ClawHub."); return Ok(()); } @@ -157,7 +157,7 @@ async fn cmd_list(config: &SkillsConfig, verbose: bool, json: bool) -> anyhow::R if !verbose { println!(); println!( - "Use --verbose for details, or 'ironclaw skills info ' for a specific skill." + "Use --verbose for details, or 'optimclaw skills info ' for a specific skill." ); } @@ -251,7 +251,7 @@ async fn cmd_info(config: &SkillsConfig, name: &str, json: bool) -> anyhow::Resu let registry = discover_skills(config).await; let skill = registry.find_by_name(name).ok_or_else(|| { anyhow::anyhow!( - "Skill '{}' not found. Use 'ironclaw skills list' to see available skills.", + "Skill '{}' not found. Use 'optimclaw skills list' to see available skills.", name ) })?; diff --git a/src/cli/snapshots/ironclaw__cli__tests__help_output.snap b/src/cli/snapshots/optimclaw__cli__tests__help_output.snap similarity index 100% rename from src/cli/snapshots/ironclaw__cli__tests__help_output.snap rename to src/cli/snapshots/optimclaw__cli__tests__help_output.snap diff --git a/src/cli/snapshots/ironclaw__cli__tests__help_output_without_import.snap b/src/cli/snapshots/optimclaw__cli__tests__help_output_without_import.snap similarity index 100% rename from src/cli/snapshots/ironclaw__cli__tests__help_output_without_import.snap rename to src/cli/snapshots/optimclaw__cli__tests__help_output_without_import.snap diff --git a/src/cli/snapshots/ironclaw__cli__tests__long_help_output.snap b/src/cli/snapshots/optimclaw__cli__tests__long_help_output.snap similarity index 100% rename from src/cli/snapshots/ironclaw__cli__tests__long_help_output.snap rename to src/cli/snapshots/optimclaw__cli__tests__long_help_output.snap diff --git a/src/cli/snapshots/ironclaw__cli__tests__long_help_output_without_import.snap b/src/cli/snapshots/optimclaw__cli__tests__long_help_output_without_import.snap similarity index 100% rename from src/cli/snapshots/ironclaw__cli__tests__long_help_output_without_import.snap rename to src/cli/snapshots/optimclaw__cli__tests__long_help_output_without_import.snap diff --git a/src/cli/status.rs b/src/cli/status.rs index 3ae825ee..4b1854c3 100644 --- a/src/cli/status.rs +++ b/src/cli/status.rs @@ -5,7 +5,7 @@ use std::path::PathBuf; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::cli::fmt; use crate::settings::Settings; @@ -40,7 +40,7 @@ pub async fn run_status_command() -> anyhow::Result<()> { let settings = load_settings(); println!(); - println!(" {}IronClaw Status{}", fmt::bold(), fmt::reset()); + println!(" {}OptimClaw Status{}", fmt::bold(), fmt::reset()); println!(); // Version @@ -91,7 +91,7 @@ pub async fn run_status_command() -> anyhow::Result<()> { let session_value = if session_path.exists() { format!("found ({})", session_path.display()) } else { - "not found (run `ironclaw onboard`)".to_string() + "not found (run `optimclaw onboard`)".to_string() }; println!("{}", fmt::kv_line("Session", &session_value, 12)); @@ -188,7 +188,7 @@ pub async fn run_status_command() -> anyhow::Result<()> { "{}", fmt::kv_line( "Config", - &crate::bootstrap::ironclaw_env_path().display().to_string(), + &crate::bootstrap::optimclaw_env_path().display().to_string(), 12, ) ); @@ -238,11 +238,11 @@ fn count_wasm_files(dir: &std::path::Path) -> usize { } fn default_tools_dir() -> PathBuf { - ironclaw_base_dir().join("tools") + optimclaw_base_dir().join("tools") } fn default_channels_dir() -> PathBuf { - ironclaw_base_dir().join("channels") + optimclaw_base_dir().join("channels") } #[cfg(test)] diff --git a/src/cli/tool.rs b/src/cli/tool.rs index 9d39c492..0617450f 100644 --- a/src/cli/tool.rs +++ b/src/cli/tool.rs @@ -10,13 +10,13 @@ use std::sync::Arc; use clap::Subcommand; use tokio::fs; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::secrets::{CreateSecretParams, SecretsStore}; use crate::tools::wasm::{CapabilitiesFile, compute_binary_hash}; /// Default tools directory. fn default_tools_dir() -> PathBuf { - ironclaw_base_dir().join("tools") + optimclaw_base_dir().join("tools") } #[derive(Subcommand, Debug, Clone)] @@ -34,7 +34,7 @@ pub enum ToolCommand { #[arg(long)] capabilities: Option, - /// Target directory for installation (default: ~/.ironclaw/tools/) + /// Target directory for installation (default: ~/.optimclaw/tools/) #[arg(short, long)] target: Option, @@ -53,7 +53,7 @@ pub enum ToolCommand { /// List installed tools List { - /// Directory to list tools from (default: ~/.ironclaw/tools/) + /// Directory to list tools from (default: ~/.optimclaw/tools/) #[arg(short, long)] dir: Option, @@ -67,7 +67,7 @@ pub enum ToolCommand { /// Name of the tool to remove name: String, - /// Directory to remove tool from (default: ~/.ironclaw/tools/) + /// Directory to remove tool from (default: ~/.optimclaw/tools/) #[arg(short, long)] dir: Option, }, @@ -77,7 +77,7 @@ pub enum ToolCommand { /// Name of the tool or path to .wasm file name_or_path: String, - /// Directory to look for tool (default: ~/.ironclaw/tools/) + /// Directory to look for tool (default: ~/.optimclaw/tools/) #[arg(short, long)] dir: Option, @@ -91,7 +91,7 @@ pub enum ToolCommand { /// Name of the tool name: String, - /// Directory to look for tool (default: ~/.ironclaw/tools/) + /// Directory to look for tool (default: ~/.optimclaw/tools/) #[arg(short, long)] dir: Option, @@ -105,7 +105,7 @@ pub enum ToolCommand { /// Name of the tool name: String, - /// Directory to look for tool (default: ~/.ironclaw/tools/) + /// Directory to look for tool (default: ~/.optimclaw/tools/) #[arg(short, long)] dir: Option, @@ -304,7 +304,7 @@ async fn list_tools(dir: Option, verbose: bool) -> anyhow::Result<()> { if !tools_dir.exists() { println!("No tools directory found at {}", tools_dir.display()); - println!("Install a tool with: ironclaw tool install "); + println!("Install a tool with: optimclaw tool install "); return Ok(()); } @@ -1195,7 +1195,7 @@ async fn setup_tool(name: String, dir: Option, user_id: String) -> anyh anyhow::anyhow!( "Tool '{}' has no setup configuration.\n\ The tool may not require setup, or setup is not defined.\n\ - Try 'ironclaw tool auth {}' for OAuth-based authentication.", + Try 'optimclaw tool auth {}' for OAuth-based authentication.", name, name ) @@ -1302,7 +1302,7 @@ mod tests { #[test] fn test_default_tools_dir() { let dir = default_tools_dir(); - assert!(dir.to_string_lossy().contains(".ironclaw")); + assert!(dir.to_string_lossy().contains(".optimclaw")); assert!(dir.to_string_lossy().contains("tools")); } diff --git a/src/config/channels.rs b/src/config/channels.rs index dec04f39..1dd1b428 100644 --- a/src/config/channels.rs +++ b/src/config/channels.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::path::PathBuf; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::config::helpers::{optional_env, parse_bool_env, parse_optional_env}; use crate::error::ConfigError; use crate::settings::Settings; @@ -14,7 +14,7 @@ pub struct ChannelsConfig { pub http: Option, pub gateway: Option, pub signal: Option, - /// Directory containing WASM channel modules (default: ~/.ironclaw/channels/). + /// Directory containing WASM channel modules (default: ~/.optimclaw/channels/). pub wasm_channels_dir: std::path::PathBuf, /// Whether WASM channels are enabled. pub wasm_channels_enabled: bool, @@ -309,9 +309,9 @@ impl ChannelsConfig { /// other modules that need to construct a gateway URL. pub const DEFAULT_GATEWAY_PORT: u16 = 3000; -/// Get the default channels directory (~/.ironclaw/channels/). +/// Get the default channels directory (~/.optimclaw/channels/). fn default_channels_dir() -> PathBuf { - ironclaw_base_dir().join("channels") + optimclaw_base_dir().join("channels") } #[cfg(test)] diff --git a/src/config/database.rs b/src/config/database.rs index 55d8baea..bee5bf21 100644 --- a/src/config/database.rs +++ b/src/config/database.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use secrecy::{ExposeSecret, SecretString}; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::config::helpers::{optional_env, parse_optional_env}; use crate::error::ConfigError; @@ -95,7 +95,7 @@ pub struct DatabaseConfig { pub ssl_mode: SslMode, // -- libSQL fields -- - /// Path to local libSQL database file (default: ~/.ironclaw/ironclaw.db). + /// Path to local libSQL database file (default: ~/.optimclaw/optimclaw.db). pub libsql_path: Option, /// Turso cloud URL for remote sync (optional). pub libsql_url: Option, @@ -116,7 +116,7 @@ impl DatabaseConfig { // PostgreSQL URL is required only when using the postgres backend. // For libsql backend, default to an empty placeholder. - // DATABASE_URL is loaded from ~/.ironclaw/.env via dotenvy early in startup. + // DATABASE_URL is loaded from ~/.optimclaw/.env via dotenvy early in startup. let url = optional_env("DATABASE_URL")? .or_else(|| { if backend == DatabaseBackend::LibSql { @@ -127,7 +127,7 @@ impl DatabaseConfig { }) .ok_or_else(|| ConfigError::MissingRequired { key: "DATABASE_URL".to_string(), - hint: "Run 'ironclaw onboard' or set DATABASE_URL environment variable".to_string(), + hint: "Run 'optimclaw onboard' or set DATABASE_URL environment variable".to_string(), })?; let pool_size = parse_optional_env("DATABASE_POOL_SIZE", 10)?; @@ -224,9 +224,9 @@ impl SslMode { } } -/// Default libSQL database path (~/.ironclaw/ironclaw.db). +/// Default libSQL database path (~/.optimclaw/optimclaw.db). pub fn default_libsql_path() -> PathBuf { - ironclaw_base_dir().join("ironclaw.db") + optimclaw_base_dir().join("optimclaw.db") } #[cfg(test)] diff --git a/src/config/helpers.rs b/src/config/helpers.rs index ff5ee706..64bcc7c7 100644 --- a/src/config/helpers.rs +++ b/src/config/helpers.rs @@ -338,7 +338,7 @@ mod tests { #[test] fn runtime_env_override_is_visible_to_env_or_override() { // Use a unique key that won't collide with real env vars. - let key = "IRONCLAW_TEST_RUNTIME_OVERRIDE_42"; + let key = "OPTIMCLAW_TEST_RUNTIME_OVERRIDE_42"; // Not set initially assert!(env_or_override(key).is_none()); @@ -352,7 +352,7 @@ mod tests { #[test] fn runtime_env_override_is_visible_to_optional_env() { - let key = "IRONCLAW_TEST_OPTIONAL_ENV_OVERRIDE_42"; + let key = "OPTIMCLAW_TEST_OPTIONAL_ENV_OVERRIDE_42"; assert_eq!(optional_env(key).unwrap(), None); @@ -364,7 +364,7 @@ mod tests { #[test] fn real_env_var_takes_priority_over_runtime_override() { let _guard = lock_env(); - let key = "IRONCLAW_TEST_ENV_PRIORITY_42"; + let key = "OPTIMCLAW_TEST_ENV_PRIORITY_42"; // Set runtime override set_runtime_env(key, "override_value"); diff --git a/src/config/hygiene.rs b/src/config/hygiene.rs index b510933a..35beb4b0 100644 --- a/src/config/hygiene.rs +++ b/src/config/hygiene.rs @@ -1,4 +1,4 @@ -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::config::helpers::{parse_bool_env, parse_optional_env}; use crate::error::ConfigError; @@ -43,14 +43,14 @@ impl HygieneConfig { } /// Convert to the workspace hygiene config, resolving the state directory - /// to the standard `~/.ironclaw` location. + /// to the standard `~/.optimclaw` location. pub fn to_workspace_config(&self) -> crate::workspace::hygiene::HygieneConfig { crate::workspace::hygiene::HygieneConfig { enabled: self.enabled, daily_retention_days: self.daily_retention_days, conversation_retention_days: self.conversation_retention_days, cadence_hours: self.cadence_hours, - state_dir: ironclaw_base_dir(), + state_dir: optimclaw_base_dir(), } } } diff --git a/src/config/llm.rs b/src/config/llm.rs index ed4b8a05..8cc9f04a 100644 --- a/src/config/llm.rs +++ b/src/config/llm.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use secrecy::SecretString; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::config::helpers::{optional_env, parse_optional_env, validate_base_url}; use crate::error::ConfigError; use crate::llm::config::*; @@ -18,7 +18,7 @@ impl LlmConfig { backend: "nearai".to_string(), session: SessionConfig { auth_base_url: "http://localhost:0".to_string(), - session_path: std::env::temp_dir().join("ironclaw-test-session.json"), + session_path: std::env::temp_dir().join("optimclaw-test-session.json"), }, nearai: NearAiConfig { model: "test-model".to_string(), @@ -203,7 +203,7 @@ impl LlmConfig { .unwrap_or_else(|| "app_EMoamEEZ73f0CkXaXp7hrann".to_string()); let session_path = optional_env("OPENAI_CODEX_SESSION_PATH")? .map(PathBuf::from) - .unwrap_or_else(|| ironclaw_base_dir().join("openai_codex_session.json")); + .unwrap_or_else(|| optimclaw_base_dir().join("openai_codex_session.json")); let token_refresh_margin_secs = parse_optional_env("OPENAI_CODEX_REFRESH_MARGIN_SECS", 300)?; Some(OpenAiCodexConfig { @@ -527,9 +527,9 @@ fn merge_extra_headers( merged } -/// Get the default session file path (~/.ironclaw/session.json). +/// Get the default session file path (~/.optimclaw/session.json). pub fn default_session_path() -> PathBuf { - ironclaw_base_dir().join("session.json") + optimclaw_base_dir().join("session.json") } #[cfg(test)] diff --git a/src/config/mod.rs b/src/config/mod.rs index a362fd09..027b2884 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,7 +1,7 @@ -//! Configuration for IronClaw. +//! Configuration for OptimClaw. //! //! Settings are loaded with priority: env var > database > default. -//! `DATABASE_URL` lives in `~/.ironclaw/.env` (loaded via dotenvy early +//! `DATABASE_URL` lives in `~/.optimclaw/.env` (loaded via dotenvy early //! in startup). Everything else comes from env vars, the DB settings //! table, or auto-detection. @@ -141,7 +141,7 @@ impl Config { http: None, gateway: None, signal: None, - wasm_channels_dir: std::env::temp_dir().join("ironclaw-test-channels"), + wasm_channels_dir: std::env::temp_dir().join("optimclaw-test-channels"), wasm_channels_enabled: false, wasm_channel_owner_ids: HashMap::new(), }, @@ -202,7 +202,7 @@ impl Config { toml_path: Option<&std::path::Path>, ) -> Result { let _ = dotenvy::dotenv(); - crate::bootstrap::load_ironclaw_env(); + crate::bootstrap::load_optimclaw_env(); // Load all settings from DB into a Settings struct let mut db_settings = match store.get_all_settings(user_id).await { @@ -225,7 +225,7 @@ impl Config { /// and by CLI commands that don't have DB access. /// Falls back to legacy `settings.json` on disk if present. /// - /// Loads both `./.env` (standard, higher priority) and `~/.ironclaw/.env` + /// Loads both `./.env` (standard, higher priority) and `~/.optimclaw/.env` /// (lower priority) via dotenvy, which never overwrites existing vars. pub async fn from_env() -> Result { Self::from_env_with_toml(None).await @@ -242,7 +242,7 @@ impl Config { /// Load and merge a TOML config file into settings. /// /// If `explicit_path` is `Some`, loads from that path (errors are fatal). - /// If `None`, tries the default path `~/.ironclaw/config.toml` (missing + /// If `None`, tries the default path `~/.optimclaw/config.toml` (missing /// file is silently ignored). fn apply_toml_overlay( settings: &mut Settings, @@ -351,7 +351,7 @@ pub(crate) fn load_bootstrap_settings( toml_path: Option<&std::path::Path>, ) -> Result { let _ = dotenvy::dotenv(); - crate::bootstrap::load_ironclaw_env(); + crate::bootstrap::load_optimclaw_env(); let mut settings = Settings::load(); Config::apply_toml_overlay(&mut settings, toml_path)?; @@ -359,7 +359,7 @@ pub(crate) fn load_bootstrap_settings( } pub(crate) fn resolve_owner_id(settings: &Settings) -> Result { - let env_owner_id = self::helpers::optional_env("IRONCLAW_OWNER_ID")?; + let env_owner_id = self::helpers::optional_env("OPTIMCLAW_OWNER_ID")?; let settings_owner_id = settings.owner_id.clone(); let configured_owner_id = env_owner_id.clone().or(settings_owner_id.clone()); @@ -376,7 +376,7 @@ pub(crate) fn resolve_owner_id(settings: &Settings) -> Result Some("http://relay:3001".into()), "CHANNEL_RELAY_API_KEY" => Some("secret".into()), - "IRONCLAW_OAUTH_CALLBACK_URL" => Some("https://tunnel.example.com".into()), - "IRONCLAW_INSTANCE_ID" => Some("my-instance".into()), + "OPTIMCLAW_OAUTH_CALLBACK_URL" => Some("https://tunnel.example.com".into()), + "OPTIMCLAW_INSTANCE_ID" => Some("my-instance".into()), "RELAY_REQUEST_TIMEOUT_SECS" => Some("60".into()), "RELAY_WEBHOOK_PATH" => Some("/custom/events".into()), _ => None, diff --git a/src/config/safety.rs b/src/config/safety.rs index edeceee0..c1a4747e 100644 --- a/src/config/safety.rs +++ b/src/config/safety.rs @@ -1,7 +1,7 @@ use crate::config::helpers::{parse_bool_env, parse_optional_env}; use crate::error::ConfigError; -pub use ironclaw_safety::SafetyConfig; +pub use optimclaw_safety::SafetyConfig; pub(crate) fn resolve_safety_config( settings: &crate::settings::Settings, diff --git a/src/config/sandbox.rs b/src/config/sandbox.rs index 01a8c327..a797c2a8 100644 --- a/src/config/sandbox.rs +++ b/src/config/sandbox.rs @@ -42,7 +42,7 @@ impl Default for SandboxModeConfig { timeout_secs: 120, memory_limit_mb: 2048, cpu_shares: 1024, - image: "ironclaw-worker:latest".to_string(), + image: "optimclaw-worker:latest".to_string(), auto_pull_image: true, extra_allowed_domains: Vec::new(), reaper_interval_secs: 300, @@ -344,7 +344,7 @@ mod tests { assert_eq!(cfg.timeout_secs, 120); assert_eq!(cfg.memory_limit_mb, 2048); assert_eq!(cfg.cpu_shares, 1024); - assert_eq!(cfg.image, "ironclaw-worker:latest"); + assert_eq!(cfg.image, "optimclaw-worker:latest"); assert!(cfg.auto_pull_image); assert!(cfg.extra_allowed_domains.is_empty()); } diff --git a/src/config/skills.rs b/src/config/skills.rs index 97970784..e8b2ec89 100644 --- a/src/config/skills.rs +++ b/src/config/skills.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::config::helpers::{optional_env, parse_bool_env, parse_optional_env}; use crate::error::ConfigError; @@ -9,10 +9,10 @@ use crate::error::ConfigError; pub struct SkillsConfig { /// Whether the skills system is enabled. pub enabled: bool, - /// Directory containing user-placed skills (default: ~/.ironclaw/skills/). + /// Directory containing user-placed skills (default: ~/.optimclaw/skills/). /// Skills here are loaded with `Trusted` trust level. pub local_dir: PathBuf, - /// Directory containing registry-installed skills (default: ~/.ironclaw/installed_skills/). + /// Directory containing registry-installed skills (default: ~/.optimclaw/installed_skills/). /// Skills here are loaded with `Installed` trust level and get read-only tool access. pub installed_dir: PathBuf, /// Maximum number of skills that can be active simultaneously. @@ -33,14 +33,14 @@ impl Default for SkillsConfig { } } -/// Get the default user skills directory (~/.ironclaw/skills/). +/// Get the default user skills directory (~/.optimclaw/skills/). fn default_skills_dir() -> PathBuf { - ironclaw_base_dir().join("skills") + optimclaw_base_dir().join("skills") } -/// Get the default installed skills directory (~/.ironclaw/installed_skills/). +/// Get the default installed skills directory (~/.optimclaw/installed_skills/). fn default_installed_skills_dir() -> PathBuf { - ironclaw_base_dir().join("installed_skills") + optimclaw_base_dir().join("installed_skills") } impl SkillsConfig { diff --git a/src/config/wasm.rs b/src/config/wasm.rs index 4c494a38..1feecfa2 100644 --- a/src/config/wasm.rs +++ b/src/config/wasm.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use std::time::Duration; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::config::helpers::{optional_env, parse_bool_env, parse_optional_env}; use crate::error::ConfigError; @@ -10,7 +10,7 @@ use crate::error::ConfigError; pub struct WasmConfig { /// Whether WASM tool execution is enabled. pub enabled: bool, - /// Directory containing installed WASM tools (default: ~/.ironclaw/tools/). + /// Directory containing installed WASM tools (default: ~/.optimclaw/tools/). pub tools_dir: PathBuf, /// Default memory limit in bytes (default: 10 MB). pub default_memory_limit: u64, @@ -38,9 +38,9 @@ impl Default for WasmConfig { } } -/// Get the default tools directory (~/.ironclaw/tools/). +/// Get the default tools directory (~/.optimclaw/tools/). fn default_tools_dir() -> PathBuf { - ironclaw_base_dir().join("tools") + optimclaw_base_dir().join("tools") } impl WasmConfig { diff --git a/src/db/CLAUDE.md b/src/db/CLAUDE.md index 22edc8f1..b353c1a7 100644 --- a/src/db/CLAUDE.md +++ b/src/db/CLAUDE.md @@ -141,7 +141,7 @@ The `Database` supertrait is composed of seven sub-traits. Leaf consumers can de ```bash # Use local SQLite file (default) -DATABASE_BACKEND=libsql LIBSQL_PATH=~/.ironclaw/test.db cargo run +DATABASE_BACKEND=libsql LIBSQL_PATH=~/.optimclaw/test.db cargo run # Use Turso cloud (embedded replica syncs local file to cloud) DATABASE_BACKEND=libsql LIBSQL_URL=libsql://xxx.turso.io LIBSQL_AUTH_TOKEN=xxx cargo run diff --git a/src/db/mod.rs b/src/db/mod.rs index e2a81412..4a5a312a 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -275,7 +275,7 @@ async fn validate_postgres(pool: &deadpool_postgres::Pool) -> Result<(), Databas if major_version < MIN_PG_MAJOR_VERSION { return Err(DatabaseError::Pool(format!( - "PostgreSQL {} detected. IronClaw requires PostgreSQL {} or later \ + "PostgreSQL {} detected. OptimClaw requires PostgreSQL {} or later \ for pgvector support.\n\ Upgrade: https://www.postgresql.org/download/", version_str, MIN_PG_MAJOR_VERSION @@ -301,7 +301,7 @@ async fn validate_postgres(pool: &deadpool_postgres::Pool) -> Result<(), Databas Ubuntu: apt install postgresql-{0}-pgvector\n \ Docker: use the pgvector/pgvector:pg{0} image\n \ Source: https://github.com/pgvector/pgvector#installation\n\n\ - Then restart PostgreSQL and re-run: ironclaw onboard", + Then restart PostgreSQL and re-run: optimclaw onboard", major_version ))); } diff --git a/src/error.rs b/src/error.rs index e4f1b957..60954a43 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,4 @@ -//! Error types for IronClaw. +//! Error types for OptimClaw. use std::time::Duration; @@ -354,7 +354,7 @@ pub enum WorkerError { #[error("Worker execution failed: {reason}")] ExecutionFailed { reason: String }, - #[error("Missing worker token (IRONCLAW_WORKER_TOKEN not set)")] + #[error("Missing worker token (OPTIMCLAW_WORKER_TOKEN not set)")] MissingToken, } diff --git a/src/extensions/discovery.rs b/src/extensions/discovery.rs index 64cdf104..2c44ce82 100644 --- a/src/extensions/discovery.rs +++ b/src/extensions/discovery.rs @@ -22,7 +22,7 @@ impl OnlineDiscovery { pub fn new() -> Self { let http_client = reqwest::Client::builder() .timeout(Duration::from_secs(10)) - .user_agent("IronClaw/1.0") + .user_agent("OptimClaw/1.0") .build() .unwrap_or_else(|_| reqwest::Client::new()); diff --git a/src/extensions/manager.rs b/src/extensions/manager.rs index 82dc5471..deae81af 100644 --- a/src/extensions/manager.rs +++ b/src/extensions/manager.rs @@ -292,7 +292,7 @@ fn channel_auth_instructions( ) -> String { if channel_name == TELEGRAM_CHANNEL_NAME && secret.name == "telegram_bot_token" { return format!( - "{} After you submit it, IronClaw will show a one-time verification code. Send `/start CODE` to your bot in Telegram and IronClaw will finish setup automatically.", + "{} After you submit it, OptimClaw will show a one-time verification code. Send `/start CODE` to your bot in Telegram and OptimClaw will finish setup automatically.", secret.prompt ); } @@ -326,11 +326,11 @@ fn telegram_verification_deep_link(bot_username: Option<&str>, code: &str) -> Op fn telegram_verification_instructions(bot_username: Option<&str>, code: &str) -> String { if let Some(username) = bot_username.filter(|username| !username.trim().is_empty()) { return format!( - "Send `/start {code}` to @{username} in Telegram. IronClaw will finish setup automatically." + "Send `/start {code}` to @{username} in Telegram. OptimClaw will finish setup automatically." ); } - format!("Send `/start {code}` to your Telegram bot. IronClaw will finish setup automatically.") + format!("Send `/start {code}` to your Telegram bot. OptimClaw will finish setup automatically.") } fn telegram_message_matches_verification_code(text: &str, code: &str) -> bool { @@ -436,7 +436,7 @@ pub struct ExtensionManager { /// `/oauth/callback` handler. pending_oauth_flows: crate::cli::oauth_defaults::PendingOAuthRegistry, /// OAuth proxy auth token for authenticating with the hosted token exchange proxy. - /// Resolved once at construction from `IRONCLAW_OAUTH_PROXY_AUTH_TOKEN`, + /// Resolved once at construction from `OPTIMCLAW_OAUTH_PROXY_AUTH_TOKEN`, /// then `GATEWAY_AUTH_TOKEN` as a backward-compatible fallback. oauth_proxy_auth_token: Option, /// Relay config captured at startup. Used by `auth_channel_relay` and @@ -619,7 +619,7 @@ impl ExtensionManager { /// instead of calling `open::that()` on the server. /// /// `base_url` is the gateway's own public URL (e.g. `https://my-gateway.example.com`), - /// used to build OAuth redirect URIs when `IRONCLAW_OAUTH_CALLBACK_URL` is not set. + /// used to build OAuth redirect URIs when `OPTIMCLAW_OAUTH_CALLBACK_URL` is not set. pub async fn enable_gateway_mode(&self, base_url: String) { self.gateway_mode .store(true, std::sync::atomic::Ordering::Release); @@ -631,7 +631,7 @@ impl ExtensionManager { /// /// Gateway mode is active when any of: /// - `enable_gateway_mode()` was called (web gateway is running), OR - /// - `IRONCLAW_OAUTH_CALLBACK_URL` is set to a non-loopback URL, OR + /// - `OPTIMCLAW_OAUTH_CALLBACK_URL` is set to a non-loopback URL, OR /// - `self.tunnel_url` is set to a non-loopback URL pub fn should_use_gateway_mode(&self) -> bool { if self.gateway_mode.load(std::sync::atomic::Ordering::Acquire) { @@ -652,7 +652,7 @@ impl ExtensionManager { /// Returns the OAuth redirect URI for gateway mode, or `None` for local mode. /// /// Priority: - /// 1. `IRONCLAW_OAUTH_CALLBACK_URL` env var (via `callback_url()`) + /// 1. `OPTIMCLAW_OAUTH_CALLBACK_URL` env var (via `callback_url()`) /// 2. `gateway_base_url` (set by `enable_gateway_mode()`) /// 3. `tunnel_url` (from config) /// 4. `None` (local/CLI mode) @@ -1251,7 +1251,7 @@ impl ExtensionManager { /// Broadcast an extension status change to the web UI via SSE. async fn broadcast_extension_status(&self, name: &str, status: &str, message: Option<&str>) { if let Some(ref sse) = *self.sse_manager.read().await { - sse.broadcast(ironclaw_common::AppEvent::ExtensionStatus { + sse.broadcast(optimclaw_common::AppEvent::ExtensionStatus { extension_name: name.to_string(), status: status.to_string(), message: message.map(|m| m.to_string()), @@ -1756,7 +1756,7 @@ impl ExtensionManager { .await; Ok(format!( - "Removed channel '{}'. Restart IronClaw for the change to take effect.", + "Removed channel '{}'. Restart OptimClaw for the change to take effect.", name )) } @@ -2630,7 +2630,7 @@ impl ExtensionManager { ExtensionError::InstallFailed(format!( "'{}' requires building from source. Build artifact not found. \ Run `cargo component build --release` in {} first, \ - or use `ironclaw registry install {}`.", + or use `optimclaw registry install {}`.", name, resolved_dir.display(), name, @@ -3720,7 +3720,7 @@ impl ExtensionManager { } if let Some(ref sse) = sse_manager { - sse.broadcast(ironclaw_common::AppEvent::AuthCompleted { + sse.broadcast(optimclaw_common::AppEvent::AuthCompleted { extension_name: ext_name, success, message, @@ -4661,7 +4661,7 @@ impl ExtensionManager { ExtensionError::Config(e.to_string()) })?; - // Generate CSRF nonce — IronClaw validates this on the callback to ensure + // Generate CSRF nonce — OptimClaw validates this on the callback to ensure // the OAuth completion is legitimate. Channel-relay embeds it in the signed // state and appends it to the post-OAuth redirect URL. let state_nonce = uuid::Uuid::new_v4().to_string(); @@ -7361,7 +7361,7 @@ mod tests { Ok(TelegramBindingResult::Pending(VerificationChallenge { code: "iclaw-7qk2m9".to_string(), instructions: - "Send `/start iclaw-7qk2m9` to @test_hot_bot in Telegram. IronClaw will finish setup automatically." + "Send `/start iclaw-7qk2m9` to @test_hot_bot in Telegram. OptimClaw will finish setup automatically." .to_string(), deep_link: Some("https://t.me/test_hot_bot?start=iclaw-7qk2m9".to_string()), })) @@ -8363,7 +8363,7 @@ mod tests { // Regression tests for a bug where MCP OAuth called `open::that()` on the // server machine instead of returning an auth URL to the gateway frontend. // The root cause was that `should_use_gateway_mode()` only checked the - // `IRONCLAW_OAUTH_CALLBACK_URL` env var, ignoring `self.tunnel_url`. + // `OPTIMCLAW_OAUTH_CALLBACK_URL` env var, ignoring `self.tunnel_url`. /// Build a minimal ExtensionManager with a custom tunnel_url. fn make_manager_with_tunnel(tunnel_url: Option) -> ExtensionManager { @@ -8377,7 +8377,7 @@ mod tests { Arc::new(InMemorySecretsStore::new(crypto)); let tools = Arc::new(crate::tools::ToolRegistry::new()); let mcp = Arc::new(McpSessionManager::new()); - let dir = std::env::temp_dir().join("ironclaw-test-gateway-mode"); + let dir = std::env::temp_dir().join("optimclaw-test-gateway-mode"); ExtensionManager::new( mcp, @@ -8398,10 +8398,10 @@ mod tests { #[test] fn should_use_gateway_mode_true_for_tunnel_url() { let _guard = crate::config::helpers::lock_env(); - let original = std::env::var("IRONCLAW_OAUTH_CALLBACK_URL").ok(); + let original = std::env::var("OPTIMCLAW_OAUTH_CALLBACK_URL").ok(); // SAFETY: Under ENV_MUTEX, no concurrent env access. unsafe { - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); } let mgr = make_manager_with_tunnel(Some("https://my-gateway.example.com".into())); @@ -8412,7 +8412,7 @@ mod tests { unsafe { if let Some(val) = original { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", val); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", val); } } } @@ -8420,9 +8420,9 @@ mod tests { #[test] fn should_use_gateway_mode_false_without_tunnel() { let _guard = crate::config::helpers::lock_env(); - let original = std::env::var("IRONCLAW_OAUTH_CALLBACK_URL").ok(); + let original = std::env::var("OPTIMCLAW_OAUTH_CALLBACK_URL").ok(); unsafe { - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); } let mgr = make_manager_with_tunnel(None); @@ -8433,7 +8433,7 @@ mod tests { unsafe { if let Some(val) = original { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", val); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", val); } } } @@ -8441,9 +8441,9 @@ mod tests { #[test] fn should_use_gateway_mode_false_for_loopback_tunnel() { let _guard = crate::config::helpers::lock_env(); - let original = std::env::var("IRONCLAW_OAUTH_CALLBACK_URL").ok(); + let original = std::env::var("OPTIMCLAW_OAUTH_CALLBACK_URL").ok(); unsafe { - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); } let mgr = make_manager_with_tunnel(Some("http://127.0.0.1:3001".into())); @@ -8454,13 +8454,13 @@ mod tests { unsafe { if let Some(val) = original { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", val); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", val); } } } /// Helper to run an async test body while holding the env mutex. - /// Clears `IRONCLAW_OAUTH_CALLBACK_URL` for the duration, restoring on drop. + /// Clears `OPTIMCLAW_OAUTH_CALLBACK_URL` for the duration, restoring on drop. struct EnvGuard { original: Option, _mutex: std::sync::MutexGuard<'static, ()>, @@ -8469,10 +8469,10 @@ mod tests { impl EnvGuard { fn new() -> Self { let guard = crate::config::helpers::lock_env(); - let original = std::env::var("IRONCLAW_OAUTH_CALLBACK_URL").ok(); + let original = std::env::var("OPTIMCLAW_OAUTH_CALLBACK_URL").ok(); // SAFETY: Under ENV_MUTEX, no concurrent env access. unsafe { - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); } Self { original, @@ -8486,9 +8486,9 @@ mod tests { // SAFETY: Under ENV_MUTEX (still held by _mutex), no concurrent env access. unsafe { if let Some(ref val) = self.original { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", val); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", val); } else { - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); } } } @@ -8527,10 +8527,10 @@ mod tests { #[test] fn gateway_callback_redirect_uri_does_not_duplicate_callback_path_from_env() { let _guard = crate::config::helpers::lock_env(); - let original = std::env::var("IRONCLAW_OAUTH_CALLBACK_URL").ok(); + let original = std::env::var("OPTIMCLAW_OAUTH_CALLBACK_URL").ok(); unsafe { std::env::set_var( - "IRONCLAW_OAUTH_CALLBACK_URL", + "OPTIMCLAW_OAUTH_CALLBACK_URL", "https://oauth.test.example/oauth/callback", ); } @@ -8543,9 +8543,9 @@ mod tests { unsafe { if let Some(val) = original { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", val); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", val); } else { - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); } } } @@ -8553,10 +8553,10 @@ mod tests { #[test] fn gateway_callback_redirect_uri_trims_trailing_slash_from_env_callback() { let _guard = crate::config::helpers::lock_env(); - let original = std::env::var("IRONCLAW_OAUTH_CALLBACK_URL").ok(); + let original = std::env::var("OPTIMCLAW_OAUTH_CALLBACK_URL").ok(); unsafe { std::env::set_var( - "IRONCLAW_OAUTH_CALLBACK_URL", + "OPTIMCLAW_OAUTH_CALLBACK_URL", "https://oauth.test.example/oauth/callback/", ); } @@ -8569,9 +8569,9 @@ mod tests { unsafe { if let Some(val) = original { - std::env::set_var("IRONCLAW_OAUTH_CALLBACK_URL", val); + std::env::set_var("OPTIMCLAW_OAUTH_CALLBACK_URL", val); } else { - std::env::remove_var("IRONCLAW_OAUTH_CALLBACK_URL"); + std::env::remove_var("OPTIMCLAW_OAUTH_CALLBACK_URL"); } } } diff --git a/src/extensions/registry.rs b/src/extensions/registry.rs index ec471834..243dc7d0 100644 --- a/src/extensions/registry.rs +++ b/src/extensions/registry.rs @@ -223,7 +223,7 @@ fn score_entry(entry: &RegistryEntry, tokens: &[String]) -> u32 { score } -/// Well-known extensions that ship with ironclaw. +/// Well-known extensions that ship with optimclaw. /// /// If `relay_url` is provided, a channel-relay Slack entry is included in the list. /// Pass `None` when the relay is not configured. diff --git a/src/hooks/bundled.rs b/src/hooks/bundled.rs index 9ca1fe92..451b7f1a 100644 --- a/src/hooks/bundled.rs +++ b/src/hooks/bundled.rs @@ -132,7 +132,7 @@ impl HookRegistrationSummary { } } -/// Register bundled built-in hooks that ship with IronClaw. +/// Register bundled built-in hooks that ship with OptimClaw. pub async fn register_bundled_hooks(registry: &Arc) -> HookRegistrationSummary { registry .register_with_priority(Arc::new(AuditLogHook), 25) diff --git a/src/import/mod.rs b/src/import/mod.rs index 51a54550..5b20a294 100644 --- a/src/import/mod.rs +++ b/src/import/mod.rs @@ -1,7 +1,7 @@ //! OpenClaw migration and import functionality. //! //! Provides tools to migrate existing OpenClaw installations (memory, history, -//! settings, and credentials) into IronClaw without data loss. +//! settings, and credentials) into OptimClaw without data loss. #[cfg(feature = "import")] pub mod openclaw; diff --git a/src/import/openclaw/memory.rs b/src/import/openclaw/memory.rs index e7029623..051c527e 100644 --- a/src/import/openclaw/memory.rs +++ b/src/import/openclaw/memory.rs @@ -7,7 +7,7 @@ use crate::import::{ImportError, ImportOptions}; use super::reader::OpenClawMemoryChunk; -/// Import a single memory chunk into IronClaw. +/// Import a single memory chunk into OptimClaw. pub async fn import_chunk( db: &Arc, chunk: &OpenClawMemoryChunk, diff --git a/src/import/openclaw/settings.rs b/src/import/openclaw/settings.rs index b9360176..ed5c0407 100644 --- a/src/import/openclaw/settings.rs +++ b/src/import/openclaw/settings.rs @@ -1,11 +1,11 @@ -//! OpenClaw configuration to IronClaw settings mapping. +//! OpenClaw configuration to OptimClaw settings mapping. use secrecy::SecretString; use std::collections::HashMap; use super::reader::OpenClawConfig; -/// Map OpenClaw configuration to IronClaw settings (dotted-key format). +/// Map OpenClaw configuration to OptimClaw settings (dotted-key format). pub fn map_openclaw_config_to_settings( config: &OpenClawConfig, ) -> HashMap { diff --git a/src/llm/CLAUDE.md b/src/llm/CLAUDE.md index 3986ff72..ac36bd88 100644 --- a/src/llm/CLAUDE.md +++ b/src/llm/CLAUDE.md @@ -25,7 +25,7 @@ Multi-provider LLM integration with circuit breaker, retry, failover, and respon | `costs.rs` | Static per-model cost table (OpenAI, Anthropic, local/Ollama heuristics) | | `rig_adapter.rs` | Adapter bridging rig-core `CompletionModel` → `LlmProvider`; used by OpenAI, Anthropic, Ollama, Tinfoil | | `smart_routing.rs` | `SmartRoutingProvider` — 13-dimension complexity scorer routes cheap vs primary model | -| `recording.rs` | `RecordingLlm` — trace capture for E2E replay testing (`IRONCLAW_RECORD_TRACE`) | +| `recording.rs` | `RecordingLlm` — trace capture for E2E replay testing (`OPTIMCLAW_RECORD_TRACE`) | | `bedrock.rs` | AWS Bedrock provider via native Converse API (feature-gated: `--features bedrock`) | ## Provider Selection @@ -46,8 +46,8 @@ Set via `LLM_BACKEND` env var: Codex auth reuse: - Set `LLM_USE_CODEX_AUTH=true` to load credentials from `~/.codex/auth.json` (override with `CODEX_AUTH_PATH`). -- If Codex is logged in with API-key mode, IronClaw uses the standard OpenAI endpoint. -- If Codex is logged in with ChatGPT OAuth mode, IronClaw routes to the private `chatgpt.com/backend-api/codex` Responses API via `codex_chatgpt.rs`. +- If Codex is logged in with API-key mode, OptimClaw uses the standard OpenAI endpoint. +- If Codex is logged in with ChatGPT OAuth mode, OptimClaw routes to the private `chatgpt.com/backend-api/codex` Responses API via `codex_chatgpt.rs`. - ChatGPT mode supports one automatic 401 refresh using the refresh token persisted in `auth.json`. ## AWS Bedrock Provider @@ -85,7 +85,7 @@ ID, migrate to it immediately. Advanced users can override headers via ## NEAR AI Provider Gotchas **Dual auth modes:** -- **Session token** (default): `NEARAI_SESSION_TOKEN=sess_...`, base URL = `https://private.near.ai`. Tokens are persisted to `~/.ironclaw/session.json` (mode 0600) and optionally to the DB `settings` table (`nearai.session_token`). On 401 responses where the body contains "session" + "expired"/"invalid", `NearAiChatProvider` calls `session.handle_auth_failure()` which triggers the interactive OAuth login flow and retries once. Plain `AuthFailed` 401s are not retried. +- **Session token** (default): `NEARAI_SESSION_TOKEN=sess_...`, base URL = `https://private.near.ai`. Tokens are persisted to `~/.optimclaw/session.json` (mode 0600) and optionally to the DB `settings` table (`nearai.session_token`). On 401 responses where the body contains "session" + "expired"/"invalid", `NearAiChatProvider` calls `session.handle_auth_failure()` which triggers the interactive OAuth login flow and retries once. Plain `AuthFailed` 401s are not retried. - **API key**: Set `NEARAI_API_KEY` (from `cloud.near.ai`), base URL defaults to `https://cloud-api.near.ai`. 401s with API key auth are immediately returned as `LlmError::AuthFailed` — no renewal. **Session renewal is interactive:** When `SessionExpired` triggers renewal, it blocks and prompts the user in the terminal (GitHub/Google OAuth or manual API key entry). This is unsuitable for headless/hosted deployments — set `NEARAI_SESSION_TOKEN` env var instead. @@ -178,7 +178,7 @@ Set `LLM_EXTRA_HEADERS=Key:Value,Key2:Value2` to inject headers into every reque Uses the Responses API at `chatgpt.com/backend-api/codex/responses` with ChatGPT subscription OAuth tokens (zero API cost — billing through subscription). -**Auth flow:** Device code OAuth via `auth.openai.com/api/accounts/deviceauth/*` endpoints. On first run, displays a code for the user to enter at a URL. Tokens are persisted to `~/.ironclaw/openai_codex_session.json` (mode 0600) and auto-refreshed before expiry. +**Auth flow:** Device code OAuth via `auth.openai.com/api/accounts/deviceauth/*` endpoints. On first run, displays a code for the user to enter at a URL. Tokens are persisted to `~/.optimclaw/openai_codex_session.json` (mode 0600) and auto-refreshed before expiry. **Provider chain:** `OpenAiCodexProvider` → `TokenRefreshingProvider` (pre-emptive refresh + retry on 401) → standard decorator chain. The `TokenRefreshingProvider` intercepts `AuthFailed`/`SessionExpired` errors, refreshes the OAuth token, and retries once. @@ -203,7 +203,7 @@ Raw provider → FailoverProvider (fallback model; only when NEARAI_FALLBACK_MODEL is set) → CircuitBreakerProvider (fast-fail; only when NEARAI_CIRCUIT_BREAKER_THRESHOLD is set) → CachedProvider (response cache; only when NEARAI_RESPONSE_CACHE_ENABLED=true) - → RecordingLlm (trace capture; only when IRONCLAW_RECORD_TRACE is set) + → RecordingLlm (trace capture; only when OPTIMCLAW_RECORD_TRACE is set) ``` `build_provider_chain()` also returns a separate standalone cheap LLM provider (for heartbeat/evaluation tasks — not part of the decorator chain). @@ -238,4 +238,4 @@ No streaming support. All providers use non-streaming (blocking) Chat Completion ## Trace Recording -Set `IRONCLAW_RECORD_TRACE=1` to enable live trace recording via `RecordingLlm`. Traces are JSON files containing: memory snapshot, HTTP exchanges from tools, and LLM steps (user inputs, text responses, tool call responses). Replay these in E2E tests via `TraceLlm`. Configure output path with `IRONCLAW_TRACE_OUTPUT` (default: `trace_{timestamp}.json`). +Set `OPTIMCLAW_RECORD_TRACE=1` to enable live trace recording via `RecordingLlm`. Traces are JSON files containing: memory snapshot, HTTP exchanges from tools, and LLM steps (user inputs, text responses, tool call responses). Replay these in E2E tests via `TraceLlm`. Configure output path with `OPTIMCLAW_TRACE_OUTPUT` (default: `trace_{timestamp}.json`). diff --git a/src/llm/bedrock.rs b/src/llm/bedrock.rs index b5f7badd..795d50dd 100644 --- a/src/llm/bedrock.rs +++ b/src/llm/bedrock.rs @@ -272,7 +272,7 @@ fn build_inference_config( // Message conversion // --------------------------------------------------------------------------- -/// Convert IronClaw `ChatMessage` list into Bedrock system blocks + messages. +/// Convert OptimClaw `ChatMessage` list into Bedrock system blocks + messages. /// /// Key differences from OpenAI/Anthropic protocol: /// 1. System messages are extracted and passed separately. @@ -442,7 +442,7 @@ fn push_message( // Tool configuration // --------------------------------------------------------------------------- -/// Build Bedrock `ToolConfiguration` from IronClaw tool definitions. +/// Build Bedrock `ToolConfiguration` from OptimClaw tool definitions. fn build_tool_config( tools: &[ToolDefinition], tool_choice: Option<&str>, @@ -544,7 +544,7 @@ fn extract_token_usage(usage: Option<&aws_sdk_bedrockruntime::types::TokenUsage> } } -/// Map Bedrock `StopReason` to IronClaw `FinishReason`. +/// Map Bedrock `StopReason` to OptimClaw `FinishReason`. fn map_stop_reason(reason: &StopReason) -> FinishReason { match reason { StopReason::EndTurn | StopReason::StopSequence => FinishReason::Stop, diff --git a/src/llm/codex_auth.rs b/src/llm/codex_auth.rs index 6f302436..85fa4ea6 100644 --- a/src/llm/codex_auth.rs +++ b/src/llm/codex_auth.rs @@ -1,8 +1,8 @@ //! Read Codex CLI credentials for LLM authentication. //! -//! When `LLM_USE_CODEX_AUTH=true`, IronClaw reads the Codex CLI's +//! When `LLM_USE_CODEX_AUTH=true`, OptimClaw reads the Codex CLI's //! `auth.json` file (default: `~/.codex/auth.json`) and extracts -//! credentials. This lets IronClaw piggyback on a Codex login without +//! credentials. This lets OptimClaw piggyback on a Codex login without //! implementing its own OAuth flow. //! //! Codex supports two auth modes: diff --git a/src/llm/codex_chatgpt.rs b/src/llm/codex_chatgpt.rs index e7dcf40d..b12bb15a 100644 --- a/src/llm/codex_chatgpt.rs +++ b/src/llm/codex_chatgpt.rs @@ -199,7 +199,7 @@ impl CodexChatGptProvider { .unwrap_or_default() } - /// Convert IronClaw messages to Responses API request JSON. + /// Convert OptimClaw messages to Responses API request JSON. fn build_request_body( &self, model: &str, @@ -640,7 +640,7 @@ impl CodexChatGptProvider { /// Remove keys with empty-string values from a JSON object. /// /// gpt-5.2-codex fills optional tool parameters with `""` (e.g. - /// `"timestamp": ""`). IronClaw's tool validation treats these as + /// `"timestamp": ""`). OptimClaw's tool validation treats these as /// invalid "non-empty input expected". Stripping them makes the /// tool see only the actually-provided values. fn strip_empty_string_values(value: Value) -> Value { @@ -725,7 +725,7 @@ impl LlmProvider for CodexChatGptProvider { let args: Value = serde_json::from_str(&tc.arguments).unwrap_or_else(|_| json!(tc.arguments)); // gpt-5.2-codex fills optional parameters with empty strings (e.g. - // `"timestamp": ""`), which IronClaw's tool validation rejects. + // `"timestamp": ""`), which OptimClaw's tool validation rejects. // Strip them so only actually-provided values reach the tool. let args = Self::strip_empty_string_values(args); ToolCall { diff --git a/src/llm/config.rs b/src/llm/config.rs index 6e8b01ae..dd3cbb93 100644 --- a/src/llm/config.rs +++ b/src/llm/config.rs @@ -9,7 +9,7 @@ use std::path::PathBuf; use secrecy::SecretString; -use crate::bootstrap::ironclaw_base_dir; +use crate::bootstrap::optimclaw_base_dir; use crate::llm::registry::ProviderProtocol; use crate::llm::session::SessionConfig; @@ -114,7 +114,7 @@ pub struct OpenAiCodexConfig { pub api_base_url: String, /// OAuth client ID (default: OpenAI's public Codex client). pub client_id: String, - /// Path to session file (default: ~/.ironclaw/openai_codex_session.json). + /// Path to session file (default: ~/.optimclaw/openai_codex_session.json). pub session_path: PathBuf, /// Seconds before expiry to proactively refresh (default: 300). pub token_refresh_margin_secs: u64, @@ -127,7 +127,7 @@ impl Default for OpenAiCodexConfig { auth_endpoint: "https://auth.openai.com".to_string(), api_base_url: "https://chatgpt.com/backend-api/codex".to_string(), client_id: "app_EMoamEEZ73f0CkXaXp7hrann".to_string(), - session_path: ironclaw_base_dir().join("openai_codex_session.json"), + session_path: optimclaw_base_dir().join("openai_codex_session.json"), token_refresh_margin_secs: 300, } } diff --git a/src/llm/gemini_oauth.rs b/src/llm/gemini_oauth.rs index a19eec12..0c942061 100644 --- a/src/llm/gemini_oauth.rs +++ b/src/llm/gemini_oauth.rs @@ -58,7 +58,7 @@ fn oauth_client_secret() -> String { } const OAUTH_SCOPE: &str = "https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"; -const GOOG_API_CLIENT: &str = concat!("gl-rust/1.0.0 ironclaw/", env!("CARGO_PKG_VERSION")); +const GOOG_API_CLIENT: &str = concat!("gl-rust/1.0.0 optimclaw/", env!("CARGO_PKG_VERSION")); const PKCE_CHARSET: &[u8] = b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~"; const STATE_CHARSET: &[u8] = b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; @@ -1205,7 +1205,7 @@ impl GeminiOauthProvider { headers.insert( "User-Agent", format!( - "GeminiCLI-ironclaw/{}/{} ({}; {}; cli)", + "GeminiCLI-optimclaw/{}/{} ({}; {}; cli)", env!("CARGO_PKG_VERSION"), self.config.model, std::env::consts::OS, @@ -1787,7 +1787,7 @@ impl GeminiOauthProvider { // Budget cap of 8192 prevents runaway thinking loops. // // NOTE: We do NOT set includeThoughts=true. The original Gemini CLI - // sets it because it displays thoughts to the user. IronClaw's reasoning + // sets it because it displays thoughts to the user. OptimClaw's reasoning // layer (reasoning.rs) strips all tags from responses, so // including thoughts just adds text that gets stripped, potentially // leaving an empty response. diff --git a/src/llm/github_copilot.rs b/src/llm/github_copilot.rs index 6fefe5af..b9211dce 100644 --- a/src/llm/github_copilot.rs +++ b/src/llm/github_copilot.rs @@ -499,7 +499,7 @@ struct OpenAiUsage { completion_tokens: u32, } -/// Convert IronClaw messages to OpenAI Chat Completions format. +/// Convert OptimClaw messages to OpenAI Chat Completions format. fn convert_messages(messages: Vec) -> Vec { messages .into_iter() diff --git a/src/llm/github_copilot_auth.rs b/src/llm/github_copilot_auth.rs index 44df743e..6f4a76dd 100644 --- a/src/llm/github_copilot_auth.rs +++ b/src/llm/github_copilot_auth.rs @@ -12,7 +12,7 @@ use tokio::sync::RwLock; // // **Known risks:** // • GitHub may rotate or revoke this client ID at any time, which would -// break authentication for all IronClaw users until the constant is +// break authentication for all OptimClaw users until the constant is // updated and a new release is shipped. // • Using another product's client ID may violate GitHub's Terms of // Service. Maintainers should seek explicit guidance from GitHub diff --git a/src/llm/mod.rs b/src/llm/mod.rs index d681547d..df776823 100644 --- a/src/llm/mod.rs +++ b/src/llm/mod.rs @@ -297,7 +297,7 @@ fn create_openai_compat_from_registry( // Use CompletionsClient (Chat Completions API) instead of the default // Client (Responses API). The Responses API path in rig-core handles - // tool results differently, which breaks IronClaw's tool call flow. + // tool results differently, which breaks OptimClaw's tool call flow. let client = client.completions_api(); let model = client.completion_model(&config.model); diff --git a/src/llm/oauth_helpers.rs b/src/llm/oauth_helpers.rs index daaf1b42..03d1db09 100644 --- a/src/llm/oauth_helpers.rs +++ b/src/llm/oauth_helpers.rs @@ -35,11 +35,11 @@ pub enum OAuthCallbackError { /// Returns the OAuth callback base URL. /// -/// Checks `IRONCLAW_OAUTH_CALLBACK_URL` env var first (useful for remote/VPS +/// Checks `OPTIMCLAW_OAUTH_CALLBACK_URL` env var first (useful for remote/VPS /// deployments where `127.0.0.1` is unreachable from the user's browser), /// then falls back to `http://{callback_host()}:{OAUTH_CALLBACK_PORT}`. pub fn callback_url() -> String { - crate::config::helpers::env_or_override("IRONCLAW_OAUTH_CALLBACK_URL") + crate::config::helpers::env_or_override("OPTIMCLAW_OAUTH_CALLBACK_URL") .unwrap_or_else(|| format!("http://{}:{}", callback_host(), OAUTH_CALLBACK_PORT)) } @@ -301,7 +301,7 @@ pub fn landing_html(provider_name: &str, success: bool) -> String { -IronClaw - {heading} +OptimClaw - {heading}