Dependency-aware planning, incremental verification, and recipe memory for LLM-assisted coding (stdlib-only core).
Project description
Trammel
Pure-Python, stdlib-only planning and execution harness for LLM-assisted coding. Decomposes goals into dependency-aware strategies, explores bounded parallel beams with genuinely different orderings, runs incremental per-step verification in isolated temp copies, propagates failure constraints, and persists successful strategies as reusable recipes in a local SQLite database (trammel.db).
Trammel is a tool for LLMs, not a tool that calls LLMs. It provides the planning discipline, verification scaffolding, and failure memory that coding assistants need to tackle multi-step tasks reliably.
Installation
pip install trammel # core (stdlib only)
pip install trammel[mcp] # with MCP server support
Or install from source:
git clone https://github.com/IronAdamant/Trammel.git
cd Trammel
pip install -e . # editable install
pip install -e '.[mcp]' # with MCP support
Publishing to PyPI (maintainers)
Releases are uploaded to PyPI via Trusted Publishing (OpenID Connect from GitHub). You do not need a PyPI API token or ~/.pypirc on your machine.
- PyPI (once): Project → Publishing → trusted publisher: GitHub →
IronAdamant/Trammel, workflowpublish.yml, environmentrelease. - Each release: Publishing a GitHub Release runs
.github/workflows/publish.yml(build wheel/sdist, tests, upload to PyPI via OIDC).
Release checklist (GitHub + PyPI)
Do this from a clean main after merging what you want to ship:
- Bump
versioninpyproject.toml(and add a Changelog entry in this README if you like). - Run tests:
python -m unittest discover -q -s tests -p 'test_*.py' - Commit and push:
git push origin main - Tag and push (replace
X.Y.Z):
git tag -a vX.Y.Z -m "Release X.Y.Z" && git push origin vX.Y.Z - Create the GitHub Release (triggers PyPI):
gh release create vX.Y.Z --repo IronAdamant/Trammel --title "vX.Y.Z" --notes "…"
Or use the GitHub UI: Releases → Draft a new release → choose the tag → Publish release.
Wait for the Publish to PyPI workflow to finish; then confirm pypi.org/project/trammel.
If you need to publish manually, use a short-lived PyPI token only for that session; do not commit tokens.
Plan fidelity and project configuration
Trammel is built to reduce repeated work across steps and sessions and to keep sub-agents aligned with the main plan (tracked plans, step claims, recipes).
Decomposition controls (stdlib-only):
strict_greenfield— If the goal implies new work (creation-style) but there is no scaffold, no explicit file paths in the goal text, and no matching recipe with scaffold steps, decomposition fails with a clear error. Use this when orchestrators must not improvise a vague greenfield plan.plan_fidelity— Included on decompose results: whether strict mode was on, whether.trammel.json/pyprojectconfig was merged, optionalfocus_globs, andmax_filescap.- Relevance signals — Each file step can include
relevance_keyword,relevance_graph, compositerelevance, andrelevance_tier(high/medium/low) so prioritization is explainable, not a single opaque score.
Optional config (no extra dependencies): merge of pyproject.toml section [tool.trammel] (Python 3.11+ tomllib) and .trammel.json (JSON overrides). Supported keys include default_scope, focus_keywords, focus_globs, max_files. The existing language field in .trammel.json remains the language-detection override.
Quickstart
Run the test suite:
python -m unittest discover -q -s tests -p 'test_*.py'
Use from Python:
from trammel import plan_and_execute, explore, synthesize, __version__
# Full pipeline: decompose → plan → explore beams → verify → store recipe
result = plan_and_execute("your goal", "/path/to/project", num_beams=3)
# Explore only (no verification): decompose + beam variants
strategy = explore("refactor auth", "/path/to/project")
# Store a caller-verified strategy as a recipe
synthesize("refactor auth", verified_strategy)
Use from the CLI:
python -m trammel --version
python -m trammel "refactor X to Y" --root /path/to/project --beams 3 --db ./trammel.db
python -m trammel "fix tests" --test-cmd pytest -x -q
python -m trammel "explore auth" --dry-run # explore only, no verification
python -m trammel "fix tests" --language python
python -m trammel "fix auth" --root /monorepo --scope services/auth # monorepo scope
echo '{"goal":"fix tests"}' | python -m trammel
Integration surfaces (MCP optional)
The authoritative plan is not tied to MCP: the same behavior is available through the Python API, CLI, and SQLite (trammel.db). In practice, sub-agents often do not use MCP (plain shells, task runners, CI, or secondary models). Trammel is designed so orchestrators can use MCP where the host supports it, while workers still align to plans, steps, recipes, and constraints via the store, exported JSON, or thin wrapper scripts.
| Surface | Role |
|---|---|
RecipeStore / trammel.db |
Durable truth for plans, step status, claims, and recipes across processes and sessions. |
Planner.decompose / explore / plan_and_execute |
Programmatic strategies without any MCP process. |
python -m trammel, JSON on stdin |
Shell and automation without MCP. |
trammel-mcp |
IDEs and hosts that expose MCP (e.g. Cursor, Claude Code). |
Roadmap and design notes (directional)
Not a commitment—ideas that fit the stdlib-only, plan-fidelity mission:
- Worth adding: versioned plan/strategy export for external runners; wire
test_cmdfrom project config into harness defaults when not overridden; optional hooks or structured logging (claims, recipe hits, decompose rejects); short orchestrator checklists (scaffold vs scope, strict mode, failure modes). - Worth changing carefully: with
relevant_only, steps may be re-sorted by relevance—treatdepends_onas execution order, not display order, or split priority vs execution in a future payload;max_filescan truncate the graph—document tradeoffs or optional dependency-aware caps later; unify.trammel.jsonhandling between language override andproject_configso one dialect evolves cleanly.
Non-goals: embeddings, vector DBs, or in-library LLM calls—those stay outside the harness.
MCP Server
Trammel exposes its capabilities as an MCP server for integration with Claude Code, Cursor, and other MCP-aware clients.
pip install trammel[mcp] # or: pip install mcp
trammel-mcp # starts stdio MCP server
See SYSTEM_PROMPT.md for a reference orchestration guide that LLM clients can use to drive the plan-verify-store loop.
Configure in .claude/.mcp.json:
{
"mcpServers": {
"trammel": {
"command": "trammel-mcp",
"args": []
}
}
}
MCP tools: the status tool reports the current count and names. Core tools include decompose (with scope, scaffold, strict_greenfield, …), explore, create_plan, get_plan, verify_step, record_step, record_steps, save_recipe, get_recipe, add_constraint, get_constraints, list_plans, history, status, list_strategies, list_recipes, update_plan_status, deactivate_constraint, prune_recipes, resume, validate_recipes, estimate, usage_stats, failure_history, resolve_failure, claim_step, release_step, available_steps, complete_plan
Architecture
Trammel treats planning as a structured search problem:
- Decompose -- Analyze project imports (Python AST; TypeScript, Go, Rust, C/C++, Java/Kotlin, C#, Ruby, PHP, Swift, Dart, Zig regex), build dependency graph, topological sort, generate steps with ordering rationale
- Explore -- Generate beam variants with genuinely different strategies (
bottom_up,top_down,risk_first,critical_path,cohesion,minimal_change), executed in parallel viaProcessPoolExecutor - Verify -- Run edits in isolated temp copies, per-step or full-run; extract structured failure analysis on failure
- Constrain -- Propagate failure reasons as persistent constraints that block repetition across sessions
- Remember -- Store successful strategies as recipes, retrieved by composite scoring (text similarity + file overlap + success ratio)
Project Layout
trammel/ Importable package
__init__.py plan_and_execute, explore, synthesize, __version__
analyzers.py LanguageAnalyzer protocol, PythonAnalyzer, TypeScriptAnalyzer, detect_language (~460 LOC)
analyzers_ext.py GoAnalyzer, RustAnalyzer, CppAnalyzer (5-pattern symbol detection), JavaAnalyzer (source root detection) (~440 LOC)
analyzers_ext2.py CSharpAnalyzer, RubyAnalyzer, PhpAnalyzer, SwiftAnalyzer, DartAnalyzer, ZigAnalyzer (~445 LOC)
core.py Planner: decomposition, constraint enforcement, step generation, plan fidelity
project_config.py Merge [tool.trammel] + .trammel.json (default_scope, focus_*, max_files)
strategies.py Beam strategy registry and 9 built-in orderings (~280 LOC)
harness.py ExecutionHarness: temp copy, edits, test runner, base-copy caching
store.py RecipeStore: SQLite persistence (8 tables), telemetry, inherits RecipeStoreMixin (~440 LOC)
store_recipes.py RecipeStoreMixin: recipe methods (save, retrieve, list, prune, trigram/file backfill) (~250 LOC)
utils.py Trigrams, cosine, failure extraction, goal normalization, shared symbol collection (~370 LOC)
cli.py Argparse CLI entry point (--dry-run, --language)
mcp_server.py MCP tool schemas and dispatch-dict routing
mcp_stdio.py MCP stdio server entry point
tests/ stdlib unittest (242 tests, 4 modules)
wiki-local/ Spec, glossary, and wiki index
SYSTEM_PROMPT.md Reference orchestration guide for LLM clients
pyproject.toml Package metadata
SQLite Schema (trammel.db)
| Table | Purpose |
|---|---|
recipes |
Successful strategies keyed by SHA-256, with pattern, constraints, success/failure counts |
recipe_trigrams |
Inverted trigram index for fast recipe retrieval (trigram → recipe sig) |
recipe_files |
File paths associated with recipe steps, for structural matching (Jaccard overlap) |
plans |
Goal + strategy snapshot with step progress tracking |
steps |
Individual work units with dependencies, rationale, verification results |
constraints |
Failure records (dependency/incompatible/requires/avoid) that prevent known-bad repetition |
trajectories |
Harness run logs per beam: outcome, steps completed, failure reason |
Integration with Stele and Chisel
Trammel works standalone. When co-installed with Stele (context retrieval) and Chisel (code analysis), all three can cooperate through the LLM's MCP tool layer where the host exposes MCP—no cross-dependencies between the three packages. Workers without MCP still use Trammel via API/CLI/store as in Integration surfaces above.
| Tool | Role |
|---|---|
| Stele | Persistent context retrieval and semantic indexing |
| Chisel | Code analysis, churn, coupling, risk mapping |
| Trammel | Planning discipline, verification, failure learning, recipe memory |
Contributing
Contributions are welcome. Please open an issue first to discuss what you would like to change.
- Fork the repository
- Create a feature branch (
git checkout -b feature/your-feature) - Make your changes (core must remain stdlib-only; tests use
unittestonly) - Run the test suite:
python -m unittest discover -q -s tests -p 'test_*.py' - Commit and push your branch
- Open a pull request
Changelog
v3.9.4 — RecipeLab findings: scaffold metrics, skip-UX, refactor hints, CI checklist
- Planner / MCP:
suppress_creation_hints,scaffold_dag_metrics,skipped_existing_scaffold; refactor-verb guard for creation inference;summary_onlysurfaces DAG + skip blocks. - Tests:
tests/test_findings_checklist.pyencodes validation matrix A–C (305 tests). Core remains stdlib-only (zero third-party runtime deps).
v3.9.1 — Documentation: MCP-optional integration, releasing guide
- README: Integration surfaces (API / CLI / SQLite vs MCP), roadmap notes, release checklist for Trusted Publishing.
- Wiki / spec: §1.1–1.2 alignment;
SYSTEM_PROMPT.mdtracked in repo (sub-agents without MCP). - No API changes — doc and packaging metadata refresh for PyPI long description.
v3.7.9 — Comprehensive cleanup: dead code, bug fixes, modernization, robustness
- Bug fixes: CLI goal validation (
str(None)bug), missingcreatedcolumn in step queries, mixin stubs now raiseNotImplementedError,_sql_inempty-input guard. - Dead code: Removed unused
_is_ignored_dirimport fromanalyzers_ext2.py. - Hardening: Replaced all positional
sqlite3.Rowunpacking with named column access (8 sites). Pre-compiled Rust/Cargo/Maven regex patterns at module level. - Simplification: Beam-count capping, step description helper, list_strategies comprehension,
_validate_registries()wrapper. - Modernization: Walrus operator in
_extract_step_files,TYPE_CHECKINGimports, private_cosinenaming, KeyboardInterrupt handling in MCP stdio. - 248 tests (all passing).
v3.7.8 — Code quality: DRY step dicts, simplified helpers, consistent isinstance
- DRY step dicts: Extracted
_STEP_COLUMNS+_step_to_dict()in store.py — eliminates duplicated step-dict construction inget_plan()andget_step(). - Simplified helpers:
word_jaccard,cosine,_strip_php_commentsin utils.py condensed (reduced total LOC). - Consistent isinstance: Fixed
type()vsisinstance()inconsistency inPythonAnalyzer.collect_typed_symbols. - 248 tests (all passing).
v3.7.4 — Code quality: dead code removal, simplification & modernization
- Bug hardening: Fixed potential
ZeroDivisionErrorinexplore_trajectories,ValueErrorwith 0 beams, replaced fragileassertwithRuntimeErrorin MCP server. - Dead code removal: Removed unused
_default_beam_count, deadTYPE_CHECKING: passblock. - Simplification: Consolidated 4 SQL COUNT queries into 1, extracted
_sql_in()helper (deduplicates 8 sites), eliminated redundant dict copies, simplified confusing list-unpacking comprehension. - Modernization:
asyncio.to_threadreplacesrun_in_executor, logger configured at module level for early error capture, lazy_get_analyzer_registry()replaces late inline imports. - 248 tests (all passing).
v3.7.3 — Code quality: deduplication, modernization & hardening
- Deduplication: Extracted shared trigram/file helpers in
store_recipes.py, deduplicated Swift SPM scanning. - Modernization:
_count_importersusesCounter, set-based symbol deduplication, f-string continuation. - Hardening: Narrowed telemetry exception to
sqlite3.Error, fixed type annotation, named constants for magic numbers. - Cleanup: Marked unused MCP handler params, fixed Dart import mutual exclusivity.
- 248 tests (all passing).
v3.7.2 — Codebase audit & cleanup
- Bug fixes: Fixed
_inject_orderingsNone-key dict comprehension, recipe mutation indecompose(), hardcoded DB path insynthesize(), missingclaimed_by/claimed_atinget_step(). - Cross-platform: Normalized Swift analyzer path separator handling.
- 248 tests (all passing).
v3.7.1 — Mixin type safety, robustness & performance
- Type safety: Added typed attribute stubs to
RecipeStoreMixinandAgentStoreMixinfor type-checker compatibility. - Robustness:
claim_steprejects non-pending steps; parallel beam fallback narrowed toOSErroronly with debug logging. - Performance:
run_incrementaloptimized from O(K^2) to O(K) via persistent base copy. - Test coverage: 9 new
collect_typed_symbolstests (Rust, C++, Java, C#, Ruby, PHP, Swift, Dart, Zig). - 248 tests (all passing).
v3.7.0 — Comprehensive audit, bug fixes & modernization
- 8 bug fixes: Critical-path cycle leak,
log_eventbare commit, schema migration over-broad catch, inconsistent win-rate formulas,trigram_signaturefingerprint type bug, Rust cargo relpath bug, Java import comment stripping, PHP grouped-use alias stripping. - Dead code: Removed
ExecutionHarness.run()alias. - Simplification: N+1 query fix in recipe retrieval, SQL-side recipe pruning,
_walk_project_sourcesshared generator,DEFAULT_DB_PATHconstant consolidation. - Modernization:
_SUPPORTED_LANGUAGESderived from registry, language/analyzer sync assertion, mid-file imports moved to top, premature Python 3.14 classifier removed. - 239 tests (all passing).
v3.6.0 — Codebase audit, bug fixes & modernization
- Bug fixes: Fixed TOCTOU race in
record_failure_patternandresolve_failure_pattern(wrapped in transactions). FixedJavaAnalyzer.pick_test_cmdfallback to use systemgradleinstead of nonexistent./gradlew. - Duplication elimination: Extracted
_count_importers(),_is_claimed_by_other(),_try_resolve()helpers.run()now delegates toverify_step(). Removed redundant_collect_fileswrappers. Merged two transactions invalidate_recipes. - Dead code removal: Always-true guard, unnecessary
or "", redundant assignment, ineffective deferred import. - Modernization:
collections.abc.Callable/Generatorimports, PEP 561py.typedmarker,get_analyzeradded to__all__,.mypy_cache/.ruff_cachein.gitignore. - Simplifications: Single-pass
_split_active_skipped, defensive.get()for constraint descriptions, simplified test assertions. - 239 tests (all passing).
v3.5.2 — Codebase cleanup & modernization
- Consolidated comment strippers: removed duplicate
_strip_js_commentsand_strip_cpp_comments, all analyzers now use the shared_strip_c_commentsfrom utils - Consistent import analysis: all regex-based analyzers now strip comments before extracting imports (fixes false positives from commented-out imports in Ruby, Dart, Zig, C#, PHP)
- Fixed PHP method pattern overlap: method pattern now requires at least one access modifier (changed
*to+), preventing duplicate symbol entries with the function pattern - Fixed Dart function false positives: added negative lookahead to exclude control flow keywords (
if,for,while, etc.) - Improved
max()type safety:detect_languageextension counting now useslambda k: counts[k]instead ofcounts.get - Modernized
str.endswith: uses native tuple form throughout_collect_*helpers - Removed redundant
storeparameter fromPlanner.explore_trajectories(usesself.store) - MCP status handler refactored: now delegates to
RecipeStore.get_status_summary()instead of raw SQL - Schema/dispatch sync assertion: module-load assertion ensures
_TOOL_SCHEMASand_DISPATCHkeys stay in sync - Store improvements: removed unreliable
__del__, narrowed schema migration exception tosqlite3.OperationalError, fixedlist_plansstatus filter, fixedget_strategy_statsreturn type, batch-fetched recipe files inlist_recipes(N+1 fix) - Fixed float equality: recipe text similarity early-exit now uses
>= 0.9999instead of== 1.0 - Logging setup fix:
mcp_stdio.pynow callslogging.basicConfigbefore server construction - CLI hardening: added JSON parse error handling for stdin input
- Language-agnostic messages: "No Python symbols" fallback message now says "No symbols found"
__main__.pyguard: addedif __name__ == "__main__"protection
3.5.1
- Multi-agent step coordination: New
claim_step,release_step, andavailable_stepsMCP tools (27 tools total). Agents claim steps before working on them — other agents see claimed steps and skip them. Claims auto-expire after 10 minutes (stale agent recovery).available_stepsreturns only steps whose dependencies are satisfied AND aren't claimed by another agent. - New
store_agents.pymixin:AgentStoreMixinwithclaim_step(),release_step(),get_available_steps().RecipeStoreinherits from bothRecipeStoreMixinandAgentStoreMixin. - Schema migration: Steps table gains
claimed_byandclaimed_atcolumns (safe migration for existing databases). - 242 tests (all passing).
3.5.0
- Failure pattern learning: New
failure_patternsSQLite table (9 tables total) accumulates structured failure signatures across sessions. When a step fails with verification data, the file + error type + message are auto-recorded. Patterns track occurrence count, first/last seen timestamps, and resolution history. failure_historyMCP tool: Query historical failure patterns by file or project-wide. Shows which files fail frequently, what error types occur, and what resolutions worked. Use before modifying a file to avoid known pitfalls.resolve_failureMCP tool: Record what fixed a known failure pattern. Builds institutional memory of what works for specific error types on specific files. 24 MCP tools total.- Auto-recording:
update_stepwithstatus="failed"automatically extracts failure analysis and records the pattern — no manual instrumentation needed. - 242 tests (all passing).
3.4.1
- C++ nested template parsing: Template patterns now handle 2 levels of nesting (
template<typename T, std::vector<int>>) instead of breaking at the first>. Also fixed in Rustimpl<>and Java/Kotlin genericfun<>patterns. - Rust workspace + relative imports:
analyze_importsnow resolvesuse super::,use self::, and workspace crate imports (readsCargo.toml[workspace] membersand member crate names). Previously onlyuse crate::was handled. - PHP grouped use statements:
use Foo\{Bar, Baz, Qux};(PHP 7.0+) now correctly expanded and resolved. Previously only simpleuse Foo\Bar;was parsed. - Swift SPM-aware module mapping: Detects
Sources/<Module>/andTests/<Module>/directory structure for Swift Package Manager projects. Falls back to parent-directory mapping for non-SPM projects. - TypeScript monorepo workspace support: Reads
package.jsonworkspacesfield (npm, yarn, pnpm patterns), discovers workspace packages, resolves bare imports (import { x } from '@scope/pkg') to workspace package entry points. - 242 tests (all passing).
3.4.0
- Usage telemetry: New
usage_eventsSQLite table (8 tables total) withlog_event()andget_usage_stats()methods onRecipeStore. Tool calls, recipe hit/miss rates, and strategy win rates tracked automatically. Newusage_statsMCP tool (22 tools total) returns aggregated telemetry over a configurable time window. - Dispatch refactor: Replaced 153-line
match/caseinmcp_server.pywith dispatch-dict pattern. Each tool has a dedicated handler function, looked up via_DISPATCHdict. Adding new tools now requires only: handler function + schema + dict entry. - Analyzer improvements: PHP class methods now detected (was major gap). Java 16+
recordkeyword supported. Dart factory/named constructors detected. - Comment stripping for 7 languages: Added
_strip_c_comments(shared by Go, Rust, Java, C#, Swift, Dart, Zig),_strip_hash_comments(Ruby), and_strip_php_comments(PHP). Previously only Python (AST), TypeScript, and C/C++ stripped comments before symbol detection. - 5 new sample repos: Jekyll (Ruby), Flame (Dart), ZLS (Zig), Laravel (PHP), Ktor (Kotlin) cloned to
sample_file_test/for analyzer validation across all 15 supported languages. - 242 tests (all passing).
3.3.1
- Strategy module extraction: Beam strategy registry and 9 built-in orderings extracted from
core.pyinto newstrategies.py(~280 LOC).core.pyreduced from 595 to 324 LOC, well under the 500 LOC limit. - Eliminated circular dependency workarounds: Moved shared
_collect_symbols_regexand_collect_typed_symbols_regexhelpers fromanalyzers.pytoutils.py. Removedfunctools.cachelazy-import wrappers fromanalyzers_ext.pyandanalyzers_ext2.py(12 lines each), replaced with direct imports. - DRY regex patterns: Derived
_*_SYMBOL_PATTERNSfrom_*_TYPED_PATTERNSvia[p for p, _ in _*_TYPED_PATTERNS]for TypeScript, Rust, Java, C#, Ruby, PHP, Swift, and Dart (8 languages). Eliminates ~70 lines of duplicated regex definitions. - DRY Python AST walking: Extracted
PythonAnalyzer._iter_ast()generator, shared by bothcollect_symbolsandcollect_typed_symbols, eliminating duplicated file-walking and AST-parsing code. - Import ordering fix: Fixed stdlib import ordering in
store_recipes.py(import osmoved before local imports). - All files under 500 LOC:
analyzers.pyreduced from 559 to 463 LOC. Total source: 3,876 to 3,771 LOC (105 lines net reduction through deduplication). - 242 tests (unchanged, all passing).
3.3.0
- Typed symbol analysis: New
collect_typed_symbols()method on all 15 analyzers returns symbols with type classification (function, class, interface, enum, struct, trait, etc.). - 3 new beam strategies (9 total):
leaf_first(zero-importer files first),hub_first(network hub files by in*out degree),test_adjacent(files with matching test files first). - Analyzer fixes: Ruby basename overwriting, Swift overly broad directory mapping, Java packageless file gap.
- Store refactor:
_init_schema()decomposed into class-level SQL constants. - 242 tests (12 new).
3.2.1
- Bug fix:
retrieve_best_recipescoring bug wherebest_scorewas updated before JSON validation — corrupted entries could shadow valid recipes. - Dead code removed: unused
total_filesvariable inestimatetool, redundantget_analyzerre-import. - Code simplification:
detect_languagereplaced 8 extension alias constants and 12-branch if/elif with data-driven loop. Lambda replaced withdefin_detect_from_config. RedundantDartAnalyzer.pick_test_cmdbranch removed. - Performance: eliminated double file reads in C#/PHP analyzers; Go analyzer reduced from two walks to one; PHP namespace lookup optimized from O(n) to O(1).
- Modernization: added return type annotations to
_get_collect_symbols_regex. Moved_SUPPORTEDto module-level_SUPPORTED_LANGUAGESfrozenset. Simplified__main__.py. - 230 tests (unchanged).
3.2.0
- Six new language analyzers:
CSharpAnalyzer(.cs),RubyAnalyzer(.rb),PhpAnalyzer(.php),SwiftAnalyzer(.swift),DartAnalyzer(.dart),ZigAnalyzer(.zig) in newanalyzers_ext2.py(~480 LOC). Total: 15 supported languages (Python, TypeScript, JavaScript, Go, Rust, C/C++, Java/Kotlin, C#, Ruby, PHP, Swift, Dart, Zig). - Config-file detection expanded: Package.swift (swift), build.zig (zig), pubspec.yaml (dart), .csproj/.sln (csharp), Gemfile (ruby), composer.json (php).
- Extension counting expanded:
.cs,.rb,.php,.swift,.dart,.zigall counted indetect_languagefallback. - Registry expanded: 15 languages in
_ANALYZER_REGISTRY. MCP_LANGUAGESlist updated to match. - Exports expanded:
CSharpAnalyzer,DartAnalyzer,PhpAnalyzer,RubyAnalyzer,SwiftAnalyzer,ZigAnalyzerexported from__init__.py. - All 21 sample repos re-tested: zero errors across all languages and scopes.
- 230 tests (15 new: symbols/imports for C#, Ruby, PHP, Swift, Dart, Zig + 6 config detection).
3.1.0
- Abbreviation handling in recipe matching: New
_ABBREVIATIONSdict inutils.pywith ~40 common coding abbreviations (gc, db, auth, api, etc.).normalize_goalexpands abbreviations before applying verb synonyms. Recipe matching that previously failed (e.g., "optimize GC" vs "optimize garbage collector") now works with 0.86+ similarity. - Analysis timing metadata:
decomposenow returnsanalysis_metain the response withlanguage,scope,files_analyzed,dep_files,dep_edges,timing_s(symbols, imports, total), and optionalwarningfor unsupported language fallbacks. estimateMCP tool: Quick file count for a project or scope without running full analysis. Returnslanguage,matching_files,recommendation("use scope" if >5000 files, "full analysis OK" otherwise). Helps LLMs decide whether to scope before analyzing large repos. 21 MCP tools total.- Iterative critical_path strategy: Converted recursive
_longestdepth computation to iterative stack-based DFS with cycle detection viain_stackset. Fixes stack overflow on deep dependency graphs (Guava's 1.66M-edge Java import graph was crashing). - 215 tests (5 new: 3 abbreviation, 1 analysis meta, 1 estimate tool).
3.0.0
- Monorepo scope support: New
scopeparameter ondecompose,explore,plan_and_execute, CLI (--scope), and MCP tools. Limits analysis to a subdirectory while keeping the full project available for test execution. Example:--scope services/authanalyzes onlyservices/auth/. - Concurrent write safety: Validated with threading tests (4 threads x 5 operations). Plans, recipes, and constraints all survive concurrent access without errors.
- 206 tests (6 new: 3 concurrent, 3 scope).
2.9.0
- Plan resumption: New
get_plan_progress(plan_id)returns accumulatedprior_editsfrom passed steps andremaining_stepsfor continuing failed plans. NewresumeMCP tool. - Recipe validation: New
validate_recipes(project_root)checks recipe file entries against current project, removes stale entries, prunes fully-stale recipes. Newvalidate_recipesMCP tool. - Config-file language detection:
detect_language()now checks config files first (Cargo.toml, go.mod, tsconfig.json, package.json, build.gradle, CMakeLists.txt, pyproject.toml) before falling back to extension counting. Config detection takes priority. - Shared file-collection helper: New
_collect_project_files(root, extensions)inutils.pyreplaces duplicatedos.walkpatterns in TypeScriptAnalyzer, CppAnalyzer, RustAnalyzer. verify_steplanguage support: MCP tool gainslanguageparameter for auto-detecting test command and error patterns.explore_trajectoriesnow uses existing_split_active_skippedhelper instead of reimplementing inline.- Full MCP dispatch test coverage: All 20 tools now have explicit dispatch tests.
- 200 tests (25 new).
2.8.0
- Codebase cleanup: Removed unused imports (
Anyfromanalyzers.py,jsonfromanalyzers_ext.py,ExecutionHarness/dumps_jsonfromtest_strategies.py). Replaced fragile lazy-import global inanalyzers_ext.pywithfunctools.cache(thread-safe, simpler). Fixed overly broadBaseException→Exceptionin transaction rollback (utils.py). Modernizedconn.commit()/conn.rollback(). Optimized_order_cohesionset creation. UpdatedSYSTEM_PROMPT.md(tool count 17→18, added C/C++/Java/Kotlin to multi-language section). - 175 tests (unchanged).
2.7.0
- Store module split: Extracted recipe methods (
save_recipe,retrieve_best_recipe,list_recipes,prune_recipes,_rebuild_trigram_index,_backfill_files) intostore_recipes.pyasRecipeStoreMixin(~210 LOC).RecipeStoreinstore.pynow inherits from it (~342 LOC, down from 540). - Expanded C++ symbol detection: Replaced single function pattern in
CppAnalyzerwith 5 targeted patterns: template functions, qualified functions (static/inline/constexpr), operator overloading, constructor/destructor detection, macro-prefixed functions (EXPORT_API etc). - Java/Kotlin source root detection: New
JavaAnalyzer._detect_source_roots(project_root)readsbuild.gradle/build.gradle.ktsandpom.xmlto find standard source directories (src/main/java,src/main/kotlin, etc). Falls back to project root.analyze_importsnow walks detected source roots instead of project root. - MCP tool
prune_recipes: Exposed recipe pruning as MCP tool withmax_age_daysandmin_success_ratioparameters. 18 MCP tools total. - 175 tests (9 new: 5 C++ expansion, 3 Java source roots, 2 MCP prune, minus 1 renamed).
2.6.0
- Parallel beam execution:
plan_and_executeruns beams concurrently viaconcurrent.futures.ProcessPoolExecutor(stdlib). Falls back to sequential on systems where process spawning fails. - C/C++ and Java/Kotlin analyzers: New
CppAnalyzer(.c/.cpp/.cc/.cxx/.h/.hpp/.hxx, class/struct/namespace/enum/typedef/function symbols,#include "..."resolution) andJavaAnalyzer(.java/.kt/.kts, class/interface/enum/fun/object/@interface symbols, package-based import resolution) inanalyzers_ext.py. MCP language enum expanded to 9 entries. - Analyzer module split:
analyzers.pysplit intoanalyzers.py(~370 LOC) +analyzers_ext.py(~400 LOC) to stay under 500 LOC per file. All existing imports preserved via re-export. - Recipe pruning: New
RecipeStore.prune_recipes(max_age_days=90, min_success_ratio=0.1)removes stale, low-quality recipes with cascade deletes torecipe_trigramsandrecipe_files. - Harness base-copy caching: New
prepare_base(project_root)andrun_from_base(edits, base_dir)create one filtered base copy; beams copy from it instead of re-filtering per beam. --dry-runand--languageCLI flags:--dry-runrunsexplore()instead ofplan_and_execute().- Decomposed
_apply_constraints: 85-line function incore.pysplit into_parse_constraints,_mark_avoided,_inject_orderings,_mark_incompatible,_add_prerequisites. - 166 tests (20 new).
2.5.0
- Code cleanup: Removed unused
import sysfromharness.py. Eliminated duplicateset(symbols) | set(dep_graph)computation inPlanner.decompose(core.py). Added defensivejson.loadserror handling inretrieve_best_recipe(store.py). Made failure default explicit inget_strategy_stats(store.py). Fixedregister_strategyparameter order inspec-project.mddocumentation. - 146 tests (unchanged).
2.4.0
- Go and Rust support: New
GoAnalyzer(regex-based, readsgo.modfor module path, resolves internal imports) andRustAnalyzer(regex-based, resolvesuse crate::andmoddeclarations). Shared_collect_symbols_regexhelper for regex-based analyzers.detect_languageexpanded to count.go/.rsfiles. Registry now supports 5 languages. - TypeScript enhancements:
_strip_c_commentsfor comment stripping before symbol/import detection. Namespace pattern added to_TS_SYMBOL_PATTERNS. - Improved beam strategies:
_order_bottom_upstable-sorts by ascending dependency count (files with fewer deps first)._order_top_downstable-sorts by descending dependency count (most consumer-facing files first). Both now genuinely use thedep_graphparameter. - Better recipe matching: New
word_substring_score(a, b)for partial word matching.goal_similarityreweighted: 0.3 trigram cosine + 0.4 word Jaccard + 0.3 substring (was 0.4/0.6). - Store improvements: Merged duplicated SQL branches in
save_recipe,list_plans,get_active_constraints. Composite scoring gains recency weighting (30-day half-life). New weights: text 0.4, files 0.25, success 0.15, recency 0.2. File trimmed from 534 to 516 lines. - MCP server refactor:
_schema()and_prop()helpers reduce from 507 to 255 lines. Added "go" and "rust" to language enums. - 146 tests (17 new: 4 Go, 3 Rust, 2 TS enhancement, 2 detection, 2 strategy, 4 matching).
2.3.0
- Code cleanup: Extracted
_split_active_skippedhelper incore.py, shared by all 6 beam strategy functions (eliminates duplicated active/skipped split pattern). Modernized_VERB_SYNONYMSinutils.pyfrom imperative loop to dict comprehension (eliminates leaked module-level variables_canonical,_variants,_v). - Documentation fixes: Corrected canonical verb form examples in glossary and spec (was "refactor", now correctly "restructure"). Fixed
register_strategyparameter order in glossary ((name, description, fn)not(name, fn, description)). - 129 tests (unchanged).
2.2.0
- Improved recipe matching: New
_VERB_SYNONYMS(40+ verb variants to 9 canonical forms),normalize_goal,word_jaccard, andgoal_similarity(0.4 trigram cosine + 0.6 word Jaccard on normalized text) inutils.py.save_recipenormalizes before trigram indexing.retrieve_best_recipeusesgoal_similarity._backfill_trigramsrenamed to_rebuild_trigram_index(rebuilds with normalized text on init). - New beam strategies (6 total, 3 new):
critical_path(longest dependency chain first — bottleneck feedback),cohesion(flood-fill connected components, largest first, toposort within),minimal_change(fewest symbols first — quick wins). - TypeScript analyzer improvements:
_TS_SYMBOL_PATTERNSlist replacing single regex (interface, enum, const enum, type alias, abstract class, decorated class, function expression). Expanded import detection (re-exports, barrel exports, type re-exports, dynamic imports). New_TS_ALIAS_IMPORT_RE,_read_ts_path_aliases,_resolve_alias. Added.mts/.mjsextensions. - 129 tests (34 new: 10 recipe matching, 9 strategy, 15 TypeScript).
2.1.0
- Code cleanup: Removed dead
jsonimport fromcore.py. Eliminated duplicated error patterns betweenutils.pyandPythonAnalyzer. Removed duplicated_pick_test_cmdfromharness.py(falls back toPythonAnalyzer). Removedanalyze_importsbackward-compat wrapper fromutils.py. - 95 tests (1 obsolete backward-compat test removed).
2.0.0
- Reference LLM integration: New
SYSTEM_PROMPT.mdproviding a reference orchestration guide for LLM clients (plan-verify-store loop). - New MCP tools:
update_plan_status(exposes existing store method),deactivate_constraint(exposes existing store method).statustool now includestoolscount in response. Tool count 16 → 17. - 96 tests (4 new).
1.9.0
- Structural recipe matching: New
recipe_filestable in SQLite schema (7 tables total) with indexes on both columns.save_recipepopulatesrecipe_fileswith file paths from strategy steps._backfill_files()auto-migrates existing databases. - Composite scoring:
retrieve_best_recipeaccepts optionalcontext_filesfor composite scoring — text similarity (0.5), file overlap via Jaccard (0.3), success ratio (0.2). Withoutcontext_files, scoring is backward-compatible (text-only). - Planner integration:
Planner.decomposepasses project file context to recipe retrieval (two-phase: text-only fast path, then structural). - New MCP tools:
list_recipes(limit=20),get_recipegainscontext_filesparameter. Tool count 14 → 16. - 92 tests (9 new recipe tests).
1.8.0
- Multi-language support: New
trammel/analyzers.pywithLanguageAnalyzerprotocol,PythonAnalyzer,TypeScriptAnalyzer(regex-based, stdlib-only),detect_language(),get_analyzer(). - Planner integration:
Planneraccepts optionalanalyzerparameter, auto-detects language.ExecutionHarnessaccepts optionalanalyzerfor language-specific test commands and error patterns. - Refactored analysis:
_collect_python_symbolsremoved fromcore.py(moved toPythonAnalyzer).analyze_importsinutils.pynow a backward-compat wrapper delegating toPythonAnalyzer.astimport removed fromutils.py. analyze_failureaccepts optionalerror_patternsparameter._IGNORED_DIRSexpanded:.next,.nuxt,coverage,.turbo,.parcel-cache.languageparameter added toplan_and_execute,explore, and MCPdecompose/exploretools.- New exports:
PythonAnalyzer,TypeScriptAnalyzer,detect_languagefromtrammel.__init__. - 83 tests (13 new in
tests/test_analyzers.py).
1.7.0
- Pluggable strategy registry: New
register_strategy()andget_strategies()API incore.pywithStrategyFnandStrategyEntrytypes. Three built-in strategies (bottom_up,top_down,risk_first) auto-registered at module load. Strategy functions use unified signature(steps, dep_graph) -> steps. - Strategy learning:
explore_trajectoriesaccepts optionalstorefor learning feedback. When provided, strategies sorted by historical success rate from trajectory data.plan_and_executeandexplorepass store to enable learning. - Strategy stats:
RecipeStore.get_strategy_stats()aggregates trajectory outcomes by variant (success/failure counts per strategy). - New MCP tool:
list_strategiesreturns registered strategy names with success/failure stats. Tool count 13 → 14. - New exports:
register_strategyandget_strategiesexported fromtrammel.__init__. - Test reorganization: New
tests/test_strategies.pywith 8 strategy-focused tests.TestBeamStrategiesmoved fromtest_trammel_extra.py. Test count 62 → 70.
1.6.0
- Simplified symbol collection:
_collect_python_symbolsreturns symbol name strings instead of redundant dicts; unusedfile,type,linefields removed (onlynamewas consumed downstream). - Removed dead parameter:
_step_rationaleno longer accepts unusedfilepathargument. - Inlined beam descriptions: Removed
_BEAM_STRATEGIESmodule-level constant; descriptions inlined at usage site, eliminating fragile index-based coupling. - Documentation fix: Removed duplicated extension point line in
spec-project.md.
1.5.0
- Concurrent write protection: All mutating
RecipeStoremethods wrapped in explicitBEGIN IMMEDIATEtransactions with exponential backoff retry onSQLITE_BUSY. Multi-statement operations likecreate_planare now atomic.db_connectsetstimeout=5.0. - Recipe retrieval at scale: Inverted trigram index (
recipe_trigramstable with B-tree index).retrieve_best_recipenow queries candidate recipes by shared trigrams before computing exact cosine, avoiding full table scans. Existing databases auto-backfill on schema init. - Constraint propagation: New
_apply_constraintsenforces active constraints during decomposition —avoidskips files,dependencyinjects ordering,incompatiblemarks conflict metadata,requiresadds prerequisite steps. Strategy output now includesconstraints_applied. - Constraint-aware beam strategies:
_order_bottom_upand_order_top_downplace skipped steps at end._order_risk_firstisolates incompatible steps and batches by package directory.explore_trajectoriesexcludes skipped steps from beam edits. - RecipeStore context manager: Added
close(),__enter__/__exit__, and__del__safety net. All public API functions and MCP server usewith RecipeStore(...).
1.4.0
- Import consistency: Converted absolute imports in
mcp_stdio.pyto relative imports, matching the rest of the package. - Dead exception handling: Removed unreachable
UnicodeDecodeErrorfrom_collect_python_symbolsexcept clause (core.py). Files are opened witherrors="replace", so the exception can never be raised. - Ignored directories: Added
.chiselto_IGNORED_DIRSinutils.py(tool cache directory, same category as.mypy_cache,.ruff_cache).
1.3.0
- Dead code removal: Removed unused test imports (
explore,synthesize,analyze_imports,cosine,trigram_bag_cosine,trigram_signature). Removed deadgoal_sliceparameter from_collect_python_symbols— computed per symbol but never consumed downstream. - Simplified topological sort: Removed redundant
rev.setdefault()call where keys are guaranteed to exist from pre-initialization. - Documentation fix:
plan_and_executeAPI signature in spec now includestest_cmdparameter.
1.2.0
- Version from metadata:
__version__now derived fromimportlib.metadataat runtime, eliminating version duplication betweenpyproject.tomland source code. - Match/case dispatch:
dispatch_toolinmcp_server.pyconverted from 13-branch if/elif chain to Python 3.10+match/case. - Configurable test command:
ExecutionHarnessacceptstest_cmdparameter for custom test runners (e.g. pytest). Propagated throughplan_and_execute, CLI (--test-cmd), and MCPverify_steptool. - Recipe retrieval optimization:
retrieve_best_recipeshort-circuits on exact match (similarity 1.0). - Tests package: Added
tests/__init__.py.
1.1.0
- Dead code removal: Removed unused
advance_plan_stepmethod fromRecipeStore, unusedjson/osimports frommcp_server.py, unusedjsonimport from tests. - Consolidated ignored-dirs: Unified hardcoded directory skip list in
harness.pywith_IGNORED_DIRSfromutils.pyvia new_is_ignored_dirhelper. Fixedegg-infopattern that could never match actual*.egg-infodirectories. - Performance:
topological_sortusescollections.dequeinstead oflist.pop(0)for O(1) queue operations. - Simplified core: Replaced verbose loop in
Planner.decomposewith set union forall_filesconstruction.
1.0.0
- Dependency-aware planning: Import analysis via AST, topological sort, steps with ordering rationale and dependencies.
- Real beam branching: Three strategies --
bottom_up,top_down,risk_first-- instead of label variations. - Incremental verification: Per-step harness with
verify_step()andrun_incremental(). - Failure analysis: Structured error extraction (type, message, file, line, suggestion).
- Constraint propagation: Persistent failure constraints that block repetition across sessions.
- MCP server: 13 tools exposed via stdio transport, matching Stele/Chisel pattern (expanded to 17 by v2.0.0).
- Enriched schema: Recipes store strategies + constraints + failure counts. Plans track step-level status. New
stepsandconstraintstables.
0.3.0
- Recipe retrieval requires minimum similarity threshold (0.3).
_collect_python_symbolscollectsasync defand skips ignored directories.- Deduplicated trigram computation; removed dead code.
0.2.0
- Correct trigram similarity for recipe retrieval; tie-break on stored success counts.
- Test subprocess uses
sys.executable; SQLiteforeign_keys=ON. - Beam
editsincludepath; JSON serialization centralized viadumps_json. __version__and CLI--version.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file trammel-3.10.0.tar.gz.
File metadata
- Download URL: trammel-3.10.0.tar.gz
- Upload date:
- Size: 154.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3abe7b5107f1affeac7adafd1c0aa0e588a6556e8f847c032cfde4f973061333
|
|
| MD5 |
040d9a9a4fa8d6c32c52aebad3ce47e4
|
|
| BLAKE2b-256 |
306bf37e844a07ac7467c4125b50270af13b288d959c63d008a069115c8554c7
|
Provenance
The following attestation bundles were made for trammel-3.10.0.tar.gz:
Publisher:
publish.yml on IronAdamant/Trammel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
trammel-3.10.0.tar.gz -
Subject digest:
3abe7b5107f1affeac7adafd1c0aa0e588a6556e8f847c032cfde4f973061333 - Sigstore transparency entry: 1203335477
- Sigstore integration time:
-
Permalink:
IronAdamant/Trammel@3461b0255832534636d7eeded24288c98aee3181 -
Branch / Tag:
refs/tags/v3.10.0 - Owner: https://github.com/IronAdamant
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3461b0255832534636d7eeded24288c98aee3181 -
Trigger Event:
release
-
Statement type:
File details
Details for the file trammel-3.10.0-py3-none-any.whl.
File metadata
- Download URL: trammel-3.10.0-py3-none-any.whl
- Upload date:
- Size: 102.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ffd9ace78b03406b7c77588db5c9df0060001decb30b63d15f5b4715b9c06db3
|
|
| MD5 |
de2dc925e47525b064b604170c76525b
|
|
| BLAKE2b-256 |
b4f7bb57a4005ceb09efe9b5b5e7b4bb84f8865bee81f30386642d7ad55c8ec5
|
Provenance
The following attestation bundles were made for trammel-3.10.0-py3-none-any.whl:
Publisher:
publish.yml on IronAdamant/Trammel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
trammel-3.10.0-py3-none-any.whl -
Subject digest:
ffd9ace78b03406b7c77588db5c9df0060001decb30b63d15f5b4715b9c06db3 - Sigstore transparency entry: 1203335479
- Sigstore integration time:
-
Permalink:
IronAdamant/Trammel@3461b0255832534636d7eeded24288c98aee3181 -
Branch / Tag:
refs/tags/v3.10.0 - Owner: https://github.com/IronAdamant
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3461b0255832534636d7eeded24288c98aee3181 -
Trigger Event:
release
-
Statement type: