devsper 2.1.6__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 (375) hide show
  1. devsper/__init__.py +14 -0
  2. devsper/agents/a2a/__init__.py +27 -0
  3. devsper/agents/a2a/client.py +126 -0
  4. devsper/agents/a2a/discovery.py +24 -0
  5. devsper/agents/a2a/server.py +128 -0
  6. devsper/agents/a2a/tool_adapter.py +68 -0
  7. devsper/agents/a2a/types.py +49 -0
  8. devsper/agents/agent.py +602 -0
  9. devsper/agents/critic.py +80 -0
  10. devsper/agents/message_bus.py +124 -0
  11. devsper/agents/roles.py +181 -0
  12. devsper/agents/run_agent.py +78 -0
  13. devsper/analytics/__init__.py +5 -0
  14. devsper/analytics/tool_analytics.py +78 -0
  15. devsper/audit/__init__.py +5 -0
  16. devsper/audit/logger.py +214 -0
  17. devsper/bus/__init__.py +29 -0
  18. devsper/bus/backends/__init__.py +5 -0
  19. devsper/bus/backends/base.py +38 -0
  20. devsper/bus/backends/memory.py +55 -0
  21. devsper/bus/backends/redis.py +146 -0
  22. devsper/bus/message.py +56 -0
  23. devsper/bus/schema_version.py +3 -0
  24. devsper/bus/topics.py +19 -0
  25. devsper/cache/__init__.py +6 -0
  26. devsper/cache/embedding_index.py +98 -0
  27. devsper/cache/hashing.py +24 -0
  28. devsper/cache/store.py +153 -0
  29. devsper/cache/task_cache.py +191 -0
  30. devsper/cli/__init__.py +6 -0
  31. devsper/cli/commands/reg.py +733 -0
  32. devsper/cli/github_oauth.py +157 -0
  33. devsper/cli/init.py +637 -0
  34. devsper/cli/main.py +2956 -0
  35. devsper/cli/run_progress.py +103 -0
  36. devsper/cli/ui/__init__.py +65 -0
  37. devsper/cli/ui/components.py +94 -0
  38. devsper/cli/ui/errors.py +104 -0
  39. devsper/cli/ui/logging.py +120 -0
  40. devsper/cli/ui/onboarding.py +102 -0
  41. devsper/cli/ui/progress.py +43 -0
  42. devsper/cli/ui/run_view.py +308 -0
  43. devsper/cli/ui/theme.py +40 -0
  44. devsper/cluster/__init__.py +29 -0
  45. devsper/cluster/election.py +84 -0
  46. devsper/cluster/local.py +97 -0
  47. devsper/cluster/node_info.py +77 -0
  48. devsper/cluster/registry.py +71 -0
  49. devsper/cluster/router.py +117 -0
  50. devsper/cluster/state_backend.py +105 -0
  51. devsper/compliance/__init__.py +5 -0
  52. devsper/compliance/pii.py +147 -0
  53. devsper/config/__init__.py +52 -0
  54. devsper/config/config_loader.py +121 -0
  55. devsper/config/defaults.py +77 -0
  56. devsper/config/resolver.py +342 -0
  57. devsper/config/schema.py +237 -0
  58. devsper/credentials/__init__.py +19 -0
  59. devsper/credentials/cli.py +197 -0
  60. devsper/credentials/migration.py +124 -0
  61. devsper/credentials/store.py +142 -0
  62. devsper/dashboard/__init__.py +9 -0
  63. devsper/dashboard/dashboard.py +87 -0
  64. devsper/dev/__init__.py +25 -0
  65. devsper/dev/builder.py +195 -0
  66. devsper/dev/debugger.py +95 -0
  67. devsper/dev/repo_index.py +138 -0
  68. devsper/dev/sandbox.py +203 -0
  69. devsper/dev/scaffold.py +122 -0
  70. devsper/embeddings/__init__.py +5 -0
  71. devsper/embeddings/service.py +36 -0
  72. devsper/explainability/__init__.py +14 -0
  73. devsper/explainability/decision_tree.py +104 -0
  74. devsper/explainability/rationale.py +38 -0
  75. devsper/explainability/simulation.py +56 -0
  76. devsper/hitl/__init__.py +13 -0
  77. devsper/hitl/approval.py +160 -0
  78. devsper/hitl/escalation.py +95 -0
  79. devsper/intelligence/__init__.py +9 -0
  80. devsper/intelligence/adaptation.py +88 -0
  81. devsper/intelligence/analysis/__init__.py +19 -0
  82. devsper/intelligence/analysis/analyzer.py +71 -0
  83. devsper/intelligence/analysis/cost_estimator.py +66 -0
  84. devsper/intelligence/analysis/formatter.py +103 -0
  85. devsper/intelligence/analysis/run_report.py +402 -0
  86. devsper/intelligence/learning_engine.py +92 -0
  87. devsper/intelligence/strategies/__init__.py +23 -0
  88. devsper/intelligence/strategies/base.py +14 -0
  89. devsper/intelligence/strategies/code_analysis_strategy.py +33 -0
  90. devsper/intelligence/strategies/data_science_strategy.py +33 -0
  91. devsper/intelligence/strategies/document_pipeline_strategy.py +33 -0
  92. devsper/intelligence/strategies/experiment_strategy.py +33 -0
  93. devsper/intelligence/strategies/research_strategy.py +34 -0
  94. devsper/intelligence/strategy_selector.py +84 -0
  95. devsper/intelligence/synthesis.py +132 -0
  96. devsper/intelligence/task_optimizer.py +92 -0
  97. devsper/knowledge/__init__.py +5 -0
  98. devsper/knowledge/extractor.py +204 -0
  99. devsper/knowledge/knowledge_graph.py +184 -0
  100. devsper/knowledge/query.py +285 -0
  101. devsper/memory/__init__.py +35 -0
  102. devsper/memory/consolidation.py +138 -0
  103. devsper/memory/embeddings.py +60 -0
  104. devsper/memory/memory_index.py +97 -0
  105. devsper/memory/memory_router.py +62 -0
  106. devsper/memory/memory_store.py +221 -0
  107. devsper/memory/memory_types.py +54 -0
  108. devsper/memory/namespaces.py +45 -0
  109. devsper/memory/scoring.py +77 -0
  110. devsper/memory/summarizer.py +52 -0
  111. devsper/nodes/__init__.py +5 -0
  112. devsper/nodes/controller.py +449 -0
  113. devsper/nodes/rpc.py +127 -0
  114. devsper/nodes/single.py +161 -0
  115. devsper/nodes/worker.py +506 -0
  116. devsper/orchestration/__init__.py +19 -0
  117. devsper/orchestration/meta_planner.py +239 -0
  118. devsper/orchestration/priority_queue.py +61 -0
  119. devsper/plugins/__init__.py +19 -0
  120. devsper/plugins/marketplace/__init__.py +0 -0
  121. devsper/plugins/plugin_loader.py +70 -0
  122. devsper/plugins/plugin_registry.py +34 -0
  123. devsper/plugins/registry.py +83 -0
  124. devsper/protocols/__init__.py +6 -0
  125. devsper/providers/__init__.py +17 -0
  126. devsper/providers/anthropic.py +84 -0
  127. devsper/providers/base.py +75 -0
  128. devsper/providers/complexity_router.py +94 -0
  129. devsper/providers/gemini.py +36 -0
  130. devsper/providers/github.py +180 -0
  131. devsper/providers/model_router.py +40 -0
  132. devsper/providers/openai.py +105 -0
  133. devsper/providers/router/__init__.py +21 -0
  134. devsper/providers/router/backends/__init__.py +19 -0
  135. devsper/providers/router/backends/anthropic_backend.py +111 -0
  136. devsper/providers/router/backends/custom_backend.py +138 -0
  137. devsper/providers/router/backends/gemini_backend.py +89 -0
  138. devsper/providers/router/backends/github_backend.py +165 -0
  139. devsper/providers/router/backends/ollama_backend.py +104 -0
  140. devsper/providers/router/backends/openai_backend.py +142 -0
  141. devsper/providers/router/backends/vllm_backend.py +35 -0
  142. devsper/providers/router/base.py +60 -0
  143. devsper/providers/router/factory.py +92 -0
  144. devsper/providers/router/legacy.py +101 -0
  145. devsper/providers/router/router.py +135 -0
  146. devsper/reasoning/__init__.py +12 -0
  147. devsper/reasoning/graph.py +59 -0
  148. devsper/reasoning/nodes.py +20 -0
  149. devsper/reasoning/store.py +67 -0
  150. devsper/runtime/__init__.py +12 -0
  151. devsper/runtime/health.py +88 -0
  152. devsper/runtime/replay.py +53 -0
  153. devsper/runtime/replay_engine.py +142 -0
  154. devsper/runtime/run_history.py +204 -0
  155. devsper/runtime/telemetry.py +116 -0
  156. devsper/runtime/visualize.py +58 -0
  157. devsper/sandbox/__init__.py +13 -0
  158. devsper/sandbox/sandbox.py +161 -0
  159. devsper/swarm/checkpointer.py +65 -0
  160. devsper/swarm/executor.py +558 -0
  161. devsper/swarm/map_reduce.py +44 -0
  162. devsper/swarm/planner.py +197 -0
  163. devsper/swarm/prefetcher.py +91 -0
  164. devsper/swarm/scheduler.py +153 -0
  165. devsper/swarm/speculation.py +47 -0
  166. devsper/swarm/swarm.py +562 -0
  167. devsper/tools/__init__.py +33 -0
  168. devsper/tools/base.py +29 -0
  169. devsper/tools/code_intelligence/__init__.py +13 -0
  170. devsper/tools/code_intelligence/api_surface_extractor.py +73 -0
  171. devsper/tools/code_intelligence/architecture_analyzer.py +65 -0
  172. devsper/tools/code_intelligence/codebase_indexer.py +71 -0
  173. devsper/tools/code_intelligence/dependency_graph_builder.py +67 -0
  174. devsper/tools/code_intelligence/design_pattern_detector.py +62 -0
  175. devsper/tools/code_intelligence/large_function_detector.py +68 -0
  176. devsper/tools/code_intelligence/module_responsibility_mapper.py +56 -0
  177. devsper/tools/code_intelligence/parallel_codebase_analysis.py +44 -0
  178. devsper/tools/code_intelligence/refactor_candidate_detector.py +81 -0
  179. devsper/tools/code_intelligence/repository_semantic_index.py +61 -0
  180. devsper/tools/code_intelligence/test_coverage_estimator.py +62 -0
  181. devsper/tools/coding/__init__.py +12 -0
  182. devsper/tools/coding/analyze_code_complexity.py +48 -0
  183. devsper/tools/coding/dependency_analyzer.py +42 -0
  184. devsper/tools/coding/extract_functions.py +38 -0
  185. devsper/tools/coding/format_python.py +50 -0
  186. devsper/tools/coding/generate_docstrings.py +40 -0
  187. devsper/tools/coding/generate_unit_tests.py +42 -0
  188. devsper/tools/coding/lint_python.py +51 -0
  189. devsper/tools/coding/refactor_function.py +41 -0
  190. devsper/tools/coding/repo_structure_map.py +54 -0
  191. devsper/tools/coding/run_python.py +53 -0
  192. devsper/tools/data/__init__.py +12 -0
  193. devsper/tools/data/column_type_detection.py +64 -0
  194. devsper/tools/data/csv_summary.py +52 -0
  195. devsper/tools/data/dataframe_filter.py +51 -0
  196. devsper/tools/data/dataframe_groupby.py +47 -0
  197. devsper/tools/data/dataframe_stats.py +38 -0
  198. devsper/tools/data/dataset_sampling.py +55 -0
  199. devsper/tools/data/dataset_schema.py +45 -0
  200. devsper/tools/data/json_pretty_print.py +37 -0
  201. devsper/tools/data/json_query.py +46 -0
  202. devsper/tools/data/missing_value_report.py +47 -0
  203. devsper/tools/data_science/__init__.py +13 -0
  204. devsper/tools/data_science/correlation_heatmap.py +72 -0
  205. devsper/tools/data_science/dataset_bias_detector.py +49 -0
  206. devsper/tools/data_science/dataset_distribution_report.py +64 -0
  207. devsper/tools/data_science/dataset_drift_detector.py +64 -0
  208. devsper/tools/data_science/dataset_outlier_detector.py +65 -0
  209. devsper/tools/data_science/dataset_profile.py +76 -0
  210. devsper/tools/data_science/distributed_dataset_processor.py +54 -0
  211. devsper/tools/data_science/feature_engineering_suggestions.py +69 -0
  212. devsper/tools/data_science/feature_importance_estimator.py +82 -0
  213. devsper/tools/data_science/model_input_validator.py +59 -0
  214. devsper/tools/data_science/time_series_analyzer.py +57 -0
  215. devsper/tools/documents/__init__.py +11 -0
  216. devsper/tools/documents/_docproc.py +56 -0
  217. devsper/tools/documents/document_to_markdown.py +29 -0
  218. devsper/tools/documents/extract_document_images.py +39 -0
  219. devsper/tools/documents/extract_document_text.py +29 -0
  220. devsper/tools/documents/extract_equations.py +36 -0
  221. devsper/tools/documents/extract_tables.py +47 -0
  222. devsper/tools/documents/summarize_document.py +42 -0
  223. devsper/tools/documents/write_latex_document.py +133 -0
  224. devsper/tools/documents/write_markdown_document.py +89 -0
  225. devsper/tools/documents/write_word_document.py +149 -0
  226. devsper/tools/experiments/__init__.py +13 -0
  227. devsper/tools/experiments/bootstrap_estimator.py +54 -0
  228. devsper/tools/experiments/experiment_report_generator.py +50 -0
  229. devsper/tools/experiments/experiment_tracker.py +36 -0
  230. devsper/tools/experiments/grid_search_runner.py +50 -0
  231. devsper/tools/experiments/model_benchmark_runner.py +45 -0
  232. devsper/tools/experiments/monte_carlo_experiment.py +38 -0
  233. devsper/tools/experiments/parameter_sweep_runner.py +51 -0
  234. devsper/tools/experiments/result_comparator.py +58 -0
  235. devsper/tools/experiments/simulation_runner.py +43 -0
  236. devsper/tools/experiments/statistical_significance_test.py +56 -0
  237. devsper/tools/experiments/swarm_map_reduce.py +42 -0
  238. devsper/tools/filesystem/__init__.py +12 -0
  239. devsper/tools/filesystem/append_file.py +42 -0
  240. devsper/tools/filesystem/file_hash.py +40 -0
  241. devsper/tools/filesystem/file_line_count.py +36 -0
  242. devsper/tools/filesystem/file_metadata.py +38 -0
  243. devsper/tools/filesystem/file_preview.py +55 -0
  244. devsper/tools/filesystem/find_large_files.py +50 -0
  245. devsper/tools/filesystem/list_directory.py +39 -0
  246. devsper/tools/filesystem/read_file.py +35 -0
  247. devsper/tools/filesystem/search_files.py +60 -0
  248. devsper/tools/filesystem/write_file.py +41 -0
  249. devsper/tools/flagship/__init__.py +15 -0
  250. devsper/tools/flagship/distributed_document_analysis.py +77 -0
  251. devsper/tools/flagship/docproc_corpus_pipeline.py +91 -0
  252. devsper/tools/flagship/repository_semantic_map.py +99 -0
  253. devsper/tools/flagship/research_graph_builder.py +111 -0
  254. devsper/tools/flagship/swarm_experiment_runner.py +86 -0
  255. devsper/tools/knowledge/__init__.py +10 -0
  256. devsper/tools/knowledge/citation_graph_builder.py +69 -0
  257. devsper/tools/knowledge/concept_frequency_analyzer.py +74 -0
  258. devsper/tools/knowledge/corpus_builder.py +66 -0
  259. devsper/tools/knowledge/cross_document_entity_linker.py +71 -0
  260. devsper/tools/knowledge/document_corpus_summary.py +68 -0
  261. devsper/tools/knowledge/document_topic_extractor.py +58 -0
  262. devsper/tools/knowledge/knowledge_graph_extractor.py +58 -0
  263. devsper/tools/knowledge/timeline_extractor.py +59 -0
  264. devsper/tools/math/__init__.py +12 -0
  265. devsper/tools/math/calculate_expression.py +52 -0
  266. devsper/tools/math/correlation.py +44 -0
  267. devsper/tools/math/distribution_summary.py +39 -0
  268. devsper/tools/math/histogram.py +53 -0
  269. devsper/tools/math/linear_regression.py +47 -0
  270. devsper/tools/math/matrix_multiply.py +38 -0
  271. devsper/tools/math/mean_std.py +35 -0
  272. devsper/tools/math/monte_carlo_simulation.py +43 -0
  273. devsper/tools/math/polynomial_fit.py +40 -0
  274. devsper/tools/math/random_sample.py +36 -0
  275. devsper/tools/mcp/__init__.py +23 -0
  276. devsper/tools/mcp/adapter.py +53 -0
  277. devsper/tools/mcp/client.py +235 -0
  278. devsper/tools/mcp/discovery.py +53 -0
  279. devsper/tools/memory/__init__.py +16 -0
  280. devsper/tools/memory/delete_memory.py +25 -0
  281. devsper/tools/memory/list_memory.py +34 -0
  282. devsper/tools/memory/search_memory.py +36 -0
  283. devsper/tools/memory/store_memory.py +47 -0
  284. devsper/tools/memory/summarize_memory.py +41 -0
  285. devsper/tools/memory/tag_memory.py +47 -0
  286. devsper/tools/pipelines.py +92 -0
  287. devsper/tools/registry.py +39 -0
  288. devsper/tools/research/__init__.py +12 -0
  289. devsper/tools/research/arxiv_download.py +55 -0
  290. devsper/tools/research/arxiv_search.py +58 -0
  291. devsper/tools/research/citation_extractor.py +35 -0
  292. devsper/tools/research/duckduckgo_search.py +42 -0
  293. devsper/tools/research/paper_metadata_extractor.py +45 -0
  294. devsper/tools/research/paper_summarizer.py +41 -0
  295. devsper/tools/research/research_question_generator.py +39 -0
  296. devsper/tools/research/topic_cluster.py +46 -0
  297. devsper/tools/research/web_search.py +47 -0
  298. devsper/tools/research/wikipedia_lookup.py +50 -0
  299. devsper/tools/research_advanced/__init__.py +14 -0
  300. devsper/tools/research_advanced/citation_context_extractor.py +60 -0
  301. devsper/tools/research_advanced/literature_review_generator.py +79 -0
  302. devsper/tools/research_advanced/methodology_extractor.py +58 -0
  303. devsper/tools/research_advanced/paper_contribution_extractor.py +50 -0
  304. devsper/tools/research_advanced/paper_dataset_identifier.py +49 -0
  305. devsper/tools/research_advanced/paper_method_comparator.py +62 -0
  306. devsper/tools/research_advanced/paper_similarity_search.py +69 -0
  307. devsper/tools/research_advanced/paper_trend_analyzer.py +69 -0
  308. devsper/tools/research_advanced/parallel_document_analyzer.py +56 -0
  309. devsper/tools/research_advanced/research_gap_finder.py +71 -0
  310. devsper/tools/research_advanced/research_topic_mapper.py +69 -0
  311. devsper/tools/research_advanced/swarm_literature_review.py +58 -0
  312. devsper/tools/scoring/__init__.py +52 -0
  313. devsper/tools/scoring/report.py +44 -0
  314. devsper/tools/scoring/scorer.py +39 -0
  315. devsper/tools/scoring/selector.py +61 -0
  316. devsper/tools/scoring/store.py +267 -0
  317. devsper/tools/selector.py +130 -0
  318. devsper/tools/system/__init__.py +12 -0
  319. devsper/tools/system/cpu_usage.py +22 -0
  320. devsper/tools/system/disk_usage.py +35 -0
  321. devsper/tools/system/environment_variables.py +29 -0
  322. devsper/tools/system/memory_usage.py +23 -0
  323. devsper/tools/system/pip_install.py +44 -0
  324. devsper/tools/system/pip_search.py +29 -0
  325. devsper/tools/system/process_list.py +34 -0
  326. devsper/tools/system/python_package_list.py +40 -0
  327. devsper/tools/system/run_shell_command.py +51 -0
  328. devsper/tools/system/system_info.py +26 -0
  329. devsper/tools/tool_runner.py +122 -0
  330. devsper/tui/__init__.py +5 -0
  331. devsper/tui/activity_feed_view.py +73 -0
  332. devsper/tui/adaptive_tasks_view.py +75 -0
  333. devsper/tui/agent_role_view.py +35 -0
  334. devsper/tui/app.py +395 -0
  335. devsper/tui/dashboard_screen.py +290 -0
  336. devsper/tui/dev_view.py +99 -0
  337. devsper/tui/inject_screen.py +73 -0
  338. devsper/tui/knowledge_graph_view.py +46 -0
  339. devsper/tui/layout.py +43 -0
  340. devsper/tui/logs_view.py +83 -0
  341. devsper/tui/memory_view.py +58 -0
  342. devsper/tui/performance_view.py +33 -0
  343. devsper/tui/reasoning_graph_view.py +39 -0
  344. devsper/tui/results_view.py +139 -0
  345. devsper/tui/swarm_view.py +37 -0
  346. devsper/tui/task_detail_screen.py +55 -0
  347. devsper/tui/task_view.py +103 -0
  348. devsper/types/event.py +97 -0
  349. devsper/types/exceptions.py +21 -0
  350. devsper/types/swarm.py +41 -0
  351. devsper/types/task.py +80 -0
  352. devsper/upgrade/__init__.py +21 -0
  353. devsper/upgrade/changelog.py +124 -0
  354. devsper/upgrade/cli.py +145 -0
  355. devsper/upgrade/installer.py +103 -0
  356. devsper/upgrade/notifier.py +52 -0
  357. devsper/upgrade/version_check.py +121 -0
  358. devsper/utils/event_logger.py +88 -0
  359. devsper/utils/http.py +43 -0
  360. devsper/utils/models.py +54 -0
  361. devsper/visualization/__init__.py +5 -0
  362. devsper/visualization/dag_export.py +67 -0
  363. devsper/workflow/__init__.py +18 -0
  364. devsper/workflow/conditions.py +157 -0
  365. devsper/workflow/context.py +108 -0
  366. devsper/workflow/loader.py +156 -0
  367. devsper/workflow/resolver.py +109 -0
  368. devsper/workflow/runner.py +562 -0
  369. devsper/workflow/schema.py +63 -0
  370. devsper/workflow/validator.py +128 -0
  371. devsper-2.1.6.dist-info/METADATA +346 -0
  372. devsper-2.1.6.dist-info/RECORD +375 -0
  373. devsper-2.1.6.dist-info/WHEEL +4 -0
  374. devsper-2.1.6.dist-info/entry_points.txt +3 -0
  375. devsper-2.1.6.dist-info/licenses/LICENSE +639 -0
