attune-ai 2.0.0__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 (457) hide show
  1. attune/__init__.py +358 -0
  2. attune/adaptive/__init__.py +13 -0
  3. attune/adaptive/task_complexity.py +127 -0
  4. attune/agent_monitoring.py +414 -0
  5. attune/cache/__init__.py +117 -0
  6. attune/cache/base.py +166 -0
  7. attune/cache/dependency_manager.py +256 -0
  8. attune/cache/hash_only.py +251 -0
  9. attune/cache/hybrid.py +457 -0
  10. attune/cache/storage.py +285 -0
  11. attune/cache_monitor.py +356 -0
  12. attune/cache_stats.py +298 -0
  13. attune/cli/__init__.py +152 -0
  14. attune/cli/__main__.py +12 -0
  15. attune/cli/commands/__init__.py +1 -0
  16. attune/cli/commands/batch.py +264 -0
  17. attune/cli/commands/cache.py +248 -0
  18. attune/cli/commands/help.py +331 -0
  19. attune/cli/commands/info.py +140 -0
  20. attune/cli/commands/inspect.py +436 -0
  21. attune/cli/commands/inspection.py +57 -0
  22. attune/cli/commands/memory.py +48 -0
  23. attune/cli/commands/metrics.py +92 -0
  24. attune/cli/commands/orchestrate.py +184 -0
  25. attune/cli/commands/patterns.py +207 -0
  26. attune/cli/commands/profiling.py +202 -0
  27. attune/cli/commands/provider.py +98 -0
  28. attune/cli/commands/routing.py +285 -0
  29. attune/cli/commands/setup.py +96 -0
  30. attune/cli/commands/status.py +235 -0
  31. attune/cli/commands/sync.py +166 -0
  32. attune/cli/commands/tier.py +121 -0
  33. attune/cli/commands/utilities.py +114 -0
  34. attune/cli/commands/workflow.py +579 -0
  35. attune/cli/core.py +32 -0
  36. attune/cli/parsers/__init__.py +68 -0
  37. attune/cli/parsers/batch.py +118 -0
  38. attune/cli/parsers/cache.py +65 -0
  39. attune/cli/parsers/help.py +41 -0
  40. attune/cli/parsers/info.py +26 -0
  41. attune/cli/parsers/inspect.py +66 -0
  42. attune/cli/parsers/metrics.py +42 -0
  43. attune/cli/parsers/orchestrate.py +61 -0
  44. attune/cli/parsers/patterns.py +54 -0
  45. attune/cli/parsers/provider.py +40 -0
  46. attune/cli/parsers/routing.py +110 -0
  47. attune/cli/parsers/setup.py +42 -0
  48. attune/cli/parsers/status.py +47 -0
  49. attune/cli/parsers/sync.py +31 -0
  50. attune/cli/parsers/tier.py +33 -0
  51. attune/cli/parsers/workflow.py +77 -0
  52. attune/cli/utils/__init__.py +1 -0
  53. attune/cli/utils/data.py +242 -0
  54. attune/cli/utils/helpers.py +68 -0
  55. attune/cli_legacy.py +3957 -0
  56. attune/cli_minimal.py +1159 -0
  57. attune/cli_router.py +437 -0
  58. attune/cli_unified.py +814 -0
  59. attune/config/__init__.py +66 -0
  60. attune/config/xml_config.py +286 -0
  61. attune/config.py +545 -0
  62. attune/coordination.py +870 -0
  63. attune/core.py +1511 -0
  64. attune/core_modules/__init__.py +15 -0
  65. attune/cost_tracker.py +626 -0
  66. attune/dashboard/__init__.py +41 -0
  67. attune/dashboard/app.py +512 -0
  68. attune/dashboard/simple_server.py +435 -0
  69. attune/dashboard/standalone_server.py +547 -0
  70. attune/discovery.py +306 -0
  71. attune/emergence.py +306 -0
  72. attune/exceptions.py +123 -0
  73. attune/feedback_loops.py +373 -0
  74. attune/hot_reload/README.md +473 -0
  75. attune/hot_reload/__init__.py +62 -0
  76. attune/hot_reload/config.py +83 -0
  77. attune/hot_reload/integration.py +229 -0
  78. attune/hot_reload/reloader.py +298 -0
  79. attune/hot_reload/watcher.py +183 -0
  80. attune/hot_reload/websocket.py +177 -0
  81. attune/levels.py +577 -0
  82. attune/leverage_points.py +441 -0
  83. attune/logging_config.py +261 -0
  84. attune/mcp/__init__.py +10 -0
  85. attune/mcp/server.py +506 -0
  86. attune/memory/__init__.py +237 -0
  87. attune/memory/claude_memory.py +469 -0
  88. attune/memory/config.py +224 -0
  89. attune/memory/control_panel.py +1290 -0
  90. attune/memory/control_panel_support.py +145 -0
  91. attune/memory/cross_session.py +845 -0
  92. attune/memory/edges.py +179 -0
  93. attune/memory/encryption.py +159 -0
  94. attune/memory/file_session.py +770 -0
  95. attune/memory/graph.py +570 -0
  96. attune/memory/long_term.py +913 -0
  97. attune/memory/long_term_types.py +99 -0
  98. attune/memory/mixins/__init__.py +25 -0
  99. attune/memory/mixins/backend_init_mixin.py +249 -0
  100. attune/memory/mixins/capabilities_mixin.py +208 -0
  101. attune/memory/mixins/handoff_mixin.py +208 -0
  102. attune/memory/mixins/lifecycle_mixin.py +49 -0
  103. attune/memory/mixins/long_term_mixin.py +352 -0
  104. attune/memory/mixins/promotion_mixin.py +109 -0
  105. attune/memory/mixins/short_term_mixin.py +182 -0
  106. attune/memory/nodes.py +179 -0
  107. attune/memory/redis_bootstrap.py +540 -0
  108. attune/memory/security/__init__.py +31 -0
  109. attune/memory/security/audit_logger.py +932 -0
  110. attune/memory/security/pii_scrubber.py +640 -0
  111. attune/memory/security/secrets_detector.py +678 -0
  112. attune/memory/short_term.py +2192 -0
  113. attune/memory/simple_storage.py +302 -0
  114. attune/memory/storage/__init__.py +15 -0
  115. attune/memory/storage_backend.py +167 -0
  116. attune/memory/summary_index.py +583 -0
  117. attune/memory/types.py +446 -0
  118. attune/memory/unified.py +182 -0
  119. attune/meta_workflows/__init__.py +74 -0
  120. attune/meta_workflows/agent_creator.py +248 -0
  121. attune/meta_workflows/builtin_templates.py +567 -0
  122. attune/meta_workflows/cli_commands/__init__.py +56 -0
  123. attune/meta_workflows/cli_commands/agent_commands.py +321 -0
  124. attune/meta_workflows/cli_commands/analytics_commands.py +442 -0
  125. attune/meta_workflows/cli_commands/config_commands.py +232 -0
  126. attune/meta_workflows/cli_commands/memory_commands.py +182 -0
  127. attune/meta_workflows/cli_commands/template_commands.py +354 -0
  128. attune/meta_workflows/cli_commands/workflow_commands.py +382 -0
  129. attune/meta_workflows/cli_meta_workflows.py +59 -0
  130. attune/meta_workflows/form_engine.py +292 -0
  131. attune/meta_workflows/intent_detector.py +409 -0
  132. attune/meta_workflows/models.py +569 -0
  133. attune/meta_workflows/pattern_learner.py +738 -0
  134. attune/meta_workflows/plan_generator.py +384 -0
  135. attune/meta_workflows/session_context.py +397 -0
  136. attune/meta_workflows/template_registry.py +229 -0
  137. attune/meta_workflows/workflow.py +984 -0
  138. attune/metrics/__init__.py +12 -0
  139. attune/metrics/collector.py +31 -0
  140. attune/metrics/prompt_metrics.py +194 -0
  141. attune/models/__init__.py +172 -0
  142. attune/models/__main__.py +13 -0
  143. attune/models/adaptive_routing.py +437 -0
  144. attune/models/auth_cli.py +444 -0
  145. attune/models/auth_strategy.py +450 -0
  146. attune/models/cli.py +655 -0
  147. attune/models/empathy_executor.py +354 -0
  148. attune/models/executor.py +257 -0
  149. attune/models/fallback.py +762 -0
  150. attune/models/provider_config.py +282 -0
  151. attune/models/registry.py +472 -0
  152. attune/models/tasks.py +359 -0
  153. attune/models/telemetry/__init__.py +71 -0
  154. attune/models/telemetry/analytics.py +594 -0
  155. attune/models/telemetry/backend.py +196 -0
  156. attune/models/telemetry/data_models.py +431 -0
  157. attune/models/telemetry/storage.py +489 -0
  158. attune/models/token_estimator.py +420 -0
  159. attune/models/validation.py +280 -0
  160. attune/monitoring/__init__.py +52 -0
  161. attune/monitoring/alerts.py +946 -0
  162. attune/monitoring/alerts_cli.py +448 -0
  163. attune/monitoring/multi_backend.py +271 -0
  164. attune/monitoring/otel_backend.py +362 -0
  165. attune/optimization/__init__.py +19 -0
  166. attune/optimization/context_optimizer.py +272 -0
  167. attune/orchestration/__init__.py +67 -0
  168. attune/orchestration/agent_templates.py +707 -0
  169. attune/orchestration/config_store.py +499 -0
  170. attune/orchestration/execution_strategies.py +2111 -0
  171. attune/orchestration/meta_orchestrator.py +1168 -0
  172. attune/orchestration/pattern_learner.py +696 -0
  173. attune/orchestration/real_tools.py +931 -0
  174. attune/pattern_cache.py +187 -0
  175. attune/pattern_library.py +542 -0
  176. attune/patterns/debugging/all_patterns.json +81 -0
  177. attune/patterns/debugging/workflow_20260107_1770825e.json +77 -0
  178. attune/patterns/refactoring_memory.json +89 -0
  179. attune/persistence.py +564 -0
  180. attune/platform_utils.py +265 -0
  181. attune/plugins/__init__.py +28 -0
  182. attune/plugins/base.py +361 -0
  183. attune/plugins/registry.py +268 -0
  184. attune/project_index/__init__.py +32 -0
  185. attune/project_index/cli.py +335 -0
  186. attune/project_index/index.py +667 -0
  187. attune/project_index/models.py +504 -0
  188. attune/project_index/reports.py +474 -0
  189. attune/project_index/scanner.py +777 -0
  190. attune/project_index/scanner_parallel.py +291 -0
  191. attune/prompts/__init__.py +61 -0
  192. attune/prompts/config.py +77 -0
  193. attune/prompts/context.py +177 -0
  194. attune/prompts/parser.py +285 -0
  195. attune/prompts/registry.py +313 -0
  196. attune/prompts/templates.py +208 -0
  197. attune/redis_config.py +302 -0
  198. attune/redis_memory.py +799 -0
  199. attune/resilience/__init__.py +56 -0
  200. attune/resilience/circuit_breaker.py +256 -0
  201. attune/resilience/fallback.py +179 -0
  202. attune/resilience/health.py +300 -0
  203. attune/resilience/retry.py +209 -0
  204. attune/resilience/timeout.py +135 -0
  205. attune/routing/__init__.py +43 -0
  206. attune/routing/chain_executor.py +433 -0
  207. attune/routing/classifier.py +217 -0
  208. attune/routing/smart_router.py +234 -0
  209. attune/routing/workflow_registry.py +343 -0
  210. attune/scaffolding/README.md +589 -0
  211. attune/scaffolding/__init__.py +35 -0
  212. attune/scaffolding/__main__.py +14 -0
  213. attune/scaffolding/cli.py +240 -0
  214. attune/scaffolding/templates/base_wizard.py.jinja2 +121 -0
  215. attune/scaffolding/templates/coach_wizard.py.jinja2 +321 -0
  216. attune/scaffolding/templates/domain_wizard.py.jinja2 +408 -0
  217. attune/scaffolding/templates/linear_flow_wizard.py.jinja2 +203 -0
  218. attune/socratic/__init__.py +256 -0
  219. attune/socratic/ab_testing.py +958 -0
  220. attune/socratic/blueprint.py +533 -0
  221. attune/socratic/cli.py +703 -0
  222. attune/socratic/collaboration.py +1114 -0
  223. attune/socratic/domain_templates.py +924 -0
  224. attune/socratic/embeddings.py +738 -0
  225. attune/socratic/engine.py +794 -0
  226. attune/socratic/explainer.py +682 -0
  227. attune/socratic/feedback.py +772 -0
  228. attune/socratic/forms.py +629 -0
  229. attune/socratic/generator.py +732 -0
  230. attune/socratic/llm_analyzer.py +637 -0
  231. attune/socratic/mcp_server.py +702 -0
  232. attune/socratic/session.py +312 -0
  233. attune/socratic/storage.py +667 -0
  234. attune/socratic/success.py +730 -0
  235. attune/socratic/visual_editor.py +860 -0
  236. attune/socratic/web_ui.py +958 -0
  237. attune/telemetry/__init__.py +39 -0
  238. attune/telemetry/agent_coordination.py +475 -0
  239. attune/telemetry/agent_tracking.py +367 -0
  240. attune/telemetry/approval_gates.py +545 -0
  241. attune/telemetry/cli.py +1231 -0
  242. attune/telemetry/commands/__init__.py +14 -0
  243. attune/telemetry/commands/dashboard_commands.py +696 -0
  244. attune/telemetry/event_streaming.py +409 -0
  245. attune/telemetry/feedback_loop.py +567 -0
  246. attune/telemetry/usage_tracker.py +591 -0
  247. attune/templates.py +754 -0
  248. attune/test_generator/__init__.py +38 -0
  249. attune/test_generator/__main__.py +14 -0
  250. attune/test_generator/cli.py +234 -0
  251. attune/test_generator/generator.py +355 -0
  252. attune/test_generator/risk_analyzer.py +216 -0
  253. attune/test_generator/templates/unit_test.py.jinja2 +272 -0
  254. attune/tier_recommender.py +384 -0
  255. attune/tools.py +183 -0
  256. attune/trust/__init__.py +28 -0
  257. attune/trust/circuit_breaker.py +579 -0
  258. attune/trust_building.py +527 -0
  259. attune/validation/__init__.py +19 -0
  260. attune/validation/xml_validator.py +281 -0
  261. attune/vscode_bridge.py +173 -0
  262. attune/workflow_commands.py +780 -0
  263. attune/workflow_patterns/__init__.py +33 -0
  264. attune/workflow_patterns/behavior.py +249 -0
  265. attune/workflow_patterns/core.py +76 -0
  266. attune/workflow_patterns/output.py +99 -0
  267. attune/workflow_patterns/registry.py +255 -0
  268. attune/workflow_patterns/structural.py +288 -0
  269. attune/workflows/__init__.py +539 -0
  270. attune/workflows/autonomous_test_gen.py +1268 -0
  271. attune/workflows/base.py +2667 -0
  272. attune/workflows/batch_processing.py +342 -0
  273. attune/workflows/bug_predict.py +1084 -0
  274. attune/workflows/builder.py +273 -0
  275. attune/workflows/caching.py +253 -0
  276. attune/workflows/code_review.py +1048 -0
  277. attune/workflows/code_review_adapters.py +312 -0
  278. attune/workflows/code_review_pipeline.py +722 -0
  279. attune/workflows/config.py +645 -0
  280. attune/workflows/dependency_check.py +644 -0
  281. attune/workflows/document_gen/__init__.py +25 -0
  282. attune/workflows/document_gen/config.py +30 -0
  283. attune/workflows/document_gen/report_formatter.py +162 -0
  284. attune/workflows/document_gen/workflow.py +1426 -0
  285. attune/workflows/document_manager.py +216 -0
  286. attune/workflows/document_manager_README.md +134 -0
  287. attune/workflows/documentation_orchestrator.py +1205 -0
  288. attune/workflows/history.py +510 -0
  289. attune/workflows/keyboard_shortcuts/__init__.py +39 -0
  290. attune/workflows/keyboard_shortcuts/generators.py +391 -0
  291. attune/workflows/keyboard_shortcuts/parsers.py +416 -0
  292. attune/workflows/keyboard_shortcuts/prompts.py +295 -0
  293. attune/workflows/keyboard_shortcuts/schema.py +193 -0
  294. attune/workflows/keyboard_shortcuts/workflow.py +509 -0
  295. attune/workflows/llm_base.py +363 -0
  296. attune/workflows/manage_docs.py +87 -0
  297. attune/workflows/manage_docs_README.md +134 -0
  298. attune/workflows/manage_documentation.py +821 -0
  299. attune/workflows/new_sample_workflow1.py +149 -0
  300. attune/workflows/new_sample_workflow1_README.md +150 -0
  301. attune/workflows/orchestrated_health_check.py +849 -0
  302. attune/workflows/orchestrated_release_prep.py +600 -0
  303. attune/workflows/output.py +413 -0
  304. attune/workflows/perf_audit.py +863 -0
  305. attune/workflows/pr_review.py +762 -0
  306. attune/workflows/progress.py +785 -0
  307. attune/workflows/progress_server.py +322 -0
  308. attune/workflows/progressive/README 2.md +454 -0
  309. attune/workflows/progressive/README.md +454 -0
  310. attune/workflows/progressive/__init__.py +82 -0
  311. attune/workflows/progressive/cli.py +219 -0
  312. attune/workflows/progressive/core.py +488 -0
  313. attune/workflows/progressive/orchestrator.py +723 -0
  314. attune/workflows/progressive/reports.py +520 -0
  315. attune/workflows/progressive/telemetry.py +274 -0
  316. attune/workflows/progressive/test_gen.py +495 -0
  317. attune/workflows/progressive/workflow.py +589 -0
  318. attune/workflows/refactor_plan.py +694 -0
  319. attune/workflows/release_prep.py +895 -0
  320. attune/workflows/release_prep_crew.py +969 -0
  321. attune/workflows/research_synthesis.py +404 -0
  322. attune/workflows/routing.py +168 -0
  323. attune/workflows/secure_release.py +593 -0
  324. attune/workflows/security_adapters.py +297 -0
  325. attune/workflows/security_audit.py +1329 -0
  326. attune/workflows/security_audit_phase3.py +355 -0
  327. attune/workflows/seo_optimization.py +633 -0
  328. attune/workflows/step_config.py +234 -0
  329. attune/workflows/telemetry_mixin.py +269 -0
  330. attune/workflows/test5.py +125 -0
  331. attune/workflows/test5_README.md +158 -0
  332. attune/workflows/test_coverage_boost_crew.py +849 -0
  333. attune/workflows/test_gen/__init__.py +52 -0
  334. attune/workflows/test_gen/ast_analyzer.py +249 -0
  335. attune/workflows/test_gen/config.py +88 -0
  336. attune/workflows/test_gen/data_models.py +38 -0
  337. attune/workflows/test_gen/report_formatter.py +289 -0
  338. attune/workflows/test_gen/test_templates.py +381 -0
  339. attune/workflows/test_gen/workflow.py +655 -0
  340. attune/workflows/test_gen.py +54 -0
  341. attune/workflows/test_gen_behavioral.py +477 -0
  342. attune/workflows/test_gen_parallel.py +341 -0
  343. attune/workflows/test_lifecycle.py +526 -0
  344. attune/workflows/test_maintenance.py +627 -0
  345. attune/workflows/test_maintenance_cli.py +590 -0
  346. attune/workflows/test_maintenance_crew.py +840 -0
  347. attune/workflows/test_runner.py +622 -0
  348. attune/workflows/tier_tracking.py +531 -0
  349. attune/workflows/xml_enhanced_crew.py +285 -0
  350. attune_ai-2.0.0.dist-info/METADATA +1026 -0
  351. attune_ai-2.0.0.dist-info/RECORD +457 -0
  352. attune_ai-2.0.0.dist-info/WHEEL +5 -0
  353. attune_ai-2.0.0.dist-info/entry_points.txt +26 -0
  354. attune_ai-2.0.0.dist-info/licenses/LICENSE +201 -0
  355. attune_ai-2.0.0.dist-info/licenses/LICENSE_CHANGE_ANNOUNCEMENT.md +101 -0
  356. attune_ai-2.0.0.dist-info/top_level.txt +5 -0
  357. attune_healthcare/__init__.py +13 -0
  358. attune_healthcare/monitors/__init__.py +9 -0
  359. attune_healthcare/monitors/clinical_protocol_monitor.py +315 -0
  360. attune_healthcare/monitors/monitoring/__init__.py +44 -0
  361. attune_healthcare/monitors/monitoring/protocol_checker.py +300 -0
  362. attune_healthcare/monitors/monitoring/protocol_loader.py +214 -0
  363. attune_healthcare/monitors/monitoring/sensor_parsers.py +306 -0
  364. attune_healthcare/monitors/monitoring/trajectory_analyzer.py +389 -0
  365. attune_llm/README.md +553 -0
  366. attune_llm/__init__.py +28 -0
  367. attune_llm/agent_factory/__init__.py +53 -0
  368. attune_llm/agent_factory/adapters/__init__.py +85 -0
  369. attune_llm/agent_factory/adapters/autogen_adapter.py +312 -0
  370. attune_llm/agent_factory/adapters/crewai_adapter.py +483 -0
  371. attune_llm/agent_factory/adapters/haystack_adapter.py +298 -0
  372. attune_llm/agent_factory/adapters/langchain_adapter.py +362 -0
  373. attune_llm/agent_factory/adapters/langgraph_adapter.py +333 -0
  374. attune_llm/agent_factory/adapters/native.py +228 -0
  375. attune_llm/agent_factory/adapters/wizard_adapter.py +423 -0
  376. attune_llm/agent_factory/base.py +305 -0
  377. attune_llm/agent_factory/crews/__init__.py +67 -0
  378. attune_llm/agent_factory/crews/code_review.py +1113 -0
  379. attune_llm/agent_factory/crews/health_check.py +1262 -0
  380. attune_llm/agent_factory/crews/refactoring.py +1128 -0
  381. attune_llm/agent_factory/crews/security_audit.py +1018 -0
  382. attune_llm/agent_factory/decorators.py +287 -0
  383. attune_llm/agent_factory/factory.py +558 -0
  384. attune_llm/agent_factory/framework.py +193 -0
  385. attune_llm/agent_factory/memory_integration.py +328 -0
  386. attune_llm/agent_factory/resilient.py +320 -0
  387. attune_llm/agents_md/__init__.py +22 -0
  388. attune_llm/agents_md/loader.py +218 -0
  389. attune_llm/agents_md/parser.py +271 -0
  390. attune_llm/agents_md/registry.py +307 -0
  391. attune_llm/claude_memory.py +466 -0
  392. attune_llm/cli/__init__.py +8 -0
  393. attune_llm/cli/sync_claude.py +487 -0
  394. attune_llm/code_health.py +1313 -0
  395. attune_llm/commands/__init__.py +51 -0
  396. attune_llm/commands/context.py +375 -0
  397. attune_llm/commands/loader.py +301 -0
  398. attune_llm/commands/models.py +231 -0
  399. attune_llm/commands/parser.py +371 -0
  400. attune_llm/commands/registry.py +429 -0
  401. attune_llm/config/__init__.py +29 -0
  402. attune_llm/config/unified.py +291 -0
  403. attune_llm/context/__init__.py +22 -0
  404. attune_llm/context/compaction.py +455 -0
  405. attune_llm/context/manager.py +434 -0
  406. attune_llm/contextual_patterns.py +361 -0
  407. attune_llm/core.py +907 -0
  408. attune_llm/git_pattern_extractor.py +435 -0
  409. attune_llm/hooks/__init__.py +24 -0
  410. attune_llm/hooks/config.py +306 -0
  411. attune_llm/hooks/executor.py +289 -0
  412. attune_llm/hooks/registry.py +302 -0
  413. attune_llm/hooks/scripts/__init__.py +39 -0
  414. attune_llm/hooks/scripts/evaluate_session.py +201 -0
  415. attune_llm/hooks/scripts/first_time_init.py +285 -0
  416. attune_llm/hooks/scripts/pre_compact.py +207 -0
  417. attune_llm/hooks/scripts/session_end.py +183 -0
  418. attune_llm/hooks/scripts/session_start.py +163 -0
  419. attune_llm/hooks/scripts/suggest_compact.py +225 -0
  420. attune_llm/learning/__init__.py +30 -0
  421. attune_llm/learning/evaluator.py +438 -0
  422. attune_llm/learning/extractor.py +514 -0
  423. attune_llm/learning/storage.py +560 -0
  424. attune_llm/levels.py +227 -0
  425. attune_llm/pattern_confidence.py +414 -0
  426. attune_llm/pattern_resolver.py +272 -0
  427. attune_llm/pattern_summary.py +350 -0
  428. attune_llm/providers.py +967 -0
  429. attune_llm/routing/__init__.py +32 -0
  430. attune_llm/routing/model_router.py +362 -0
  431. attune_llm/security/IMPLEMENTATION_SUMMARY.md +413 -0
  432. attune_llm/security/PHASE2_COMPLETE.md +384 -0
  433. attune_llm/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
  434. attune_llm/security/QUICK_REFERENCE.md +316 -0
  435. attune_llm/security/README.md +262 -0
  436. attune_llm/security/__init__.py +62 -0
  437. attune_llm/security/audit_logger.py +929 -0
  438. attune_llm/security/audit_logger_example.py +152 -0
  439. attune_llm/security/pii_scrubber.py +640 -0
  440. attune_llm/security/secrets_detector.py +678 -0
  441. attune_llm/security/secrets_detector_example.py +304 -0
  442. attune_llm/security/secure_memdocs.py +1192 -0
  443. attune_llm/security/secure_memdocs_example.py +278 -0
  444. attune_llm/session_status.py +745 -0
  445. attune_llm/state.py +246 -0
  446. attune_llm/utils/__init__.py +5 -0
  447. attune_llm/utils/tokens.py +349 -0
  448. attune_software/SOFTWARE_PLUGIN_README.md +57 -0
  449. attune_software/__init__.py +13 -0
  450. attune_software/cli/__init__.py +120 -0
  451. attune_software/cli/inspect.py +362 -0
  452. attune_software/cli.py +574 -0
  453. attune_software/plugin.py +188 -0
  454. workflow_scaffolding/__init__.py +11 -0
  455. workflow_scaffolding/__main__.py +12 -0
  456. workflow_scaffolding/cli.py +206 -0
  457. workflow_scaffolding/generator.py +265 -0
