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.
- {clawed-2.5.3 → clawed-3.0.0}/.gitignore +8 -0
- {clawed-2.5.3 → clawed-3.0.0}/PKG-INFO +34 -25
- {clawed-2.5.3 → clawed-3.0.0}/README.md +31 -22
- {clawed-2.5.3 → clawed-3.0.0}/clawed/__init__.py +2 -2
- {clawed-2.5.3 → clawed-3.0.0}/clawed/__main__.py +2 -2
- clawed-3.0.0/clawed/_cli_bundle/.gitkeep +0 -0
- clawed-3.0.0/clawed/_entry_router.py +160 -0
- clawed-3.0.0/clawed/_json_output.py +63 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/config_llm.py +17 -1
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/config_profile.py +31 -1
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/export.py +16 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/game.py +53 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/generate.py +97 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/generate_assessment.py +31 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/generate_unit.py +36 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/train.py +30 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/compile_game.py +14 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/export_pptx.py +193 -65
- clawed-3.0.0/daemon/index.ts +165 -0
- clawed-3.0.0/daemon/process-manager.ts +240 -0
- clawed-3.0.0/daemon/telegram-bridge.ts +356 -0
- {clawed-2.5.3 → clawed-3.0.0}/pyproject.toml +7 -6
- clawed-3.0.0/scripts/build.sh +100 -0
- clawed-3.0.0/scripts/bump_version.sh +30 -0
- clawed-3.0.0/scripts/ingest_jon.py +157 -0
- clawed-3.0.0/scripts/install.sh +261 -0
- clawed-3.0.0/scripts/post_release.py +96 -0
- clawed-3.0.0/scripts/publish.sh +76 -0
- {clawed-2.5.3 → clawed-3.0.0}/LICENSE +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/_legacy_gateway.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/__init__.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/approvals.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/autonomy.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/context.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/core.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/custom_tools.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/drive/__init__.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/drive/auth.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/drive/client.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/fake_llm.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/loop.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/__init__.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/curriculum.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/curriculum_kb.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/embeddings.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/episodes.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/identity.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/loader.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/memory/preferences.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/planner.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/prompt.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/scheduler.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/__init__.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/base.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/configure_profile.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/curriculum_map.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/drive_create_doc.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/drive_create_slides.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/drive_list.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/drive_organize.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/drive_read.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/drive_upload.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/export_document.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/gap_analysis.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/generate_assessment.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/generate_lesson.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/generate_lesson_bundle.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/generate_materials.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/generate_unit.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/ingest_materials.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/parent_comm.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/read_heartbeat.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/read_workspace.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/request_approval.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/schedule_task.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/search_lessons.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/search_my_materials.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/search_standards.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/student_insights.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/sub_packet.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/switch_model.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/agent_core/tools/update_soul.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/analytics.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/__init__.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/deps.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/__init__.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/chat.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/export.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/feedback.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/gateway_chat.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/generate.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/ingest.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/lessons.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/school.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/settings.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/routes/tools.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/server.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/static/app.js +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/static/style.css +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/static/widget.js +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/analytics.html +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/base.html +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/dashboard.html +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/generate.html +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/index.html +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/lesson.html +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/profile.html +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/settings.html +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/stats.html +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/api/templates/students.html +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/assessment.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/asset_registry.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/async_utils.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/auth/__init__.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/auth/google_auth.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/bot_state.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/chat.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/cli.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/cli_chat.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/__init__.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/_helpers.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/bot.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/config.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/queue.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/schedule_cmd.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/sub.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/commands/workspace_cmd.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/compile_slides.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/compile_student.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/compile_teacher.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/config.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/corpus.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/curriculum_map.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/database.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/__init__.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_assessment.json +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_formative_assessment.json +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_lesson_materials.json +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_lesson_science_g6.json +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_lesson_social_studies_g8.json +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_master_content.json +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_pacing_guide.json +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_quiz.json +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_rubric.json +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_unit_plan.json +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/demo/demo_year_map.json +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/differentiation.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/doc_export.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/drive.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/evaluation.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/export_docx.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/export_handout.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/export_markdown.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/export_pdf.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/export_templates.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/export_theme.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/exporter.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/failure_codes.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/feedback.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/formats/__init__.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/formats/flipchart.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/formats/notebook.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/formats/xbk.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/gateway.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/gateway_response.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/generation.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/generation_report.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/__init__.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/export.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/feedback.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/gaps.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/generate.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/ingest.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/misc.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/onboard.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/schedule.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/handlers/standards.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/hermes_plugin.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/image_pipeline.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/improver.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/ingestor.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/io.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/lesson.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/llm.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/master_content.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/materials.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/mcp_server.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/memory_engine.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/model_router.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/models.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/multi_agent.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/onboarding.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/openclaw_plugin.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/parent_comm.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/persona.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/persona_evolution.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/planner.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/504_accommodations.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/admin_lesson_plan.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/assessment.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/curriculum_gaps.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/dbq_assessment.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/differentiation.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/formative_assessment.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/iep_modification.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/lesson_plan.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/master_content.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/multi_agent_researcher.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/multi_agent_reviewer.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/pacing_guide.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/parent_note.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/persona_extract.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/quiz.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/rubric.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/student_packet.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/sub_packet.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/summative_assessment.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/tiered_assignments.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/unit_plan.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/worksheet.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/prompts/year_map.txt +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/quality.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/reading_report.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/review_output.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/router.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/sanitize.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/scheduler.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/school.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/search.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/__init__.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/art.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/base.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/computer_science.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/ela.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/foreign_language.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/history.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/library.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/math.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/music.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/physical_education.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/science.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/social_studies.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/skills/special_education.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/slide_images.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/standards.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/state.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/state_standards.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/student_bot.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/student_cli.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/student_telegram_bot.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/sub_packet.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/task_queue.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/templates_lib.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/tools.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/__init__.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/cli.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/hermes.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/openclaw.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/student_telegram.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/telegram.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/transports/web.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/tui.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/tui_chat.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/validation.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/voice.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/voice_check.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/clawed/workspace.py +0 -0
- {clawed-2.5.3 → clawed-3.0.0}/eduagent/__init__.py +0 -0
- {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:
|
|
4
|
-
Summary:
|
|
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 ::
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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
|
-
- **
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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
|
-
- **
|
|
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.
|
|
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__ = "
|
|
20
|
+
__version__ = "3.0.0"
|
|
21
21
|
__author__ = "Jon Maccarello & Claw-ED contributors"
|
|
22
|
-
__description__ = "
|
|
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.
|
|
14
|
-
|
|
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}")
|