agent-borg 3.2.1__tar.gz → 3.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agent_borg-3.2.1 → agent_borg-3.2.2}/PKG-INFO +18 -8
- {agent_borg-3.2.1 → agent_borg-3.2.2}/README.md +17 -7
- {agent_borg-3.2.1 → agent_borg-3.2.2}/agent_borg.egg-info/PKG-INFO +18 -8
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/__init__.py +1 -1
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/pack_taxonomy.py +148 -9
- {agent_borg-3.2.1 → agent_borg-3.2.2}/pyproject.toml +1 -1
- {agent_borg-3.2.1 → agent_borg-3.2.2}/agent_borg.egg-info/SOURCES.txt +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/agent_borg.egg-info/dependency_links.txt +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/agent_borg.egg-info/entry_points.txt +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/agent_borg.egg-info/requires.txt +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/agent_borg.egg-info/top_level.txt +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/benchmark/skills/test_skills.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/benchmarks/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/benchmarks/report.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/benchmarks/runner.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/benchmarks/scorer.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/benchmarks/tasks.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/benchmarks/tests/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/benchmarks/tests/test_benchmarks.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/cli.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/agentskills_converter.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/aggregator.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/apply.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/changes.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/conditions.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/contextual_selector.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/convert.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/crypto.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/failure_memory.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/feedback_loop.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/generator.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/mutation_engine.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/openclaw_converter.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/privacy.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/proof_gates.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/publish.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/safety.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/schema.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/search.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/semantic_search.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/session.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/signals.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/trace_matcher.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/traces.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/uri.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/core/v3_integration.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/db/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/db/analytics.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/db/embeddings.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/db/migrations.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/db/reputation.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/db/store.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/alpha_signal.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/api_clients/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/api_clients/alchemy.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/api_clients/arkham.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/api_clients/base.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/api_clients/birdeye.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/api_clients/cache.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/api_clients/defillama.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/api_clients/dexscreener.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/api_clients/goplus.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/api_clients/helius.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/cli.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/cron/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/cron/alpha_cron.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/cron/delivery.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/cron/liquidation_cron.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/cron/live_scans.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/cron/portfolio_cron.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/cron/risk_cron.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/cron/state.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/cron/whale_cron.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/cron/yield_cron.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/data_models.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/dojo_bridge.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/liquidation_watcher.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/lp_manager.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/mcp_tools.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/mev/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/mev/flashbots.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/mev/jito.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/portfolio_monitor.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/risk_engine.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/security/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/security/keystore.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/security/tx_guard.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/strategy_backtester.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/strategy_selector.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/swap_executor.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/v2/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/v2/borg_bridge.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/v2/circuit_breaker.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/v2/daily_brief.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/v2/drift.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/v2/models.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/v2/outcome_store.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/v2/pack_store.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/v2/recommender.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/v2/reputation.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/v2/seed_packs.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/v2/warnings.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/whale_tracker.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/defi/yield_scanner.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/auto_fixer.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/cron_runner.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/data_models.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/failure_classifier.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/learning_curve.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/pipeline.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/report_generator.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/session_reader.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/skill_gap_detector.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/tests/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/tests/test_auto_fixer.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/tests/test_failure_classifier.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/tests/test_learning_curve.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/tests/test_pipeline.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/tests/test_report_generator.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/tests/test_session_reader.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/dojo/tests/test_skill_gap_detector.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/eval/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/eval/e1a_seed_pack_validation.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/fleet/syncer.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/integrations/__init__.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/integrations/agent_hook.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/integrations/http_server.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/integrations/mcp_server.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/integrations/nudge.py +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/borg/SKILL.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/circular-dependency-migration.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/code-review.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/configuration-error.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/defi-risk-check.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/defi-yield-strategy.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/guild-autopilot/SKILL.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/import-cycle.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/migration-state-desync.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/missing-dependency.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/missing-foreign-key.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/null-pointer-chain.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/permission-denied.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/race-condition.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/schema-drift.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/systematic-debugging.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/test-driven-development.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/timeout-hang.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/borg/seeds_data/type-mismatch.md +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/setup.cfg +0 -0
- {agent_borg-3.2.1 → agent_borg-3.2.2}/tests/test_e2e_verify.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-borg
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.2
|
|
4
4
|
Summary: Collective memory for AI coding agents — your agent learns from every session
|
|
5
5
|
Author-email: Hermes Team <aleshbrown@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -39,12 +39,22 @@ Requires-Dist: agent-borg[crypto,defi,dev,embeddings]; extra == "all"
|
|
|
39
39
|
|
|
40
40
|
# Borg
|
|
41
41
|
|
|
42
|
-
**
|
|
42
|
+
**A Python/Django debugging expert that's honest about what it doesn't know.**
|
|
43
43
|
|
|
44
44
|
[](https://pypi.org/project/agent-borg/)
|
|
45
|
-
[]()
|
|
46
46
|
[]()
|
|
47
47
|
|
|
48
|
+
> **v3.2.2 honesty patch.** Earlier versions of `borg debug` would route any
|
|
49
|
+
> error containing the substring "Error" to a Django migration pack — including
|
|
50
|
+
> Rust, Go, Docker, and JavaScript errors. v3.2.2 deletes that fallback and
|
|
51
|
+
> adds a non-Python language guard. Borg now refuses to give a Python answer
|
|
52
|
+
> to a non-Python error and tells you so explicitly. JS/TS, Rust, Go,
|
|
53
|
+
> Docker, and Kubernetes pack coverage is on the roadmap (see
|
|
54
|
+
> `docs/20260408-0623_classifier_prd/`). If you are a Python/Django developer
|
|
55
|
+
> `borg debug` should still help; if you are not, we would rather say
|
|
56
|
+
> "we don't know yet" than give you a confidently wrong answer.
|
|
57
|
+
|
|
48
58
|
---
|
|
49
59
|
|
|
50
60
|
## Get Started in 30 Seconds
|
|
@@ -128,9 +138,9 @@ Borg is collective memory. When one agent solves a problem, every agent learns.
|
|
|
128
138
|
|
|
129
139
|
## Features
|
|
130
140
|
|
|
131
|
-
- **
|
|
141
|
+
- **Python/Django expert** — 12 hand-authored packs covering migrations, schema drift, imports, types, permissions, timeouts, and more
|
|
142
|
+
- **Honest about scope** — non-Python errors return "no match" rather than wrong advice
|
|
132
143
|
- **Works offline** — no API calls, no cloud, runs locally
|
|
133
|
-
- **Collective learning** — fixes improve from real agent outcomes
|
|
134
144
|
- **Platform export** — one command to generate .cursorrules, .clinerules, CLAUDE.md, or .windsurfrules
|
|
135
145
|
- **17 MCP tools** — plug into any MCP-compatible agent
|
|
136
146
|
- **Task guidance** — get step-by-step approaches before you start coding
|
|
@@ -175,8 +185,8 @@ borg generate systematic-debugging --format windsurf
|
|
|
175
185
|
## Quick Start
|
|
176
186
|
|
|
177
187
|
```bash
|
|
178
|
-
# 1. Debug
|
|
179
|
-
borg debug "
|
|
188
|
+
# 1. Debug a Python/Django error
|
|
189
|
+
borg debug "django.db.utils.OperationalError: no such column: app_user.email"
|
|
180
190
|
|
|
181
191
|
# 2. Get task guidance before you start
|
|
182
192
|
borg observe "refactor authentication to use JWT tokens"
|
|
@@ -188,7 +198,7 @@ borg search "docker networking"
|
|
|
188
198
|
borg generate systematic-debugging --format cursor
|
|
189
199
|
|
|
190
200
|
# 5. Classify an error without full guidance
|
|
191
|
-
borg debug --classify "
|
|
201
|
+
borg debug --classify "django.db.utils.OperationalError: no such column"
|
|
192
202
|
```
|
|
193
203
|
|
|
194
204
|
---
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
# Borg
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**A Python/Django debugging expert that's honest about what it doesn't know.**
|
|
4
4
|
|
|
5
5
|
[](https://pypi.org/project/agent-borg/)
|
|
6
|
-
[]()
|
|
7
7
|
[]()
|
|
8
8
|
|
|
9
|
+
> **v3.2.2 honesty patch.** Earlier versions of `borg debug` would route any
|
|
10
|
+
> error containing the substring "Error" to a Django migration pack — including
|
|
11
|
+
> Rust, Go, Docker, and JavaScript errors. v3.2.2 deletes that fallback and
|
|
12
|
+
> adds a non-Python language guard. Borg now refuses to give a Python answer
|
|
13
|
+
> to a non-Python error and tells you so explicitly. JS/TS, Rust, Go,
|
|
14
|
+
> Docker, and Kubernetes pack coverage is on the roadmap (see
|
|
15
|
+
> `docs/20260408-0623_classifier_prd/`). If you are a Python/Django developer
|
|
16
|
+
> `borg debug` should still help; if you are not, we would rather say
|
|
17
|
+
> "we don't know yet" than give you a confidently wrong answer.
|
|
18
|
+
|
|
9
19
|
---
|
|
10
20
|
|
|
11
21
|
## Get Started in 30 Seconds
|
|
@@ -89,9 +99,9 @@ Borg is collective memory. When one agent solves a problem, every agent learns.
|
|
|
89
99
|
|
|
90
100
|
## Features
|
|
91
101
|
|
|
92
|
-
- **
|
|
102
|
+
- **Python/Django expert** — 12 hand-authored packs covering migrations, schema drift, imports, types, permissions, timeouts, and more
|
|
103
|
+
- **Honest about scope** — non-Python errors return "no match" rather than wrong advice
|
|
93
104
|
- **Works offline** — no API calls, no cloud, runs locally
|
|
94
|
-
- **Collective learning** — fixes improve from real agent outcomes
|
|
95
105
|
- **Platform export** — one command to generate .cursorrules, .clinerules, CLAUDE.md, or .windsurfrules
|
|
96
106
|
- **17 MCP tools** — plug into any MCP-compatible agent
|
|
97
107
|
- **Task guidance** — get step-by-step approaches before you start coding
|
|
@@ -136,8 +146,8 @@ borg generate systematic-debugging --format windsurf
|
|
|
136
146
|
## Quick Start
|
|
137
147
|
|
|
138
148
|
```bash
|
|
139
|
-
# 1. Debug
|
|
140
|
-
borg debug "
|
|
149
|
+
# 1. Debug a Python/Django error
|
|
150
|
+
borg debug "django.db.utils.OperationalError: no such column: app_user.email"
|
|
141
151
|
|
|
142
152
|
# 2. Get task guidance before you start
|
|
143
153
|
borg observe "refactor authentication to use JWT tokens"
|
|
@@ -149,7 +159,7 @@ borg search "docker networking"
|
|
|
149
159
|
borg generate systematic-debugging --format cursor
|
|
150
160
|
|
|
151
161
|
# 5. Classify an error without full guidance
|
|
152
|
-
borg debug --classify "
|
|
162
|
+
borg debug --classify "django.db.utils.OperationalError: no such column"
|
|
153
163
|
```
|
|
154
164
|
|
|
155
165
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-borg
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.2
|
|
4
4
|
Summary: Collective memory for AI coding agents — your agent learns from every session
|
|
5
5
|
Author-email: Hermes Team <aleshbrown@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -39,12 +39,22 @@ Requires-Dist: agent-borg[crypto,defi,dev,embeddings]; extra == "all"
|
|
|
39
39
|
|
|
40
40
|
# Borg
|
|
41
41
|
|
|
42
|
-
**
|
|
42
|
+
**A Python/Django debugging expert that's honest about what it doesn't know.**
|
|
43
43
|
|
|
44
44
|
[](https://pypi.org/project/agent-borg/)
|
|
45
|
-
[]()
|
|
46
46
|
[]()
|
|
47
47
|
|
|
48
|
+
> **v3.2.2 honesty patch.** Earlier versions of `borg debug` would route any
|
|
49
|
+
> error containing the substring "Error" to a Django migration pack — including
|
|
50
|
+
> Rust, Go, Docker, and JavaScript errors. v3.2.2 deletes that fallback and
|
|
51
|
+
> adds a non-Python language guard. Borg now refuses to give a Python answer
|
|
52
|
+
> to a non-Python error and tells you so explicitly. JS/TS, Rust, Go,
|
|
53
|
+
> Docker, and Kubernetes pack coverage is on the roadmap (see
|
|
54
|
+
> `docs/20260408-0623_classifier_prd/`). If you are a Python/Django developer
|
|
55
|
+
> `borg debug` should still help; if you are not, we would rather say
|
|
56
|
+
> "we don't know yet" than give you a confidently wrong answer.
|
|
57
|
+
|
|
48
58
|
---
|
|
49
59
|
|
|
50
60
|
## Get Started in 30 Seconds
|
|
@@ -128,9 +138,9 @@ Borg is collective memory. When one agent solves a problem, every agent learns.
|
|
|
128
138
|
|
|
129
139
|
## Features
|
|
130
140
|
|
|
131
|
-
- **
|
|
141
|
+
- **Python/Django expert** — 12 hand-authored packs covering migrations, schema drift, imports, types, permissions, timeouts, and more
|
|
142
|
+
- **Honest about scope** — non-Python errors return "no match" rather than wrong advice
|
|
132
143
|
- **Works offline** — no API calls, no cloud, runs locally
|
|
133
|
-
- **Collective learning** — fixes improve from real agent outcomes
|
|
134
144
|
- **Platform export** — one command to generate .cursorrules, .clinerules, CLAUDE.md, or .windsurfrules
|
|
135
145
|
- **17 MCP tools** — plug into any MCP-compatible agent
|
|
136
146
|
- **Task guidance** — get step-by-step approaches before you start coding
|
|
@@ -175,8 +185,8 @@ borg generate systematic-debugging --format windsurf
|
|
|
175
185
|
## Quick Start
|
|
176
186
|
|
|
177
187
|
```bash
|
|
178
|
-
# 1. Debug
|
|
179
|
-
borg debug "
|
|
188
|
+
# 1. Debug a Python/Django error
|
|
189
|
+
borg debug "django.db.utils.OperationalError: no such column: app_user.email"
|
|
180
190
|
|
|
181
191
|
# 2. Get task guidance before you start
|
|
182
192
|
borg observe "refactor authentication to use JWT tokens"
|
|
@@ -188,7 +198,7 @@ borg search "docker networking"
|
|
|
188
198
|
borg generate systematic-debugging --format cursor
|
|
189
199
|
|
|
190
200
|
# 5. Classify an error without full guidance
|
|
191
|
-
borg debug --classify "
|
|
201
|
+
borg debug --classify "django.db.utils.OperationalError: no such column"
|
|
192
202
|
```
|
|
193
203
|
|
|
194
204
|
---
|
|
@@ -79,10 +79,109 @@ _ERROR_KEYWORDS: List[Tuple[str, str]] = [
|
|
|
79
79
|
# Schema drift
|
|
80
80
|
("OperationalError", "schema_drift"),
|
|
81
81
|
("SyncError", "schema_drift"),
|
|
82
|
-
#
|
|
83
|
-
|
|
82
|
+
# NOTE: v3.2.2 — the bare ("Error", "schema_drift") fallback was removed.
|
|
83
|
+
# It was a generic substring trap that routed every error containing the
|
|
84
|
+
# word "error" — Rust E0382, Docker ENOSPC, Go panics, JS TypeError — to
|
|
85
|
+
# the Django schema_drift pack. See docs/20260408-0623_classifier_prd/
|
|
86
|
+
# for the full PRD and the new confidence-gated classifier roadmap.
|
|
84
87
|
]
|
|
85
88
|
|
|
89
|
+
|
|
90
|
+
# -----------------------------------------------------------------------
|
|
91
|
+
# Phase 0 language detection — non-Python locking signals
|
|
92
|
+
# -----------------------------------------------------------------------
|
|
93
|
+
# Each entry is a regex that, if matched, locks the input to a specific
|
|
94
|
+
# non-Python language. Phase 0 only needs to detect "this is definitely
|
|
95
|
+
# NOT Python" so classify_error can refuse to answer instead of routing
|
|
96
|
+
# to a Python/Django pack. Phase 1 (ARCHITECTURE_SPEC.md §5.1) replaces
|
|
97
|
+
# this with a full multi-language detection cascade.
|
|
98
|
+
import re as _re
|
|
99
|
+
|
|
100
|
+
_NON_PYTHON_LOCKING_SIGNALS: List[Tuple[str, "_re.Pattern[str]"]] = [
|
|
101
|
+
# Rust — rustc error codes and borrow checker
|
|
102
|
+
("rust", _re.compile(r"error\[E\d{4}\]")),
|
|
103
|
+
("rust", _re.compile(r"\bborrow checker\b", _re.IGNORECASE)),
|
|
104
|
+
("rust", _re.compile(r"borrow of moved value", _re.IGNORECASE)),
|
|
105
|
+
("rust", _re.compile(r"\bcargo (build|run|test|check)\b")),
|
|
106
|
+
("rust", _re.compile(r"\brustc\b")),
|
|
107
|
+
("rust", _re.compile(r"does not live long enough")),
|
|
108
|
+
("rust", _re.compile(r"cannot borrow .* as mutable")),
|
|
109
|
+
# Go — runtime panics, goroutines, modules
|
|
110
|
+
("go", _re.compile(r"\bgoroutine \d+ \[")),
|
|
111
|
+
("go", _re.compile(r"panic: runtime error")),
|
|
112
|
+
("go", _re.compile(r"invalid memory address or nil pointer dereference")),
|
|
113
|
+
("go", _re.compile(r"\bgo\.mod\b")),
|
|
114
|
+
("go", _re.compile(r"go: cannot find module")),
|
|
115
|
+
# JavaScript / Node.js
|
|
116
|
+
("javascript", _re.compile(r"Cannot read propert(?:y|ies) of (?:null|undefined)")),
|
|
117
|
+
("javascript", _re.compile(r"\bReferenceError\b.*is not defined")),
|
|
118
|
+
("javascript", _re.compile(r"UnhandledPromiseRejectionWarning")),
|
|
119
|
+
("javascript", _re.compile(r"\bnode_modules\b")),
|
|
120
|
+
("javascript", _re.compile(r"at .*\.(?:js|mjs|cjs):\d+")),
|
|
121
|
+
("javascript", _re.compile(r"npm ERR!")),
|
|
122
|
+
# TypeScript — compiler errors
|
|
123
|
+
("typescript", _re.compile(r"\bTS\d{4}\b")),
|
|
124
|
+
("typescript", _re.compile(r"is not assignable to type")),
|
|
125
|
+
("typescript", _re.compile(r"\.tsx?:\d+:\d+")),
|
|
126
|
+
# React / Next.js
|
|
127
|
+
("react", _re.compile(r"Hydration failed because", _re.IGNORECASE)),
|
|
128
|
+
("react", _re.compile(r"Text content does not match server-rendered HTML")),
|
|
129
|
+
("react", _re.compile(r"Invalid hook call")),
|
|
130
|
+
("react", _re.compile(r"Each child in a list should have a unique \"key\" prop")),
|
|
131
|
+
# Docker / BuildKit
|
|
132
|
+
("docker", _re.compile(r"\bENOSPC\b")),
|
|
133
|
+
("docker", _re.compile(r"no space left on device", _re.IGNORECASE)),
|
|
134
|
+
("docker", _re.compile(r"failed to solve:")),
|
|
135
|
+
("docker", _re.compile(r"^docker:", _re.MULTILINE)),
|
|
136
|
+
("docker", _re.compile(r"COPY failed:")),
|
|
137
|
+
("docker", _re.compile(r"manifest unknown")),
|
|
138
|
+
# Kubernetes
|
|
139
|
+
("kubernetes", _re.compile(r"CrashLoopBackOff")),
|
|
140
|
+
("kubernetes", _re.compile(r"ImagePullBackOff")),
|
|
141
|
+
("kubernetes", _re.compile(r"ErrImagePull")),
|
|
142
|
+
("kubernetes", _re.compile(r"OOMKilled")),
|
|
143
|
+
("kubernetes", _re.compile(r"\bkubectl\b")),
|
|
144
|
+
("kubernetes", _re.compile(r"FailedScheduling")),
|
|
145
|
+
]
|
|
146
|
+
|
|
147
|
+
# Python "positive lock" signals — if any of these match we KEEP processing
|
|
148
|
+
# Python keywords even if a non-Python signal also fires (polyglot logs).
|
|
149
|
+
_PYTHON_LOCKING_SIGNALS: List["_re.Pattern[str]"] = [
|
|
150
|
+
_re.compile(r"Traceback \(most recent call last\)"),
|
|
151
|
+
_re.compile(r"\bpython3?(?:\.\d+)?\b"),
|
|
152
|
+
_re.compile(r"\.py:\d+"),
|
|
153
|
+
_re.compile(r"\bmanage\.py\b"),
|
|
154
|
+
_re.compile(r"\bdjango\."),
|
|
155
|
+
_re.compile(r"\bflask\b", _re.IGNORECASE),
|
|
156
|
+
_re.compile(r"\bfastapi\b", _re.IGNORECASE),
|
|
157
|
+
_re.compile(r"\bpip install\b"),
|
|
158
|
+
_re.compile(r"ModuleNotFoundError: No module named"),
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def _detect_language_quick(error_message: str) -> Optional[str]:
|
|
163
|
+
"""Phase 0 language detector — return non-Python language if locked.
|
|
164
|
+
|
|
165
|
+
Returns one of {'rust','go','javascript','typescript','react','docker',
|
|
166
|
+
'kubernetes'} when a high-confidence non-Python signal fires AND no
|
|
167
|
+
Python locking signal also fires. Returns None otherwise (which means
|
|
168
|
+
"Python or unknown — proceed with the legacy keyword table").
|
|
169
|
+
|
|
170
|
+
Phase 1 will replace this with the full cascade in
|
|
171
|
+
ARCHITECTURE_SPEC.md §4.3 / §5.1.
|
|
172
|
+
"""
|
|
173
|
+
if not error_message:
|
|
174
|
+
return None
|
|
175
|
+
# If any Python locking signal fires, treat as Python (keep current behaviour).
|
|
176
|
+
for pat in _PYTHON_LOCKING_SIGNALS:
|
|
177
|
+
if pat.search(error_message):
|
|
178
|
+
return None
|
|
179
|
+
# Otherwise, the first non-Python locking signal wins.
|
|
180
|
+
for lang, pat in _NON_PYTHON_LOCKING_SIGNALS:
|
|
181
|
+
if pat.search(error_message):
|
|
182
|
+
return lang
|
|
183
|
+
return None
|
|
184
|
+
|
|
86
185
|
# Canonical list of all known problem classes (must match seed pack filenames)
|
|
87
186
|
PROBLEM_CLASSES: List[str] = [
|
|
88
187
|
"circular_dependency",
|
|
@@ -187,11 +286,25 @@ def classify_error(error_message: str) -> Optional[str]:
|
|
|
187
286
|
"""
|
|
188
287
|
Classify an error message string into a problem_class.
|
|
189
288
|
|
|
190
|
-
|
|
191
|
-
|
|
289
|
+
v3.2.2 (Phase 0 of the multi-language classifier roadmap):
|
|
290
|
+
1. Detect non-Python locking signals (Rust E0xxx, Go panic, JS
|
|
291
|
+
Cannot read properties of, TS####, React Hydration failed,
|
|
292
|
+
Docker ENOSPC, Kubernetes CrashLoopBackOff, etc.). If any
|
|
293
|
+
fire, return None ("we don't know yet, refusing to give a
|
|
294
|
+
Python answer to a non-Python error").
|
|
295
|
+
2. Otherwise fall back to the legacy substring keyword table
|
|
296
|
+
(Python/Django coverage unchanged).
|
|
297
|
+
|
|
298
|
+
Phase 1+ (ARCHITECTURE_SPEC.md §3-§7) replaces this with a
|
|
299
|
+
confidence-scored Match | UnknownMatch dataclass return type.
|
|
300
|
+
|
|
301
|
+
See docs/20260408-0623_classifier_prd/ for the full PRD.
|
|
192
302
|
"""
|
|
193
303
|
if not error_message:
|
|
194
304
|
return None
|
|
305
|
+
# Phase 0 language guard — refuse to answer non-Python errors.
|
|
306
|
+
if _detect_language_quick(error_message) is not None:
|
|
307
|
+
return None
|
|
195
308
|
lower = error_message.lower()
|
|
196
309
|
for keyword, problem_class in _ERROR_KEYWORDS:
|
|
197
310
|
if keyword.lower() in lower:
|
|
@@ -393,17 +506,43 @@ def debug_error(error_message: str, show_evidence: bool = True) -> str:
|
|
|
393
506
|
show_evidence: Include evidence stats in output
|
|
394
507
|
|
|
395
508
|
Returns:
|
|
396
|
-
Formatted guidance string, or
|
|
397
|
-
no matching problem_class is found.
|
|
509
|
+
Formatted guidance string, or an "I don't know yet" UnknownMatch
|
|
510
|
+
block when no matching problem_class is found. v3.2.2 (Phase 0)
|
|
511
|
+
explicitly refuses to print Python/Django guidance for detected
|
|
512
|
+
non-Python errors — it returns the UnknownMatch block instead.
|
|
398
513
|
"""
|
|
514
|
+
# Phase 0: detect non-Python languages first so the UnknownMatch
|
|
515
|
+
# block can name the language we DID detect.
|
|
516
|
+
detected_lang = _detect_language_quick(error_message) if error_message else None
|
|
517
|
+
|
|
399
518
|
# Step 1: classify
|
|
400
519
|
problem_class = classify_error(error_message)
|
|
401
520
|
|
|
402
521
|
if not problem_class:
|
|
522
|
+
lang_line = (
|
|
523
|
+
f"Detected language: {detected_lang}. "
|
|
524
|
+
"Borg currently has Python/Django expert packs only.\n"
|
|
525
|
+
f"v3.2.2 refuses to give a Python answer to a {detected_lang} "
|
|
526
|
+
"error — see docs/20260408-0623_classifier_prd/ for the\n"
|
|
527
|
+
"multi-language classifier roadmap."
|
|
528
|
+
) if detected_lang else (
|
|
529
|
+
"Borg's current packs are Python/Django specific.\n"
|
|
530
|
+
"If your error is Python/Django, try pasting more of the traceback."
|
|
531
|
+
)
|
|
403
532
|
return (
|
|
404
|
-
"
|
|
405
|
-
"
|
|
406
|
-
"
|
|
533
|
+
"============================================================\n"
|
|
534
|
+
f"ERROR: {error_message[:120]}{'...' if len(error_message) > 120 else ''}\n"
|
|
535
|
+
"============================================================\n"
|
|
536
|
+
"[unknown] No matching problem class found.\n"
|
|
537
|
+
"\n"
|
|
538
|
+
f"{lang_line}\n"
|
|
539
|
+
"\n"
|
|
540
|
+
"Known Python/Django problem classes:\n"
|
|
541
|
+
" " + ", ".join(PROBLEM_CLASSES) + "\n"
|
|
542
|
+
"\n"
|
|
543
|
+
"Help us add coverage for your language:\n"
|
|
544
|
+
" https://github.com/bensargotest-sys/agent-borg/issues/new\n"
|
|
545
|
+
"============================================================"
|
|
407
546
|
)
|
|
408
547
|
|
|
409
548
|
# Step 2: load pack
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|