Skip to content

Releases: kannamma-labs/cie

0.1.5 — AST/file-index single source, input validation hardening, vulnerability ingestion

Choose a tag to compare

@arunsoman arunsoman released this 01 Sep 16:32
b79aa45

Rolls up everything merged to main since v0.1.4:

Added

  • AST mirror + get_meta/get_function — cie as the single source where the actual file and its AST stay in sync. Every write path (write_file, apply_patch, ...) refreshes the mirror in the same call; reads never touch disk.
  • File-path index — ls/dir/file_hierarchy/file_names_like/path_prefix — one sorted, lazily-built path array per project root, same single-source discipline as the AST mirror.
  • vision.md — the project's why, linked from the README title line.
  • README 30-second demo — a real recorded session, cie asked about itself.
  • Vulnerability ingestion — vulnerability_scan_run/vulnerabilities — cross-references already-extracted PACKAGE nodes against an externally-generated pip-audit/npm-audit JSON report into Vulnerability nodes + AFFECTS edges. Ingestion only: no scanner, no network call. report_path is jailed under the project root; rescans correctly clear fixed findings and never wipe out a different ecosystem's last scan.

Fixed

  • search_symbol's kind and affected_by's direction are now validated against real values instead of silently returning a misleading empty or wrong result on a bad input — confirmed live on astropy__astropy-14995, where a downstream repair agent burned 8 queries chasing an uncertainty that was never real.

Suite: 348 passed; 10 pre-existing failures are unrelated missing optional tree-sitter grammar packages (tree_sitter_cpp/tree_sitter_c_sharp). Tool surface: 135 → 144.

No PyPI publish with this release — tag + GitHub Release only.

Full changelog: https://github.com/kannamma-labs/cie/blob/main/CHANGELOG.md#015---2026-09-01--astfile-index-single-source-input-validation-hardening-vulnerability-ingestion

0.1.4 — direct-calls TESTS edges

Choose a tag to compare

@arunsoman arunsoman released this 31 Aug 02:17

What changed

Found by dogfooding cie on itself: a 308-test suite resolved exactly one TESTS edge. Behavioral test names (pytest best practice) starve the naming heuristic; monkeypatch starves the @patch heuristic.

New heuristic (4) — direct calls: a resolved calls edge from a test symbol to a production symbol (FUNC/METHOD/CLASS, non-test file, not conftest.py) now mints a TESTS edge directly — EXTRACTED, the same proof standard the naming-match upgrade uses, without the name gate.

Measured on cie itself:

  • TESTS edges: 1 → 562 (total edges 5,992 → 6,553)
  • test_map(resolve_backend): 0 → 7 tests; run_init: 0 → 12; build_tool_service_embedded: 0 → 18

Still honestly not exhaustive: a test that only reaches its target through a helper gets no edge — the test_map hint says exactly that.

Suite: 312 passed (+4 ground-truth tests: behavioral link, test-file-helper skip, conftest skip, no-duplicate). Artifacts: sdist + wheel, twine PASSED.

0.1.3 — one storage-backend selection rule, every front-end

Choose a tag to compare

@arunsoman arunsoman released this 31 Aug 01:57

What changed

One rule for choosing storage, identical across front-ends — the product principle: least friction to users and their existing infrastructure.

cie-mcp /path/to/project                # auto: serves .cie/graph.db if you indexed, else Neo4j
cie-mcp /path/to/project --backend neo4j   # explicit — always honored
CIE_BACKEND=embedded                     # one env var, both `cie` and `cie-mcp` obey
  • Resolution: explicit --backend {auto,embedded,neo4j} > CIE_BACKEND env (stray values fall through, never fatal) > --embedded (permanent alias — every entry cie init ever wrote keeps working) > auto.
  • The resolved choice is stated on stderr at startup (backend=… storage=… policy=…) — never silent; stdout stays byte-clean (it is the JSON-RPC channel). Live-verified: a no-flag spawn on a freshly indexed project auto-picked embedded, full 135-tool handshake + real tool call clean over stdout.
  • Fixed: explicit --backend auto was previously read as Neo4j (truthy-string bug) — an indexed project could query the wrong store; regression-pinned.
  • cie init writes the canonical --backend embedded; selection is orthogonal to configuration (NEO4J_* / legacy CIE_NEO4J_* / --neo4j-* still configure Neo4j however selected). HTTP tool-mount remains Neo4j-only, documented as such.
  • README gained the per-front-end selection matrix under "Storage backends & config".

Suite: 308 passed. Artifacts: sdist + wheel, twine PASSED, clean-venv verified.

0.1.2 — native client compatibility + one-click install

Choose a tag to compare

@arunsoman arunsoman released this 31 Aug 01:23

What changed

Fixed — native client compatibility

Registered cie init entries carried a bare "cie-mcp" command, which only resolves if the MCP client's PATH includes the install bin — GUI-launched Claude Code/Cursor/Codex processes typically don't. cie init now writes a spawn-robust command everywhere (project .mcp.json, ~/.cursor/mcp.json, the Codex TOML snippet, the managed AGENTS.md/CLAUDE.md block): absolute console-script path, else the running interpreter via -m cie.mcp_server.

Verified with the real Claude Code CLI (2.1.251), not a mock client: cie init → claude mcp list shows cie … ✔ Connected → a one-shot claude -p agent call of search_symbol through the registered server returned the correct indexed file. Cursor/Codex: config formats verified against their documented shapes — those apps aren't on the test machine, so they're labeled format-verified, not claimed as live.

Added — one-click install (README top)

uv tool install "cie-mcp[mcp] @ git+https://github.com/kannamma-labs/cie.git@v0.1.2"
cie init .          # per project: index, register client, write context files

The whole chain was run end-to-end on 2026-08-31. Browser deep-link "one-click" is deliberately not claimed: cie is a local stdio server pointed at a specific project with a policy you choose — that's what cie init computes.

Carried in

R10 (first-party semantic retrieval — measured recall@8 = 1.0 on all 16 labeled questions) shipped in the v0.1.1 artifact; its changelog entry had stayed under [Unreleased] through the rename cut and lands here verbatim with an attribution note.

Suite: 294 passed (two new command-resolution tests; the real-client handshake test now spawns the entry exactly as written). Artifacts: sdist + wheel built, twine PASSED, clean-venv rehearsal (85 read tools under readonly policy).

cie 0.1.1 — PyPI distribution renamed to cie-mcp

Choose a tag to compare

@arunsoman arunsoman released this 30 Aug 22:45

[0.1.1] - 2026-08-31 — PyPI distribution renamed to cie-mcp

pypi.org/project/cie is an unrelated project (cluster311/cie10, ICD-10
codes) — the finding recorded in the 0.1.0 release notes becomes this
change: the distribution ships under cie-mcp from now on. The
import package, the cie CLI, the cie-mcp console script, the repo,
and the tags are unchanged; only the pip string moves:
pip install "cie-mcp[mcp]" (was pip install "cie[mcp] @ git+…"-only).

Added

  • First PyPI artifact for the project, under the new distribution name
    (core + mcp/http extras; console scripts cie and cie-mcp).
  • GitHub install remains supported and pinned in README alongside the
    PyPI line (same commit, so both routes verify identical code).

Changed

  • Distribution name cie → cie-mcp in pyproject.toml; version
    0.1.0 → 0.1.1 (the v0.1.0 GitHub release/tag stays as-is — dated
    record under the old name). Extras migrate with the distribution:
    cie-mcp[mcp], cie-mcp[http].

Install (updated)

pip install "cie-mcp[mcp]"   # from PyPI once the 0.1.1 upload lands
  • The upload runs with the maintainer's PyPI token or a trusted-publisher
    workflow — this release commit is the artifact source (wheel verified:
    twine check PASSED; clean-venv rehearsal: index 858/1822, MCP
    handshake 85 read-only tools, callers(close) executes).
  • GitHub route, unchanged and equal:
    pip install "cie-mcp[mcp] @ git+https://github.com/kannamma-labs/cie.git"

cie 0.1.0 — first stable

Choose a tag to compare

@arunsoman arunsoman released this 30 Aug 21:58

[0.1.0] - 2026-08-31 — first stable

Cut from the same tree as 0.1.0a3 plus everything below — the P0/P1
roadmap (R1–R9, R11–R17) landed between the last alpha and this cut: the
message bus is the same code base, now verified at 279 tests, a 135-tool
surface with 0 conformance crashes, and 9 languages. Released from GitHub
while a PyPI distribution-name decision is pending (cie on PyPI is an
unrelated project).

