EvoCLI v0.1.0
Personal AI Engineering Runtime — Rust Host + Python Soul
Fixed — Quality & Integration Sweep (49 issues across 6 waves)
Dependencies
- Remove
rocketryzombie dependency (was declared but never imported after scheduling moved to Rust Job Queue) - Add
keyring>=24.0(required by agent.py API key lookup, was missing from pyproject.toml) - Add
tomli>=2.0; python_version < '3.11'for Python 3.10 compatibility (7 files usedimport tomllibwhich is 3.11+ stdlib only)
Rust Host
- Remove 5 dead_code functions:
default_provider,default_fast_model,default_smart_model(config.rs),project_id()(event_bus.rs),default_tiers_for(init.rs),git_diff(git.rs) - Remove unused
Confirmimport from init.rs (code used fully-qualifieddialoguer::Confirm::new()) - Fix unnecessary
mutat tool_dispatch.rs:1418 (let mut entriesinwrite_tree) - Add
#[allow(dead_code)]toevent_bus::global()with explanation comment - Add
#[allow(unused_mut)]towith_code_index!macro to suppress 17 spurious warnings - Fix
jobs.dbschema migration order:POST_MIGRATION_INDEXnow runs afterMIGRATIONsoproject_idcolumn exists before index creation - Add
[dev-dependencies] tempfile = "3"for jobs.db migration tests
MCP Exposure
- Expose 8 previously missing tools via
evocli_as_mcp_tools():code_intel_communities,code_intel_processes,web_fetch,git_snapshot_list,git_snapshot_restore,fs_read_range,contracts_list,contracts_get_checkpoints - Update
EVOCLI_MCP_TOOL_COUNT: 62 → 70; unit testtool_count_matches_expectedvalidates this
Python Soul — Core Logic
- Fix
code_intel.ranked_context: was returning hardcodedscore=1.0for all symbols; now usessqrt(caller_count) + mention_bonusscoring with descending sort - Fix session_id in
handle_agent_run: wascwd_<md5>(shared across conversations in same dir); nowsess_<uuid4>per conversation - Fix session_id in
handle_agent_streamand all slash commands (/add,/btw,/compress,/undo,/plan): DRY'd into_derive_stream_session_id()helper with design rationale documented - Fix TUI
lib.rs: bothagent.streamsubmit paths now explicitly passsession_id(FNV-1a hash of CWD for project continuity);override_session_idfield added toAppstruct forevocli session resume - Fix
evolution/decay_detector.py: 2 bareexcept: pass→log.debugwith context - Fix
handlers/agent.py::auto-continue:if False:guard documented with protocol limitation explanation and Options A/B/C roadmap
Python Soul — Memory System
- Add
normalize_project_id()tostate.py: mapsNone/"."/"global"→os.path.abspath(os.getcwd()); prevents".","global", and actual cwd paths from hashing to different memory buckets - Fix ALL 11 memory handlers in
handlers/memory.pyto extract and passproject_idfrom params tostate.get_memory(project_id=project_id)(previously all calledstate.get_memory()ignoring caller's project context) - Fix
metrics.py::handle_evolution_transfer(): was no-opparams.get("project_id")(value discarded); now properly passed toget_memory() - Fix
evolution/failure_miner.py::mine(): ignored itsproject_idparameter; now passed toget_memory() - Fix
code_chunks.py::generate_community_summaries(): stored summaries with wrong project_id; now usespidfrom outer loop - Fix
memory_client.py::add(): global-scoped memories now stored withproject_id="global"instead ofself.project_id, enabling cross-project retrieval via vector search filter - Fix
memory_client.py::search(): tool memory matching now also checkstagsfield as fallback for legacy entries withouttool_id - Fix
evolution/knowledge_classifier.py::promote_if_transferable(): usedget_memory(project_id="global")which normalized to cwd; now usesget_memory(project_id=None)and letsadd(priority="global")setproject_id="global"in the stored entry - Fix
state.py::reset_all(): was resetting_memory(old single-instance var); now also calls_memories.clear()to clear the per-project memory dict
Python Soul — Context Engine
- Fix
context_engine.py:get_memory()replaced withget_memory_if_ready(project_id)— avoids blocking the asyncio event loop on fastembed/LanceDB model initialization (30+ seconds on first run) - Fix
context_engine.py: Superpowers Skill guidance injection guarded by_embedder_cache is not None AND _skill_engine is not None— prevents blockingSkillEngine(real_bridge)initialization during context build - Fix
context_engine.py: addedskip_repomapguard — RepoMap skipped when nocurrent_fileanchor, preventing full tree-sitter codebase scan on empty requests - Fix
code_analysis.py::_resolve_symbol_id: bareexcept: pass→log.debugwith context
Python Soul — Path Safety
- Fix
state.py::_history_path(): now uses SHA-256 suffix to prevent both path traversal and filename collisions between session IDs that normalize to the same safe prefix - Fix
session.py::SessionManager._path(): same SHA-256 collision-resistant sanitization
Python Soul — agent.py
- Fix
code_chunks.get_index(): changed from single_indexglobal singleton ("first caller wins") to_index_cache: dict[str, CodeChunkIndex]keyed byos.path.abspath(project_id) - Fix
agent.py::code_semantic_search: was callingget_index(self._session_id)(session-keyed, bug: all sessions after first got wrong project index); now callsget_index(os.getcwd()) - Fix 6 critical bare
except Exception: passin agent.py →log.debugwith error context (API key lookup, event recording, stream tool parsing, context injection)
Python Soul — BOM
- Remove UTF-8 BOM from
prompt_manager.pyandhandlers/system.py(causedast.parse()failures in tooling)
Tests
- Add 2 jobs.db migration tests:
test_fresh_db_creation,test_legacy_db_migration(fresh DB + legacy schema upgrade) - Add 4 code_analysis handler tests: response structure,
risk_levelfield, list return, `_RANKED_CONTEXT_WE
[截断]
安装
Windows
# 解压 zip 后:
.\setup.ps1 && .\evocli.exe init && .\evocli.exeLinux x86_64
tar -xzf evocli-v0.1.0-linux-x86_64.tar.gz
cd evocli-v0.1.0-linux-x86_64/
bash setup.sh && ./evocli init && ./evocli平台
| 平台 | 文件 |
|---|---|
| Linux x86_64 | evocli-v0.1.0-linux-x86_64.tar.gz |
| Windows x86_64 | evocli-v0.1.0-windows-x86_64.zip |
macOS / Linux aarch64: 暂不提供预编译包(依赖 ONNX/tantivy 的 SIMD 检测与交叉编译不兼容)。
源码构建:cargo build --release --bin evocli
sha256sum --check checksums-sha256.txt