clawed 2.5.3__tar.gz → 3.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. {clawed-2.5.3 → clawed-3.0.0}/.gitignore +8 -0
  2. {clawed-2.5.3 → clawed-3.0.0}/PKG-INFO +34 -25
  3. {clawed-2.5.3 → clawed-3.0.0}/README.md +31 -22
  4. {clawed-2.5.3 → clawed-3.0.0}/clawed/__init__.py +2 -2
  5. {clawed-2.5.3 → clawed-3.0.0}/clawed/__main__.py +2 -2
  6. clawed-3.0.0/clawed/_cli_bundle/.gitkeep +0 -0
  7. clawed-3.0.0/clawed/_entry_router.py +160 -0
  8. clawed-3.0.0/clawed/_json_output.py +63 -0
  9. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/config_llm.py +17 -1
  10. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/config_profile.py +31 -1
  11. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/export.py +16 -0
  12. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/game.py +53 -0
  13. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/generate.py +97 -0
  14. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/generate_assessment.py +31 -0
  15. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/generate_unit.py +36 -0
  16. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/train.py +30 -0
  17. {clawed-2.5.3 → clawed-3.0.0}/clawed/compile_game.py +14 -0
  18. {clawed-2.5.3 → clawed-3.0.0}/clawed/export_pptx.py +193 -65
  19. clawed-3.0.0/daemon/index.ts +165 -0
  20. clawed-3.0.0/daemon/process-manager.ts +240 -0
  21. clawed-3.0.0/daemon/telegram-bridge.ts +356 -0
  22. {clawed-2.5.3 → clawed-3.0.0}/pyproject.toml +7 -6
  23. clawed-3.0.0/scripts/build.sh +100 -0
  24. clawed-3.0.0/scripts/bump_version.sh +30 -0
  25. clawed-3.0.0/scripts/ingest_jon.py +157 -0
  26. clawed-3.0.0/scripts/install.sh +261 -0
  27. clawed-3.0.0/scripts/post_release.py +96 -0
  28. clawed-3.0.0/scripts/publish.sh +76 -0
  29. {clawed-2.5.3 → clawed-3.0.0}/LICENSE +0 -0
  30. {clawed-2.5.3 → clawed-3.0.0}/clawed/_legacy_gateway.py +0 -0
  31. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent.py +0 -0
  32. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/__init__.py +0 -0
  33. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/approvals.py +0 -0
  34. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/autonomy.py +0 -0
  35. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/context.py +0 -0
  36. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/core.py +0 -0
  37. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/custom_tools.py +0 -0
  38. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/drive/__init__.py +0 -0
  39. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/drive/auth.py +0 -0
  40. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/drive/client.py +0 -0
  41. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/fake_llm.py +0 -0
  42. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/loop.py +0 -0
  43. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/__init__.py +0 -0
  44. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/curriculum.py +0 -0
  45. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/curriculum_kb.py +0 -0
  46. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/embeddings.py +0 -0
  47. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/episodes.py +0 -0
  48. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/identity.py +0 -0
  49. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/loader.py +0 -0
  50. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/preferences.py +0 -0
  51. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/planner.py +0 -0
  52. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/prompt.py +0 -0
  53. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/scheduler.py +0 -0
  54. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/__init__.py +0 -0
  55. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/base.py +0 -0
  56. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/configure_profile.py +0 -0
  57. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/curriculum_map.py +0 -0
  58. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/drive_create_doc.py +0 -0
  59. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/drive_create_slides.py +0 -0
  60. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/drive_list.py +0 -0
  61. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/drive_organize.py +0 -0
  62. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/drive_read.py +0 -0
  63. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/drive_upload.py +0 -0
  64. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/export_document.py +0 -0
  65. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/gap_analysis.py +0 -0
  66. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/generate_assessment.py +0 -0
  67. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/generate_lesson.py +0 -0
  68. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/generate_lesson_bundle.py +0 -0
  69. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/generate_materials.py +0 -0
  70. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/generate_unit.py +0 -0
  71. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/ingest_materials.py +0 -0
  72. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/parent_comm.py +0 -0
  73. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/read_heartbeat.py +0 -0
  74. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/read_workspace.py +0 -0
  75. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/request_approval.py +0 -0
  76. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/schedule_task.py +0 -0
  77. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/search_lessons.py +0 -0
  78. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/search_my_materials.py +0 -0
  79. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/search_standards.py +0 -0
  80. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/student_insights.py +0 -0
  81. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/sub_packet.py +0 -0
  82. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/switch_model.py +0 -0
  83. {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/update_soul.py +0 -0
  84. {clawed-2.5.3 → clawed-3.0.0}/clawed/analytics.py +0 -0
  85. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/__init__.py +0 -0
  86. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/deps.py +0 -0
  87. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/__init__.py +0 -0
  88. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/chat.py +0 -0
  89. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/export.py +0 -0
  90. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/feedback.py +0 -0
  91. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/gateway_chat.py +0 -0
  92. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/generate.py +0 -0
  93. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/ingest.py +0 -0
  94. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/lessons.py +0 -0
  95. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/school.py +0 -0
  96. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/settings.py +0 -0
  97. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/tools.py +0 -0
  98. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/server.py +0 -0
  99. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/static/app.js +0 -0
  100. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/static/style.css +0 -0
  101. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/static/widget.js +0 -0
  102. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/analytics.html +0 -0
  103. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/base.html +0 -0
  104. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/dashboard.html +0 -0
  105. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/generate.html +0 -0
  106. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/index.html +0 -0
  107. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/lesson.html +0 -0
  108. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/profile.html +0 -0
  109. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/settings.html +0 -0
  110. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/stats.html +0 -0
  111. {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/students.html +0 -0
  112. {clawed-2.5.3 → clawed-3.0.0}/clawed/assessment.py +0 -0
  113. {clawed-2.5.3 → clawed-3.0.0}/clawed/asset_registry.py +0 -0
  114. {clawed-2.5.3 → clawed-3.0.0}/clawed/async_utils.py +0 -0
  115. {clawed-2.5.3 → clawed-3.0.0}/clawed/auth/__init__.py +0 -0
  116. {clawed-2.5.3 → clawed-3.0.0}/clawed/auth/google_auth.py +0 -0
  117. {clawed-2.5.3 → clawed-3.0.0}/clawed/bot_state.py +0 -0
  118. {clawed-2.5.3 → clawed-3.0.0}/clawed/chat.py +0 -0
  119. {clawed-2.5.3 → clawed-3.0.0}/clawed/cli.py +0 -0
  120. {clawed-2.5.3 → clawed-3.0.0}/clawed/cli_chat.py +0 -0
  121. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/__init__.py +0 -0
  122. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/_helpers.py +0 -0
  123. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/bot.py +0 -0
  124. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/config.py +0 -0
  125. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/queue.py +0 -0
  126. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/schedule_cmd.py +0 -0
  127. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/sub.py +0 -0
  128. {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/workspace_cmd.py +0 -0
  129. {clawed-2.5.3 → clawed-3.0.0}/clawed/compile_slides.py +0 -0
  130. {clawed-2.5.3 → clawed-3.0.0}/clawed/compile_student.py +0 -0
  131. {clawed-2.5.3 → clawed-3.0.0}/clawed/compile_teacher.py +0 -0
  132. {clawed-2.5.3 → clawed-3.0.0}/clawed/config.py +0 -0
  133. {clawed-2.5.3 → clawed-3.0.0}/clawed/corpus.py +0 -0
  134. {clawed-2.5.3 → clawed-3.0.0}/clawed/curriculum_map.py +0 -0
  135. {clawed-2.5.3 → clawed-3.0.0}/clawed/database.py +0 -0
  136. {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/__init__.py +0 -0
  137. {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_assessment.json +0 -0
  138. {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_formative_assessment.json +0 -0
  139. {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_lesson_materials.json +0 -0
  140. {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_lesson_science_g6.json +0 -0
  141. {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_lesson_social_studies_g8.json +0 -0
  142. {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_master_content.json +0 -0
  143. {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_pacing_guide.json +0 -0
  144. {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_quiz.json +0 -0
  145. {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_rubric.json +0 -0
  146. {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_unit_plan.json +0 -0
  147. {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_year_map.json +0 -0
  148. {clawed-2.5.3 → clawed-3.0.0}/clawed/differentiation.py +0 -0
  149. {clawed-2.5.3 → clawed-3.0.0}/clawed/doc_export.py +0 -0
  150. {clawed-2.5.3 → clawed-3.0.0}/clawed/drive.py +0 -0
  151. {clawed-2.5.3 → clawed-3.0.0}/clawed/evaluation.py +0 -0
  152. {clawed-2.5.3 → clawed-3.0.0}/clawed/export_docx.py +0 -0
  153. {clawed-2.5.3 → clawed-3.0.0}/clawed/export_handout.py +0 -0
  154. {clawed-2.5.3 → clawed-3.0.0}/clawed/export_markdown.py +0 -0
  155. {clawed-2.5.3 → clawed-3.0.0}/clawed/export_pdf.py +0 -0
  156. {clawed-2.5.3 → clawed-3.0.0}/clawed/export_templates.py +0 -0
  157. {clawed-2.5.3 → clawed-3.0.0}/clawed/export_theme.py +0 -0
  158. {clawed-2.5.3 → clawed-3.0.0}/clawed/exporter.py +0 -0
  159. {clawed-2.5.3 → clawed-3.0.0}/clawed/failure_codes.py +0 -0
  160. {clawed-2.5.3 → clawed-3.0.0}/clawed/feedback.py +0 -0
  161. {clawed-2.5.3 → clawed-3.0.0}/clawed/formats/__init__.py +0 -0
  162. {clawed-2.5.3 → clawed-3.0.0}/clawed/formats/flipchart.py +0 -0
  163. {clawed-2.5.3 → clawed-3.0.0}/clawed/formats/notebook.py +0 -0
  164. {clawed-2.5.3 → clawed-3.0.0}/clawed/formats/xbk.py +0 -0
  165. {clawed-2.5.3 → clawed-3.0.0}/clawed/gateway.py +0 -0
  166. {clawed-2.5.3 → clawed-3.0.0}/clawed/gateway_response.py +0 -0
  167. {clawed-2.5.3 → clawed-3.0.0}/clawed/generation.py +0 -0
  168. {clawed-2.5.3 → clawed-3.0.0}/clawed/generation_report.py +0 -0
  169. {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/__init__.py +0 -0
  170. {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/export.py +0 -0
  171. {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/feedback.py +0 -0
  172. {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/gaps.py +0 -0
  173. {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/generate.py +0 -0
  174. {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/ingest.py +0 -0
  175. {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/misc.py +0 -0
  176. {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/onboard.py +0 -0
  177. {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/schedule.py +0 -0
  178. {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/standards.py +0 -0
  179. {clawed-2.5.3 → clawed-3.0.0}/clawed/hermes_plugin.py +0 -0
  180. {clawed-2.5.3 → clawed-3.0.0}/clawed/image_pipeline.py +0 -0
  181. {clawed-2.5.3 → clawed-3.0.0}/clawed/improver.py +0 -0
  182. {clawed-2.5.3 → clawed-3.0.0}/clawed/ingestor.py +0 -0
  183. {clawed-2.5.3 → clawed-3.0.0}/clawed/io.py +0 -0
  184. {clawed-2.5.3 → clawed-3.0.0}/clawed/lesson.py +0 -0
  185. {clawed-2.5.3 → clawed-3.0.0}/clawed/llm.py +0 -0
  186. {clawed-2.5.3 → clawed-3.0.0}/clawed/master_content.py +0 -0
  187. {clawed-2.5.3 → clawed-3.0.0}/clawed/materials.py +0 -0
  188. {clawed-2.5.3 → clawed-3.0.0}/clawed/mcp_server.py +0 -0
  189. {clawed-2.5.3 → clawed-3.0.0}/clawed/memory_engine.py +0 -0
  190. {clawed-2.5.3 → clawed-3.0.0}/clawed/model_router.py +0 -0
  191. {clawed-2.5.3 → clawed-3.0.0}/clawed/models.py +0 -0
  192. {clawed-2.5.3 → clawed-3.0.0}/clawed/multi_agent.py +0 -0
  193. {clawed-2.5.3 → clawed-3.0.0}/clawed/onboarding.py +0 -0
  194. {clawed-2.5.3 → clawed-3.0.0}/clawed/openclaw_plugin.py +0 -0
  195. {clawed-2.5.3 → clawed-3.0.0}/clawed/parent_comm.py +0 -0
  196. {clawed-2.5.3 → clawed-3.0.0}/clawed/persona.py +0 -0
  197. {clawed-2.5.3 → clawed-3.0.0}/clawed/persona_evolution.py +0 -0
  198. {clawed-2.5.3 → clawed-3.0.0}/clawed/planner.py +0 -0
  199. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/504_accommodations.txt +0 -0
  200. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/admin_lesson_plan.txt +0 -0
  201. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/assessment.txt +0 -0
  202. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/curriculum_gaps.txt +0 -0
  203. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/dbq_assessment.txt +0 -0
  204. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/differentiation.txt +0 -0
  205. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/formative_assessment.txt +0 -0
  206. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/iep_modification.txt +0 -0
  207. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/lesson_plan.txt +0 -0
  208. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/master_content.txt +0 -0
  209. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/multi_agent_researcher.txt +0 -0
  210. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/multi_agent_reviewer.txt +0 -0
  211. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/pacing_guide.txt +0 -0
  212. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/parent_note.txt +0 -0
  213. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/persona_extract.txt +0 -0
  214. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/quiz.txt +0 -0
  215. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/rubric.txt +0 -0
  216. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/student_packet.txt +0 -0
  217. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/sub_packet.txt +0 -0
  218. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/summative_assessment.txt +0 -0
  219. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/tiered_assignments.txt +0 -0
  220. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/unit_plan.txt +0 -0
  221. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/worksheet.txt +0 -0
  222. {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/year_map.txt +0 -0
  223. {clawed-2.5.3 → clawed-3.0.0}/clawed/quality.py +0 -0
  224. {clawed-2.5.3 → clawed-3.0.0}/clawed/reading_report.py +0 -0
  225. {clawed-2.5.3 → clawed-3.0.0}/clawed/review_output.py +0 -0
  226. {clawed-2.5.3 → clawed-3.0.0}/clawed/router.py +0 -0
  227. {clawed-2.5.3 → clawed-3.0.0}/clawed/sanitize.py +0 -0
  228. {clawed-2.5.3 → clawed-3.0.0}/clawed/scheduler.py +0 -0
  229. {clawed-2.5.3 → clawed-3.0.0}/clawed/school.py +0 -0
  230. {clawed-2.5.3 → clawed-3.0.0}/clawed/search.py +0 -0
  231. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/__init__.py +0 -0
  232. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/art.py +0 -0
  233. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/base.py +0 -0
  234. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/computer_science.py +0 -0
  235. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/ela.py +0 -0
  236. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/foreign_language.py +0 -0
  237. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/history.py +0 -0
  238. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/library.py +0 -0
  239. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/math.py +0 -0
  240. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/music.py +0 -0
  241. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/physical_education.py +0 -0
  242. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/science.py +0 -0
  243. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/social_studies.py +0 -0
  244. {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/special_education.py +0 -0
  245. {clawed-2.5.3 → clawed-3.0.0}/clawed/slide_images.py +0 -0
  246. {clawed-2.5.3 → clawed-3.0.0}/clawed/standards.py +0 -0
  247. {clawed-2.5.3 → clawed-3.0.0}/clawed/state.py +0 -0
  248. {clawed-2.5.3 → clawed-3.0.0}/clawed/state_standards.py +0 -0
  249. {clawed-2.5.3 → clawed-3.0.0}/clawed/student_bot.py +0 -0
  250. {clawed-2.5.3 → clawed-3.0.0}/clawed/student_cli.py +0 -0
  251. {clawed-2.5.3 → clawed-3.0.0}/clawed/student_telegram_bot.py +0 -0
  252. {clawed-2.5.3 → clawed-3.0.0}/clawed/sub_packet.py +0 -0
  253. {clawed-2.5.3 → clawed-3.0.0}/clawed/task_queue.py +0 -0
  254. {clawed-2.5.3 → clawed-3.0.0}/clawed/templates_lib.py +0 -0
  255. {clawed-2.5.3 → clawed-3.0.0}/clawed/tools.py +0 -0
  256. {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/__init__.py +0 -0
  257. {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/cli.py +0 -0
  258. {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/hermes.py +0 -0
  259. {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/openclaw.py +0 -0
  260. {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/student_telegram.py +0 -0
  261. {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/telegram.py +0 -0
  262. {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/web.py +0 -0
  263. {clawed-2.5.3 → clawed-3.0.0}/clawed/tui.py +0 -0
  264. {clawed-2.5.3 → clawed-3.0.0}/clawed/tui_chat.py +0 -0
  265. {clawed-2.5.3 → clawed-3.0.0}/clawed/validation.py +0 -0
  266. {clawed-2.5.3 → clawed-3.0.0}/clawed/voice.py +0 -0
  267. {clawed-2.5.3 → clawed-3.0.0}/clawed/voice_check.py +0 -0
  268. {clawed-2.5.3 → clawed-3.0.0}/clawed/workspace.py +0 -0
  269. {clawed-2.5.3 → clawed-3.0.0}/eduagent/__init__.py +0 -0
  270. {clawed-2.5.3 → clawed-3.0.0}/eduagent/_compat.py +0 -0
@@ -18,6 +18,7 @@ build/
18
18
  !examples/**/*.json
19
19
  !eduagent/demo/*.json
20
20
  !clawed/demo/*.json
21
+ !cli/**/*.json
21
22
  eduagent_output/
22
23
  clawed_output/
23
24
  eduagent_data/
@@ -38,6 +39,13 @@ clawed_data/
38
39
  htmlcov/
39
40
  .ruff_cache/
40
41
 
42
+ # CLI (TypeScript/Ink build)
43
+ cli/node_modules/
44
+ cli/dist/
45
+ cli/.bun/
46
+ cli/source/cli.js
47
+ cli/source/cli.js.map
48
+
41
49
  # Build prompts (internal)
42
50
  BUILD_PROMPT.md
43
51
 
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clawed
3
- Version: 2.5.3
4
- Summary: Free AI lesson planner for teachers. Learns your teaching voice from your curriculum files and generates complete lesson packages. Open source, runs locally, no subscription.
3
+ Version: 3.0.0
4
+ Summary: Your AI co-teacher. Generate lessons, games, slides, and assessments from your terminal. Learns your teaching voice, aligns to your state standards, and works with any LLM provider.
5
5
  Project-URL: Homepage, https://sirhanmacx.github.io/Claw-ED
6
6
  Project-URL: Documentation, https://github.com/SirhanMacx/Claw-ED#readme
7
7
  Project-URL: Repository, https://github.com/SirhanMacx/Claw-ED
@@ -12,7 +12,7 @@ Author: Jon Maccarello & Claw-ED contributors
12
12
  License-Expression: MIT
13
13
  License-File: LICENSE
14
14
  Keywords: ai,ai-for-teachers,claw-ed,clawed,curriculum,edtech,education,hermes-agent,k12,lesson-plan-generator,lesson-planner,lesson-planning,lesson-plans,open-source-education,pedagogy,teacher-tools,teachers,teaching,teaching-assistant
15
- Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Development Status :: 4 - Beta
16
16
  Classifier: Environment :: Console
17
17
  Classifier: Intended Audience :: Education
18
18
  Classifier: License :: OSI Approved :: MIT License
@@ -74,9 +74,9 @@ Provides-Extra: voice
74
74
  Requires-Dist: faster-whisper>=0.10.0; extra == 'voice'
75
75
  Description-Content-Type: text/markdown
76
76
 
77
- # Claw-ED
77
+ # Claw-ED v3
78
78
 
79
- **Your AI co-teacher. Learns your voice. Generates lessons that sound like you wrote them.**
79
+ **The agentic layer for education. Your AI co-teacher that lives in the terminal.**
80
80
 
81
81
  <p align="center">
82
82
  <a href="https://pypi.org/project/clawed/"><img src="https://img.shields.io/pypi/v/clawed?color=blue" alt="PyPI version"></a>
@@ -88,7 +88,9 @@ Description-Content-Type: text/markdown
88
88
 
89
89
  ---
90
90
 
91
- Claw-ED is an open-source AI teaching assistant that learns your actual teaching style from your curriculum files. Not a generic lesson template generator a personal agent that captures your voice, your scaffolding patterns, your assessment style, and your classroom personality. It generates complete lesson packages that your colleagues would swear you wrote yourself.
91
+ Claw-ED v3 is a persistent AI teaching assistant that lives in your terminal and on your phone. Talk naturally "make me a lesson on WWI for my 8th graders" and it generates complete lesson packages in your voice. Not a chatbot. An agent that knows your curriculum, your standards, your students, and your teaching style.
92
+
93
+ **New in v3:** Beautiful interactive terminal (Ink TUI), always-on Telegram bot, multi-provider LLM support (Anthropic, OpenAI, Google, Ollama), natural language routing.
92
94
 
93
95
  ```bash
94
96
  pip install clawed
@@ -195,7 +197,9 @@ Your curriculum files (PDF, DOCX, PPTX, and 20+ formats)
195
197
  | `clawed standards list -g 8 -s "Math"` | Browse state standards |
196
198
  | `clawed gap-analyze` | Find curriculum gaps |
197
199
  | `clawed train --benchmark -n 5` | Score lesson quality |
198
- | `clawed bot --token TOKEN` | Connect Telegram bot |
200
+ | `clawed daemon start` | Start always-on Telegram bot (background) |
201
+ | `clawed daemon stop` | Stop the Telegram daemon |
202
+ | `clawed daemon status` | Show daemon uptime and health |
199
203
  | `clawed serve` | Web dashboard |
200
204
  | `clawed mcp-server` | MCP server (for Claude Code integration) |
201
205
  | `clawed game create "Topic" -g 8` | Generate an interactive HTML learning game |
@@ -280,28 +284,33 @@ Claw-ED can work while you sleep:
280
284
  ## Architecture
281
285
 
282
286
  ```
283
- Teacher (Telegram, CLI, Web, MCP)
287
+ Teacher (Terminal or Phone)
288
+ |
289
+ ┌────┴─────┐
290
+ │ Ink TUI │ ←── Beautiful interactive terminal (TypeScript)
291
+ │ or │
292
+ │ Telegram │ ←── Always-on thin client via background daemon
293
+ └────┬─────┘
294
+ |
295
+ Multi-Provider LLM Router
296
+ (Anthropic | OpenAI | Google | Ollama)
297
+ |
298
+ ↕ tool_use / function_calling
299
+ |
300
+ 14 Claw-ED Tools (TypeScript → Python subprocess)
301
+ |
302
+ Python Engine (lesson, game, export, standards, persona, ...)
284
303
  |
285
- Gateway (feature-flag router)
286
- |-- Control Plane (deterministic: files, onboarding, export)
287
- |-- Agent Loop (LLM with 28 typed tools)
288
- | |
289
- Tool Registry Workspace
290
- - generate_lesson - SOUL.md (identity)
291
- - search_materials - HEARTBEAT.md (schedule)
292
- - generate_assessment - Memory (3-layer cognitive)
293
- - curriculum_map |
294
- - export_document Curriculum KB
295
- - 23 more tools (semantic search over your files)
296
- |
297
- Professional exports (DOCX, PPTX, PDF, Google Docs)
304
+ Professional exports (DOCX, PPTX, HTML games, PDF)
298
305
  ```
299
306
 
300
307
  **Key design decisions:**
301
308
 
302
309
  - **Agent-first.** Natural language goes through an LLM that decides which tools to call. No rigid command parsing.
303
310
  - **Master Content Track.** One LLM generation produces a unified `MasterContent` object. Teacher view, student packet, and slideshow are compiled mechanically — no redundant AI calls.
304
- - **Fail-closed quality gates.** Every generation is validated. If quality review crashes, it reports failure instead of silently passing.
311
+ - **Subprocess bridge.** TypeScript CLI calls Python engine via `python3 -m clawed <cmd> --json`. Clean separation, independent testing, single install.
312
+ - **Multi-provider.** Teacher picks their provider (free Ollama to premium Claude). Claw-ED picks the best model within it.
313
+ - **Always-on daemon.** Background process keeps Telegram bot online. Teachers generate lessons from their phone.
305
314
  - **Subject-specific skills.** 13 built-in subject skills (Math, Science, History, ELA, Music, Art, PE, CS, Foreign Language, Library, Special Ed, and more) tune the generation for each discipline's pedagogy.
306
315
 
307
316
  ---
@@ -376,7 +385,7 @@ Claw-ED is built by a teacher for teachers. Join the conversation:
376
385
  - **[Report issues](https://github.com/SirhanMacx/Claw-ED/issues)** — bugs, feature requests, quality feedback
377
386
  - **[Star the repo](https://github.com/SirhanMacx/Claw-ED)** — it helps other teachers find us
378
387
 
379
- 14,000+ installs and growing. If Claw-ED saved you prep time, tell a colleague.
388
+ 14,000+ installs and growing. The agentic layer for education starts here.
380
389
 
381
390
  ---
382
391
 
@@ -384,6 +393,6 @@ Claw-ED is built by a teacher for teachers. Join the conversation:
384
393
 
385
394
  MIT License. Free for personal and commercial use.
386
395
 
387
- Built by educators, for educators.
396
+ Built by educators, for educators. The agentic layer for education.
388
397
 
389
- [GitHub](https://github.com/SirhanMacx/Claw-ED) | [PyPI](https://pypi.org/project/clawed/) | [Discussions](https://github.com/SirhanMacx/Claw-ED/discussions) | [Changelog](CHANGELOG.md)
398
+ [GitHub](https://github.com/SirhanMacx/Claw-ED) | [PyPI](https://pypi.org/project/clawed/) | [Game Gallery](https://sirhanmacx.github.io/Claw-ED/games) | [Discussions](https://github.com/SirhanMacx/Claw-ED/discussions) | [Changelog](CHANGELOG.md)
@@ -1,6 +1,6 @@
1
- # Claw-ED
1
+ # Claw-ED v3
2
2
 
3
- **Your AI co-teacher. Learns your voice. Generates lessons that sound like you wrote them.**
3
+ **The agentic layer for education. Your AI co-teacher that lives in the terminal.**
4
4
 
5
5
  <p align="center">
6
6
  <a href="https://pypi.org/project/clawed/"><img src="https://img.shields.io/pypi/v/clawed?color=blue" alt="PyPI version"></a>
@@ -12,7 +12,9 @@
12
12
 
13
13
  ---
14
14
 
15
- Claw-ED is an open-source AI teaching assistant that learns your actual teaching style from your curriculum files. Not a generic lesson template generator a personal agent that captures your voice, your scaffolding patterns, your assessment style, and your classroom personality. It generates complete lesson packages that your colleagues would swear you wrote yourself.
15
+ Claw-ED v3 is a persistent AI teaching assistant that lives in your terminal and on your phone. Talk naturally "make me a lesson on WWI for my 8th graders" and it generates complete lesson packages in your voice. Not a chatbot. An agent that knows your curriculum, your standards, your students, and your teaching style.
16
+
17
+ **New in v3:** Beautiful interactive terminal (Ink TUI), always-on Telegram bot, multi-provider LLM support (Anthropic, OpenAI, Google, Ollama), natural language routing.
16
18
 
17
19
  ```bash
18
20
  pip install clawed
@@ -119,7 +121,9 @@ Your curriculum files (PDF, DOCX, PPTX, and 20+ formats)
119
121
  | `clawed standards list -g 8 -s "Math"` | Browse state standards |
120
122
  | `clawed gap-analyze` | Find curriculum gaps |
121
123
  | `clawed train --benchmark -n 5` | Score lesson quality |
122
- | `clawed bot --token TOKEN` | Connect Telegram bot |
124
+ | `clawed daemon start` | Start always-on Telegram bot (background) |
125
+ | `clawed daemon stop` | Stop the Telegram daemon |
126
+ | `clawed daemon status` | Show daemon uptime and health |
123
127
  | `clawed serve` | Web dashboard |
124
128
  | `clawed mcp-server` | MCP server (for Claude Code integration) |
125
129
  | `clawed game create "Topic" -g 8` | Generate an interactive HTML learning game |
@@ -204,28 +208,33 @@ Claw-ED can work while you sleep:
204
208
  ## Architecture
205
209
 
206
210
  ```
207
- Teacher (Telegram, CLI, Web, MCP)
211
+ Teacher (Terminal or Phone)
212
+ |
213
+ ┌────┴─────┐
214
+ │ Ink TUI │ ←── Beautiful interactive terminal (TypeScript)
215
+ │ or │
216
+ │ Telegram │ ←── Always-on thin client via background daemon
217
+ └────┬─────┘
218
+ |
219
+ Multi-Provider LLM Router
220
+ (Anthropic | OpenAI | Google | Ollama)
221
+ |
222
+ ↕ tool_use / function_calling
223
+ |
224
+ 14 Claw-ED Tools (TypeScript → Python subprocess)
225
+ |
226
+ Python Engine (lesson, game, export, standards, persona, ...)
208
227
  |
209
- Gateway (feature-flag router)
210
- |-- Control Plane (deterministic: files, onboarding, export)
211
- |-- Agent Loop (LLM with 28 typed tools)
212
- | |
213
- Tool Registry Workspace
214
- - generate_lesson - SOUL.md (identity)
215
- - search_materials - HEARTBEAT.md (schedule)
216
- - generate_assessment - Memory (3-layer cognitive)
217
- - curriculum_map |
218
- - export_document Curriculum KB
219
- - 23 more tools (semantic search over your files)
220
- |
221
- Professional exports (DOCX, PPTX, PDF, Google Docs)
228
+ Professional exports (DOCX, PPTX, HTML games, PDF)
222
229
  ```
223
230
 
224
231
  **Key design decisions:**
225
232
 
226
233
  - **Agent-first.** Natural language goes through an LLM that decides which tools to call. No rigid command parsing.
227
234
  - **Master Content Track.** One LLM generation produces a unified `MasterContent` object. Teacher view, student packet, and slideshow are compiled mechanically — no redundant AI calls.
228
- - **Fail-closed quality gates.** Every generation is validated. If quality review crashes, it reports failure instead of silently passing.
235
+ - **Subprocess bridge.** TypeScript CLI calls Python engine via `python3 -m clawed <cmd> --json`. Clean separation, independent testing, single install.
236
+ - **Multi-provider.** Teacher picks their provider (free Ollama to premium Claude). Claw-ED picks the best model within it.
237
+ - **Always-on daemon.** Background process keeps Telegram bot online. Teachers generate lessons from their phone.
229
238
  - **Subject-specific skills.** 13 built-in subject skills (Math, Science, History, ELA, Music, Art, PE, CS, Foreign Language, Library, Special Ed, and more) tune the generation for each discipline's pedagogy.
230
239
 
231
240
  ---
@@ -300,7 +309,7 @@ Claw-ED is built by a teacher for teachers. Join the conversation:
300
309
  - **[Report issues](https://github.com/SirhanMacx/Claw-ED/issues)** — bugs, feature requests, quality feedback
301
310
  - **[Star the repo](https://github.com/SirhanMacx/Claw-ED)** — it helps other teachers find us
302
311
 
303
- 14,000+ installs and growing. If Claw-ED saved you prep time, tell a colleague.
312
+ 14,000+ installs and growing. The agentic layer for education starts here.
304
313
 
305
314
  ---
306
315
 
@@ -308,6 +317,6 @@ Claw-ED is built by a teacher for teachers. Join the conversation:
308
317
 
309
318
  MIT License. Free for personal and commercial use.
310
319
 
311
- Built by educators, for educators.
320
+ Built by educators, for educators. The agentic layer for education.
312
321
 
313
- [GitHub](https://github.com/SirhanMacx/Claw-ED) | [PyPI](https://pypi.org/project/clawed/) | [Discussions](https://github.com/SirhanMacx/Claw-ED/discussions) | [Changelog](CHANGELOG.md)
322
+ [GitHub](https://github.com/SirhanMacx/Claw-ED) | [PyPI](https://pypi.org/project/clawed/) | [Game Gallery](https://sirhanmacx.github.io/Claw-ED/games) | [Discussions](https://github.com/SirhanMacx/Claw-ED/discussions) | [Changelog](CHANGELOG.md)
@@ -17,9 +17,9 @@ if hasattr(sys.stderr, "reconfigure"):
17
17
  except Exception:
18
18
  pass
19
19
 
20
- __version__ = "2.5.3"
20
+ __version__ = "3.0.0"
21
21
  __author__ = "Jon Maccarello & Claw-ED contributors"
22
- __description__ = "Personal AI teaching agent. Learns your voice, works while you sleep."
22
+ __description__ = "Your AI co-teacher. Generate lessons, games, slides, and assessments from your terminal."
23
23
 
24
24
  # Central I/O — re-exported for convenience
25
25
  from clawed.io import output_dir as output_dir # noqa: F401
@@ -10,8 +10,8 @@ def main():
10
10
  if hasattr(sys.stderr, "reconfigure"):
11
11
  sys.stderr.reconfigure(encoding="utf-8", errors="replace")
12
12
 
13
- from clawed.cli import app
14
- app()
13
+ from clawed._entry_router import main as entry_main
14
+ entry_main()
15
15
  except KeyboardInterrupt:
16
16
  sys.exit(130)
17
17
  except SystemExit:
File without changes
@@ -0,0 +1,160 @@
1
+ """Claw-ED v3 entry point router.
2
+
3
+ Routes to the TypeScript Ink TUI (if Node.js available) or falls back
4
+ to the Python typer CLI. The teacher never needs to know about this
5
+ routing — they just run `clawed`.
6
+
7
+ Usage:
8
+ clawed → Interactive mode (Ink TUI or Python REPL)
9
+ clawed lesson "Topic" → Direct command (routes to Python --json if Ink TUI)
10
+ clawed --python ... → Force Python CLI (skip Node.js check)
11
+ clawed daemon start → Start background Telegram daemon
12
+ """
13
+ from __future__ import annotations
14
+
15
+ import os
16
+ import shutil
17
+ import subprocess
18
+ import sys
19
+ from pathlib import Path
20
+
21
+
22
+ def _find_bundled_cli_js() -> str | None:
23
+ """Find the pre-built cli.js bundled in the package."""
24
+ # Check package data directory
25
+ pkg_dir = Path(__file__).parent
26
+ cli_js = pkg_dir / "_cli_bundle" / "cli.js"
27
+ if cli_js.exists():
28
+ return str(cli_js)
29
+
30
+ # Check if we're in a dev environment with the cli/ directory
31
+ repo_root = pkg_dir.parent
32
+ dev_cli = repo_root / "cli" / "source" / "cli.js"
33
+ if dev_cli.exists():
34
+ return str(dev_cli)
35
+
36
+ return None
37
+
38
+
39
+ def _find_daemon_entry() -> str | None:
40
+ """Find the daemon entry point."""
41
+ pkg_dir = Path(__file__).parent
42
+ repo_root = pkg_dir.parent
43
+
44
+ # Dev environment
45
+ daemon_ts = repo_root / "daemon" / "index.ts"
46
+ daemon_js = repo_root / "daemon" / "dist" / "index.js"
47
+
48
+ if daemon_js.exists():
49
+ return str(daemon_js)
50
+ if daemon_ts.exists():
51
+ # Use ts-node or tsx for dev mode
52
+ return str(daemon_ts)
53
+
54
+ # Bundled daemon
55
+ bundled = pkg_dir / "_cli_bundle" / "daemon.js"
56
+ if bundled.exists():
57
+ return str(bundled)
58
+
59
+ return None
60
+
61
+
62
+ def _show_node_notice() -> None:
63
+ """One-time notice when Node.js is not installed."""
64
+ notice_file = Path.home() / ".eduagent" / ".node_notice_shown"
65
+ if notice_file.exists():
66
+ return
67
+
68
+ print(
69
+ "\n"
70
+ " Claw-ED v3.0 — running in classic mode (Python CLI)\n"
71
+ "\n"
72
+ " For the full interactive AI assistant experience,\n"
73
+ " install Node.js 18+: https://nodejs.org\n"
74
+ "\n"
75
+ " Classic mode supports all commands:\n"
76
+ " clawed lesson \"Topic\" -g 8 -s \"US History\"\n"
77
+ " clawed game create \"Topic\"\n"
78
+ " clawed ingest ~/Documents/\n"
79
+ "\n"
80
+ )
81
+
82
+ try:
83
+ notice_file.parent.mkdir(parents=True, exist_ok=True)
84
+ notice_file.touch()
85
+ except OSError:
86
+ pass # Non-critical: notice may show again next time
87
+
88
+
89
+ def _handle_daemon(args: list[str]) -> None:
90
+ """Route daemon commands to the Node.js daemon process."""
91
+ node = shutil.which("node")
92
+ daemon_entry = _find_daemon_entry()
93
+
94
+ if not node:
95
+ print("The Telegram daemon requires Node.js 18+.")
96
+ print("Install from: https://nodejs.org")
97
+ sys.exit(1)
98
+
99
+ if not daemon_entry:
100
+ print("Daemon entry point not found. Reinstall clawed or check your installation.")
101
+ sys.exit(1)
102
+
103
+ # Check if it's a .ts file (dev mode) — use tsx or ts-node
104
+ if daemon_entry.endswith(".ts"):
105
+ tsx = shutil.which("tsx")
106
+ if tsx:
107
+ result = subprocess.run([tsx, daemon_entry] + args)
108
+ else:
109
+ result = subprocess.run([node, "--loader", "ts-node/esm", daemon_entry] + args)
110
+ else:
111
+ result = subprocess.run([node, daemon_entry] + args)
112
+
113
+ sys.exit(result.returncode)
114
+
115
+
116
+ def main() -> None:
117
+ """Entry point for the `clawed` command.
118
+
119
+ Priority:
120
+ 1. daemon commands → Node.js daemon
121
+ 2. --python flag → force Python CLI
122
+ 3. Node.js available + cli.js found → Ink TUI
123
+ 4. Fallback → Python typer CLI
124
+ """
125
+ args = sys.argv[1:]
126
+
127
+ # Route daemon commands to the Node.js daemon
128
+ if args and args[0] == "daemon":
129
+ _handle_daemon(args[1:])
130
+ return
131
+
132
+ # Allow forcing Python CLI
133
+ if "--python" in args:
134
+ args.remove("--python")
135
+ sys.argv = [sys.argv[0]] + args
136
+ _run_python_cli()
137
+ return
138
+
139
+ # Try Node.js + bundled CLI for interactive/direct commands
140
+ node = shutil.which("node")
141
+ cli_js = _find_bundled_cli_js()
142
+
143
+ if node and cli_js:
144
+ result = subprocess.run([node, cli_js] + args)
145
+ sys.exit(result.returncode)
146
+ else:
147
+ if not args:
148
+ # Interactive mode without Node.js — show notice
149
+ _show_node_notice()
150
+ _run_python_cli()
151
+
152
+
153
+ def _run_python_cli() -> None:
154
+ """Run the Python typer CLI (fallback or forced mode)."""
155
+ from clawed.cli import app
156
+ app()
157
+
158
+
159
+ if __name__ == "__main__":
160
+ main()
@@ -0,0 +1,63 @@
1
+ """Structured JSON output for CLI commands.
2
+
3
+ Every command that supports --json uses this module to produce
4
+ a standard envelope: {status, command, data, files, warnings, errors}.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import json
9
+ import sys
10
+ import traceback
11
+ from typing import Any
12
+
13
+
14
+ def json_envelope(
15
+ command: str,
16
+ *,
17
+ status: str = "success",
18
+ data: Any = None,
19
+ files: list[str] | None = None,
20
+ warnings: list[str] | None = None,
21
+ errors: list[str] | None = None,
22
+ ) -> dict[str, Any]:
23
+ """Build a standard JSON envelope."""
24
+ return {
25
+ "status": status,
26
+ "command": command,
27
+ "data": data,
28
+ "files": files or [],
29
+ "warnings": warnings or [],
30
+ "errors": errors or [],
31
+ }
32
+
33
+
34
+ def emit_json(envelope: dict[str, Any]) -> None:
35
+ """Write JSON envelope to stdout and flush."""
36
+ json.dump(envelope, sys.stdout, default=str)
37
+ sys.stdout.write("\n")
38
+ sys.stdout.flush()
39
+
40
+
41
+ def run_json_command(command: str, fn, **kwargs) -> None:
42
+ """Run a function and emit its result as JSON.
43
+
44
+ fn must return a dict with optional keys: data, files, warnings.
45
+ On exception, emits error envelope.
46
+ """
47
+ try:
48
+ result = fn(**kwargs)
49
+ if result is None:
50
+ result = {}
51
+ envelope = json_envelope(
52
+ command,
53
+ data=result.get("data"),
54
+ files=result.get("files", []),
55
+ warnings=result.get("warnings", []),
56
+ )
57
+ except Exception as e:
58
+ envelope = json_envelope(
59
+ command,
60
+ status="error",
61
+ errors=[str(e), traceback.format_exc()],
62
+ )
63
+ emit_json(envelope)
@@ -7,6 +7,7 @@ from typing import Optional
7
7
  import typer
8
8
  from rich.panel import Panel
9
9
 
10
+ from clawed._json_output import run_json_command
10
11
  from clawed.commands._helpers import console
11
12
  from clawed.commands.config import config_app
12
13
  from clawed.models import AppConfig, LLMProvider
@@ -142,9 +143,24 @@ def config_set_search_key(
142
143
  console.print(f"[green]\u2713 {provider.title()} search key saved.[/green]")
143
144
 
144
145
 
146
+ def _config_show_json():
147
+ """Return config data for JSON output."""
148
+ cfg = AppConfig.load()
149
+ return {
150
+ "data": cfg.model_dump() if hasattr(cfg, "model_dump") else cfg.dict(),
151
+ "files": [],
152
+ }
153
+
154
+
145
155
  @config_app.command("show")
146
- def config_show():
156
+ def config_show(
157
+ json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
158
+ ):
147
159
  """Show current configuration."""
160
+ if json_output:
161
+ run_json_command("config.show", _config_show_json)
162
+ return
163
+
148
164
  from clawed.config import get_api_key
149
165
 
150
166
  cfg = AppConfig.load()
@@ -8,6 +8,7 @@ import typer
8
8
  from rich.panel import Panel
9
9
  from rich.table import Table
10
10
 
11
+ from clawed._json_output import run_json_command
11
12
  from clawed.commands._helpers import console, load_persona_or_exit
12
13
  from clawed.commands.config import (
13
14
  class_app,
@@ -22,8 +23,20 @@ from clawed.commands.config import (
22
23
 
23
24
 
24
25
  @persona_app.command("show")
25
- def persona_show():
26
+ def persona_show(
27
+ json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
28
+ ):
26
29
  """Display the current teacher persona."""
30
+ if json_output:
31
+ def _persona_show_json():
32
+ persona = load_persona_or_exit()
33
+ return {
34
+ "data": {"persona": persona.model_dump() if hasattr(persona, "model_dump") else persona.dict()},
35
+ "files": [],
36
+ }
37
+ run_json_command("config.persona.show", _persona_show_json)
38
+ return
39
+
27
40
  persona = load_persona_or_exit()
28
41
  console.print(
29
42
  Panel(persona.to_prompt_context(), title="Teacher Persona")
@@ -41,8 +54,25 @@ def standards_list(
41
54
  subject: str = typer.Option(
42
55
  ..., "--subject", "-s", help="Subject (math, ela, science, history)"
43
56
  ),
57
+ json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
44
58
  ):
45
59
  """List education standards for a grade and subject."""
60
+ if json_output:
61
+ def _standards_json():
62
+ from clawed.standards import get_standards as _get_stds
63
+ results = _get_stds(subject, grade)
64
+ return {
65
+ "data": {
66
+ "standards": [
67
+ {"code": s.code, "description": s.description, "band": getattr(s, "band", "")}
68
+ for s in results
69
+ ] if results else []
70
+ },
71
+ "files": [],
72
+ }
73
+ run_json_command("config.standards.list", _standards_json)
74
+ return
75
+
46
76
  from clawed.standards import get_standards, resolve_subject
47
77
 
48
78
  canonical = resolve_subject(subject)
@@ -15,6 +15,7 @@ import typer
15
15
  from rich.panel import Panel
16
16
  from rich.table import Table
17
17
 
18
+ from clawed._json_output import run_json_command
18
19
  from clawed.commands._helpers import console
19
20
  from clawed.database import Database
20
21
 
@@ -305,8 +306,23 @@ def export_cmd(
305
306
  "-f",
306
307
  help="Export format: classroom",
307
308
  ),
309
+ json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
308
310
  ):
309
311
  """Export a lesson plan (e.g., to Google Classroom JSON)."""
312
+ if json_output:
313
+ def _export_json():
314
+ p = Path(lesson_file).expanduser().resolve()
315
+ if not p.exists():
316
+ raise FileNotFoundError(f"File not found: {p}")
317
+ data = json.loads(p.read_text(encoding="utf-8"))
318
+ out_path = p.with_suffix(".classroom.json")
319
+ return {
320
+ "data": {"title": data.get("title", ""), "format": fmt},
321
+ "files": [str(out_path)] if out_path.exists() else [],
322
+ }
323
+ run_json_command("export", _export_json)
324
+ return
325
+
310
326
  path = Path(lesson_file).expanduser().resolve()
311
327
  if not path.exists():
312
328
  console.print(f"[red]File not found:[/red] {path}")