devtorch-core 3.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. devtorch_core/__init__.py +158 -0
  2. devtorch_core/aggphi_textual.py +275 -0
  3. devtorch_core/alerts/__init__.py +23 -0
  4. devtorch_core/alerts/base.py +46 -0
  5. devtorch_core/alerts/config.py +60 -0
  6. devtorch_core/alerts/dispatcher.py +110 -0
  7. devtorch_core/alerts/jira.py +96 -0
  8. devtorch_core/alerts/linear.py +72 -0
  9. devtorch_core/alerts/pagerduty.py +66 -0
  10. devtorch_core/alerts/slack.py +81 -0
  11. devtorch_core/alerts/teams.py +70 -0
  12. devtorch_core/audit/__init__.py +43 -0
  13. devtorch_core/audit/exporter.py +297 -0
  14. devtorch_core/audit/privacy.py +101 -0
  15. devtorch_core/audit/scrubber.py +149 -0
  16. devtorch_core/audit/service.py +67 -0
  17. devtorch_core/audit/signing.py +127 -0
  18. devtorch_core/broadcast/__init__.py +4 -0
  19. devtorch_core/broadcast/broadcaster.py +100 -0
  20. devtorch_core/broadcast/watcher.py +71 -0
  21. devtorch_core/capability.py +639 -0
  22. devtorch_core/cloud/__init__.py +1 -0
  23. devtorch_core/cloud/client_config.py +472 -0
  24. devtorch_core/cloud/client_configs/.claude-opencode-fallback.json +8 -0
  25. devtorch_core/cloud/client_configs/.claude-stdio.json +13 -0
  26. devtorch_core/cloud/client_configs/.cursor-mcp.json +13 -0
  27. devtorch_core/cloud/client_configs/.opencode-bridge.json +13 -0
  28. devtorch_core/cloud/client_configs/.opencode.json +15 -0
  29. devtorch_core/cloud/client_configs/.vscode-mcp.json +13 -0
  30. devtorch_core/cloud/devtorch-mcp-bridge.js +357 -0
  31. devtorch_core/cloud/mcp_client.py +229 -0
  32. devtorch_core/cloud/setup.py +144 -0
  33. devtorch_core/cloud/sync.py +143 -0
  34. devtorch_core/cloud/sync_bundle.py +603 -0
  35. devtorch_core/cloud/sync_conflicts.py +159 -0
  36. devtorch_core/cloud/sync_state.py +159 -0
  37. devtorch_core/cloud/team_sync.py +283 -0
  38. devtorch_core/codex/__init__.py +9 -0
  39. devtorch_core/codex/__main__.py +97 -0
  40. devtorch_core/codex/capture.py +208 -0
  41. devtorch_core/codex/proxy.py +412 -0
  42. devtorch_core/concept_catalog.py +209 -0
  43. devtorch_core/consolidation/__init__.py +3 -0
  44. devtorch_core/consolidation/synthesizer.py +87 -0
  45. devtorch_core/consolidation/workflow.py +175 -0
  46. devtorch_core/daemon/__init__.py +27 -0
  47. devtorch_core/daemon/supervisor.py +293 -0
  48. devtorch_core/daemon/watcher.py +244 -0
  49. devtorch_core/dashboard_api.py +2012 -0
  50. devtorch_core/deltaf.py +97 -0
  51. devtorch_core/disclosure.py +50 -0
  52. devtorch_core/divergence/__init__.py +3 -0
  53. devtorch_core/divergence/detector.py +166 -0
  54. devtorch_core/gateway/__init__.py +32 -0
  55. devtorch_core/gateway/key_manager.py +124 -0
  56. devtorch_core/gateway/metrics_webhook.py +252 -0
  57. devtorch_core/gateway/policy.py +262 -0
  58. devtorch_core/gateway/server.py +727 -0
  59. devtorch_core/gateway/sso.py +233 -0
  60. devtorch_core/gcc.py +1246 -0
  61. devtorch_core/github/__init__.py +35 -0
  62. devtorch_core/github/app.py +240 -0
  63. devtorch_core/github/comment_builder.py +113 -0
  64. devtorch_core/github/pat.py +76 -0
  65. devtorch_core/github/pr_parser.py +82 -0
  66. devtorch_core/github/pr_reporter.py +555 -0
  67. devtorch_core/gitlab/__init__.py +177 -0
  68. devtorch_core/hitl/__init__.py +4 -0
  69. devtorch_core/hitl/channels.py +129 -0
  70. devtorch_core/hitl/orchestrator.py +95 -0
  71. devtorch_core/hooks/__init__.py +17 -0
  72. devtorch_core/hooks/claude_code.py +228 -0
  73. devtorch_core/hooks/git_capture.py +341 -0
  74. devtorch_core/hooks/git_commit.py +182 -0
  75. devtorch_core/hooks/installer.py +733 -0
  76. devtorch_core/hooks/pre_commit.py +157 -0
  77. devtorch_core/hooks/runner.py +344 -0
  78. devtorch_core/identity/__init__.py +4 -0
  79. devtorch_core/identity/agent.py +86 -0
  80. devtorch_core/identity/providers.py +85 -0
  81. devtorch_core/invariants.py +182 -0
  82. devtorch_core/mcp/__init__.py +10 -0
  83. devtorch_core/mcp/auth.py +177 -0
  84. devtorch_core/mcp/server.py +1049 -0
  85. devtorch_core/metrics/__init__.py +35 -0
  86. devtorch_core/metrics/aggregate.py +215 -0
  87. devtorch_core/metrics/calibrate.py +198 -0
  88. devtorch_core/metrics/calibration.py +125 -0
  89. devtorch_core/metrics/credibility.py +288 -0
  90. devtorch_core/metrics/delivery_time.py +70 -0
  91. devtorch_core/metrics/dhs.py +126 -0
  92. devtorch_core/metrics/mcs.py +96 -0
  93. devtorch_core/metrics/roi.py +88 -0
  94. devtorch_core/metrics/session_writer.py +81 -0
  95. devtorch_core/metrics/shadow_ai.py +117 -0
  96. devtorch_core/metrics/sprint_writer.py +243 -0
  97. devtorch_core/observability/__init__.py +78 -0
  98. devtorch_core/observability/datadog.py +157 -0
  99. devtorch_core/observability/formatter.py +119 -0
  100. devtorch_core/observability/report.py +264 -0
  101. devtorch_core/observability/servicenow.py +147 -0
  102. devtorch_core/observability/splunk.py +218 -0
  103. devtorch_core/observability/webhook.py +227 -0
  104. devtorch_core/parser/__init__.py +30 -0
  105. devtorch_core/parser/blocks.py +216 -0
  106. devtorch_core/parser/inference.py +159 -0
  107. devtorch_core/parser/thinking.py +112 -0
  108. devtorch_core/projects.py +169 -0
  109. devtorch_core/prompt_artifact.py +76 -0
  110. devtorch_core/proxy/__init__.py +9 -0
  111. devtorch_core/proxy/routes/__init__.py +1 -0
  112. devtorch_core/proxy/routes/anthropic.py +264 -0
  113. devtorch_core/proxy/routes/azure_openai.py +336 -0
  114. devtorch_core/proxy/routes/gemini.py +331 -0
  115. devtorch_core/proxy/routes/groq.py +284 -0
  116. devtorch_core/proxy/routes/ollama.py +279 -0
  117. devtorch_core/proxy/routes/openai.py +287 -0
  118. devtorch_core/proxy/server.py +356 -0
  119. devtorch_core/query/__init__.py +15 -0
  120. devtorch_core/query/grep.py +181 -0
  121. devtorch_core/query/hybrid.py +86 -0
  122. devtorch_core/query/semantic.py +157 -0
  123. devtorch_core/rdp.py +105 -0
  124. devtorch_core/reasoning/__init__.py +4 -0
  125. devtorch_core/reasoning/entry.py +31 -0
  126. devtorch_core/reasoning/store.py +122 -0
  127. devtorch_core/reasoning_plus/__init__.py +70 -0
  128. devtorch_core/reasoning_plus/augmenter.py +326 -0
  129. devtorch_core/reasoning_plus/capture.py +51 -0
  130. devtorch_core/reasoning_plus/config.py +256 -0
  131. devtorch_core/reasoning_plus/context.py +262 -0
  132. devtorch_core/reasoning_plus/learning/__init__.py +72 -0
  133. devtorch_core/reasoning_plus/learning/analytics.py +141 -0
  134. devtorch_core/reasoning_plus/learning/api.py +313 -0
  135. devtorch_core/reasoning_plus/learning/chain.py +285 -0
  136. devtorch_core/reasoning_plus/learning/composer.py +74 -0
  137. devtorch_core/reasoning_plus/learning/cross_project.py +234 -0
  138. devtorch_core/reasoning_plus/learning/embeddings.py +209 -0
  139. devtorch_core/reasoning_plus/learning/extractor.py +207 -0
  140. devtorch_core/reasoning_plus/learning/models.py +116 -0
  141. devtorch_core/reasoning_plus/learning/provenance.py +126 -0
  142. devtorch_core/reasoning_plus/learning/recorder.py +81 -0
  143. devtorch_core/reasoning_plus/learning/relevance.py +122 -0
  144. devtorch_core/reasoning_plus/learning/state.py +86 -0
  145. devtorch_core/reasoning_plus/learning/store.py +160 -0
  146. devtorch_core/reasoning_plus/learning/theta_learning_bridge.py +94 -0
  147. devtorch_core/reasoning_plus/prompt.py +90 -0
  148. devtorch_core/rep.py +134 -0
  149. devtorch_core/rep_network/__init__.py +25 -0
  150. devtorch_core/rep_network/merge.py +70 -0
  151. devtorch_core/rep_network/node.py +137 -0
  152. devtorch_core/rep_network/server.py +140 -0
  153. devtorch_core/rep_network/sync.py +207 -0
  154. devtorch_core/sensitivity.py +182 -0
  155. devtorch_core/serve.py +258 -0
  156. devtorch_core/session/__init__.py +39 -0
  157. devtorch_core/session/disagreement.py +188 -0
  158. devtorch_core/session/models.py +114 -0
  159. devtorch_core/session/orchestrator.py +182 -0
  160. devtorch_core/session/planner.py +169 -0
  161. devtorch_core/session/simulator.py +132 -0
  162. devtorch_core/signing.py +290 -0
  163. devtorch_core/sis.py +197 -0
  164. devtorch_core/storage.py +308 -0
  165. devtorch_core/templates/__init__.py +6 -0
  166. devtorch_core/templates/engine.py +122 -0
  167. devtorch_core/templates/go.py +18 -0
  168. devtorch_core/templates/infra.py +19 -0
  169. devtorch_core/templates/library/__init__.py +18 -0
  170. devtorch_core/templates/library/api_design.md +27 -0
  171. devtorch_core/templates/library/bug_fix.md +27 -0
  172. devtorch_core/templates/library/decision_record.md +27 -0
  173. devtorch_core/templates/library/engine.py +228 -0
  174. devtorch_core/templates/library/security_review.md +30 -0
  175. devtorch_core/templates/python.py +19 -0
  176. devtorch_core/templates/react.py +18 -0
  177. devtorch_core/templates/typescript.py +18 -0
  178. devtorch_core/theta.py +221 -0
  179. devtorch_core/theta_synthesis.py +268 -0
  180. devtorch_core/topics.py +320 -0
  181. devtorch_core/variance.py +219 -0
  182. devtorch_core/wrapper/__init__.py +52 -0
  183. devtorch_core/wrapper/anthropic.py +487 -0
  184. devtorch_core/wrapper/base.py +562 -0
  185. devtorch_core/wrapper/bedrock.py +342 -0
  186. devtorch_core/wrapper/gemini.py +422 -0
  187. devtorch_core/wrapper/ollama.py +527 -0
  188. devtorch_core/wrapper/openai.py +461 -0
  189. devtorch_core-3.0.1.dist-info/METADATA +867 -0
  190. devtorch_core-3.0.1.dist-info/RECORD +193 -0
  191. devtorch_core-3.0.1.dist-info/WHEEL +5 -0
  192. devtorch_core-3.0.1.dist-info/entry_points.txt +2 -0
  193. devtorch_core-3.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,144 @@