@@ -0,0 +1,103 @@
1
+ """
2
+ CLI run progress: read event log and return status line + parallel task info for live feedback.
3
+ """
4
+
5
+ import os
6
+
7
+
8
+ def read_run_status(
9
+ log_path: str | None,
10
+ worker_count: int = 0,
11
+ ) -> tuple[str, list[str]]:
12
+ """
13
+ Read event log and return (status_message, running_task_ids).
14
+ running_task_ids are task ids that have task_started but not yet task_completed.
15
+ worker_count: if > 0, show "up to N in parallel" in executor messages.
16
+ """
17
+ if not log_path or not os.path.isfile(log_path):
18
+ return "Starting…", []
19
+
20
+ events = []
21
+ try:
22
+ from devsper.types.event import Event
23
+
24
+ with open(log_path, "r") as f:
25
+ for line in f:
26
+ line = line.strip()
27
+ if not line:
28
+ continue
29
+ try:
30
+ events.append(Event.model_validate_json(line))
31
+ except Exception:
32
+ continue
33
+ except Exception:
34
+ return "Running…", []
35
+
36
+ if not events:
37
+ return "Starting…", []
38
+
39
+ # task_id -> description
40
+ task_descriptions: dict[str, str] = {}
41
+ # track which tasks have started and which have completed
42
+ started: set[str] = set()
43
+ completed: set[str] = set()
44
+
45
+ for e in events:
46
+ payload = e.payload or {}
47
+ tid = (payload.get("task_id") or "").strip()
48
+ ev = getattr(e.type, "value", str(e.type))
49
+
50
+ if ev == "task_created" and tid:
51
+ task_descriptions[tid] = (payload.get("description") or "").strip()
52
+ elif ev in ("task_started", "agent_started") and tid:
53
+ started.add(tid)
54
+ elif ev in ("task_completed", "task_failed", "agent_finished") and tid:
55
+ completed.add(tid)
56
+
57
+ running_ids = sorted(started - completed)
58
+ total_tasks = len(task_descriptions)
59
+ completed_count = len(completed)
60
+
61
+ def _truncate(s: str, max_len: int = 52) -> str:
62
+ s = (s or "").strip()
63
+ if len(s) <= max_len:
64
+ return s
65
+ return s[: max_len - 1].rstrip() + "…"
66
+
67
+ last = events[-1]
68
+ ev_type = getattr(last.type, "value", str(last.type))
69
+ payload = last.payload or {}
70
+ task_id = (payload.get("task_id") or "").strip()
71
+ desc = task_descriptions.get(task_id)
72
+
73
+ if ev_type == "swarm_started":
74
+ return "Planning your request…", []
75
+ if ev_type == "planner_started":
76
+ return "Planning your request…", []
77
+ if ev_type == "task_created":
78
+ return f"Planned {total_tasks} task(s). Starting…", []
79
+ if ev_type == "planner_finished":
80
+ n = payload.get("subtask_count", total_tasks) or total_tasks
81
+ tail = f", up to {worker_count} in parallel" if worker_count > 1 else ""
82
+ return f"Executing {n} step(s){tail}…", []
83
+ if ev_type == "executor_started":
84
+ if total_tasks:
85
+ tail = f" (up to {worker_count} in parallel)" if worker_count > 1 else ""
86
+ return f"Executing step 1 of {total_tasks}…{tail}", []
87
+ return "Executing…", []
88
+ if ev_type in ("agent_started", "task_started"):
89
+ step_label = f"Step {completed_count + 1} of {total_tasks}: " if total_tasks else ""
90
+ part = (step_label + _truncate(desc)) if desc else (step_label or "Working on task…")
91
+ if len(running_ids) > 1:
92
+ part += f" [parallel: {len(running_ids)} tasks]"
93
+ return part.rstrip(": ") or "Working…", running_ids
94
+ if ev_type in ("task_completed", "agent_finished"):
95
+ if total_tasks and completed_count < total_tasks:
96
+ return f"Finished step {completed_count} of {total_tasks}. Next…", running_ids
97
+ return f"Finished step {completed_count} of {total_tasks}. Assembling…", running_ids
98
+ if ev_type == "executor_finished":
99
+ return "Assembling result…", []
100
+ if ev_type == "swarm_finished":
101
+ return "Done.", []
102
+
103
+ return "Running…", running_ids
@@ -0,0 +1,65 @@
1
+ """
2
+ CLI UI: theme, components, logging, progress, errors.
3
+ All CLI code imports from devsper.cli.ui, never from rich directly.
4
+ """
5
+
6
+ from devsper.cli.ui.theme import THEME, console, err_console, reconfigure_console
7
+ from devsper.cli.ui.components import (
8
+ CostDisplay,
9
+ ErrorPanel,
10
+ devsperHeader,
11
+ RoleTag,
12
+ SectionHeader,
13
+ StatusBadge,
14
+ TaskRow,
15
+ )
16
+ from devsper.cli.ui.errors import (
17
+ ConfigNotFoundError,
18
+ devsperError,
19
+ ModelNotFoundError,
20
+ NoWorkersError,
21
+ ProviderConnectionError,
22
+ RedisConnectionError,
23
+ print_error,
24
+ print_unexpected_error,
25
+ )
26
+ from devsper.cli.ui.logging import get_logger, set_log_level, get_log_level, devsperLogger
27
+ from devsper.cli.ui.progress import devsperProgress, progress_spinner_style
28
+ from devsper.cli.ui.run_view import RunViewState, run_live_view, print_run_summary
29
+
30
+ try:
31
+ from devsper.cli.ui.onboarding import run_init_wizard
32
+ except ImportError:
33
+ run_init_wizard = None # type: ignore[misc, assignment]
34
+
35
+ __all__ = [
36
+ "CostDisplay",
37
+ "ConfigNotFoundError",
38
+ "ErrorPanel",
39
+ "devsperError",
40
+ "devsperHeader",
41
+ "devsperLogger",
42
+ "devsperProgress",
43
+ "ModelNotFoundError",
44
+ "NoWorkersError",
45
+ "ProviderConnectionError",
46
+ "RedisConnectionError",
47
+ "RoleTag",
48
+ "SectionHeader",
49
+ "StatusBadge",
50
+ "TaskRow",
51
+ "THEME",
52
+ "console",
53
+ "err_console",
54
+ "get_logger",
55
+ "get_log_level",
56
+ "print_error",
57
+ "print_unexpected_error",
58
+ "print_run_summary",
59
+ "progress_spinner_style",
60
+ "reconfigure_console",
61
+ "run_live_view",
62
+ "RunViewState",
63
+ "run_init_wizard",
64
+ "set_log_level",
65
+ ]
@@ -0,0 +1,94 @@
1
+ """
2
+ Reusable Rich renderables for CLI. All CLI code imports from here, not rich directly.
3
+ """
4
+
5
+ from rich.panel import Panel
6
+ from rich.rule import Rule
7
+ from rich.table import Table
8
+ from rich.text import Text
9
+
10
+ from devsper.cli.ui.theme import console
11
+
12
+ # Status badge styles
13
+ BADGE_STYLES = {
14
+ "SUCCESS": "hive.success",
15
+ "FAILED": "hive.error",
16
+ "RUNNING": "hive.secondary",
17
+ "SKIPPED": "hive.muted",
18
+ "CACHED": "hive.primary",
19
+ "PENDING": "hive.dim",
20
+ }
21
+
22
+
23
+ def devsperHeader(
24
+ version: str = "",
25
+ model: str = "",
26
+ workers: int = 0,
27
+ ) -> Text:
28
+ """Single-line wordmark + version. Example: ⬡ devsper v2.1.5 · claude-sonnet-4 · 4 workers"""
29
+ parts = [Text("⬡ devsper", style="hive.primary")]
30
+ if version:
31
+ parts.append(Text(f" v{version}", style="hive.muted"))
32
+ if model:
33
+ parts.append(Text(f" · {model}", style="hive.muted"))
34
+ if workers:
35
+ parts.append(Text(f" · {workers} workers", style="hive.muted"))
36
+ out = Text()
37
+ for p in parts:
38
+ out.append_text(p)
39
+ return out
40
+
41
+
42
+ def StatusBadge(text: str, style: str | None = None) -> Text:
43
+ """Inline colored badge: [SUCCESS], [FAILED], [RUNNING], etc."""
44
+ key = text.upper().replace(" ", "_")
45
+ s = style or BADGE_STYLES.get(key, "hive.muted")
46
+ return Text(f"[{text}]", style=s)
47
+
48
+
49
+ def TaskRow(
50
+ short_id: str,
51
+ description: str,
52
+ role: str = "",
53
+ duration: str = "—",
54
+ status: str = "pending",
55
+ icon: str | None = None,
56
+ ) -> Text:
57
+ """Single-line task summary. status: pending|running|completed|failed|cached|skipped."""
58
+ if icon is None:
59
+ icon = {"pending": "○", "running": "◐", "completed": "✓", "failed": "✗", "cached": "⚡", "skipped": "⊘"}.get(status, "○")
60
+ style = {"completed": "hive.success", "failed": "hive.error", "cached": "hive.primary", "skipped": "hive.muted", "running": "hive.secondary", "pending": "hive.dim"}.get(status, "hive.dim")
61
+ desc = (description or "")[:45]
62
+ if len((description or "")) > 45:
63
+ desc = desc.rstrip() + "…"
64
+ role_part = f" {role}" if role else ""
65
+ return Text().append(icon + " ", style=style).append(short_id + " ", style="hive.secondary").append(desc, style="dim").append(role_part, style="hive.muted").append(" ", style="").append(duration, style="hive.muted")
66
+
67
+
68
+ def RoleTag(role: str) -> Text:
69
+ """Colored inline tag per role: research->blue, code->teal, analysis->purple, critic->orange, architect->amber."""
70
+ styles = {"research": "hive.secondary", "code": "hive.tool", "analysis": "hive.agent", "critic": "hive.planner", "architect": "hive.primary"}
71
+ s = styles.get((role or "").lower(), "hive.muted")
72
+ return Text(role or "—", style=s)
73
+
74
+
75
+ def CostDisplay(usd: float | None) -> Text:
76
+ """$0.0034 in pink, '—' in muted if None."""
77
+ if usd is None:
78
+ return Text("—", style="hive.muted")
79
+ return Text(f"${usd:.4f}", style="hive.cost")
80
+
81
+
82
+ def SectionHeader(title: str) -> Rule:
83
+ """Amber rule with title."""
84
+ return Rule(title, style="hive.primary", characters="─")
85
+
86
+
87
+ def ErrorPanel(message: str, hint: str | None = None, docs_url: str | None = None) -> Panel:
88
+ """Red-bordered panel, title 'Error'. No tracebacks to end users."""
89
+ body = message
90
+ if hint:
91
+ body += "\n\n" + f"Hint: {hint}"
92
+ if docs_url:
93
+ body += "\n" + f"Docs: {docs_url}"
94
+ return Panel(body, title="Error", border_style="hive.error")
@@ -0,0 +1,104 @@
1
+ """
2
+ Typed errors with actionable hints. No raw tracebacks shown to end users.
3
+ """
4
+
5
+ from devsper.cli.ui.theme import err_console
6
+ from devsper.cli.ui.components import ErrorPanel
7
+
8
+ DOCS_BASE = "https://docs.devsper.com"
9
+ REPO_ISSUES = "https://github.com/devsper-com/runtime/issues/new"
10
+
11
+
12
+ class devsperError(Exception):
13
+ """Base CLI error with message, hint, docs, exit code."""
14
+
15
+ def __init__(
16
+ self,
17
+ message: str,
18
+ hint: str | None = None,
19
+ docs_url: str | None = None,
20
+ exit_code: int = 1,
21
+ ) -> None:
22
+ super().__init__(message)
23
+ self.message = message
24
+ self.hint = hint
25
+ self.docs_url = docs_url
26
+ self.exit_code = exit_code
27
+
28
+
29
+ class ProviderConnectionError(devsperError):
30
+ def __init__(self, message: str, provider: str = "") -> None:
31
+ super().__init__(
32
+ message,
33
+ hint="Check your API key with: devsper credentials list",
34
+ docs_url=f"{DOCS_BASE}/providers" if provider else None,
35
+ )
36
+
37
+
38
+ class ConfigNotFoundError(devsperError):
39
+ def __init__(self, message: str = "No configuration found.") -> None:
40
+ super().__init__(message, hint="Run devsper init to create a configuration")
41
+
42
+
43
+ class RedisConnectionError(devsperError):
44
+ def __init__(self, message: str = "Cannot connect to Redis.") -> None:
45
+ super().__init__(
46
+ message,
47
+ hint="Start Redis with: docker run -p 6379:6379 redis:7-alpine",
48
+ )
49
+
50
+
51
+ class NoWorkersError(devsperError):
52
+ def __init__(self, message: str = "No workers available.") -> None:
53
+ super().__init__(message, hint="Start a worker with: devsper node start --role worker")
54
+
55
+
56
+ class ModelNotFoundError(devsperError):
57
+ def __init__(self, model_name: str) -> None:
58
+ super().__init__(
59
+ f"Model not found: {model_name}",
60
+ hint="Available models: devsper doctor | grep model",
61
+ )
62
+
63
+
64
+ def print_error(e: devsperError, json_output: bool = False) -> None:
65
+ """Print error to stderr. If json_output, print {\"error\", \"hint\", \"exit_code\"}."""
66
+ if json_output:
67
+ import json
68
+ err_console.print(json.dumps({
69
+ "error": e.message,
70
+ "hint": e.hint,
71
+ "docs_url": getattr(e, "docs_url", None),
72
+ "exit_code": e.exit_code,
73
+ }))
74
+ return
75
+ panel = ErrorPanel(e.message, hint=e.hint, docs_url=getattr(e, "docs_url", None))
76
+ err_console.print(panel)
77
+
78
+
79
+ def print_unexpected_error(exc: BaseException, json_output: bool = False) -> None:
80
+ """Condensed traceback (last 3 frames) + bug report hint."""
81
+ if json_output:
82
+ import json
83
+ err_console.print(json.dumps({
84
+ "error": str(exc),
85
+ "hint": "Unexpected error; see logs.",
86
+ "exit_code": 1,
87
+ }))
88
+ return
89
+ import traceback
90
+ tb_lines = traceback.format_exception(type(exc), exc, exc.__traceback__)
91
+ # Last 3 frames only
92
+ condensed = "".join(tb_lines[-3:]) if len(tb_lines) >= 3 else "".join(tb_lines)
93
+ from devsper.cli.ui.theme import THEME
94
+ from rich.panel import Panel
95
+ from rich.console import Console
96
+ c = Console(stderr=True, theme=THEME)
97
+ c.print(Panel(condensed.strip(), title="Traceback", border_style="hive.dim"))
98
+ c.print("\n[dim]This looks like a bug. Please report it:[/]")
99
+ c.print(f" [link={REPO_ISSUES}]{REPO_ISSUES}[/]")
100
+ try:
101
+ import devsper
102
+ c.print(f" devsper {getattr(devsper, '__version__', '?')} Python {__import__('sys').version.split()[0]} {__import__('platform').system()}")
103
+ except Exception:
104
+ pass
@@ -0,0 +1,120 @@
1
+ """
2
+ Structured logger matching tracing (Rust) compact format for visual consistency.
3
+ All subsystems use get_logger(target) instead of logging.getLogger().
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ from datetime import datetime, timezone
9
+ from typing import Any
10
+
11
+ # Log level: 0=TRACE, 1=DEBUG, 2=INFO, 3=WARN, 4=ERROR. Controlled by env/global.
12
+ _CLI_LOG_LEVEL = 2 # INFO default
13
+
14
+
15
+ def set_log_level(level: str | int) -> None:
16
+ """level: 'trace'|'debug'|'info'|'warn'|'error' or 0-4."""
17
+ global _CLI_LOG_LEVEL
18
+ if isinstance(level, int):
19
+ _CLI_LOG_LEVEL = level
20
+ return
21
+ _CLI_LOG_LEVEL = {"trace": 0, "debug": 1, "info": 2, "warn": 3, "warning": 3, "error": 4}.get((level or "").lower(), 2)
22
+
23
+
24
+ def get_log_level() -> int:
25
+ return _CLI_LOG_LEVEL
26
+
27
+
28
+ # Target -> style for the target column
29
+ TARGET_STYLES = {
30
+ "planner": "hive.planner",
31
+ "executor": "hive.secondary",
32
+ "agent": "hive.agent",
33
+ "tool": "hive.tool",
34
+ "memory": "hive.agent",
35
+ "scheduler": "hive.muted",
36
+ "bus": "hive.dim",
37
+ "swarm": "hive.primary",
38
+ "hitl": "hive.warning",
39
+ }
40
+
41
+
42
+ def _level_style(level: str) -> str:
43
+ if level == "WARN":
44
+ return "hive.warning"
45
+ if level == "ERROR":
46
+ return "hive.error"
47
+ if level == "DEBUG":
48
+ return "hive.muted"
49
+ if level == "TRACE":
50
+ return "hive.dim"
51
+ return ""
52
+
53
+
54
+ def _format_ts() -> str:
55
+ return datetime.now(timezone.utc).strftime("%H:%M:%S.") + f"{datetime.now().microsecond // 1000:03d}"
56
+
57
+
58
+ class devsperLogger:
59
+ """Logger that emits tracing-compatible compact lines: timestamp LEVEL target message key=val ..."""
60
+
61
+ def __init__(self, target: str, run_id_short: str = "") -> None:
62
+ self.target = target
63
+ self.run_id_short = (run_id_short or "")[:8]
64
+
65
+ def _emit(self, level: str, message: str, **fields: Any) -> None:
66
+ lvl_num = {"TRACE": 0, "DEBUG": 1, "INFO": 2, "WARN": 3, "ERROR": 4}.get(level, 2)
67
+ if lvl_num < _CLI_LOG_LEVEL:
68
+ return
69
+ ts = _format_ts()
70
+ target_style = TARGET_STYLES.get(self.target, "hive.muted")
71
+ level_style = _level_style(level)
72
+ parts: list[str] = [ts, " ", level, " ", self.target, " ", message]
73
+ if fields:
74
+ pairs = " ".join(f"{k}={v}" for k, v in fields.items())
75
+ parts.append(" ")
76
+ parts.append(pairs)
77
+ if self.run_id_short:
78
+ parts.append(" ")
79
+ parts.append(f"run_id={self.run_id_short}")
80
+ line = "".join(parts)
81
+ # Use Rich markup for colors when printing
82
+ try:
83
+ from devsper.cli.ui.theme import err_console
84
+ if level_style:
85
+ line = f"[{level_style}]{level}[/] [{target_style}]{self.target}[/] {message}"
86
+ if fields:
87
+ line += " " + " ".join(f"[hive.muted]{k}={v}[/]" for k, v in fields.items())
88
+ if self.run_id_short:
89
+ line += f" [hive.muted]run_id={self.run_id_short}[/]"
90
+ line = f"[hive.muted]{ts}[/] " + line
91
+ else:
92
+ line = f"[hive.muted]{ts}[/] {level} [{target_style}]{self.target}[/] {message}"
93
+ if fields:
94
+ line += " " + " ".join(f"[hive.muted]{k}={v}[/]" for k, v in fields.items())
95
+ if self.run_id_short:
96
+ line += f" [hive.muted]run_id={self.run_id_short}[/]"
97
+ err_console.print(line)
98
+ except Exception:
99
+ print(line, file=sys.stderr)
100
+
101
+ def trace(self, message: str, **fields: Any) -> None:
102
+ self._emit("TRACE", message, **fields)
103
+
104
+ def debug(self, message: str, **fields: Any) -> None:
105
+ self._emit("DEBUG", message, **fields)
106
+
107
+ def info(self, message: str, **fields: Any) -> None:
108
+ self._emit("INFO", message, **fields)
109
+
110
+ def warning(self, message: str, **fields: Any) -> None:
111
+ self._emit("WARN", message, **fields)
112
+
113
+ def error(self, message: str, **fields: Any) -> None:
114
+ self._emit("ERROR", message, **fields)
115
+
116
+
117
+ def get_logger(target: str, run_id: str = "") -> devsperLogger:
118
+ """Return logger bound to target name. run_id shortened to 8 chars in output."""
119
+ short = (run_id or "")[:8]
120
+ return devsperLogger(target, short)
@@ -0,0 +1,102 @@
1
+ """
2
+ Init wizard: welcome screen, provider setup, model selection, workers, features, write config.
3
+ Uses theme and components; --no-interactive writes minimal config and prints next steps.
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ from rich.panel import Panel
11
+ from rich.text import Text
12
+
13
+ from devsper.cli.ui.theme import console
14
+
15
+
16
+ DOCS_URL = "https://docs.devsper.com"
17
+ GITHUB_URL = "https://github.com/devsper-com/runtime"
18
+
19
+
20
+ def _wordmark_ascii() -> str:
21
+ """6-line block letters 'devsper' in ASCII. Fallback if pyfiglet missing."""
22
+ try:
23
+ import pyfiglet
24
+ return pyfiglet.figlet_format("devsper", font="standard").rstrip()
25
+ except ImportError:
26
+ return """
27
+ _ _ _ _ __ __ _____ __ __ ___ _ _ ____
28
+ | | | | | | | \\/ | ____| | \\/ | _ \\| \\ | | _ \\
29
+ | |_| | | | | |\\/| | _| | |\\/| | | | | \\| | | | |
30
+ | _ | |_| | | | | |___ | | | | |_| | |\\ | |_| |
31
+ |_| |_|\\___/|_| |_|_____| |_| |_|___/|_| \\_|____/
32
+ """.strip()
33
+
34
+
35
+ class InitWizard:
36
+ """Interactive init: welcome, providers, models, workers, features, write config."""
37
+
38
+ def __init__(self, cwd: Path | None = None) -> None:
39
+ self.cwd = cwd or Path.cwd()
40
+
41
+ def run(self, no_interactive: bool = False) -> int:
42
+ """Run full wizard or minimal write when no_interactive."""
43
+ if no_interactive:
44
+ return self._run_minimal()
45
+ return self._run_interactive()
46
+
47
+ def _run_minimal(self) -> int:
48
+ """Write minimal devsper.toml and print next steps."""
49
+ from devsper.cli.init import _build_init_toml
50
+ toml = _build_init_toml(workers=4, planner="auto", worker="auto")
51
+ path = self.cwd / "devsper.toml"
52
+ path.write_text(toml, encoding="utf-8")
53
+ console.print("[hive.success]✓[/] Wrote [cyan]devsper.toml[/]")
54
+ console.print()
55
+ console.print("Next steps:")
56
+ console.print(" 1) Set API keys: [cyan]devsper credentials set <provider> api_key[/]")
57
+ console.print(" 2) Run: [cyan]devsper run \"your task\"[/]")
58
+ console.print(f" Docs: [link={DOCS_URL}]{DOCS_URL}[/]")
59
+ return 0
60
+
61
+ def _run_interactive(self) -> int:
62
+ """Step 1: Welcome. Then delegate to existing init flow."""
63
+ # Step 1 — Welcome
64
+ console.clear()
65
+ wordmark = _wordmark_ascii()
66
+ console.print(Text(wordmark, style="hive.primary"))
67
+ console.print()
68
+ console.print("Welcome to devsper — distributed AI swarm runtime", style="hive.muted")
69
+ try:
70
+ import devsper
71
+ ver = getattr(devsper, "__version__", "?")
72
+ console.print(f"v{ver} · [link={DOCS_URL}]{DOCS_URL}[/] · [link={GITHUB_URL}]{GITHUB_URL}[/]", style="hive.muted")
73
+ except Exception:
74
+ console.print(f"[link={DOCS_URL}]{DOCS_URL}[/] · [link={GITHUB_URL}]{GITHUB_URL}[/]", style="hive.muted")
75
+ console.print()
76
+ try:
77
+ from rich.prompt import Prompt
78
+ Prompt.ask("[dim]Press Enter to continue[/]", default="")
79
+ except Exception:
80
+ input("Press Enter to continue...")
81
+ # Delegate to existing init (writes toml and .env)
82
+ from devsper.cli.init import _run_init_interactive, _write_env_file
83
+ toml_content, api_keys = _run_init_interactive(self.cwd)
84
+ path = self.cwd / "devsper.toml"
85
+ path.write_text(toml_content, encoding="utf-8")
86
+ if api_keys:
87
+ _write_env_file(self.cwd, api_keys)
88
+ console.print()
89
+ console.print(Panel(
90
+ "Try it: [cyan]devsper run \"research quantum computing breakthroughs\"[/]\n\n"
91
+ f"Docs: {DOCS_URL}\n"
92
+ "Discord: https://discord.gg/devsper",
93
+ title="You're all set",
94
+ border_style="hive.success",
95
+ ))
96
+ return 0
97
+
98
+
99
+ def run_init_wizard(no_interactive: bool = False, cwd: Path | None = None) -> int:
100
+ """Entry point for devsper init."""
101
+ wizard = InitWizard(cwd=cwd)
102
+ return wizard.run(no_interactive=no_interactive)
@@ -0,0 +1,43 @@
1
+ """
2
+ Styled progress bars for long operations. Amber fill, dim track, consistent columns.
3
+ """
4
+
5
+ from rich.progress import (
6
+ Progress,
7
+ SpinnerColumn,
8
+ TextColumn,
9
+ BarColumn,
10
+ TaskProgressColumn,
11
+ TimeElapsedColumn,
12
+ )
13
+ from rich.text import Text
14
+
15
+ from devsper.cli.ui.theme import console
16
+
17
+ # Spinner names: dots2, line, arrow (Rich built-in)
18
+ SPINNER_THINKING = "dots2"
19
+ SPINNER_NETWORK = "line"
20
+ SPINNER_BUILDING = "arrow"
21
+ SPINNER_SUCCESS = "dots2" # we override with static ✓ when done
22
+
23
+
24
+ def devsperProgress(
25
+ transient: bool = False,
26
+ console_use: object = None,
27
+ ) -> Progress:
28
+ """Progress with hive styling: amber bar, dim track, spinner, task count, elapsed."""
29
+ c = console_use or console
30
+ return Progress(
31
+ SpinnerColumn(style="hive.primary", finished_style="hive.success"),
32
+ TextColumn("[bold]{task.description}"),
33
+ BarColumn(bar_width=30, complete_style="hive.primary", finished_style="hive.success", pulse_style="hive.dim"),
34
+ TaskProgressColumn(style="hive.muted"),
35
+ TimeElapsedColumn(style="hive.muted"),
36
+ console=c,
37
+ transient=transient,
38
+ )
39
+
40
+
41
+ def progress_spinner_style(operation: str) -> str:
42
+ """Spinner style by operation: thinking, network, building, success."""
43
+ return "hive.primary"