cct-cli 0.7.9.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- calc_terminal/__init__.py +14 -0
- calc_terminal/__main__.py +14 -0
- calc_terminal/activity.py +1334 -0
- calc_terminal/agent.py +3387 -0
- calc_terminal/agent_runtime.py +519 -0
- calc_terminal/ai_context.py +447 -0
- calc_terminal/ai_modes.py +752 -0
- calc_terminal/ai_personalization.py +286 -0
- calc_terminal/ai_preview_feedback.py +213 -0
- calc_terminal/aicore.py +2572 -0
- calc_terminal/anim.py +367 -0
- calc_terminal/app.py +3685 -0
- calc_terminal/art.py +639 -0
- calc_terminal/atomsim.py +368 -0
- calc_terminal/attachments.py +743 -0
- calc_terminal/benchmark_system.py +414 -0
- calc_terminal/browser/__init__.py +36 -0
- calc_terminal/browser/browser_state.py +346 -0
- calc_terminal/browser/devserver.py +176 -0
- calc_terminal/browser/engine.py +494 -0
- calc_terminal/browser/navigation.py +84 -0
- calc_terminal/browser/preview.py +429 -0
- calc_terminal/browser/preview_entry.py +95 -0
- calc_terminal/browser/project_detector.py +144 -0
- calc_terminal/browser/server.py +449 -0
- calc_terminal/browser/state.py +75 -0
- calc_terminal/browser/watcher.py +99 -0
- calc_terminal/browser_gui/__init__.py +1 -0
- calc_terminal/browser_gui/__main__.py +3 -0
- calc_terminal/browser_gui/launcher.py +173 -0
- calc_terminal/browser_gui/playwright_browser.py +117 -0
- calc_terminal/browser_gui/qt_browser.py +1501 -0
- calc_terminal/browser_gui/webview_browser.py +57 -0
- calc_terminal/capabilities/__init__.py +35 -0
- calc_terminal/capabilities/adapters/__init__.py +33 -0
- calc_terminal/capabilities/adapters/bioinformatics.py +204 -0
- calc_terminal/capabilities/adapters/browser_adapter.py +205 -0
- calc_terminal/capabilities/adapters/filesystem.py +206 -0
- calc_terminal/capabilities/adapters/git_adapter.py +202 -0
- calc_terminal/capabilities/adapters/jupyter_adapter.py +138 -0
- calc_terminal/capabilities/adapters/ml_frameworks.py +158 -0
- calc_terminal/capabilities/adapters/platforms.py +200 -0
- calc_terminal/capabilities/adapters/python_exec.py +93 -0
- calc_terminal/capabilities/adapters/quantum_adapter.py +150 -0
- calc_terminal/capabilities/adapters/scientific_comp.py +123 -0
- calc_terminal/capabilities/adapters/structural_bio.py +161 -0
- calc_terminal/capabilities/adapters/terminal.py +99 -0
- calc_terminal/capabilities/bus.py +178 -0
- calc_terminal/capabilities/discovery.py +207 -0
- calc_terminal/capabilities/schema.py +221 -0
- calc_terminal/cat.ico +0 -0
- calc_terminal/cat_browser.py +2018 -0
- calc_terminal/chat_store.py +703 -0
- calc_terminal/cli.py +1178 -0
- calc_terminal/code_editor.py +640 -0
- calc_terminal/collaboration.py +723 -0
- calc_terminal/commands_data.py +139 -0
- calc_terminal/compatibility_engine.py +352 -0
- calc_terminal/compute/__init__.py +31 -0
- calc_terminal/compute/fabric.py +350 -0
- calc_terminal/config.py +227 -0
- calc_terminal/core/__init__.py +41 -0
- calc_terminal/core/checkpoint.py +156 -0
- calc_terminal/core/input/__init__.py +45 -0
- calc_terminal/core/mode_registry.py +300 -0
- calc_terminal/core/project_graph.py +172 -0
- calc_terminal/core/recovery.py +129 -0
- calc_terminal/core/security_layer.py +112 -0
- calc_terminal/core/task_graph.py +202 -0
- calc_terminal/core/unified_runtime.py +184 -0
- calc_terminal/core/verification.py +257 -0
- calc_terminal/customization.py +1566 -0
- calc_terminal/derivations.py +153 -0
- calc_terminal/device_control.py +263 -0
- calc_terminal/diagnostics/__init__.py +27 -0
- calc_terminal/diagnostics/doctor_engine.py +382 -0
- calc_terminal/diagnostics/self_test.py +247 -0
- calc_terminal/doctor.py +519 -0
- calc_terminal/easter_eggs.py +274 -0
- calc_terminal/editor/__init__.py +1 -0
- calc_terminal/editor/actions.py +263 -0
- calc_terminal/editor/commands.py +160 -0
- calc_terminal/editor/shortcuts.py +226 -0
- calc_terminal/engine.py +259 -0
- calc_terminal/errors.py +120 -0
- calc_terminal/event_stream.py +146 -0
- calc_terminal/eventbus.py +133 -0
- calc_terminal/extensions.py +733 -0
- calc_terminal/fallback_cli.py +1321 -0
- calc_terminal/first_run.py +265 -0
- calc_terminal/fomoji_auth.py +1043 -0
- calc_terminal/formulas.py +82 -0
- calc_terminal/fs_cache.py +121 -0
- calc_terminal/fs_watcher.py +277 -0
- calc_terminal/game.py +193 -0
- calc_terminal/gen1.py +5 -0
- calc_terminal/generators.py +245 -0
- calc_terminal/gestures/__init__.py +42 -0
- calc_terminal/gestures/bindings.py +175 -0
- calc_terminal/gestures/manager.py +477 -0
- calc_terminal/goodbye.py +363 -0
- calc_terminal/gpu3d.py +290 -0
- calc_terminal/graphs.py +358 -0
- calc_terminal/hardware_analyzer.py +440 -0
- calc_terminal/host/__init__.py +30 -0
- calc_terminal/host/browser_manager.py +187 -0
- calc_terminal/host/desktop.py +1386 -0
- calc_terminal/host/launcher.py +395 -0
- calc_terminal/host/terminal.py +279 -0
- calc_terminal/identity.py +216 -0
- calc_terminal/input/__init__.py +54 -0
- calc_terminal/input/capabilities.py +258 -0
- calc_terminal/input/focus.py +87 -0
- calc_terminal/input/gestures.py +64 -0
- calc_terminal/input/pointer.py +114 -0
- calc_terminal/input/touch.py +345 -0
- calc_terminal/keys.py +84 -0
- calc_terminal/live_automation.py +165 -0
- calc_terminal/mathtext.py +433 -0
- calc_terminal/mcp.py +386 -0
- calc_terminal/memory.py +337 -0
- calc_terminal/memory_v2.py +479 -0
- calc_terminal/metrics.py +333 -0
- calc_terminal/mode_detection.py +146 -0
- calc_terminal/model.py +2431 -0
- calc_terminal/model_router.py +665 -0
- calc_terminal/models/__init__.py +0 -0
- calc_terminal/models/active_state.py +187 -0
- calc_terminal/models/dynamic_registry.py +584 -0
- calc_terminal/models/manager.py +781 -0
- calc_terminal/models/model_metadata.json +3526 -0
- calc_terminal/models/profiles.py +194 -0
- calc_terminal/models/registry.py +265 -0
- calc_terminal/models/schema.py +197 -0
- calc_terminal/models/validator.py +287 -0
- calc_terminal/models/verification_engine.py +368 -0
- calc_terminal/native_picker.py +215 -0
- calc_terminal/ollama_catalog.py +279 -0
- calc_terminal/ollama_download.py +233 -0
- calc_terminal/orchestrator.py +304 -0
- calc_terminal/package_research.py +322 -0
- calc_terminal/packages.py +1024 -0
- calc_terminal/pc_specs.py +116 -0
- calc_terminal/permissions.py +334 -0
- calc_terminal/pet.py +106 -0
- calc_terminal/pipeline.py +505 -0
- calc_terminal/platform/__init__.py +491 -0
- calc_terminal/platform/desktop.py +491 -0
- calc_terminal/platform/web.py +781 -0
- calc_terminal/preview/__init__.py +1 -0
- calc_terminal/preview/dev_server.py +303 -0
- calc_terminal/preview/diagnostics.py +131 -0
- calc_terminal/preview/live_reload.py +66 -0
- calc_terminal/preview/manager.py +129 -0
- calc_terminal/project_stats.py +209 -0
- calc_terminal/projects.py +328 -0
- calc_terminal/providers/__init__.py +0 -0
- calc_terminal/providers/adapters/__init__.py +80 -0
- calc_terminal/providers/adapters/anthropic_adapter.py +127 -0
- calc_terminal/providers/adapters/base.py +106 -0
- calc_terminal/providers/adapters/chinese_adapters.py +420 -0
- calc_terminal/providers/adapters/gemini_adapter.py +101 -0
- calc_terminal/providers/adapters/ollama_adapter.py +83 -0
- calc_terminal/providers/adapters/openai_adapter.py +159 -0
- calc_terminal/providers/adapters/other_adapters.py +246 -0
- calc_terminal/providers/anthropic_provider.py +172 -0
- calc_terminal/providers/auto_update.py +416 -0
- calc_terminal/providers/base_provider.py +105 -0
- calc_terminal/providers/discovery_manager.py +207 -0
- calc_terminal/providers/gemini_provider.py +178 -0
- calc_terminal/providers/lifecycle.py +767 -0
- calc_terminal/providers/ollama_adapter.py +707 -0
- calc_terminal/providers/openai_provider.py +254 -0
- calc_terminal/providers/provider_manager.py +1827 -0
- calc_terminal/providers/providers.json +4075 -0
- calc_terminal/reactionsim.py +279 -0
- calc_terminal/registry.py +337 -0
- calc_terminal/report.py +162 -0
- calc_terminal/research/__init__.py +45 -0
- calc_terminal/research/artifact_intel.py +126 -0
- calc_terminal/research/data_lineage.py +123 -0
- calc_terminal/research/experiment_ledger.py +303 -0
- calc_terminal/research/reproducibility.py +131 -0
- calc_terminal/resilience/__init__.py +47 -0
- calc_terminal/resilience/agent_state.py +121 -0
- calc_terminal/resilience/capability_matcher.py +174 -0
- calc_terminal/resilience/circuit_breaker.py +158 -0
- calc_terminal/resilience/failover_engine.py +230 -0
- calc_terminal/resilience/health_monitor.py +192 -0
- calc_terminal/resilience/ollama_adapter.py +125 -0
- calc_terminal/resilience/orchestrator.py +312 -0
- calc_terminal/resilience/types.py +134 -0
- calc_terminal/sandbox.py +98 -0
- calc_terminal/scires.py +558 -0
- calc_terminal/security_scanner.py +126 -0
- calc_terminal/session.py +294 -0
- calc_terminal/sim3d.py +206 -0
- calc_terminal/solver.py +276 -0
- calc_terminal/sound.py +127 -0
- calc_terminal/task_reports.py +287 -0
- calc_terminal/terminal_host.py +201 -0
- calc_terminal/terminal_identity.py +411 -0
- calc_terminal/test_ai_mode_reliability.py +344 -0
- calc_terminal/test_browser.py +368 -0
- calc_terminal/test_code_editor_upgrade.py +485 -0
- calc_terminal/test_customization.py +1148 -0
- calc_terminal/test_customization_ui.py +612 -0
- calc_terminal/test_dynamic_registry.py +304 -0
- calc_terminal/test_extensions.py +436 -0
- calc_terminal/test_overhaul.py +557 -0
- calc_terminal/test_project_detect.py +255 -0
- calc_terminal/test_root_cause_fix.py +527 -0
- calc_terminal/test_stability.py +532 -0
- calc_terminal/test_terminal_identity.py +132 -0
- calc_terminal/test_v079_speed.py +460 -0
- calc_terminal/theme.py +1107 -0
- calc_terminal/timeline.py +139 -0
- calc_terminal/todos.py +246 -0
- calc_terminal/tool_call_normalizer.py +419 -0
- calc_terminal/tui.py +104 -0
- calc_terminal/ui/__init__.py +8 -0
- calc_terminal/ui/activity_panel.py +231 -0
- calc_terminal/ui/activity_stream_panel.py +238 -0
- calc_terminal/ui/animations.py +122 -0
- calc_terminal/ui/app.py +7271 -0
- calc_terminal/ui/attach_panel.py +597 -0
- calc_terminal/ui/attachments.py +424 -0
- calc_terminal/ui/backup_panel.py +810 -0
- calc_terminal/ui/browser_shell.py +887 -0
- calc_terminal/ui/cat_agent.py +357 -0
- calc_terminal/ui/chats_panel.py +899 -0
- calc_terminal/ui/command_palette.py +125 -0
- calc_terminal/ui/command_palette_modal.py +166 -0
- calc_terminal/ui/composer.py +1141 -0
- calc_terminal/ui/context_menu.py +197 -0
- calc_terminal/ui/conversation.py +1435 -0
- calc_terminal/ui/customization_panel.py +1229 -0
- calc_terminal/ui/dashboard.py +404 -0
- calc_terminal/ui/design_system.py +557 -0
- calc_terminal/ui/diff_panel.py +213 -0
- calc_terminal/ui/editor.py +2102 -0
- calc_terminal/ui/empty_state.py +302 -0
- calc_terminal/ui/events.py +487 -0
- calc_terminal/ui/extensions_panel.py +815 -0
- calc_terminal/ui/footer.py +166 -0
- calc_terminal/ui/gestures_panel.py +383 -0
- calc_terminal/ui/goodbye_screen.py +100 -0
- calc_terminal/ui/header.py +1034 -0
- calc_terminal/ui/help_panel.py +254 -0
- calc_terminal/ui/live_activities.py +914 -0
- calc_terminal/ui/mcp_panel.py +570 -0
- calc_terminal/ui/memory_center.py +524 -0
- calc_terminal/ui/mode_colors_panel.py +525 -0
- calc_terminal/ui/nav_screens.py +747 -0
- calc_terminal/ui/ollama_panel.py +536 -0
- calc_terminal/ui/palette.py +221 -0
- calc_terminal/ui/permission_panel.py +269 -0
- calc_terminal/ui/personalization_panel.py +517 -0
- calc_terminal/ui/personalize_center.py +1568 -0
- calc_terminal/ui/preview_panel.py +441 -0
- calc_terminal/ui/resizers.py +402 -0
- calc_terminal/ui/sidebar.py +1285 -0
- calc_terminal/ui/statusbar.py +168 -0
- calc_terminal/ui/theme_css.py +1396 -0
- calc_terminal/ui/thinking.py +226 -0
- calc_terminal/ui/timeline_panel.py +102 -0
- calc_terminal/ui/todo_panel.py +193 -0
- calc_terminal/ui/viewport.py +136 -0
- calc_terminal/ui/vision_panel.py +489 -0
- calc_terminal/ui/welcome_modal.py +343 -0
- calc_terminal/ui/widgets.py +160 -0
- calc_terminal/ui/workspace.py +831 -0
- calc_terminal/viewers/__init__.py +1 -0
- calc_terminal/viewers/document_viewer.py +252 -0
- calc_terminal/viewers/image_viewer.py +241 -0
- calc_terminal/viewers/pdf_viewer.py +203 -0
- calc_terminal/viewers/presentation_viewer.py +164 -0
- calc_terminal/viewers/registry.py +120 -0
- calc_terminal/viewers/spreadsheet_viewer.py +204 -0
- calc_terminal/vision/__init__.py +89 -0
- calc_terminal/vision/analysis.py +194 -0
- calc_terminal/vision/annotations.py +297 -0
- calc_terminal/vision/capture.py +171 -0
- calc_terminal/vision/context.py +231 -0
- calc_terminal/vision/correlation.py +169 -0
- calc_terminal/vision/cursor.py +258 -0
- calc_terminal/vision/events.py +66 -0
- calc_terminal/vision/frame_pipeline.py +259 -0
- calc_terminal/vision/priority.py +218 -0
- calc_terminal/vision/provider.py +180 -0
- calc_terminal/vision/safety.py +149 -0
- calc_terminal/vision/session.py +281 -0
- calc_terminal/vision/verify.py +162 -0
- calc_terminal/vision.py +514 -0
- calc_terminal/vscode_integration.py +113 -0
- calc_terminal/web/__init__.py +8 -0
- calc_terminal/web/cat_runtime.py +710 -0
- calc_terminal/web/server.py +2891 -0
- calc_terminal/web/static/css/app.css +3152 -0
- calc_terminal/web/static/icons/badge-72.png +0 -0
- calc_terminal/web/static/icons/cat.ico +0 -0
- calc_terminal/web/static/icons/icon-128.png +0 -0
- calc_terminal/web/static/icons/icon-144.png +0 -0
- calc_terminal/web/static/icons/icon-152.png +0 -0
- calc_terminal/web/static/icons/icon-192.png +0 -0
- calc_terminal/web/static/icons/icon-384.png +0 -0
- calc_terminal/web/static/icons/icon-512.png +0 -0
- calc_terminal/web/static/icons/icon-72.png +0 -0
- calc_terminal/web/static/icons/icon-96.png +0 -0
- calc_terminal/web/static/icons/icon.svg +34 -0
- calc_terminal/web/static/icons/new-project.png +0 -0
- calc_terminal/web/static/icons/open-project.png +0 -0
- calc_terminal/web/static/index.html +734 -0
- calc_terminal/web/static/js/app.js +2403 -0
- calc_terminal/web/static/manifest.json +88 -0
- calc_terminal/web/static/sw.js +230 -0
- calc_terminal/workflow_engine.py +769 -0
- calc_terminal/workspace.py +593 -0
- calc_terminal/workspace_index.py +385 -0
- cct_cli-0.7.9.0.dist-info/METADATA +210 -0
- cct_cli-0.7.9.0.dist-info/RECORD +325 -0
- cct_cli-0.7.9.0.dist-info/WHEEL +5 -0
- cct_cli-0.7.9.0.dist-info/entry_points.txt +4 -0
- cct_cli-0.7.9.0.dist-info/licenses/LICENSE +21 -0
- cct_cli-0.7.9.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Real calculus derivations for chemical kinetics rate laws.
|
|
3
|
+
|
|
4
|
+
These are NOT random numericals — they are the actual step-by-step
|
|
5
|
+
derivation of the integrated rate law from the differential rate law,
|
|
6
|
+
using proper mathematical notation (stacked fractions via mathtext,
|
|
7
|
+
"x" for multiplication, integral signs, etc.), the way it is worked
|
|
8
|
+
out on paper / on a board.
|
|
9
|
+
|
|
10
|
+
Each function returns a dict consumed by engine.render_derivation():
|
|
11
|
+
topic, goal, steps: [(label, [compose-parts]), ...], result, note
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from .mathtext import frac_part as F, sub, sup
|
|
15
|
+
|
|
16
|
+
MUL = "\u00d7" # x (never "*")
|
|
17
|
+
INT = "\u222b" # integral sign
|
|
18
|
+
DDT = "d[R]/dt"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def zero_order_derivation():
|
|
22
|
+
steps = [
|
|
23
|
+
("Rate law (differential form)",
|
|
24
|
+
[f"Rate = \u2212d[R]/dt = k[R]", sup(0), " = k"]),
|
|
25
|
+
("Separate the variables",
|
|
26
|
+
["\u2212d[R] = k ", "dt"]),
|
|
27
|
+
("Integrate both sides",
|
|
28
|
+
[INT, " ", "from [R]", sub(0), " to [R]", " \u2212d[R] = k ", INT, " from 0 to t dt"]),
|
|
29
|
+
("Evaluate the integral",
|
|
30
|
+
["\u2212([R] \u2212 [R]", sub(0), ") = k(t \u2212 0)"]),
|
|
31
|
+
("Rearrange for [R]",
|
|
32
|
+
["[R] = [R]", sub(0), " \u2212 kt"]),
|
|
33
|
+
("Solve for k (rearranged form)",
|
|
34
|
+
["k = ", F(f"[R]{sub(0)} \u2212 [R]", "t")]),
|
|
35
|
+
]
|
|
36
|
+
return {
|
|
37
|
+
"topic": "Derivation \u00b7 Zero Order Integrated Rate Law",
|
|
38
|
+
"goal": "Derive [R] = [R]\u2080 \u2212 kt starting from the differential rate law of a zero order reaction.",
|
|
39
|
+
"steps": steps,
|
|
40
|
+
"result": f"[R] = [R]{sub(0)} \u2212 kt (equivalently k = ([R]{sub(0)} \u2212 [R]) / t )",
|
|
41
|
+
"note": "For a zero order reaction the rate is independent of concentration, so [R] falls "
|
|
42
|
+
"LINEARLY with time \u2014 a straight line of slope \u2212k when [R] is plotted against t.",
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def first_order_derivation():
|
|
47
|
+
steps = [
|
|
48
|
+
("Rate law (differential form)",
|
|
49
|
+
["Rate = \u2212d[R]/dt = k[R]"]),
|
|
50
|
+
("Separate the variables",
|
|
51
|
+
["\u2212", F("d[R]", "[R]"), " = k dt"]),
|
|
52
|
+
("Integrate both sides",
|
|
53
|
+
[INT, " from [R]", sub(0), " to [R] \u2212", F("d[R]", "[R]"), " = k ", INT, " from 0 to t dt"]),
|
|
54
|
+
("Evaluate the integral (\u222bd[R]/[R] = ln[R])",
|
|
55
|
+
["\u2212(ln[R] \u2212 ln[R]", sub(0), ") = kt"]),
|
|
56
|
+
("Combine logarithms",
|
|
57
|
+
["ln(", f"[R]{sub(0)}", "/[R]) = kt"]),
|
|
58
|
+
("Solve for k, convert ln \u2192 log",
|
|
59
|
+
["k = ", F("1", "t"), " ln(", f"[R]{sub(0)}", "/[R]) = ", F("2.303", "t"),
|
|
60
|
+
f" log{sub(10)}([R]{sub(0)}/[R])"]),
|
|
61
|
+
]
|
|
62
|
+
return {
|
|
63
|
+
"topic": "Derivation \u00b7 First Order Integrated Rate Law",
|
|
64
|
+
"goal": "Derive k = (2.303/t) log([R]\u2080/[R]) starting from the differential rate law of a first order reaction.",
|
|
65
|
+
"steps": steps,
|
|
66
|
+
"result": f"k = (2.303/t) \u00d7 log{sub(10)}([R]{sub(0)}/[R]) (equivalently [R] = [R]{sub(0)} e{sup('-kt')} )",
|
|
67
|
+
"note": "Because the exponent is linear in t, a plot of ln[R] (or log[R]) against t is a straight "
|
|
68
|
+
"line of slope \u2212k \u2014 the diagnostic test for first order kinetics.",
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def second_order_derivation():
|
|
73
|
+
steps = [
|
|
74
|
+
("Rate law (differential form)",
|
|
75
|
+
["Rate = \u2212d[R]/dt = k[R]", sup(2)]),
|
|
76
|
+
("Separate the variables",
|
|
77
|
+
["\u2212", F("d[R]", "[R]" + sup(2)), " = k dt"]),
|
|
78
|
+
("Integrate both sides",
|
|
79
|
+
[INT, " from [R]", sub(0), " to [R] \u2212", F("d[R]", "[R]" + sup(2)), " = k ", INT, " from 0 to t dt"]),
|
|
80
|
+
("Evaluate the integral (\u222bd[R]/[R]\u00b2 = \u22121/[R])",
|
|
81
|
+
[F("1", "[R]"), " \u2212 ", F("1", f"[R]{sub(0)}"), " = kt"]),
|
|
82
|
+
("Rearrange",
|
|
83
|
+
[F("1", "[R]"), " = ", F("1", f"[R]{sub(0)}"), " + kt"]),
|
|
84
|
+
]
|
|
85
|
+
return {
|
|
86
|
+
"topic": "Derivation \u00b7 Second Order Integrated Rate Law",
|
|
87
|
+
"goal": "Derive 1/[R] = 1/[R]\u2080 + kt starting from the differential rate law of a second order reaction.",
|
|
88
|
+
"steps": steps,
|
|
89
|
+
"result": f"1/[R] = 1/[R]{sub(0)} + kt",
|
|
90
|
+
"note": "A plot of 1/[R] against t is a straight line of slope +k \u2014 the diagnostic test for "
|
|
91
|
+
"second order kinetics (unlike zero order, which is linear in [R] itself).",
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
def third_order_derivation():
|
|
95
|
+
steps = [
|
|
96
|
+
("Rate law (differential form)",
|
|
97
|
+
["Rate = \u2212d[R]/dt = k[R]", sup(3)]),
|
|
98
|
+
("Separate the variables",
|
|
99
|
+
["\u2212", F("d[R]", "[R]" + sup(3)), " = k dt"]),
|
|
100
|
+
("Integrate both sides",
|
|
101
|
+
[INT, " from [R]", sub(0), " to [R] \u2212", F("d[R]", "[R]" + sup(3)), " = k ", INT, " from 0 to t dt"]),
|
|
102
|
+
("Evaluate the integral (\u222bdx/x\u00b3 = \u22121/(2x\u00b2))",
|
|
103
|
+
[F("1", "2[R]" + sup(2)), " \u2212 ", F("1", f"2[R]{sub(0)}" + sup(2)), " = kt"]),
|
|
104
|
+
("Rearrange",
|
|
105
|
+
[F("1", "[R]" + sup(2)), " = ", F("1", f"[R]{sub(0)}" + sup(2)), " + 2kt"]),
|
|
106
|
+
]
|
|
107
|
+
return {
|
|
108
|
+
"topic": "Derivation \u00b7 Third Order Integrated Rate Law",
|
|
109
|
+
"goal": "Derive 1/[R]\u00b2 = 1/[R]\u2080\u00b2 + 2kt starting from the differential rate law of a third order reaction.",
|
|
110
|
+
"steps": steps,
|
|
111
|
+
"result": f"1/[R]{sup(2)} = 1/[R]{sub(0)}{sup(2)} + 2kt",
|
|
112
|
+
"note": "A plot of 1/[R]\u00b2 against t is a straight line of slope +2k \u2014 the diagnostic test for "
|
|
113
|
+
"third order kinetics.",
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
def half_life_first_derivation():
|
|
117
|
+
steps = [
|
|
118
|
+
("Start from the first order integrated law",
|
|
119
|
+
["k = ", F("2.303", "t"), f" log{sub(10)}([R]{sub(0)}/[R])"]),
|
|
120
|
+
(f"At t = t{sub('1/2')}, [R] = [R]",
|
|
121
|
+
[f"[R] = [R]{sub(0)}/2 \u21d2 [R]{sub(0)}/[R] = 2"]),
|
|
122
|
+
("Substitute and simplify",
|
|
123
|
+
["k = ", F("2.303", f"t{sub('1/2')}"), f" log{sub(10)}(2)"]),
|
|
124
|
+
("Use log\u2081\u2080(2) = 0.301",
|
|
125
|
+
["k = ", F("2.303 \u00d7 0.301", f"t{sub('1/2')}"), f" = ", F("0.693", f"t{sub('1/2')}")]),
|
|
126
|
+
("Solve for t\u2081/\u2082",
|
|
127
|
+
[f"t{sub('1/2')}", " = ", F("0.693", "k")]),
|
|
128
|
+
]
|
|
129
|
+
return {
|
|
130
|
+
"topic": "Derivation \u00b7 First Order Half-Life",
|
|
131
|
+
"goal": "Derive t\u00bd = 0.693/k from the first order integrated rate law.",
|
|
132
|
+
"steps": steps,
|
|
133
|
+
"result": f"t{sub('1/2')} = 0.693 / k",
|
|
134
|
+
"note": "Notice [R]\u2080 cancels out completely \u2014 first order half-life does NOT depend on the "
|
|
135
|
+
"starting concentration, unlike zero or second order.",
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
DERIVATIONS = {
|
|
140
|
+
"zero": zero_order_derivation,
|
|
141
|
+
"first": first_order_derivation,
|
|
142
|
+
"second": second_order_derivation,
|
|
143
|
+
"third": third_order_derivation,
|
|
144
|
+
"halflife": half_life_first_derivation,
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
DERIVATION_KEYWORDS = [
|
|
148
|
+
(r"zero\s*order", "zero"),
|
|
149
|
+
(r"second\s*order", "second"),
|
|
150
|
+
(r"third\s*order", "third"),
|
|
151
|
+
(r"half.?life", "halflife"),
|
|
152
|
+
(r"first\s*order", "first"),
|
|
153
|
+
]
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CCT — device_control.py: Responsible Device Control (v0.7.7 spec
|
|
3
|
+
section 14).
|
|
4
|
+
|
|
5
|
+
An extensible automation framework for interacting with the user's own
|
|
6
|
+
authorized devices, designed so that:
|
|
7
|
+
|
|
8
|
+
* every capability is a registered provider (Desktop / Android / iOS /
|
|
9
|
+
Browser / Terminal / Simulation) with an explicit availability
|
|
10
|
+
check — nothing claims to drive a device it can't;
|
|
11
|
+
* every action that affects a real device requires explicit user
|
|
12
|
+
approval (permissions.manager's "device_control" key + the same
|
|
13
|
+
inline permission-card flow installs use) and is recorded in the
|
|
14
|
+
activity log (eventbus -> session timeline) with the action, target,
|
|
15
|
+
and outcome — spec section 14's "every action ... clearly visible
|
|
16
|
+
in the activity log";
|
|
17
|
+
* the framework itself never executes anything: providers return a
|
|
18
|
+
plan (what command/API call would run, what it affects) and the
|
|
19
|
+
CALLER (the permission flow) decides. This keeps "device control"
|
|
20
|
+
honest — the same separation the spec asks for between automation
|
|
21
|
+
and user control.
|
|
22
|
+
|
|
23
|
+
Built-in providers, stated plainly:
|
|
24
|
+
* terminal — runs commands on the user's machine (delegates to the
|
|
25
|
+
existing shell_commands permission; the same
|
|
26
|
+
subprocess runner agent.py's run_terminal tool uses).
|
|
27
|
+
* simulation— CCT's own in-app simulations (atom, orbital, reaction):
|
|
28
|
+
sandboxed by construction, still approval-gated.
|
|
29
|
+
* desktop / android / ios / browser — EXTENSION POINTS, not working
|
|
30
|
+
drivers: they register with `available()` returning
|
|
31
|
+
False until a provider module implements them
|
|
32
|
+
(e.g. adb for Android, Playwright for browser). The
|
|
33
|
+
framework is complete; the drivers are future work —
|
|
34
|
+
the spec's "where platform APIs allow" is honored by
|
|
35
|
+
not faking support we don't have.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
if __name__ == "__main__":
|
|
39
|
+
print("This is a library file and is not meant to be run directly.")
|
|
40
|
+
import sys
|
|
41
|
+
sys.exit(1)
|
|
42
|
+
|
|
43
|
+
import shutil
|
|
44
|
+
import time
|
|
45
|
+
|
|
46
|
+
from . import eventbus
|
|
47
|
+
|
|
48
|
+
ACTIVITY_LOG = [] # [{ts, provider, action, target, decision, outcome}]
|
|
49
|
+
MAX_LOG = 200
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# -------------------------------------------------------------- providers --
|
|
53
|
+
class DeviceProvider:
|
|
54
|
+
"""Base class for a device-control capability. Subclasses implement
|
|
55
|
+
`available()` and `plan(action, params)`; the permission flow calls
|
|
56
|
+
`plan()` FIRST, shows the user what would happen, and only then
|
|
57
|
+
`execute()` (which providers implement only if they can really
|
|
58
|
+
do the thing)."""
|
|
59
|
+
|
|
60
|
+
key = "unnamed"
|
|
61
|
+
label = "Unnamed provider"
|
|
62
|
+
description = ""
|
|
63
|
+
|
|
64
|
+
def available(self):
|
|
65
|
+
return False
|
|
66
|
+
|
|
67
|
+
def plan(self, action, params):
|
|
68
|
+
"""Returns {"action": str, "target": str, "effect": str,
|
|
69
|
+
"command": [argv] or None} — the user-visible description of
|
|
70
|
+
what WOULD happen. Never None."""
|
|
71
|
+
return {"action": action, "target": "", "effect": "not implemented",
|
|
72
|
+
"command": None}
|
|
73
|
+
|
|
74
|
+
def execute(self, plan):
|
|
75
|
+
"""Actually performs the planned action. Only called after the
|
|
76
|
+
user approved `plan`. Providers that can't execute return a
|
|
77
|
+
refusal dict instead of faking it."""
|
|
78
|
+
return {"ok": False, "note": f"provider '{self.key}' has no executor"}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class TerminalProvider(DeviceProvider):
|
|
82
|
+
"""Terminal automation — runs commands through the exact same
|
|
83
|
+
subprocess runner agent.py's run_terminal tool uses."""
|
|
84
|
+
|
|
85
|
+
key = "terminal"
|
|
86
|
+
label = "Terminal"
|
|
87
|
+
description = "Run commands on this machine (shell, git, python, docker...)."
|
|
88
|
+
|
|
89
|
+
def available(self):
|
|
90
|
+
return True
|
|
91
|
+
|
|
92
|
+
def plan(self, action, params):
|
|
93
|
+
# Accept either "command" or the generic "target" param — the
|
|
94
|
+
# CLI /devices flow hands over {"target": "<command>"}.
|
|
95
|
+
cmd = str(params.get("command") or params.get("target") or "").strip()
|
|
96
|
+
return {"action": action,
|
|
97
|
+
"target": cmd,
|
|
98
|
+
"effect": f"Runs in your terminal: $ {cmd}",
|
|
99
|
+
"command": cmd}
|
|
100
|
+
|
|
101
|
+
def execute(self, plan):
|
|
102
|
+
import subprocess
|
|
103
|
+
cmd = plan.get("command")
|
|
104
|
+
if not cmd:
|
|
105
|
+
return {"ok": False, "note": "no command in plan"}
|
|
106
|
+
from . import workspace
|
|
107
|
+
cwd = workspace.root_dir() or None
|
|
108
|
+
try:
|
|
109
|
+
proc = subprocess.run(
|
|
110
|
+
cmd, shell=True, cwd=cwd, capture_output=True, text=True,
|
|
111
|
+
timeout=min(max(float(plan.get("timeout", 60) or 60), 1.0), 300.0),
|
|
112
|
+
encoding="utf-8", errors="replace")
|
|
113
|
+
except subprocess.TimeoutExpired:
|
|
114
|
+
return {"ok": False, "note": "command timed out"}
|
|
115
|
+
except OSError as e:
|
|
116
|
+
return {"ok": False, "note": f"could not run: {e}"}
|
|
117
|
+
return {"ok": proc.returncode == 0, "exit_code": proc.returncode,
|
|
118
|
+
"output": ((proc.stdout or "") + (proc.stderr or "")).strip()}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class SimulationProvider(DeviceProvider):
|
|
122
|
+
"""CCT's own in-app simulations — sandboxed by construction but
|
|
123
|
+
still approval-gated (spec: every action affecting the user's
|
|
124
|
+
environment is visible and approved)."""
|
|
125
|
+
|
|
126
|
+
key = "simulation"
|
|
127
|
+
label = "Simulation"
|
|
128
|
+
description = "CAT's in-app simulations (atom, orbital, reaction sims)."
|
|
129
|
+
|
|
130
|
+
def available(self):
|
|
131
|
+
return True
|
|
132
|
+
|
|
133
|
+
def plan(self, action, params):
|
|
134
|
+
sim = str(params.get("simulation", params.get("target", ""))).strip()
|
|
135
|
+
return {"action": action,
|
|
136
|
+
"target": sim,
|
|
137
|
+
"effect": f"Runs the in-app '{sim}' simulation (no system changes)",
|
|
138
|
+
"command": None}
|
|
139
|
+
|
|
140
|
+
def execute(self, plan):
|
|
141
|
+
# In-app simulations render in the terminal/UI directly — the
|
|
142
|
+
# caller (app.py / ui/app.py) starts them after approval; this
|
|
143
|
+
# provider only needs to confirm the plan is runnable.
|
|
144
|
+
return {"ok": True, "note": "simulation started by caller"}
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class _ScaffoldedProvider(DeviceProvider):
|
|
148
|
+
"""Extension-point providers (desktop/android/ios/browser): they
|
|
149
|
+
exist so the framework is complete and the permission/logging
|
|
150
|
+
machinery is real, but `available()` stays False until an actual
|
|
151
|
+
driver module is implemented."""
|
|
152
|
+
|
|
153
|
+
def available(self):
|
|
154
|
+
return False
|
|
155
|
+
|
|
156
|
+
def plan(self, action, params):
|
|
157
|
+
return {"action": action,
|
|
158
|
+
"target": str(params.get("target", "")),
|
|
159
|
+
"effect": f"{self.label} automation is not available in this build "
|
|
160
|
+
"(no driver module registered).",
|
|
161
|
+
"command": None}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class _Desktop(_ScaffoldedProvider):
|
|
165
|
+
key = "desktop"
|
|
166
|
+
label = "Desktop"
|
|
167
|
+
description = "Desktop automation (mouse/keyboard/windows) — extension point."
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class _Android(_ScaffoldedProvider):
|
|
171
|
+
key = "android"
|
|
172
|
+
label = "Android"
|
|
173
|
+
description = "Android automation via adb — extension point (drivers: adb)."
|
|
174
|
+
|
|
175
|
+
def available(self):
|
|
176
|
+
return bool(shutil.which("adb")) and False # scaffolded: no driver yet
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class _IOS(_ScaffoldedProvider):
|
|
180
|
+
key = "ios"
|
|
181
|
+
label = "iOS"
|
|
182
|
+
description = "iOS automation where platform APIs allow — extension point."
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class _Browser(_ScaffoldedProvider):
|
|
186
|
+
key = "browser"
|
|
187
|
+
label = "Browser"
|
|
188
|
+
description = "Browser automation — extension point (drivers: playwright/selenium)."
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
PROVIDERS = {
|
|
192
|
+
p.key: p for p in (
|
|
193
|
+
TerminalProvider(), SimulationProvider(), _Desktop(), _Android(),
|
|
194
|
+
_IOS(), _Browser())
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
# ------------------------------------------------------------- registry --
|
|
199
|
+
def register_provider(provider):
|
|
200
|
+
"""Extension API: register a DeviceProvider subclass instance under
|
|
201
|
+
its own key (replaces any provider with the same key)."""
|
|
202
|
+
PROVIDERS[provider.key] = provider
|
|
203
|
+
return provider
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def available_providers():
|
|
207
|
+
"""[{key, label, description, available}] for the /devices view."""
|
|
208
|
+
return [{"key": p.key, "label": p.label, "description": p.description,
|
|
209
|
+
"available": p.available()}
|
|
210
|
+
for p in PROVIDERS.values()]
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def provider(key):
|
|
214
|
+
return PROVIDERS.get(key)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
# --------------------------------------------------------------- logging --
|
|
218
|
+
def log_action(provider_key, action, target, decision, outcome=""):
|
|
219
|
+
entry = {"ts": time.time(), "provider": provider_key, "action": action,
|
|
220
|
+
"target": target, "decision": decision, "outcome": outcome}
|
|
221
|
+
ACTIVITY_LOG.append(entry)
|
|
222
|
+
del ACTIVITY_LOG[:-MAX_LOG]
|
|
223
|
+
eventbus.bus.publish(eventbus.DEVICE_ACTION, provider=provider_key,
|
|
224
|
+
action=action, target=target, decision=decision,
|
|
225
|
+
detail=outcome or action)
|
|
226
|
+
return entry
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def activity(limit=50):
|
|
230
|
+
"""Newest first."""
|
|
231
|
+
return list(reversed(ACTIVITY_LOG))[:limit]
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
# -------------------------------------------------------------- the gate --
|
|
235
|
+
def plan_action(provider_key, action, params):
|
|
236
|
+
"""The one entry point the permission flows call: resolves the
|
|
237
|
+
provider, builds the user-visible plan. Returns
|
|
238
|
+
{"ok": bool, "plan": {..}, "reason": str}. Callers then run the
|
|
239
|
+
existing permission-card flow (device_control key) and only call
|
|
240
|
+
execute_approved() if the user says yes."""
|
|
241
|
+
p = provider(provider_key)
|
|
242
|
+
if p is None:
|
|
243
|
+
return {"ok": False, "plan": None, "reason": f"unknown provider '{provider_key}'"}
|
|
244
|
+
if not p.available():
|
|
245
|
+
return {"ok": False, "plan": None, "reason": f"{p.label} automation is not available in this build"}
|
|
246
|
+
return {"ok": True, "plan": p.plan(action, params), "reason": ""}
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def execute_approved(provider_key, plan, params):
|
|
250
|
+
"""Runs a provider's plan AFTER the user approved it. Logs the
|
|
251
|
+
action with its outcome either way."""
|
|
252
|
+
p = provider(provider_key)
|
|
253
|
+
if p is None:
|
|
254
|
+
log_action(provider_key, (plan or {}).get("action", "?"),
|
|
255
|
+
(plan or {}).get("target", ""), "denied", "unknown provider")
|
|
256
|
+
return {"ok": False, "note": "unknown provider"}
|
|
257
|
+
result = p.execute(plan)
|
|
258
|
+
outcome = "approved"
|
|
259
|
+
if not result.get("ok"):
|
|
260
|
+
outcome += " \u2014 " + str(result.get("note", "execution failed"))
|
|
261
|
+
log_action(provider_key, (plan or {}).get("action", "?"),
|
|
262
|
+
(plan or {}).get("target", ""), "approved", outcome)
|
|
263
|
+
return result
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CAT Diagnostics Package per §32, §33.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from calc_terminal.diagnostics.doctor_engine import (
|
|
8
|
+
DimensionHealth,
|
|
9
|
+
DoctorReport,
|
|
10
|
+
DoctorEngine,
|
|
11
|
+
doctor_engine,
|
|
12
|
+
)
|
|
13
|
+
from calc_terminal.diagnostics.self_test import (
|
|
14
|
+
SubsystemTestResult,
|
|
15
|
+
SelfTestReport,
|
|
16
|
+
run_self_test,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"DimensionHealth",
|
|
21
|
+
"DoctorReport",
|
|
22
|
+
"DoctorEngine",
|
|
23
|
+
"doctor_engine",
|
|
24
|
+
"SubsystemTestResult",
|
|
25
|
+
"SelfTestReport",
|
|
26
|
+
"run_self_test",
|
|
27
|
+
]
|