@@ -0,0 +1,391 @@
1
+ """Output generators for keyboard shortcut files.
2
+
3
+ Generates:
4
+ - VSCode keybindings.json (per layout)
5
+ - Bash/Zsh alias scripts
6
+ - Markdown documentation with ASCII keyboard diagrams
7
+ """
8
+
9
+ import json
10
+ from pathlib import Path
11
+
12
+ from attune.config import _validate_file_path
13
+
14
+ from .schema import (
15
+ FeatureManifest,
16
+ GeneratedShortcuts,
17
+ KeyboardLayout,
18
+ LayoutShortcuts,
19
+ ShortcutAssignment,
20
+ )
21
+
22
+
23
+ class VSCodeKeybindingsGenerator:
24
+ """Generate VSCode keybindings.json files for each layout."""
25
+
26
+ def generate(
27
+ self,
28
+ shortcuts: GeneratedShortcuts,
29
+ output_dir: Path,
30
+ ) -> dict[str, Path]:
31
+ """Generate keybindings files for all layouts.
32
+
33
+ Returns dict of layout -> output file path.
34
+ """
35
+ output_dir.mkdir(parents=True, exist_ok=True)
36
+ generated_files = {}
37
+
38
+ for layout, layout_shortcuts in shortcuts.layouts.items():
39
+ output_file = output_dir / f"{layout.value}.json"
40
+ bindings = self._generate_bindings(shortcuts.manifest, layout_shortcuts)
41
+ validated_output = _validate_file_path(str(output_file))
42
+ validated_output.write_text(json.dumps(bindings, indent=2))
43
+ generated_files[layout.value] = validated_output
44
+
45
+ return generated_files
46
+
47
+ def _generate_bindings(
48
+ self,
49
+ manifest: FeatureManifest,
50
+ layout_shortcuts: LayoutShortcuts,
51
+ ) -> list[dict]:
52
+ """Generate VSCode keybinding entries."""
53
+ bindings = []
54
+ prefix = manifest.prefix
55
+
56
+ for shortcut in layout_shortcuts.shortcuts:
57
+ # Find the feature to get the command
58
+ command = self._find_command(manifest, shortcut.feature_id)
59
+ if not command:
60
+ continue
61
+
62
+ bindings.append(
63
+ {
64
+ "key": f"{prefix} {shortcut.key}",
65
+ "mac": f"{prefix.replace('ctrl', 'cmd')} {shortcut.key}",
66
+ "command": command,
67
+ "// mnemonic": shortcut.mnemonic,
68
+ },
69
+ )
70
+
71
+ return bindings
72
+
73
+ def _find_command(self, manifest: FeatureManifest, feature_id: str) -> str | None:
74
+ """Find command for a feature ID."""
75
+ for feature in manifest.all_features():
76
+ if feature.id == feature_id:
77
+ return feature.command
78
+ return None
79
+
80
+
81
+ class CLIAliasGenerator:
82
+ """Generate shell alias scripts for CLI commands."""
83
+
84
+ BASH_HEADER = """#!/bin/bash
85
+ # Keyboard Conductor CLI Aliases for {project_name}
86
+ # Generated by Empathy Framework
87
+ #
88
+ # Add to your .bashrc or .zshrc:
89
+ # source {output_file}
90
+ #
91
+ # Mnemonic: {mnemonic}
92
+
93
+ """
94
+
95
+ def generate(
96
+ self,
97
+ shortcuts: GeneratedShortcuts,
98
+ output_file: Path,
99
+ ) -> Path:
100
+ """Generate a shell alias script."""
101
+ output_file.parent.mkdir(parents=True, exist_ok=True)
102
+
103
+ # Use QWERTY layout for CLI (most common)
104
+ layout_shortcuts = shortcuts.layouts.get(KeyboardLayout.QWERTY)
105
+ if not layout_shortcuts:
106
+ layout_shortcuts = next(iter(shortcuts.layouts.values()), None)
107
+
108
+ validated_output = _validate_file_path(str(output_file))
109
+ if not layout_shortcuts:
110
+ validated_output.write_text("# No shortcuts generated\n")
111
+ return validated_output
112
+
113
+ lines = [
114
+ self.BASH_HEADER.format(
115
+ project_name=shortcuts.manifest.project_name,
116
+ output_file=validated_output.name,
117
+ mnemonic=layout_shortcuts.phrase_mnemonic,
118
+ ),
119
+ ]
120
+
121
+ for shortcut in layout_shortcuts.shortcuts:
122
+ # Find the CLI alias for this feature
123
+ cli_alias = self._find_cli_alias(shortcuts.manifest, shortcut.feature_id)
124
+ if not cli_alias:
125
+ continue
126
+
127
+ # Create a short alias (e.g., "em" for empathy morning)
128
+ short_alias = f"e{shortcut.key}"
129
+ lines.append(f'alias {short_alias}="{cli_alias}" # {shortcut.mnemonic}')
130
+
131
+ validated_output.write_text("\n".join(lines))
132
+ return validated_output
133
+
134
+ def _find_cli_alias(self, manifest: FeatureManifest, feature_id: str) -> str | None:
135
+ """Find CLI alias for a feature ID."""
136
+ for feature in manifest.all_features():
137
+ if feature.id == feature_id and feature.cli_alias:
138
+ return feature.cli_alias
139
+ return None
140
+
141
+
142
+ class MarkdownDocGenerator:
143
+ """Generate Markdown documentation with keyboard cheatsheets."""
144
+
145
+ TEMPLATE = """# {project_name} Keyboard Shortcuts
146
+
147
+ > {phrase_mnemonic}
148
+
149
+ ## Quick Reference
150
+
151
+ Hold **{prefix}** (Mac: **{mac_prefix}**) then press one key:
152
+
153
+ {cheatsheet}
154
+
155
+ ## Keyboard Layout
156
+
157
+ ```
158
+ {keyboard_diagram}
159
+ ```
160
+
161
+ ## Scales (Learning Progression)
162
+
163
+ {scales_section}
164
+
165
+ ## All Shortcuts
166
+
167
+ {full_table}
168
+
169
+ ---
170
+
171
+ *Generated by [Empathy Framework](https://github.com/Smart-AI-Memory/empathy-framework) Keyboard Conductor*
172
+ """
173
+
174
+ KEYBOARD_DIAGRAM = """
175
+ ┌─────────────────────────────────────┐
176
+ │ [Q][W][E][R][T][Y][U][I][O][P] │
177
+ │ [{a}][{s}][{d}][{f}][G][H][J][K][L] │
178
+ │ [{z}][X][{c}][{v}][{b}][N][M] │
179
+ └─────────────────────────────────────┘
180
+ """
181
+
182
+ def generate(
183
+ self,
184
+ shortcuts: GeneratedShortcuts,
185
+ output_file: Path,
186
+ ) -> Path:
187
+ """Generate Markdown documentation."""
188
+ output_file.parent.mkdir(parents=True, exist_ok=True)
189
+
190
+ # Use QWERTY layout as default for docs
191
+ layout_shortcuts = shortcuts.layouts.get(KeyboardLayout.QWERTY)
192
+ if not layout_shortcuts:
193
+ layout_shortcuts = next(iter(shortcuts.layouts.values()), None)
194
+
195
+ validated_output = _validate_file_path(str(output_file))
196
+ if not layout_shortcuts:
197
+ validated_output.write_text("# No shortcuts generated\n")
198
+ return validated_output
199
+
200
+ manifest = shortcuts.manifest
201
+ prefix = manifest.prefix
202
+ mac_prefix = prefix.replace("ctrl", "cmd")
203
+
204
+ content = self.TEMPLATE.format(
205
+ project_name=manifest.project_name,
206
+ phrase_mnemonic=layout_shortcuts.phrase_mnemonic,
207
+ prefix=prefix,
208
+ mac_prefix=mac_prefix,
209
+ cheatsheet=self._generate_cheatsheet(manifest, layout_shortcuts),
210
+ keyboard_diagram=self._generate_keyboard_diagram(layout_shortcuts),
211
+ scales_section=self._generate_scales_section(manifest, layout_shortcuts),
212
+ full_table=self._generate_full_table(manifest, layout_shortcuts),
213
+ )
214
+
215
+ validated_output.write_text(content)
216
+ return validated_output
217
+
218
+ def _generate_cheatsheet(
219
+ self,
220
+ manifest: FeatureManifest,
221
+ layout_shortcuts: LayoutShortcuts,
222
+ ) -> str:
223
+ """Generate quick reference cheatsheet."""
224
+ lines = []
225
+
226
+ # Group by scale
227
+ scales = layout_shortcuts.scale_assignments
228
+ scale_features = {
229
+ "Daily (Start Here)": scales.daily,
230
+ "Frequent": scales.frequent,
231
+ "Advanced": scales.advanced,
232
+ }
233
+
234
+ for scale_name, keys in scale_features.items():
235
+ if not keys:
236
+ continue
237
+
238
+ lines.append(f"### {scale_name}")
239
+ for key in keys:
240
+ shortcut = self._find_shortcut_by_key(layout_shortcuts, key)
241
+ if shortcut:
242
+ feature = self._find_feature(manifest, shortcut.feature_id)
243
+ name = feature.name if feature else shortcut.feature_id
244
+ lines.append(f"- **{key.upper()}** = {name}")
245
+ lines.append("")
246
+
247
+ return "\n".join(lines)
248
+
249
+ def _generate_keyboard_diagram(self, layout_shortcuts: LayoutShortcuts) -> str:
250
+ """Generate ASCII keyboard diagram highlighting active keys."""
251
+ # Map of positions to highlight
252
+ key_positions = {}
253
+ for shortcut in layout_shortcuts.shortcuts:
254
+ key_positions[shortcut.key.lower()] = shortcut.key.upper()
255
+
256
+ # Create the diagram with highlights
257
+ diagram = self.KEYBOARD_DIAGRAM
258
+
259
+ # Replace placeholders with actual keys or defaults
260
+ replacements = {
261
+ "a": key_positions.get("a", "A"),
262
+ "s": key_positions.get("s", "S"),
263
+ "d": key_positions.get("d", "D"),
264
+ "f": key_positions.get("f", "F"),
265
+ "z": key_positions.get("z", "Z"),
266
+ "c": key_positions.get("c", "C"),
267
+ "v": key_positions.get("v", "V"),
268
+ "b": key_positions.get("b", "B"),
269
+ }
270
+
271
+ for placeholder, value in replacements.items():
272
+ diagram = diagram.replace(f"{{{placeholder}}}", value)
273
+
274
+ return diagram
275
+
276
+ def _generate_scales_section(
277
+ self,
278
+ manifest: FeatureManifest,
279
+ layout_shortcuts: LayoutShortcuts,
280
+ ) -> str:
281
+ """Generate learning progression section."""
282
+ lines = []
283
+ scales = layout_shortcuts.scale_assignments
284
+
285
+ lines.append("### Scale 1: The Basics (4 notes)")
286
+ lines.append("```")
287
+ for key in scales.daily:
288
+ shortcut = self._find_shortcut_by_key(layout_shortcuts, key)
289
+ if shortcut:
290
+ feature = self._find_feature(manifest, shortcut.feature_id)
291
+ name = feature.name if feature else shortcut.feature_id
292
+ lines.append(f"{key.upper()} = {name}")
293
+ lines.append("```")
294
+ lines.append("")
295
+
296
+ lines.append("### Scale 2: The Workflows (add 4 more)")
297
+ lines.append("```")
298
+ for key in scales.frequent:
299
+ shortcut = self._find_shortcut_by_key(layout_shortcuts, key)
300
+ if shortcut:
301
+ feature = self._find_feature(manifest, shortcut.feature_id)
302
+ name = feature.name if feature else shortcut.feature_id
303
+ lines.append(f"{key.upper()} = {name}")
304
+ lines.append("```")
305
+ lines.append("")
306
+
307
+ lines.append("### Scale 3: Full Orchestra (power users)")
308
+ lines.append("```")
309
+ for key in scales.advanced:
310
+ shortcut = self._find_shortcut_by_key(layout_shortcuts, key)
311
+ if shortcut:
312
+ feature = self._find_feature(manifest, shortcut.feature_id)
313
+ name = feature.name if feature else shortcut.feature_id
314
+ lines.append(f"{key.upper()} = {name}")
315
+ lines.append("```")
316
+
317
+ return "\n".join(lines)
318
+
319
+ def _generate_full_table(
320
+ self,
321
+ manifest: FeatureManifest,
322
+ layout_shortcuts: LayoutShortcuts,
323
+ ) -> str:
324
+ """Generate full table of all shortcuts."""
325
+ lines = [
326
+ "| Key | Command | Mnemonic |",
327
+ "|-----|---------|----------|",
328
+ ]
329
+
330
+ for shortcut in layout_shortcuts.shortcuts:
331
+ feature = self._find_feature(manifest, shortcut.feature_id)
332
+ name = feature.name if feature else shortcut.feature_id
333
+ lines.append(f"| {shortcut.key.upper()} | {name} | {shortcut.mnemonic} |")
334
+
335
+ return "\n".join(lines)
336
+
337
+ def _find_shortcut_by_key(
338
+ self,
339
+ layout_shortcuts: LayoutShortcuts,
340
+ key: str,
341
+ ) -> ShortcutAssignment | None:
342
+ """Find shortcut by key."""
343
+ for shortcut in layout_shortcuts.shortcuts:
344
+ if shortcut.key.lower() == key.lower():
345
+ return shortcut
346
+ return None
347
+
348
+ def _find_feature(self, manifest: FeatureManifest, feature_id: str):
349
+ """Find feature by ID."""
350
+ for feature in manifest.all_features():
351
+ if feature.id == feature_id:
352
+ return feature
353
+ return None
354
+
355
+
356
+ class ComprehensiveGenerator:
357
+ """Generate all output formats at once."""
358
+
359
+ def __init__(self):
360
+ self.vscode_gen = VSCodeKeybindingsGenerator()
361
+ self.cli_gen = CLIAliasGenerator()
362
+ self.markdown_gen = MarkdownDocGenerator()
363
+
364
+ def generate_all(
365
+ self,
366
+ shortcuts: GeneratedShortcuts,
367
+ output_dir: Path,
368
+ ) -> dict[str, Path]:
369
+ """Generate all output formats.
370
+
371
+ Returns dict of format -> output path(s).
372
+ """
373
+ output_dir.mkdir(parents=True, exist_ok=True)
374
+ generated = {}
375
+
376
+ # VSCode keybindings (one per layout)
377
+ keybindings_dir = output_dir / "keybindings"
378
+ vscode_files = self.vscode_gen.generate(shortcuts, keybindings_dir)
379
+ generated["vscode"] = vscode_files
380
+
381
+ # CLI aliases
382
+ aliases_file = output_dir / "aliases.sh"
383
+ self.cli_gen.generate(shortcuts, aliases_file)
384
+ generated["cli"] = aliases_file
385
+
386
+ # Markdown documentation
387
+ docs_file = output_dir / "KEYBOARD_SHORTCUTS.md"
388
+ self.markdown_gen.generate(shortcuts, docs_file)
389
+ generated["docs"] = docs_file
390
+
391
+ return generated