1
+ """One-command Cloudflare Worker deployment for DevTorch MCP server.
2
+
3
+ This module wraps ``deploy/cloudflare-worker/setup-mcp-server.sh`` so it can be
4
+ called as ``devtorch cloud setup``. It is intentionally thin: the shell script
5
+ still owns the npm/wrangler lifecycle; Python only validates CLI arguments and
6
+ forwards them.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import os
12
+ import subprocess
13
+ import sys
14
+ from pathlib import Path
15
+ from typing import Sequence
16
+
17
+ # ---------------------------------------------------------------------------
18
+ # Constants
19
+ # ---------------------------------------------------------------------------
20
+
21
+ _PACKAGE_DIR = Path(__file__).resolve().parent
22
+ _REPO_ROOT = _PACKAGE_DIR.parents[1]
23
+ SETUP_SCRIPT = _REPO_ROOT / "deploy" / "cloudflare-worker" / "setup-mcp-server.sh"
24
+
25
+
26
+ # ---------------------------------------------------------------------------
27
+ # Public API
28
+ # ---------------------------------------------------------------------------
29
+
30
+
31
+ def run_cloud_setup(
32
+ *,
33
+ env_file: str | Path | None = None,
34
+ org: str | None = None,
35
+ repo: str | None = None,
36
+ ide: str | None = None,
37
+ openai_key: str | None = None,
38
+ non_interactive: bool = False,
39
+ skip_key: bool = False,
40
+ skip_client_config: bool = False,
41
+ dry_run: bool = False,
42
+ ) -> dict[str, str | list[str]]:
43
+ """Build and optionally run the Cloudflare Worker setup command.
44
+
45
+ Args:
46
+ env_file: Path to an environment file to source before running the script.
47
+ org: DevTorch org ID. Required in non-interactive mode.
48
+ repo: DevTorch repo ID. Required in non-interactive mode.
49
+ ide: IDE to configure (opencode, claude, cursor, vscode, stdio).
50
+ openai_key: Optional OpenAI API key for the DRPL embedding backend.
51
+ non_interactive: Run without prompts (requires ``org`` and ``repo``).
52
+ skip_key: Skip creating a new API key.
53
+ skip_client_config: Skip installing MCP client config.
54
+ dry_run: If True, return the command without executing it.
55
+
56
+ Returns:
57
+ A dict with ``script`` and ``args`` (the constructed argument list).
58
+ """
59
+ if not SETUP_SCRIPT.exists():
60
+ raise FileNotFoundError(
61
+ f"Setup script not found: {SETUP_SCRIPT}. "
62
+ "Is the DevTorch repo checkout complete?"
63
+ )
64
+
65
+ if non_interactive and (not org or not repo):
66
+ raise ValueError("--non-interactive requires --org and --repo")
67
+
68
+ if non_interactive and not skip_client_config and not ide:
69
+ raise ValueError("--non-interactive requires --ide unless --skip-client-config is set")
70
+
71
+ args: list[str] = [str(SETUP_SCRIPT)]
72
+ if env_file:
73
+ args.extend(["--env-file", str(env_file)])
74
+ if non_interactive:
75
+ args.append("--non-interactive")
76
+ if org:
77
+ args.extend(["--org", org])
78
+ if repo:
79
+ args.extend(["--repo", repo])
80
+ if ide:
81
+ args.extend(["--ide", ide])
82
+ if openai_key:
83
+ args.extend(["--openai-key", openai_key])
84
+ if skip_key:
85
+ args.append("--skip-key")
86
+ if skip_client_config:
87
+ args.append("--skip-client-config")
88
+
89
+ if dry_run:
90
+ return {"script": str(SETUP_SCRIPT), "args": args}
91
+
92
+ result = subprocess.run(args, capture_output=False, text=True, check=False)
93
+ return {
94
+ "script": str(SETUP_SCRIPT),
95
+ "args": args,
96
+ "returncode": str(result.returncode),
97
+ }
98
+
99
+
100
+ def main(argv: Sequence[str] | None = None) -> int:
101
+ """CLI entry point used by ``devtorch cloud setup``."""
102
+ import argparse
103
+
104
+ parser = argparse.ArgumentParser(
105
+ description="Deploy a self-hosted DevTorch MCP server on Cloudflare Workers.",
106
+ )
107
+ parser.add_argument("--env-file", help="Path to environment file to source")
108
+ parser.add_argument("--org", help="DevTorch org ID")
109
+ parser.add_argument("--repo", help="DevTorch repo ID")
110
+ parser.add_argument("--ide", choices=["opencode", "claude", "cursor", "vscode", "stdio"],
111
+ help="IDE to configure locally")
112
+ parser.add_argument("--openai-key", help="OpenAI API key for DRPL embedding backend")
113
+ parser.add_argument("--non-interactive", action="store_true",
114
+ help="Run without prompts (requires --org and --repo)")
115
+ parser.add_argument("--skip-key", action="store_true", help="Skip creating API key")
116
+ parser.add_argument("--skip-client-config", action="store_true", help="Skip IDE config")
117
+ parser.add_argument("--dry-run", action="store_true", help="Print command instead of running")
118
+ args = parser.parse_args(argv)
119
+
120
+ try:
121
+ result = run_cloud_setup(
122
+ env_file=args.env_file,
123
+ org=args.org,
124
+ repo=args.repo,
125
+ ide=args.ide,
126
+ openai_key=args.openai_key,
127
+ non_interactive=args.non_interactive,
128
+ skip_key=args.skip_key,
129
+ skip_client_config=args.skip_client_config,
130
+ dry_run=args.dry_run,
131
+ )
132
+ except (FileNotFoundError, ValueError) as exc:
133
+ print(f"error: {exc}", file=sys.stderr)
134
+ return 1
135
+
136
+ if args.dry_run:
137
+ print(" ".join(result["args"]))
138
+ return 0
139
+
140
+ return int(result.get("returncode", "0"))
141
+
142
+
143
+ if __name__ == "__main__":
144
+ raise SystemExit(main())
@@ -0,0 +1,143 @@
1
+ """One-way local -> cloud reasoning sync.
2
+
3
+ Pushes local .GCC commits to the DevTorch cloud MCP worker so that
4
+ cloud-connected agents' `devtorch_context` sees reasoning recorded by
5
+ local-only agents (hooks / CLI). Uses the worker's direct-POST fallback:
6
+ POST /messages without an SSE session returns the JSON-RPC result in the
7
+ response body.
8
+
9
+ Transport hardening: if the direct-POST path fails, we open an SSE
10
+ handshake once, capture the live endpoint URL, and retry through that
11
+ session-bound endpoint. The SSE-derived URL is cached for all subsequent
12
+ commits in the same sync run.
13
+
14
+ Cursor: .GCC/cloud_sync_state.json {"last_pushed_index": N}. Commit ids are
15
+ sequential hex (COMMIT_INDEX), so the cursor is a simple integer.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import json
21
+ import urllib.error
22
+ import urllib.request
23
+ from pathlib import Path
24
+
25
+ _STATE_FILE = "cloud_sync_state.json"
26
+ _USER_AGENT = "devtorch-cloud-sync"
27
+
28
+ _SSE_ENDPOINT_CACHE: str | None = None
29
+
30
+
31
+ def _sse_handshake(sse_url: str, api_key: str, timeout: float) -> str:
32
+ """Open an SSE connection, capture the endpoint URL, and return it."""
33
+ req = urllib.request.Request(
34
+ sse_url,
35
+ headers={
36
+ "Accept": "text/event-stream",
37
+ "X-DevTorch-Key": api_key,
38
+ "User-Agent": _USER_AGENT,
39
+ },
40
+ )
41
+ with urllib.request.urlopen(req, timeout=timeout) as resp:
42
+ # Read line-by-line so the chunked HTTP reader does not block waiting
43
+ # for the next chunk after the endpoint event (the server keeps the SSE
44
+ # connection open for subsequent messages).
45
+ event_type = None
46
+ data = None
47
+ while True:
48
+ line = resp.readline()
49
+ if not line:
50
+ break
51
+ line = line.decode("utf-8", errors="replace")
52
+ if line.startswith("event:"):
53
+ event_type = line[6:].strip()
54
+ elif line.startswith("data:"):
55
+ data = line[5:].strip()
56
+ elif line.strip() == "":
57
+ if event_type == "endpoint" and data:
58
+ return data
59
+ event_type = None
60
+ data = None
61
+ raise RuntimeError("SSE endpoint event not received")
62
+
63
+
64
+ def sync_commits(
65
+ gcc_dir: Path,
66
+ messages_url: str,
67
+ api_key: str,
68
+ timeout: float = 30.0,
69
+ from_now: bool = False,
70
+ ) -> dict:
71
+ gcc_dir = Path(gcc_dir)
72
+ if not gcc_dir.is_dir():
73
+ raise ValueError(f"{gcc_dir} is not an initialized .GCC repository")
74
+ try:
75
+ top = int((gcc_dir / "COMMIT_INDEX").read_text(encoding="utf-8").strip() or "0")
76
+ except (OSError, ValueError):
77
+ top = 0
78
+
79
+ state_path = gcc_dir / _STATE_FILE
80
+ try:
81
+ cursor = int(json.loads(state_path.read_text(encoding="utf-8"))["last_pushed_index"])
82
+ except (OSError, ValueError, KeyError, json.JSONDecodeError):
83
+ cursor = 0
84
+
85
+ if cursor > top:
86
+ cursor = 0
87
+
88
+ if from_now:
89
+ state_path.write_text(
90
+ json.dumps({"last_pushed_index": top}) + "\n", encoding="utf-8"
91
+ )
92
+ return {"pushed": 0, "skipped": top, "cursor": top}
93
+
94
+ global _SSE_ENDPOINT_CACHE
95
+ pushed = 0
96
+ for index in range(cursor + 1, top + 1):
97
+ commit_id = format(index, "08x")
98
+ commit_path = gcc_dir / "commits" / f"{commit_id}.json"
99
+ try:
100
+ obj = json.loads(commit_path.read_text(encoding="utf-8"))
101
+ except (OSError, json.JSONDecodeError):
102
+ continue
103
+ message = (
104
+ f"[synced from local {commit_id} @ {obj.get('timestamp', 'unknown')}] "
105
+ f"{obj.get('message', '')}"
106
+ )
107
+ try:
108
+ _post_commit(messages_url, api_key, index, message, timeout)
109
+ except (urllib.error.HTTPError, urllib.error.URLError, TimeoutError):
110
+ if _SSE_ENDPOINT_CACHE is None:
111
+ sse_url = messages_url.rsplit("/", 1)[0] + "/sse"
112
+ _SSE_ENDPOINT_CACHE = _sse_handshake(sse_url, api_key, timeout)
113
+ _post_commit(_SSE_ENDPOINT_CACHE, api_key, index, message, timeout)
114
+ pushed += 1
115
+ state_path.write_text(
116
+ json.dumps({"last_pushed_index": index}) + "\n", encoding="utf-8"
117
+ )
118
+
119
+ return {"pushed": pushed, "skipped": cursor, "cursor": max(cursor, top)}
120
+
121
+
122
+ def _post_commit(
123
+ messages_url: str, api_key: str, rpc_id: int, message: str, timeout: float
124
+ ) -> None:
125
+ payload = {
126
+ "jsonrpc": "2.0",
127
+ "id": rpc_id,
128
+ "method": "tools/call",
129
+ "params": {"name": "devtorch_commit", "arguments": {"message": message}},
130
+ }
131
+ req = urllib.request.Request(
132
+ messages_url,
133
+ data=json.dumps(payload).encode(),
134
+ headers={
135
+ "Content-Type": "application/json",
136
+ "X-DevTorch-Key": api_key,
137
+ "User-Agent": _USER_AGENT,
138
+ },
139
+ )
140
+ with urllib.request.urlopen(req, timeout=timeout) as resp:
141
+ body = json.loads(resp.read().decode())
142
+ if body.get("error") or body.get("result", {}).get("isError"):
143
+ raise RuntimeError(f"cloud commit failed: {json.dumps(body)[:200]}")