gobby 0.2.5__py3-none-any.whl

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.
Files changed (383) hide show
  1. gobby/__init__.py +3 -0
  2. gobby/adapters/__init__.py +30 -0
  3. gobby/adapters/base.py +93 -0
  4. gobby/adapters/claude_code.py +276 -0
  5. gobby/adapters/codex.py +1292 -0
  6. gobby/adapters/gemini.py +343 -0
  7. gobby/agents/__init__.py +37 -0
  8. gobby/agents/codex_session.py +120 -0
  9. gobby/agents/constants.py +112 -0
  10. gobby/agents/context.py +362 -0
  11. gobby/agents/definitions.py +133 -0
  12. gobby/agents/gemini_session.py +111 -0
  13. gobby/agents/registry.py +618 -0
  14. gobby/agents/runner.py +968 -0
  15. gobby/agents/session.py +259 -0
  16. gobby/agents/spawn.py +916 -0
  17. gobby/agents/spawners/__init__.py +77 -0
  18. gobby/agents/spawners/base.py +142 -0
  19. gobby/agents/spawners/cross_platform.py +266 -0
  20. gobby/agents/spawners/embedded.py +225 -0
  21. gobby/agents/spawners/headless.py +226 -0
  22. gobby/agents/spawners/linux.py +125 -0
  23. gobby/agents/spawners/macos.py +277 -0
  24. gobby/agents/spawners/windows.py +308 -0
  25. gobby/agents/tty_config.py +319 -0
  26. gobby/autonomous/__init__.py +32 -0
  27. gobby/autonomous/progress_tracker.py +447 -0
  28. gobby/autonomous/stop_registry.py +269 -0
  29. gobby/autonomous/stuck_detector.py +383 -0
  30. gobby/cli/__init__.py +67 -0
  31. gobby/cli/__main__.py +8 -0
  32. gobby/cli/agents.py +529 -0
  33. gobby/cli/artifacts.py +266 -0
  34. gobby/cli/daemon.py +329 -0
  35. gobby/cli/extensions.py +526 -0
  36. gobby/cli/github.py +263 -0
  37. gobby/cli/init.py +53 -0
  38. gobby/cli/install.py +614 -0
  39. gobby/cli/installers/__init__.py +37 -0
  40. gobby/cli/installers/antigravity.py +65 -0
  41. gobby/cli/installers/claude.py +363 -0
  42. gobby/cli/installers/codex.py +192 -0
  43. gobby/cli/installers/gemini.py +294 -0
  44. gobby/cli/installers/git_hooks.py +377 -0
  45. gobby/cli/installers/shared.py +737 -0
  46. gobby/cli/linear.py +250 -0
  47. gobby/cli/mcp.py +30 -0
  48. gobby/cli/mcp_proxy.py +698 -0
  49. gobby/cli/memory.py +304 -0
  50. gobby/cli/merge.py +384 -0
  51. gobby/cli/projects.py +79 -0
  52. gobby/cli/sessions.py +622 -0
  53. gobby/cli/tasks/__init__.py +30 -0
  54. gobby/cli/tasks/_utils.py +658 -0
  55. gobby/cli/tasks/ai.py +1025 -0
  56. gobby/cli/tasks/commits.py +169 -0
  57. gobby/cli/tasks/crud.py +685 -0
  58. gobby/cli/tasks/deps.py +135 -0
  59. gobby/cli/tasks/labels.py +63 -0
  60. gobby/cli/tasks/main.py +273 -0
  61. gobby/cli/tasks/search.py +178 -0
  62. gobby/cli/tui.py +34 -0
  63. gobby/cli/utils.py +513 -0
  64. gobby/cli/workflows.py +927 -0
  65. gobby/cli/worktrees.py +481 -0
  66. gobby/config/__init__.py +129 -0
  67. gobby/config/app.py +551 -0
  68. gobby/config/extensions.py +167 -0
  69. gobby/config/features.py +472 -0
  70. gobby/config/llm_providers.py +98 -0
  71. gobby/config/logging.py +66 -0
  72. gobby/config/mcp.py +346 -0
  73. gobby/config/persistence.py +247 -0
  74. gobby/config/servers.py +141 -0
  75. gobby/config/sessions.py +250 -0
  76. gobby/config/tasks.py +784 -0
  77. gobby/hooks/__init__.py +104 -0
  78. gobby/hooks/artifact_capture.py +213 -0
  79. gobby/hooks/broadcaster.py +243 -0
  80. gobby/hooks/event_handlers.py +723 -0
  81. gobby/hooks/events.py +218 -0
  82. gobby/hooks/git.py +169 -0
  83. gobby/hooks/health_monitor.py +171 -0
  84. gobby/hooks/hook_manager.py +856 -0
  85. gobby/hooks/hook_types.py +575 -0
  86. gobby/hooks/plugins.py +813 -0
  87. gobby/hooks/session_coordinator.py +396 -0
  88. gobby/hooks/verification_runner.py +268 -0
  89. gobby/hooks/webhooks.py +339 -0
  90. gobby/install/claude/commands/gobby/bug.md +51 -0
  91. gobby/install/claude/commands/gobby/chore.md +51 -0
  92. gobby/install/claude/commands/gobby/epic.md +52 -0
  93. gobby/install/claude/commands/gobby/eval.md +235 -0
  94. gobby/install/claude/commands/gobby/feat.md +49 -0
  95. gobby/install/claude/commands/gobby/nit.md +52 -0
  96. gobby/install/claude/commands/gobby/ref.md +52 -0
  97. gobby/install/claude/hooks/HOOK_SCHEMAS.md +632 -0
  98. gobby/install/claude/hooks/hook_dispatcher.py +364 -0
  99. gobby/install/claude/hooks/validate_settings.py +102 -0
  100. gobby/install/claude/hooks-template.json +118 -0
  101. gobby/install/codex/hooks/hook_dispatcher.py +153 -0
  102. gobby/install/codex/prompts/forget.md +7 -0
  103. gobby/install/codex/prompts/memories.md +7 -0
  104. gobby/install/codex/prompts/recall.md +7 -0
  105. gobby/install/codex/prompts/remember.md +13 -0
  106. gobby/install/gemini/hooks/hook_dispatcher.py +268 -0
  107. gobby/install/gemini/hooks-template.json +138 -0
  108. gobby/install/shared/plugins/code_guardian.py +456 -0
  109. gobby/install/shared/plugins/example_notify.py +331 -0
  110. gobby/integrations/__init__.py +10 -0
  111. gobby/integrations/github.py +145 -0
  112. gobby/integrations/linear.py +145 -0
  113. gobby/llm/__init__.py +40 -0
  114. gobby/llm/base.py +120 -0
  115. gobby/llm/claude.py +578 -0
  116. gobby/llm/claude_executor.py +503 -0
  117. gobby/llm/codex.py +322 -0
  118. gobby/llm/codex_executor.py +513 -0
  119. gobby/llm/executor.py +316 -0
  120. gobby/llm/factory.py +34 -0
  121. gobby/llm/gemini.py +258 -0
  122. gobby/llm/gemini_executor.py +339 -0
  123. gobby/llm/litellm.py +287 -0
  124. gobby/llm/litellm_executor.py +303 -0
  125. gobby/llm/resolver.py +499 -0
  126. gobby/llm/service.py +236 -0
  127. gobby/mcp_proxy/__init__.py +29 -0
  128. gobby/mcp_proxy/actions.py +175 -0
  129. gobby/mcp_proxy/daemon_control.py +198 -0
  130. gobby/mcp_proxy/importer.py +436 -0
  131. gobby/mcp_proxy/lazy.py +325 -0
  132. gobby/mcp_proxy/manager.py +798 -0
  133. gobby/mcp_proxy/metrics.py +609 -0
  134. gobby/mcp_proxy/models.py +139 -0
  135. gobby/mcp_proxy/registries.py +215 -0
  136. gobby/mcp_proxy/schema_hash.py +381 -0
  137. gobby/mcp_proxy/semantic_search.py +706 -0
  138. gobby/mcp_proxy/server.py +549 -0
  139. gobby/mcp_proxy/services/__init__.py +0 -0
  140. gobby/mcp_proxy/services/fallback.py +306 -0
  141. gobby/mcp_proxy/services/recommendation.py +224 -0
  142. gobby/mcp_proxy/services/server_mgmt.py +214 -0
  143. gobby/mcp_proxy/services/system.py +72 -0
  144. gobby/mcp_proxy/services/tool_filter.py +231 -0
  145. gobby/mcp_proxy/services/tool_proxy.py +309 -0
  146. gobby/mcp_proxy/stdio.py +565 -0
  147. gobby/mcp_proxy/tools/__init__.py +27 -0
  148. gobby/mcp_proxy/tools/agents.py +1103 -0
  149. gobby/mcp_proxy/tools/artifacts.py +207 -0
  150. gobby/mcp_proxy/tools/hub.py +335 -0
  151. gobby/mcp_proxy/tools/internal.py +337 -0
  152. gobby/mcp_proxy/tools/memory.py +543 -0
  153. gobby/mcp_proxy/tools/merge.py +422 -0
  154. gobby/mcp_proxy/tools/metrics.py +283 -0
  155. gobby/mcp_proxy/tools/orchestration/__init__.py +23 -0
  156. gobby/mcp_proxy/tools/orchestration/cleanup.py +619 -0
  157. gobby/mcp_proxy/tools/orchestration/monitor.py +380 -0
  158. gobby/mcp_proxy/tools/orchestration/orchestrate.py +746 -0
  159. gobby/mcp_proxy/tools/orchestration/review.py +736 -0
  160. gobby/mcp_proxy/tools/orchestration/utils.py +16 -0
  161. gobby/mcp_proxy/tools/session_messages.py +1056 -0
  162. gobby/mcp_proxy/tools/task_dependencies.py +219 -0
  163. gobby/mcp_proxy/tools/task_expansion.py +591 -0
  164. gobby/mcp_proxy/tools/task_github.py +393 -0
  165. gobby/mcp_proxy/tools/task_linear.py +379 -0
  166. gobby/mcp_proxy/tools/task_orchestration.py +77 -0
  167. gobby/mcp_proxy/tools/task_readiness.py +522 -0
  168. gobby/mcp_proxy/tools/task_sync.py +351 -0
  169. gobby/mcp_proxy/tools/task_validation.py +843 -0
  170. gobby/mcp_proxy/tools/tasks/__init__.py +25 -0
  171. gobby/mcp_proxy/tools/tasks/_context.py +112 -0
  172. gobby/mcp_proxy/tools/tasks/_crud.py +516 -0
  173. gobby/mcp_proxy/tools/tasks/_factory.py +176 -0
  174. gobby/mcp_proxy/tools/tasks/_helpers.py +129 -0
  175. gobby/mcp_proxy/tools/tasks/_lifecycle.py +517 -0
  176. gobby/mcp_proxy/tools/tasks/_lifecycle_validation.py +301 -0
  177. gobby/mcp_proxy/tools/tasks/_resolution.py +55 -0
  178. gobby/mcp_proxy/tools/tasks/_search.py +215 -0
  179. gobby/mcp_proxy/tools/tasks/_session.py +125 -0
  180. gobby/mcp_proxy/tools/workflows.py +973 -0
  181. gobby/mcp_proxy/tools/worktrees.py +1264 -0
  182. gobby/mcp_proxy/transports/__init__.py +0 -0
  183. gobby/mcp_proxy/transports/base.py +95 -0
  184. gobby/mcp_proxy/transports/factory.py +44 -0
  185. gobby/mcp_proxy/transports/http.py +139 -0
  186. gobby/mcp_proxy/transports/stdio.py +213 -0
  187. gobby/mcp_proxy/transports/websocket.py +136 -0
  188. gobby/memory/backends/__init__.py +116 -0
  189. gobby/memory/backends/mem0.py +408 -0
  190. gobby/memory/backends/memu.py +485 -0
  191. gobby/memory/backends/null.py +111 -0
  192. gobby/memory/backends/openmemory.py +537 -0
  193. gobby/memory/backends/sqlite.py +304 -0
  194. gobby/memory/context.py +87 -0
  195. gobby/memory/manager.py +1001 -0
  196. gobby/memory/protocol.py +451 -0
  197. gobby/memory/search/__init__.py +66 -0
  198. gobby/memory/search/text.py +127 -0
  199. gobby/memory/viz.py +258 -0
  200. gobby/prompts/__init__.py +13 -0
  201. gobby/prompts/defaults/expansion/system.md +119 -0
  202. gobby/prompts/defaults/expansion/user.md +48 -0
  203. gobby/prompts/defaults/external_validation/agent.md +72 -0
  204. gobby/prompts/defaults/external_validation/external.md +63 -0
  205. gobby/prompts/defaults/external_validation/spawn.md +83 -0
  206. gobby/prompts/defaults/external_validation/system.md +6 -0
  207. gobby/prompts/defaults/features/import_mcp.md +22 -0
  208. gobby/prompts/defaults/features/import_mcp_github.md +17 -0
  209. gobby/prompts/defaults/features/import_mcp_search.md +16 -0
  210. gobby/prompts/defaults/features/recommend_tools.md +32 -0
  211. gobby/prompts/defaults/features/recommend_tools_hybrid.md +35 -0
  212. gobby/prompts/defaults/features/recommend_tools_llm.md +30 -0
  213. gobby/prompts/defaults/features/server_description.md +20 -0
  214. gobby/prompts/defaults/features/server_description_system.md +6 -0
  215. gobby/prompts/defaults/features/task_description.md +31 -0
  216. gobby/prompts/defaults/features/task_description_system.md +6 -0
  217. gobby/prompts/defaults/features/tool_summary.md +17 -0
  218. gobby/prompts/defaults/features/tool_summary_system.md +6 -0
  219. gobby/prompts/defaults/research/step.md +58 -0
  220. gobby/prompts/defaults/validation/criteria.md +47 -0
  221. gobby/prompts/defaults/validation/validate.md +38 -0
  222. gobby/prompts/loader.py +346 -0
  223. gobby/prompts/models.py +113 -0
  224. gobby/py.typed +0 -0
  225. gobby/runner.py +488 -0
  226. gobby/search/__init__.py +23 -0
  227. gobby/search/protocol.py +104 -0
  228. gobby/search/tfidf.py +232 -0
  229. gobby/servers/__init__.py +7 -0
  230. gobby/servers/http.py +636 -0
  231. gobby/servers/models.py +31 -0
  232. gobby/servers/routes/__init__.py +23 -0
  233. gobby/servers/routes/admin.py +416 -0
  234. gobby/servers/routes/dependencies.py +118 -0
  235. gobby/servers/routes/mcp/__init__.py +24 -0
  236. gobby/servers/routes/mcp/hooks.py +135 -0
  237. gobby/servers/routes/mcp/plugins.py +121 -0
  238. gobby/servers/routes/mcp/tools.py +1337 -0
  239. gobby/servers/routes/mcp/webhooks.py +159 -0
  240. gobby/servers/routes/sessions.py +582 -0
  241. gobby/servers/websocket.py +766 -0
  242. gobby/sessions/__init__.py +13 -0
  243. gobby/sessions/analyzer.py +322 -0
  244. gobby/sessions/lifecycle.py +240 -0
  245. gobby/sessions/manager.py +563 -0
  246. gobby/sessions/processor.py +225 -0
  247. gobby/sessions/summary.py +532 -0
  248. gobby/sessions/transcripts/__init__.py +41 -0
  249. gobby/sessions/transcripts/base.py +125 -0
  250. gobby/sessions/transcripts/claude.py +386 -0
  251. gobby/sessions/transcripts/codex.py +143 -0
  252. gobby/sessions/transcripts/gemini.py +195 -0
  253. gobby/storage/__init__.py +21 -0
  254. gobby/storage/agents.py +409 -0
  255. gobby/storage/artifact_classifier.py +341 -0
  256. gobby/storage/artifacts.py +285 -0
  257. gobby/storage/compaction.py +67 -0
  258. gobby/storage/database.py +357 -0
  259. gobby/storage/inter_session_messages.py +194 -0
  260. gobby/storage/mcp.py +680 -0
  261. gobby/storage/memories.py +562 -0
  262. gobby/storage/merge_resolutions.py +550 -0
  263. gobby/storage/migrations.py +860 -0
  264. gobby/storage/migrations_legacy.py +1359 -0
  265. gobby/storage/projects.py +166 -0
  266. gobby/storage/session_messages.py +251 -0
  267. gobby/storage/session_tasks.py +97 -0
  268. gobby/storage/sessions.py +817 -0
  269. gobby/storage/task_dependencies.py +223 -0
  270. gobby/storage/tasks/__init__.py +42 -0
  271. gobby/storage/tasks/_aggregates.py +180 -0
  272. gobby/storage/tasks/_crud.py +449 -0
  273. gobby/storage/tasks/_id.py +104 -0
  274. gobby/storage/tasks/_lifecycle.py +311 -0
  275. gobby/storage/tasks/_manager.py +889 -0
  276. gobby/storage/tasks/_models.py +300 -0
  277. gobby/storage/tasks/_ordering.py +119 -0
  278. gobby/storage/tasks/_path_cache.py +110 -0
  279. gobby/storage/tasks/_queries.py +343 -0
  280. gobby/storage/tasks/_search.py +143 -0
  281. gobby/storage/workflow_audit.py +393 -0
  282. gobby/storage/worktrees.py +547 -0
  283. gobby/sync/__init__.py +29 -0
  284. gobby/sync/github.py +333 -0
  285. gobby/sync/linear.py +304 -0
  286. gobby/sync/memories.py +284 -0
  287. gobby/sync/tasks.py +641 -0
  288. gobby/tasks/__init__.py +8 -0
  289. gobby/tasks/build_verification.py +193 -0
  290. gobby/tasks/commits.py +633 -0
  291. gobby/tasks/context.py +747 -0
  292. gobby/tasks/criteria.py +342 -0
  293. gobby/tasks/enhanced_validator.py +226 -0
  294. gobby/tasks/escalation.py +263 -0
  295. gobby/tasks/expansion.py +626 -0
  296. gobby/tasks/external_validator.py +764 -0
  297. gobby/tasks/issue_extraction.py +171 -0
  298. gobby/tasks/prompts/expand.py +327 -0
  299. gobby/tasks/research.py +421 -0
  300. gobby/tasks/tdd.py +352 -0
  301. gobby/tasks/tree_builder.py +263 -0
  302. gobby/tasks/validation.py +712 -0
  303. gobby/tasks/validation_history.py +357 -0
  304. gobby/tasks/validation_models.py +89 -0
  305. gobby/tools/__init__.py +0 -0
  306. gobby/tools/summarizer.py +170 -0
  307. gobby/tui/__init__.py +5 -0
  308. gobby/tui/api_client.py +281 -0
  309. gobby/tui/app.py +327 -0
  310. gobby/tui/screens/__init__.py +25 -0
  311. gobby/tui/screens/agents.py +333 -0
  312. gobby/tui/screens/chat.py +450 -0
  313. gobby/tui/screens/dashboard.py +377 -0
  314. gobby/tui/screens/memory.py +305 -0
  315. gobby/tui/screens/metrics.py +231 -0
  316. gobby/tui/screens/orchestrator.py +904 -0
  317. gobby/tui/screens/sessions.py +412 -0
  318. gobby/tui/screens/tasks.py +442 -0
  319. gobby/tui/screens/workflows.py +289 -0
  320. gobby/tui/screens/worktrees.py +174 -0
  321. gobby/tui/widgets/__init__.py +21 -0
  322. gobby/tui/widgets/chat.py +210 -0
  323. gobby/tui/widgets/conductor.py +104 -0
  324. gobby/tui/widgets/menu.py +132 -0
  325. gobby/tui/widgets/message_panel.py +160 -0
  326. gobby/tui/widgets/review_gate.py +224 -0
  327. gobby/tui/widgets/task_tree.py +99 -0
  328. gobby/tui/widgets/token_budget.py +166 -0
  329. gobby/tui/ws_client.py +258 -0
  330. gobby/utils/__init__.py +3 -0
  331. gobby/utils/daemon_client.py +235 -0
  332. gobby/utils/git.py +222 -0
  333. gobby/utils/id.py +38 -0
  334. gobby/utils/json_helpers.py +161 -0
  335. gobby/utils/logging.py +376 -0
  336. gobby/utils/machine_id.py +135 -0
  337. gobby/utils/metrics.py +589 -0
  338. gobby/utils/project_context.py +182 -0
  339. gobby/utils/project_init.py +263 -0
  340. gobby/utils/status.py +256 -0
  341. gobby/utils/validation.py +80 -0
  342. gobby/utils/version.py +23 -0
  343. gobby/workflows/__init__.py +4 -0
  344. gobby/workflows/actions.py +1310 -0
  345. gobby/workflows/approval_flow.py +138 -0
  346. gobby/workflows/artifact_actions.py +103 -0
  347. gobby/workflows/audit_helpers.py +110 -0
  348. gobby/workflows/autonomous_actions.py +286 -0
  349. gobby/workflows/context_actions.py +394 -0
  350. gobby/workflows/definitions.py +130 -0
  351. gobby/workflows/detection_helpers.py +208 -0
  352. gobby/workflows/engine.py +485 -0
  353. gobby/workflows/evaluator.py +669 -0
  354. gobby/workflows/git_utils.py +96 -0
  355. gobby/workflows/hooks.py +169 -0
  356. gobby/workflows/lifecycle_evaluator.py +613 -0
  357. gobby/workflows/llm_actions.py +70 -0
  358. gobby/workflows/loader.py +333 -0
  359. gobby/workflows/mcp_actions.py +60 -0
  360. gobby/workflows/memory_actions.py +272 -0
  361. gobby/workflows/premature_stop.py +164 -0
  362. gobby/workflows/session_actions.py +139 -0
  363. gobby/workflows/state_actions.py +123 -0
  364. gobby/workflows/state_manager.py +104 -0
  365. gobby/workflows/stop_signal_actions.py +163 -0
  366. gobby/workflows/summary_actions.py +344 -0
  367. gobby/workflows/task_actions.py +249 -0
  368. gobby/workflows/task_enforcement_actions.py +901 -0
  369. gobby/workflows/templates.py +52 -0
  370. gobby/workflows/todo_actions.py +84 -0
  371. gobby/workflows/webhook.py +223 -0
  372. gobby/workflows/webhook_executor.py +399 -0
  373. gobby/worktrees/__init__.py +5 -0
  374. gobby/worktrees/git.py +690 -0
  375. gobby/worktrees/merge/__init__.py +20 -0
  376. gobby/worktrees/merge/conflict_parser.py +177 -0
  377. gobby/worktrees/merge/resolver.py +485 -0
  378. gobby-0.2.5.dist-info/METADATA +351 -0
  379. gobby-0.2.5.dist-info/RECORD +383 -0
  380. gobby-0.2.5.dist-info/WHEEL +5 -0
  381. gobby-0.2.5.dist-info/entry_points.txt +2 -0
  382. gobby-0.2.5.dist-info/licenses/LICENSE.md +193 -0
  383. gobby-0.2.5.dist-info/top_level.txt +1 -0