Added

  • R15 — cie init: one-command onboarding. Detects installed MCP
    clients (Claude Code / Cursor by config presence; Codex detected and
    given the exact TOML snippet — never auto-edited), registers cie's
    stdio server idempotently (existing entries byte-preserved; invalid
    JSON refused, not 'fixed'), writes managed context blocks into
    AGENTS.md/CLAUDE.md (cie:init markers, user content outside
    them untouched, re-run = refresh-in-place), and defaults the client's
    policy to readonly — writes are an explicit --policy full opt-
    in, not an onboarding side effect. Verified end to end: the
    registered entry, spawned exactly as a client would, handshakes over
    real stdio and lists 85 read tools with zero write tools
    (scripts/record_init.sh + tool-test-lab/dogfood_mcp_stdio_list.py).
    13 tests.

Added

  • R16 — the run-tool isolation story made explicit. New
    docs/security.md states the threat model precisely: the cwd jail +
    hard-timeout/process-group kill + bounded output that IS there, and
    equally plainly what is NOT (no fs sandbox beyond cwd, no network
    restriction, no container isolation) — plus the surface-by-surface
    matrix of what each caller can reach (HTTP default refuses run
    server-side before any process spawns, machine-checked by a test that
    monkeypatches Popen to blow up on any invocation; MCP readonly
    never registers it). Optional CIE_RUN_WRAPPER container seam —
    documented as convenience, not enforcement, with the pin that absent
    the env var behavior is byte-identical.

Added

  • R9 — reproducible benchmark harness + a third independent repo.
    scripts/benchmark.sh + scripts/benchmark_tasks.py turn the
    benchmark-doc methodology into a script: clone at the pinned commit →
    index → run the three canonical task shapes on BOTH sides (naive
    grep/read vs tool calls), emitting the JSON the docs' tables are
    pasted from — plus the requested token-per-query metric, measured as
    response-payload chars (tokenizer-free, labeled as such — ours gets
    measured, codebase-memory-mcp's "120× fewer tokens" stays a
    vendor-claim). Third dataset: docs/benchmarks-urllib3.md (urllib3 @
    85a8a9cf, 36 files / 667 nodes / 1,307 edges) — wins (receiver-wise
    caller attribution: 12 graph edges vs 28 undifferentiated grep
    matches; 2.24× file-skeleton compression) AND misses (28/40
    unresolved call sites — the known heuristic-recall gap, bigger on
    this repo, published as found). The psf/requests numbers regenerate
    via the same harness and match the published doc.

Added

  • R8 — cie export-html: the shareable artifact. One static,
    self-contained HTML snapshot of a project's graph, centered on what no
    competitor renders: task→file→test chains (real TESTS edges from the
    index pass), orphan symbols, the atomic-task list, indexed files, and
    a text filter — no server, no auth surface, no network access, opens
    via file:// (zero external references asserted in tests).
    scripts/record_export_html.sh reproduces end to end: clone psf/
    requests at the pinned commit → index → export → headless-Chrome
    screenshots straight from file:// (committed to docs/images/).
    CLI: cie export-html [PATH] --out FILE [--max-chains N].

Added

  • R11 — streamable-HTTP transport for cie-mcp. The --transport streamable-http choice is now actually usable end to end: --host
    (default 127.0.0.1) / --port (8000) kwargs wired into the SDK's
    HTTP run path, the same server-side ToolPolicy applies on every
    transport. Live-verified with the official streamable-http client
    against a real spawned server (tool-test-lab/dogfood_mcp_http.py):
    HTTP tools/list == exactly the 85-tool inspector prediction, and a
    write attempt is refused server-side (the tool is never registered —
    never trusted to the client). Browser-mode Inspector is the human
    path; the harness is its scriptable twin.

Added

  • R7 — edge provenance tagging: callers/callees disclose HOW each
    answer was reached.
    Every row in callers/callees carries
    provenance — "graph" (a persisted, confidence-tagged edge) vs
    "heuristic-name-match" (the fallback served it, say so per row) —
    and the envelope carries resolution (CallResolutionStat, persisted
    by cie index/cie load in the edge-resolution pass): per-name
    {total_call_sites, unresolved_call_sites, resolved_edges}. The
    benchmark docs' honest miss ("resolved 3 of 6 real call sites on
    requests") is now a field in tool output — live-verified on
    psf/requests: resolution: {total: 19, unresolved: 16, resolved: 3}
    (name-keyed; see benchmarks-requests.md's reconciliation note).
    callgraph.resolve_call_edges gained the same-pass stats companion
    (resolution_stats); ground-truth provenance tests pin the labels
    against known-by-inspection truth.

Added

  • R14 — the PRD-hierarchy store lands on embedded SQLite. Its last
    Neo4j-only feature is gone: cie/embedded_hierarchy_repository.py's
    SQLiteHierarchyRepository implements the same HierarchyRepository
    protocol (push_hierarchy/get_children/get_lineage/
    get_hierarchy_node/get_project_tree) over one local file
    (.cie/hierarchy.db beside the other embedded stores). Intentional,
    documented backend differences: one HAS_CHILD edge direction (nothing
    writes the host wide-schema's CHILD_OF on this path) and name-keyed,
    unconditional REALIZED_BY edges (the task layer lives in a separate
    file; Neo4j's write validates them against stored AtomicTask nodes).
    The three hierarchy tools are real ToolService methods now — the
    last HTTP-only alias handlers; HTTP_WRITE_ALIASES is EMPTY
    (permanently, pinned), push_hierarchy joined WRITE_TOOLS, and the
    default cie-mcp --embedded serves the full PRD tree (opt out with
    --no-hierarchy / hierarchy_tracking=False; the tools then return
    unavailable[HIERARCHY_STORE_NOT_CONFIGURED], never silent-empties).
    CLI hierarchy:* commands also work against embedded now (R2's seam
    extends to the hierarchy repo). 21 tests
    (tests/test_embedded_hierarchy_repository.py, B1's bar) + the pinned
    honest-unavailable-when-off test. cie/hierarchy.py's docstring
    pointer to a nonexistent in-memory fake corrected in the same pass.

Added

  • R5 — the 503 surface shrinks 18 → 5, each with a machine-readable
    reason.
    The four protobox-leftover modules
    (cie/community_detect.py, cie/contracts.py, cie/state_machine.py,
    cie/test_orchestration.py) no longer import core.llm at module
    level: the import (and the Prompt/LlmAgent definitions it fed)
    moved into the one function per module that actually calls the LLM.
    Everything whose logic was pure now runs standalone —
    community_detect_run (label propagation), community_search,
    contracts (query), validate_types, inject_assertions,
    strip_assertions, test_plan, run_tests, test_results,
    coverage_gaps, nook_and_corner_test, unified_coverage_report —
    no shell LLM dependency at all. The five tools that genuinely need a host-only
    backend (qa, contracts_run, state_machine_run,
    community_summarize_run, decompose_page) now 503 with
    error.reason slugs (OPTIONAL_BACKEND_MISSING:core /
    HOST_PLUGIN_MISSING:decompose-detector) instead of prose — the error
    envelope grows the optional reason field, the conformance
    harness surfaces it, and tests/test_unavailable_reasons.py
    pins the registry + a no-quiet-regrowth gate. Found and fixed en
    route by the new bucket scan: failing_context("") crashed
    (IsADirectoryError) through the heuristic fallback — now an honest
    validation-hint envelope. Live conformance: 132 tools, 100
    verified / 23 graceful / 5 unavailable / 4 backend-gated / 0
    crashes
    (tool-test-lab/surface_results.json, fresh artifact).

  • MCP write-side parity for the task/QA layer (roadmap R1). The six
    task/QA write-back tools — push_tasks, set_task_status,
    link_artifact, append_repair_events, record_coverage,
    record_coverage_snapshot — are real ToolService methods now, so
    the default cie-mcp --embedded install (which introspects only
    ToolService) serves the full task/QA surface over MCP, instead of it
    being HTTP-only alias handlers. Same kwargs, same envelope shapes,
    same hints as the handlers they replace; they were added to
    WRITE_TOOLS in the same commit (push_hierarchy stays an HTTP alias
    until its embedded backend lands in R14). The read-only HTTP/MCP
    story is unchanged and pinned by tests — promoted writes are 403 by
    default server-side, per tool. Surface: 126 → 132 tools, live
    conformance 88 verified / 22 graceful / 18 unavailable-by-design / 4
    backend-gated / 0 crashes (tool-test-lab/surface_results.json —
    fresh artifact, this commit), with an execution check over a real MCP
    stdio session against .cie/tasks.db.

Fixed

  • The CLI answers the zero-config quickstart (roadmap R2). Query
    commands (cie files, cie search-symbol, cie callers, cie skeleton, cie tasks:*, …) are no longer hardwired to build a Neo4j
    connection: the same engine answers against the local SQLite graph
    cie index writes. Selection rule: --backend flag › CIE_BACKEND
    env › auto (embedded when a .cie/graph.db exists at --db/CIE_DB/
    cwd, else Neo4j — unchanged for existing Neo4j users). Task commands
    read/write the sibling .cie/tasks.db via the existing embedded task
    re...
Read more

0.1.0a3 — dogfooded alpha

Pre-release

Choose a tag to compare

@arunsoman arunsoman released this 30 Aug 14:02

Third alpha, cut after dogfooding cie against itself (cie index . on this repo, then a live MCP conformance run across the full 126-tool surface).

Highlights

  • Loader hygiene (cie/extract.py): the tree walk behind cie index / reindex / graph_diff now skips virtualenvs, dependency, cache, build and VCS directories. Indexing a venv holding a stale pip-installed copy of the project used to duplicate every callers() answer (this repo: 1,779 files / ~28k nodes indexed → now 84 / 1,554).
  • Blast radius is now ground-truth-verified (tests/test_graph_semantics_ground_truth.py): one fixture project where every true caller/callee is known by construction, asserted as exact sets. It caught and fixed two wrong-answer bugs: file_skeleton("app.py") leaked test_app.py's symbols (substring path matching), and affected_by omitted dependent TESTS edges — the test file was silently absent from its own blast radius. Both backends (SQLite + Neo4j) fixed.
  • Live MCP crash fixes: the embedded task repository is thread-safe (get_task / list_pending_tasks / task_dependency_closure / blame_history crashed because tool handlers run in worker threads); optional backends (core.llm, decompose plugins) now degrade as SPEC §0 kind="unavailable" (HTTP 503) instead of raw crashes (qa, decompose_page + 15 others).
  • Full-surface conformance, post-fix: 85 verified ok / 19 graceful error contracts / 18 unavailable-by-design / 4 backend-gated (need live Neo4j) — 0 crashes. Harness in tool-test-lab/.
  • Repair transaction layer (propose_patch / apply_patch / verify_patch) ships in this alpha, per the changelog it was drafted into.

Housekeeping

  • 155/155 tests passing (was 129); test surface grew by 4 files, including exact-set ground truth.
  • Versioning continues the documented PEP 440 ladder toward the eventual 0.1.0 stable (that stable cut remains a deliberate gate, per goal.md C1 — not faked by this alpha).

cie 0.1.0a2 — corrected alpha

Pre-release

Choose a tag to compare

@arunsoman arunsoman released this 28 Aug 14:00

cie 0.1.0a2 — corrected alpha. Supersedes 0.1.0a1.

⚠️ 0.1.0a1 is superseded. Its MCP server only ran on mcp 1.x; on mcp 2.x (what pip install "cie[mcp]" resolves to today) the tests failed to import. Use 0.1.0a2.

What's fixed in 0.1.0a2

  • The MCP server now runs on both mcp 1.x and 2.x. build_mcp_server is version-agnostic: it prefers mcp 2.x's mcp.server.mcpserver.MCPServer and falls back to mcp 1.x's mcp.server.fastmcp.FastMCP (in mcp 2.x, FastMCP was renamed to MCPServer and mcp.server.fastmcp is a stub that raises). The call_tool test normalizes the two return shapes (2.x CallToolResult vs 1.x list[ContentBlock]). Verified on both with a real stdio JSON-RPC handshake.
  • Python 3.10 actually works. cie/data_model.py imported tomllib unconditionally, but tomllib is 3.11+ stdlib — so it failed to import on 3.10, contradicting requires-python = ">=3.10". Now uses a tomli backport fallback (conditional dependency tomli; python_version < "3.11").

CI

All green: pytest across Python 3.10 / 3.11 / 3.12 / 3.13, plus a real MCP stdio handshake smoke check on every push.

Quickstart (unchanged)

pip install "cie[mcp]"
cie index /path/to/your/project
cie-mcp /path/to/your/project --embedded        # full (read+write) by default
cie-mcp /path/to/your/project --embedded --policy readonly   # read-only client

See CHANGELOG.md for the full history. ⚠️ Alpha — the API surface may still change before 0.1.0.

cie 0.1.0a1 — first alpha

Pre-release

Choose a tag to compare

@arunsoman arunsoman released this 28 Aug 13:43

⚠️ Superseded by 0.1.0a2.

This tag's MCP server only ran on mcp 1.x; on mcp 2.x (what pip install "cie[mcp]" resolves to today) the tests fail to import, and its cie.data_model failed to import on Python 3.10. Both are fixed in 0.1.0a2 — use that.


Original 0.1.0a1 notes: first alpha release of cie — Code Insight Engine. See the CHANGELOG for what it shipped.