gobby/memory/viz.py ADDED
@@ -0,0 +1,258 @@
1
+ """
2
+ Memory Knowledge Graph Visualization.
3
+
4
+ Exports memory data as an interactive HTML graph using vis.js.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import html
10
+ import json
11
+ from typing import TYPE_CHECKING, Any
12
+
13
+ if TYPE_CHECKING:
14
+ from gobby.storage.memories import Memory, MemoryCrossRef
15
+
16
+
17
+ # Color palette for memory types
18
+ MEMORY_TYPE_COLORS = {
19
+ "fact": "#4CAF50", # Green
20
+ "preference": "#2196F3", # Blue
21
+ "pattern": "#FF9800", # Orange
22
+ "context": "#9C27B0", # Purple
23
+ }
24
+
25
+ DEFAULT_COLOR = "#607D8B" # Grey for unknown types
26
+
27
+
28
+ def export_memory_graph(
29
+ memories: list[Memory],
30
+ crossrefs: list[MemoryCrossRef],
31
+ title: str = "Memory Knowledge Graph",
32
+ ) -> str:
33
+ """
34
+ Export memories and their cross-references as an interactive HTML graph.
35
+
36
+ Uses vis.js for rendering. The output is a standalone HTML file that can
37
+ be opened in any browser without additional dependencies.
38
+
39
+ Args:
40
+ memories: List of Memory objects to visualize
41
+ crossrefs: List of cross-references defining edges between memories
42
+ title: Title to display on the HTML page
43
+
44
+ Returns:
45
+ Complete HTML document as a string
46
+ """
47
+ # Build nodes data
48
+ nodes = []
49
+ for memory in memories:
50
+ # Size based on importance (15-40 range)
51
+ size = 15 + (memory.importance * 25)
52
+
53
+ # Color based on type
54
+ color = MEMORY_TYPE_COLORS.get(memory.memory_type, DEFAULT_COLOR)
55
+
56
+ # Truncate content for label
57
+ label = memory.content[:50] + "..." if len(memory.content) > 50 else memory.content
58
+
59
+ nodes.append(
60
+ {
61
+ "id": memory.id,
62
+ "label": label,
63
+ "title": _build_tooltip(memory),
64
+ "color": color,
65
+ "size": size,
66
+ "font": {"size": 10},
67
+ }
68
+ )
69
+
70
+ # Build edges data
71
+ edges = []
72
+ memory_ids = {m.id for m in memories}
73
+ for ref in crossrefs:
74
+ # Only include edges where both nodes exist
75
+ if ref.source_id in memory_ids and ref.target_id in memory_ids:
76
+ # Edge width based on similarity (1-5 range)
77
+ width = 1 + (ref.similarity * 4)
78
+ edges.append(
79
+ {
80
+ "from": ref.source_id,
81
+ "to": ref.target_id,
82
+ "width": width,
83
+ "title": f"Similarity: {ref.similarity:.2f}",
84
+ }
85
+ )
86
+
87
+ # Generate HTML
88
+ return _generate_html(nodes, edges, title)
89
+
90
+
91
+ def _build_tooltip(memory: Memory) -> str:
92
+ """Build HTML tooltip for a memory node."""
93
+ tags_str = ", ".join(memory.tags) if memory.tags else "none"
94
+ return f"""
95
+ <div style="max-width: 300px; padding: 8px;">
96
+ <strong>Type:</strong> {html.escape(memory.memory_type)}<br>
97
+ <strong>Importance:</strong> {memory.importance:.2f}<br>
98
+ <strong>Tags:</strong> {html.escape(tags_str)}<br>
99
+ <strong>ID:</strong> {html.escape(memory.id[:12])}...<br>
100
+ <hr style="margin: 4px 0;">
101
+ <div style="white-space: pre-wrap; word-wrap: break-word;">
102
+ {html.escape(memory.content)}
103
+ </div>
104
+ </div>
105
+ """.strip()
106
+
107
+
108
+ def _generate_html(nodes: list[dict[str, Any]], edges: list[dict[str, Any]], title: str) -> str:
109
+ """Generate the complete HTML document with vis.js."""
110
+ nodes_json = json.dumps(nodes)
111
+ edges_json = json.dumps(edges)
112
+
113
+ return f"""<!DOCTYPE html>
114
+ <html lang="en">
115
+ <head>
116
+ <meta charset="UTF-8">
117
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
118
+ <title>{html.escape(title)}</title>
119
+ <script src="https://unpkg.com/vis-network@9.1.6/standalone/umd/vis-network.min.js"></script>
120
+ <style>
121
+ * {{
122
+ margin: 0;
123
+ padding: 0;
124
+ box-sizing: border-box;
125
+ }}
126
+ body {{
127
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
128
+ background: #1a1a2e;
129
+ color: #eee;
130
+ }}
131
+ #header {{
132
+ padding: 16px 24px;
133
+ background: #16213e;
134
+ border-bottom: 1px solid #0f3460;
135
+ display: flex;
136
+ justify-content: space-between;
137
+ align-items: center;
138
+ }}
139
+ #header h1 {{
140
+ font-size: 1.25rem;
141
+ font-weight: 500;
142
+ }}
143
+ #legend {{
144
+ display: flex;
145
+ gap: 16px;
146
+ font-size: 0.85rem;
147
+ }}
148
+ .legend-item {{
149
+ display: flex;
150
+ align-items: center;
151
+ gap: 6px;
152
+ }}
153
+ .legend-dot {{
154
+ width: 12px;
155
+ height: 12px;
156
+ border-radius: 50%;
157
+ }}
158
+ #graph {{
159
+ width: 100%;
160
+ height: calc(100vh - 60px);
161
+ }}
162
+ #stats {{
163
+ position: absolute;
164
+ bottom: 16px;
165
+ left: 16px;
166
+ background: rgba(22, 33, 62, 0.9);
167
+ padding: 12px 16px;
168
+ border-radius: 8px;
169
+ font-size: 0.85rem;
170
+ }}
171
+ </style>
172
+ </head>
173
+ <body>
174
+ <div id="header">
175
+ <h1>{html.escape(title)}</h1>
176
+ <div id="legend">
177
+ <div class="legend-item">
178
+ <div class="legend-dot" style="background: #4CAF50;"></div>
179
+ <span>Fact</span>
180
+ </div>
181
+ <div class="legend-item">
182
+ <div class="legend-dot" style="background: #2196F3;"></div>
183
+ <span>Preference</span>
184
+ </div>
185
+ <div class="legend-item">
186
+ <div class="legend-dot" style="background: #FF9800;"></div>
187
+ <span>Pattern</span>
188
+ </div>
189
+ <div class="legend-item">
190
+ <div class="legend-dot" style="background: #9C27B0;"></div>
191
+ <span>Context</span>
192
+ </div>
193
+ </div>
194
+ </div>
195
+ <div id="graph"></div>
196
+ <div id="stats">
197
+ Nodes: {len(nodes)} | Edges: {len(edges)}
198
+ </div>
199
+ <script>
200
+ const nodes = new vis.DataSet({nodes_json});
201
+ const edges = new vis.DataSet({edges_json});
202
+
203
+ const container = document.getElementById('graph');
204
+ const data = {{ nodes, edges }};
205
+
206
+ const options = {{
207
+ nodes: {{
208
+ shape: 'dot',
209
+ borderWidth: 2,
210
+ shadow: true,
211
+ font: {{
212
+ color: '#eee'
213
+ }}
214
+ }},
215
+ edges: {{
216
+ color: {{
217
+ color: '#4a4a6a',
218
+ highlight: '#7a7aaa',
219
+ hover: '#6a6a8a'
220
+ }},
221
+ smooth: {{
222
+ type: 'continuous'
223
+ }}
224
+ }},
225
+ physics: {{
226
+ stabilization: {{
227
+ iterations: 100
228
+ }},
229
+ barnesHut: {{
230
+ gravitationalConstant: -2000,
231
+ springConstant: 0.04,
232
+ springLength: 150
233
+ }}
234
+ }},
235
+ interaction: {{
236
+ hover: true,
237
+ tooltipDelay: 200,
238
+ hideEdgesOnDrag: true
239
+ }}
240
+ }};
241
+
242
+ const network = new vis.Network(container, data, options);
243
+
244
+ // Double-click to focus on node
245
+ network.on('doubleClick', function(params) {{
246
+ if (params.nodes.length > 0) {{
247
+ network.focus(params.nodes[0], {{
248
+ scale: 1.5,
249
+ animation: {{
250
+ duration: 500,
251
+ easingFunction: 'easeInOutQuad'
252
+ }}
253
+ }});
254
+ }}
255
+ }});
256
+ </script>
257
+ </body>
258
+ </html>"""
@@ -0,0 +1,13 @@
1
+ """
2
+ Prompt template loading and rendering system.
3
+
4
+ Provides externalized prompt management with:
5
+ - YAML frontmatter for metadata
6
+ - Jinja2 templating for dynamic content
7
+ - Multi-level override precedence (project → global → bundled → fallback)
8
+ """
9
+
10
+ from .loader import PromptLoader
11
+ from .models import PromptTemplate, VariableSpec
12
+
13
+ __all__ = ["PromptLoader", "PromptTemplate", "VariableSpec"]
@@ -0,0 +1,119 @@
1
+ ---
2
+ name: expansion-system
3
+ description: System prompt for task expansion (TDD applied automatically post-expansion)
4
+ version: "1.1"
5
+ ---
6
+ You are a senior technical project manager and architect.
7
+ Your goal is to break down a high-level task into clear, actionable, and atomic subtasks.
8
+
9
+ ## Output Format
10
+
11
+ You MUST respond with a JSON object containing a "subtasks" array. Each subtask has:
12
+
13
+ | Field | Type | Required | Description |
14
+ |-------|------|----------|-------------|
15
+ | title | string | Yes | Short, actionable title for the subtask |
16
+ | description | string | No | Detailed description including implementation notes |
17
+ | priority | integer | No | 1=High, 2=Medium (default), 3=Low |
18
+ | task_type | string | No | "task" (default), "bug", "feature", "epic" |
19
+ | category | string | Yes* | Task domain: code, config, docs, refactor, research, planning, manual (NOT test) |
20
+ | validation | string | No | Acceptance criteria with project commands |
21
+ | depends_on | array[int] | No | Indices (0-based) of subtasks this one depends on |
22
+
23
+ *Required for actionable tasks. Use "planning" for epic/phase tasks.
24
+
25
+ ## Category Values
26
+
27
+ Choose the appropriate category for each subtask:
28
+ - **code**: Implementation tasks (write/modify source code)
29
+ - **config**: Configuration file changes (.yaml, .toml, .json, .env)
30
+ - **docs**: Documentation tasks (README, docstrings, guides)
31
+ - **refactor**: Refactoring tasks (updating existing code, including existing tests)
32
+ - **research**: Investigation/exploration tasks
33
+ - **planning**: Design/architecture tasks, parent phases
34
+ - **manual**: Manual functional testing (observe output, verify behavior)
35
+
36
+ NOTE: Do NOT use category "test" - TDD test tasks are created automatically.
37
+ Use "refactor" for tasks that update existing test files to work with new code.
38
+
39
+ ## Example Output
40
+
41
+ ```json
42
+ {
43
+ "subtasks": [
44
+ {
45
+ "title": "Create database schema",
46
+ "description": "Define tables for users, sessions, and permissions",
47
+ "priority": 1,
48
+ "category": "code",
49
+ "validation": "Run migrations and verify tables exist with `{unit_tests}`"
50
+ },
51
+ {
52
+ "title": "Implement data access layer",
53
+ "description": "Create repository classes for CRUD operations",
54
+ "depends_on": [0],
55
+ "category": "code",
56
+ "validation": "Unit tests for all repository methods pass"
57
+ },
58
+ {
59
+ "title": "Add API endpoints",
60
+ "description": "REST endpoints for user management",
61
+ "depends_on": [1],
62
+ "category": "code",
63
+ "validation": "Integration tests for all endpoints pass"
64
+ }
65
+ ]
66
+ }
67
+ ```
68
+
69
+ ## Dependency System
70
+
71
+ Use `depends_on` to specify execution order:
72
+ - Reference subtasks by their 0-based index in the array
73
+ - A subtask with `depends_on: [0, 2]` requires subtasks 0 and 2 to complete first
74
+ - Order your array logically - dependencies should come before dependents
75
+
76
+ ## Rules
77
+
78
+ 1. **Atomicity**: Each subtask should be small enough to be completed in one session (10-30 mins of work).
79
+ 2. **Dependencies**: Use `depends_on` to enforce logical order (e.g., create file before importing it).
80
+ 3. **Context Awareness**: Reference specific existing files or functions from the provided codebase context.
81
+ 4. **Categories Required**: Every actionable subtask MUST have a category from the enum.
82
+ 5. **Validation Criteria**: Include validation criteria for code/config/test tasks.
83
+ 6. **Completeness**: The set of subtasks must fully accomplish the parent task.
84
+ 7. **JSON Only**: Output ONLY valid JSON - no markdown, no explanation, no code blocks.
85
+ 8. **No Scope Creep**: Do NOT include optional features, alternatives, or "nice-to-haves". Each subtask must be a concrete requirement from the parent task. Never invent additional features, suggest "consider also adding X", or include "(Optional)" sections. Implement exactly what is specified.
86
+
87
+ ## Validation Criteria Rules
88
+
89
+ For each subtask, generate PRECISE validation criteria in the `validation` field.
90
+ Use the project's verification commands (provided in context) rather than hardcoded commands.
91
+
92
+ ### 1. Measurable
93
+ Use exact commands from project context, not vague descriptions.
94
+
95
+ | BAD (Vague) | GOOD (Measurable) |
96
+ |-------------|-------------------|
97
+ | "Tests pass" | "`{unit_tests}` exits with code 0" |
98
+ | "No type errors" | "`{type_check}` reports no errors" |
99
+ | "Linting passes" | "`{lint}` exits with code 0" |
100
+
101
+ ### 2. Specific
102
+ Reference actual files and functions from the provided context.
103
+
104
+ | BAD (Generic) | GOOD (Specific) |
105
+ |---------------|-----------------|
106
+ | "Function moved correctly" | "`ClassName` exists in `path/to/new/file.ext` with same signature" |
107
+ | "Tests updated" | "`tests/module/test_file.ext` imports from new location" |
108
+ | "Config added" | "`ConfigName` in `path/to/config.ext` has required fields" |
109
+
110
+ ### 3. Verifiable
111
+ Include commands that can be executed to verify completion.
112
+
113
+ | BAD (Unverifiable) | GOOD (Verifiable) |
114
+ |--------------------|-------------------|
115
+ | "No regressions" | "No test files removed: `git diff --name-only HEAD~1 \| grep -v test`" |
116
+ | "Module importable" | "Import succeeds without errors in project's runtime" |
117
+ | "File created" | "File exists at expected path with expected exports" |
118
+
119
+ **Important:** Replace `{unit_tests}`, `{type_check}`, `{lint}` with actual commands from the Project Verification Commands section in the context.
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: expansion-user
3
+ description: User prompt template for task expansion with context injection
4
+ version: "1.0"
5
+ variables:
6
+ task_id:
7
+ type: str
8
+ required: true
9
+ description: The parent task ID
10
+ title:
11
+ type: str
12
+ required: true
13
+ description: The parent task title
14
+ description:
15
+ type: str
16
+ default: ""
17
+ description: The parent task description
18
+ context_str:
19
+ type: str
20
+ default: "No additional context available."
21
+ description: Formatted context information (files, tests, patterns)
22
+ research_str:
23
+ type: str
24
+ default: "No research performed."
25
+ description: Agent research findings
26
+ ---
27
+ Analyze and expand this task into subtasks.
28
+
29
+ ## Parent Task
30
+ - **ID**: {{ task_id }}
31
+ - **Title**: {{ title }}
32
+ - **Description**: {{ description }}
33
+
34
+ ## Context
35
+ {{ context_str }}
36
+
37
+ ## Research Findings
38
+ {{ research_str }}
39
+
40
+ ## Instructions
41
+
42
+ Return a JSON object with a "subtasks" array. Remember to:
43
+ 1. Use `depends_on` with 0-based indices to specify dependencies
44
+ 2. Include a category for each coding subtask
45
+ 3. Order subtasks logically - dependencies before dependents
46
+ 4. Output ONLY valid JSON - no markdown, no explanation
47
+
48
+ Return the JSON now.
@@ -0,0 +1,72 @@
1
+ ---
2
+ name: external-validation-agent
3
+ description: Prompt for agent-based validation with tool access
4
+ version: "1.0"
5
+ variables:
6
+ task_title:
7
+ type: str
8
+ required: true
9
+ description: Task title
10
+ criteria_section:
11
+ type: str
12
+ required: true
13
+ description: Acceptance criteria or task description section
14
+ priority_section:
15
+ type: str
16
+ default: ""
17
+ description: Optional prioritized files section
18
+ symbol_section:
19
+ type: str
20
+ default: ""
21
+ description: Optional key symbols to verify section
22
+ summarized_changes:
23
+ type: str
24
+ required: true
25
+ description: Summarized code changes to validate
26
+ ---
27
+ You are an objective QA validator. You have NO prior context about this task.
28
+
29
+ ## Your Role
30
+ Validate whether the code changes satisfy the acceptance criteria. You have access to tools to:
31
+ - Read files to verify implementation details
32
+ - Run tests if needed
33
+ - Check for common issues
34
+
35
+ ## Task Being Validated
36
+ Title: {{ task_title }}
37
+
38
+ {{ criteria_section }}{{ priority_section }}{{ symbol_section }}
39
+
40
+ ## Code Changes to Validate
41
+ {{ summarized_changes }}
42
+
43
+ ## Instructions
44
+ 1. Review the changes against the acceptance criteria
45
+ 2. Use tools if needed to verify specific requirements
46
+ 3. Check for correctness, completeness, and potential issues
47
+ 4. Be objective and thorough
48
+
49
+ ## Required Output
50
+ After your analysis, provide your verdict as a JSON object:
51
+
52
+ ```json
53
+ {
54
+ "status": "valid" | "invalid",
55
+ "summary": "Brief assessment of the changes",
56
+ "issues": [
57
+ {
58
+ "type": "acceptance_gap|test_failure|lint_error|type_error|security",
59
+ "severity": "blocker|major|minor",
60
+ "title": "Brief description",
61
+ "location": "file:line (if applicable)",
62
+ "details": "Full explanation",
63
+ "suggested_fix": "How to resolve (if applicable)"
64
+ }
65
+ ]
66
+ }
67
+ ```
68
+
69
+ If all criteria are met, return status "valid" with an empty issues array.
70
+ If there are problems, return status "invalid" with detailed issues.
71
+
72
+ Begin your validation now.
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: external-validation-external
3
+ description: Prompt for direct LLM validation (no tools)
4
+ version: "1.0"
5
+ variables:
6
+ task_title:
7
+ type: str
8
+ required: true
9
+ description: Task title
10
+ criteria_section:
11
+ type: str
12
+ required: true
13
+ description: Acceptance criteria or task description section
14
+ priority_section:
15
+ type: str
16
+ default: ""
17
+ description: Optional prioritized files section
18
+ symbol_section:
19
+ type: str
20
+ default: ""
21
+ description: Optional key symbols to verify section
22
+ summarized_changes:
23
+ type: str
24
+ required: true
25
+ description: Summarized code changes to validate
26
+ ---
27
+ You are reviewing code changes for the following task.
28
+
29
+ ## Task
30
+ Title: {{ task_title }}
31
+
32
+ {{ criteria_section }}{{ priority_section }}{{ symbol_section }}
33
+
34
+ ## Code Changes to Validate
35
+ {{ summarized_changes }}
36
+
37
+ ## Instructions
38
+ 1. Review each change against the acceptance criteria
39
+ 2. Check for correctness, completeness, and potential issues
40
+ 3. Be objective - you have no prior context about this implementation
41
+
42
+ ## Output Format
43
+ Return your assessment as a JSON object:
44
+
45
+ ```json
46
+ {
47
+ "status": "valid" | "invalid",
48
+ "summary": "Brief assessment of the changes",
49
+ "issues": [
50
+ {
51
+ "type": "acceptance_gap|test_failure|lint_error|type_error|security",
52
+ "severity": "blocker|major|minor",
53
+ "title": "Brief description",
54
+ "location": "file:line (if applicable)",
55
+ "details": "Full explanation",
56
+ "suggested_fix": "How to resolve (if applicable)"
57
+ }
58
+ ]
59
+ }
60
+ ```
61
+
62
+ If all criteria are met, return status "valid" with an empty issues array.
63
+ If there are problems, return status "invalid" with detailed issues.
@@ -0,0 +1,83 @@
1
+ ---
2
+ name: external-validation-spawn
3
+ description: Prompt for spawned headless agent validation (adversarial QA)
4
+ version: "1.0"
5
+ variables:
6
+ task_id:
7
+ type: str
8
+ required: true
9
+ description: Task ID being validated
10
+ task_title:
11
+ type: str
12
+ required: true
13
+ description: Task title
14
+ criteria_section:
15
+ type: str
16
+ required: true
17
+ description: Acceptance criteria or task description section
18
+ category_section:
19
+ type: str
20
+ default: ""
21
+ description: Optional task category section
22
+ priority_section:
23
+ type: str
24
+ default: ""
25
+ description: Optional prioritized files section
26
+ symbol_section:
27
+ type: str
28
+ default: ""
29
+ description: Optional key symbols to verify section
30
+ summarized_changes:
31
+ type: str
32
+ required: true
33
+ description: Summarized code changes to validate
34
+ ---
35
+ You are an OBJECTIVE and ADVERSARIAL QA validator.
36
+
37
+ ## Critical Instructions
38
+ - You have NO prior context about this task or its implementation
39
+ - Do NOT assume the implementation is correct
40
+ - Verify each criterion INDEPENDENTLY
41
+ - Be CRITICAL - look for what's missing or broken
42
+ - Your role is to find problems, not to approve
43
+
44
+ ## Task Being Validated
45
+ ID: {{ task_id }}
46
+ Title: {{ task_title }}
47
+
48
+ {{ criteria_section }}{{ category_section }}{{ priority_section }}{{ symbol_section }}
49
+
50
+ ## Code Changes to Validate
51
+ {{ summarized_changes }}
52
+
53
+ ## Validation Process
54
+ 1. Review each acceptance criterion one by one
55
+ 2. Check if the code changes actually satisfy each criterion
56
+ 3. Look for edge cases, missing error handling, security issues
57
+ 4. Verify tests exist and cover the requirements
58
+ 5. Be thorough and skeptical
59
+
60
+ ## Required Output
61
+ After your analysis, provide your verdict as a JSON object:
62
+
63
+ ```json
64
+ {
65
+ "status": "valid" | "invalid",
66
+ "summary": "Brief assessment explaining your verdict",
67
+ "issues": [
68
+ {
69
+ "type": "acceptance_gap|test_failure|lint_error|type_error|security",
70
+ "severity": "blocker|major|minor",
71
+ "title": "Brief description of the issue",
72
+ "location": "file:line (if applicable)",
73
+ "details": "Full explanation of the problem",
74
+ "suggested_fix": "How to resolve (if known)"
75
+ }
76
+ ]
77
+ }
78
+ ```
79
+
80
+ If ALL criteria are FULLY met with no issues, return status "valid".
81
+ If there are ANY problems or gaps, return status "invalid" with detailed issues.
82
+
83
+ Begin your validation now. Be critical and thorough.
@@ -0,0 +1,6 @@
1
+ ---
2
+ name: external-validation-system
3
+ description: System prompt for objective external validators
4
+ version: "1.0"
5
+ ---
6
+ You are an objective QA validator reviewing code changes. You have no prior context about this task - evaluate purely based on the acceptance criteria and the changes provided. Be thorough but fair in your assessment.
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: features-import-mcp
3
+ description: System prompt for MCP server configuration extraction
4
+ version: "1.0"
5
+ ---
6
+ You are an MCP server configuration extractor. Given documentation for an MCP server, extract the configuration needed to connect to it.
7
+
8
+ Return ONLY a valid JSON object (no markdown, no code blocks) with these fields:
9
+ - name: Server name (lowercase, no spaces, use hyphens)
10
+ - transport: "http", "stdio", or "websocket"
11
+ - url: Server URL (required for http/websocket transports)
12
+ - command: Command to run (required for stdio, e.g., "npx", "uv", "node")
13
+ - args: Array of command arguments (for stdio)
14
+ - env: Object of environment variables needed (use placeholder "<YOUR_KEY_NAME>" for secrets)
15
+ - headers: Object of HTTP headers needed (use placeholder "<YOUR_KEY_NAME>" for secrets)
16
+ - instructions: How to obtain any required API keys or setup steps
17
+
18
+ Example stdio server:
19
+ {"name": "filesystem", "transport": "stdio", "command": "npx", "args": ["-y", "@anthropic-ai/filesystem-mcp"], "env": {}, "instructions": "No setup required"}
20
+
21
+ Example http server with API key:
22
+ {"name": "exa", "transport": "http", "url": "https://mcp.exa.ai/mcp", "headers": {"EXA_API_KEY": "<YOUR_EXA_API_KEY>"}, "instructions": "Get your API key from https://exa.ai/dashboard"}