@trac3er/oh-my-god 1.0.2
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.
- package/.claude-plugin/marketplace.json +36 -0
- package/.claude-plugin/plugin.json +23 -0
- package/.claude-plugin/scripts/install.sh +49 -0
- package/.claude-plugin/scripts/uninstall.sh +80 -0
- package/.claude-plugin/scripts/update.sh +84 -0
- package/.mcp.json +20 -0
- package/LICENSE +21 -0
- package/OMG-setup.sh +1093 -0
- package/README.md +335 -0
- package/THIRD_PARTY_NOTICES.md +24 -0
- package/UPSTREAM_DIFF.md +20 -0
- package/agents/__init__.py +1 -0
- package/agents/_model_roles.yaml +26 -0
- package/agents/designer.md +67 -0
- package/agents/explore.md +60 -0
- package/agents/model_roles.py +196 -0
- package/agents/omg-api-builder.md +23 -0
- package/agents/omg-architect-mode.md +43 -0
- package/agents/omg-architect.md +13 -0
- package/agents/omg-backend-engineer.md +43 -0
- package/agents/omg-critic.md +16 -0
- package/agents/omg-database-engineer.md +43 -0
- package/agents/omg-escalation-router.md +17 -0
- package/agents/omg-executor.md +12 -0
- package/agents/omg-frontend-designer.md +42 -0
- package/agents/omg-implement-mode.md +50 -0
- package/agents/omg-infra-engineer.md +43 -0
- package/agents/omg-qa-tester.md +16 -0
- package/agents/omg-research-mode.md +43 -0
- package/agents/omg-security-auditor.md +43 -0
- package/agents/omg-testing-engineer.md +43 -0
- package/agents/plan.md +80 -0
- package/agents/quick_task.md +64 -0
- package/agents/reviewer.md +83 -0
- package/agents/task.md +71 -0
- package/commands/OMG:ccg.md +22 -0
- package/commands/OMG:compat.md +57 -0
- package/commands/OMG:crazy.md +125 -0
- package/commands/OMG:domain-init.md +11 -0
- package/commands/OMG:escalate.md +52 -0
- package/commands/OMG:health-check.md +45 -0
- package/commands/OMG:init.md +134 -0
- package/commands/OMG:mode.md +44 -0
- package/commands/OMG:project-init.md +11 -0
- package/commands/OMG:ralph-start.md +43 -0
- package/commands/OMG:ralph-stop.md +23 -0
- package/commands/OMG:teams.md +39 -0
- package/commands/ai-commit.md +113 -0
- package/commands/ccg.md +9 -0
- package/commands/create-agent.md +183 -0
- package/commands/omc-teams.md +9 -0
- package/commands/session-branch.md +85 -0
- package/commands/session-fork.md +53 -0
- package/commands/session-merge.md +134 -0
- package/commands/theme.md +44 -0
- package/config/lsp_languages.yaml +324 -0
- package/config/themes/catppuccin-frappe.yaml +14 -0
- package/config/themes/catppuccin-latte.yaml +14 -0
- package/config/themes/catppuccin-macchiato.yaml +14 -0
- package/config/themes/catppuccin-mocha.yaml +14 -0
- package/config/themes/dracula.yaml +14 -0
- package/config/themes/gruvbox-dark.yaml +14 -0
- package/config/themes/nord.yaml +14 -0
- package/config/themes/one-dark.yaml +14 -0
- package/config/themes/solarized-dark.yaml +14 -0
- package/config/themes/tokyo-night.yaml +14 -0
- package/control_plane/__init__.py +2 -0
- package/control_plane/openapi.yaml +109 -0
- package/control_plane/server.py +107 -0
- package/control_plane/service.py +148 -0
- package/crates/omg-natives/Cargo.toml +17 -0
- package/crates/omg-natives/src/clipboard.rs +5 -0
- package/crates/omg-natives/src/glob.rs +15 -0
- package/crates/omg-natives/src/grep.rs +15 -0
- package/crates/omg-natives/src/highlight.rs +15 -0
- package/crates/omg-natives/src/html.rs +14 -0
- package/crates/omg-natives/src/image.rs +5 -0
- package/crates/omg-natives/src/keys.rs +5 -0
- package/crates/omg-natives/src/lib.rs +36 -0
- package/crates/omg-natives/src/prof.rs +5 -0
- package/crates/omg-natives/src/ps.rs +5 -0
- package/crates/omg-natives/src/shell.rs +5 -0
- package/crates/omg-natives/src/task.rs +5 -0
- package/crates/omg-natives/src/text.rs +14 -0
- package/hooks/_agent_registry.py +421 -0
- package/hooks/_budget.py +31 -0
- package/hooks/_common.py +476 -0
- package/hooks/_learnings.py +126 -0
- package/hooks/_memory.py +103 -0
- package/hooks/circuit-breaker.py +270 -0
- package/hooks/config-guard.py +163 -0
- package/hooks/context_pressure.py +53 -0
- package/hooks/credential_store.py +801 -0
- package/hooks/fetch-rate-limits.py +212 -0
- package/hooks/firewall.py +48 -0
- package/hooks/hashline-formatter-bridge.py +224 -0
- package/hooks/hashline-injector.py +273 -0
- package/hooks/hashline-validator.py +216 -0
- package/hooks/idle-detector.py +95 -0
- package/hooks/intentgate-keyword-detector.py +188 -0
- package/hooks/magic-keyword-router.py +195 -0
- package/hooks/policy_engine.py +310 -0
- package/hooks/post-tool-failure.py +19 -0
- package/hooks/post-write.py +199 -0
- package/hooks/pre-compact.py +204 -0
- package/hooks/pre-tool-inject.py +98 -0
- package/hooks/prompt-enhancer.py +672 -0
- package/hooks/quality-runner.py +191 -0
- package/hooks/secret-guard.py +47 -0
- package/hooks/session-end-capture.py +137 -0
- package/hooks/session-start.py +275 -0
- package/hooks/shadow_manager.py +297 -0
- package/hooks/state_migration.py +209 -0
- package/hooks/stop-gate.py +7 -0
- package/hooks/stop_dispatcher.py +929 -0
- package/hooks/test-validator.py +138 -0
- package/hooks/todo-state-tracker.py +114 -0
- package/hooks/tool-ledger.py +126 -0
- package/hooks/trust_review.py +524 -0
- package/install.sh +9 -0
- package/omg_natives/__init__.py +186 -0
- package/omg_natives/_bindings.py +165 -0
- package/omg_natives/clipboard.py +36 -0
- package/omg_natives/glob.py +42 -0
- package/omg_natives/grep.py +61 -0
- package/omg_natives/highlight.py +54 -0
- package/omg_natives/html.py +157 -0
- package/omg_natives/image.py +51 -0
- package/omg_natives/keys.py +46 -0
- package/omg_natives/prof.py +39 -0
- package/omg_natives/ps.py +93 -0
- package/omg_natives/shell.py +58 -0
- package/omg_natives/task.py +41 -0
- package/omg_natives/text.py +50 -0
- package/package.json +26 -0
- package/plugins/README.md +82 -0
- package/plugins/advanced/commands/OMG:code-review.md +114 -0
- package/plugins/advanced/commands/OMG:deep-plan.md +221 -0
- package/plugins/advanced/commands/OMG:handoff.md +115 -0
- package/plugins/advanced/commands/OMG:learn.md +110 -0
- package/plugins/advanced/commands/OMG:maintainer.md +31 -0
- package/plugins/advanced/commands/OMG:ralph-start.md +43 -0
- package/plugins/advanced/commands/OMG:ralph-stop.md +23 -0
- package/plugins/advanced/commands/OMG:security-review.md +119 -0
- package/plugins/advanced/commands/OMG:sequential-thinking.md +20 -0
- package/plugins/advanced/commands/OMG:ship.md +46 -0
- package/plugins/advanced/plugin.json +96 -0
- package/plugins/core/plugin.json +82 -0
- package/pytest.ini +5 -0
- package/registry/__init__.py +1 -0
- package/registry/verify_artifact.py +90 -0
- package/rules/contextual/architect-mode.md +9 -0
- package/rules/contextual/big-picture.md +20 -0
- package/rules/contextual/code-hygiene.md +26 -0
- package/rules/contextual/context-management.md +19 -0
- package/rules/contextual/context-minimization.md +32 -0
- package/rules/contextual/ddd-sdd.md +28 -0
- package/rules/contextual/dependency-safety.md +16 -0
- package/rules/contextual/doc-check.md +13 -0
- package/rules/contextual/implement-mode.md +9 -0
- package/rules/contextual/infra-safety.md +14 -0
- package/rules/contextual/outside-in.md +13 -0
- package/rules/contextual/persistent-mode.md +24 -0
- package/rules/contextual/research-mode.md +9 -0
- package/rules/contextual/security-domains.md +25 -0
- package/rules/contextual/vision-detection.md +27 -0
- package/rules/contextual/web-search.md +25 -0
- package/rules/contextual/write-verify.md +23 -0
- package/rules/core/00-truth.md +20 -0
- package/rules/core/01-surgical.md +19 -0
- package/rules/core/02-circuit-breaker.md +22 -0
- package/rules/core/03-ensemble.md +28 -0
- package/rules/core/04-testing.md +30 -0
- package/runtime/__init__.py +32 -0
- package/runtime/adapters/__init__.py +13 -0
- package/runtime/adapters/claude.py +60 -0
- package/runtime/adapters/gpt.py +53 -0
- package/runtime/adapters/local.py +53 -0
- package/runtime/business_workflow.py +220 -0
- package/runtime/compat.py +1299 -0
- package/runtime/custom_agent_loader.py +366 -0
- package/runtime/dispatcher.py +47 -0
- package/runtime/ecosystem.py +371 -0
- package/runtime/legacy_compat.py +7 -0
- package/runtime/omc_compat.py +7 -0
- package/runtime/omc_contract_snapshot.json +916 -0
- package/runtime/omg_compat_contract_snapshot.json +916 -0
- package/runtime/subagent_dispatcher.py +362 -0
- package/runtime/team_router.py +838 -0
- package/scripts/check-omc-contract-snapshot.py +12 -0
- package/scripts/check-omg-compat-contract-snapshot.py +137 -0
- package/scripts/check-omg-standalone-clean.py +102 -0
- package/scripts/legacy_to_omg_migrate.py +29 -0
- package/scripts/migrate-omc.py +464 -0
- package/scripts/omc_to_omg_migrate.py +12 -0
- package/scripts/omg.py +493 -0
- package/scripts/settings-merge.py +224 -0
- package/scripts/verify-no-omc.sh +5 -0
- package/scripts/verify-standalone.sh +21 -0
- package/templates/idea.yml +30 -0
- package/templates/policy.yaml +15 -0
- package/templates/profile.yaml +25 -0
- package/templates/runtime.yaml +12 -0
- package/templates/working-memory.md +17 -0
- package/tools/__init__.py +2 -0
- package/tools/browser_consent.py +289 -0
- package/tools/browser_stealth.py +481 -0
- package/tools/browser_tool.py +448 -0
- package/tools/changelog_generator.py +268 -0
- package/tools/commit_splitter.py +361 -0
- package/tools/config_discovery.py +151 -0
- package/tools/config_merger.py +449 -0
- package/tools/git_inspector.py +298 -0
- package/tools/lsp_client.py +275 -0
- package/tools/lsp_discovery.py +231 -0
- package/tools/lsp_operations.py +392 -0
- package/tools/python_repl.py +656 -0
- package/tools/python_sandbox.py +609 -0
- package/tools/search_providers/__init__.py +77 -0
- package/tools/search_providers/brave.py +115 -0
- package/tools/search_providers/exa.py +116 -0
- package/tools/search_providers/jina.py +104 -0
- package/tools/search_providers/perplexity.py +139 -0
- package/tools/search_providers/synthetic.py +74 -0
- package/tools/session_snapshot.py +736 -0
- package/tools/ssh_manager.py +912 -0
- package/tools/theme_engine.py +294 -0
- package/tools/theme_selector.py +137 -0
- package/tools/web_search.py +622 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"""OMG Natives — Rust-accelerated hot paths with pure-Python fallbacks.
|
|
2
|
+
|
|
3
|
+
When the Rust binary is built and installed (via ``maturin develop``),
|
|
4
|
+
this package delegates to the compiled ``omg_natives._native`` extension.
|
|
5
|
+
Otherwise, every public function falls back to a pure-Python implementation
|
|
6
|
+
so that OMG works identically — just slower on CPU-intensive paths.
|
|
7
|
+
|
|
8
|
+
Feature flag: ``OMG_RUST_ENGINE_ENABLED`` (default: False)
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import fnmatch as _fnmatch
|
|
14
|
+
import os as _os
|
|
15
|
+
import re as _re
|
|
16
|
+
import sys as _sys
|
|
17
|
+
from pathlib import Path as _Path
|
|
18
|
+
from typing import List, Optional
|
|
19
|
+
|
|
20
|
+
# ---------------------------------------------------------------------------
|
|
21
|
+
# Feature flag — follows the hooks/_common.get_feature_flag pattern
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
def _get_feature_flag(flag_name: str, default: bool = False) -> bool:
|
|
25
|
+
"""Minimal feature-flag check (env var only, no settings.json dependency).
|
|
26
|
+
|
|
27
|
+
Mirrors the resolution logic of ``hooks/_common.get_feature_flag`` but
|
|
28
|
+
avoids importing hooks internals so this package stays self-contained.
|
|
29
|
+
"""
|
|
30
|
+
env_key = f"OMG_{flag_name.upper()}_ENABLED"
|
|
31
|
+
env_val = _os.environ.get(env_key, "").lower()
|
|
32
|
+
if env_val in ("0", "false", "no"):
|
|
33
|
+
return False
|
|
34
|
+
if env_val in ("1", "true", "yes"):
|
|
35
|
+
return True
|
|
36
|
+
# Try full get_feature_flag if available
|
|
37
|
+
try:
|
|
38
|
+
_sys.path.insert(0, str(_Path(__file__).resolve().parent))
|
|
39
|
+
from hooks._common import get_feature_flag # type: ignore[import-untyped]
|
|
40
|
+
return get_feature_flag(flag_name, default=default)
|
|
41
|
+
except Exception:
|
|
42
|
+
return default
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
OMG_RUST_ENABLED: bool = _get_feature_flag("RUST_ENGINE", default=False)
|
|
46
|
+
|
|
47
|
+
# ---------------------------------------------------------------------------
|
|
48
|
+
# Try importing compiled Rust extension
|
|
49
|
+
# ---------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
RUST_AVAILABLE: bool = False
|
|
52
|
+
|
|
53
|
+
if OMG_RUST_ENABLED:
|
|
54
|
+
try:
|
|
55
|
+
from omg_natives._native import * # noqa: F401, F403
|
|
56
|
+
RUST_AVAILABLE = True
|
|
57
|
+
except ImportError:
|
|
58
|
+
RUST_AVAILABLE = False
|
|
59
|
+
|
|
60
|
+
# ---------------------------------------------------------------------------
|
|
61
|
+
# Pure-Python fallback implementations
|
|
62
|
+
# ---------------------------------------------------------------------------
|
|
63
|
+
|
|
64
|
+
if not RUST_AVAILABLE:
|
|
65
|
+
|
|
66
|
+
def grep(pattern: str, path: str) -> List[str]:
|
|
67
|
+
"""Search for *pattern* (regex) in the file at *path*.
|
|
68
|
+
|
|
69
|
+
Returns a list of matching lines (without trailing newline).
|
|
70
|
+
"""
|
|
71
|
+
matches: List[str] = []
|
|
72
|
+
try:
|
|
73
|
+
compiled = _re.compile(pattern)
|
|
74
|
+
with open(path, "r", encoding="utf-8", errors="ignore") as fh:
|
|
75
|
+
for line in fh:
|
|
76
|
+
if compiled.search(line):
|
|
77
|
+
matches.append(line.rstrip("\n"))
|
|
78
|
+
except (OSError, _re.error):
|
|
79
|
+
pass
|
|
80
|
+
return matches
|
|
81
|
+
|
|
82
|
+
def glob_match(pattern: str, base: str = ".") -> List[str]:
|
|
83
|
+
"""Return file paths under *base* that match the glob *pattern*.
|
|
84
|
+
|
|
85
|
+
Pure-Python implementation using ``os.walk`` + ``fnmatch``.
|
|
86
|
+
"""
|
|
87
|
+
results: List[str] = []
|
|
88
|
+
base_path = _Path(base).resolve()
|
|
89
|
+
try:
|
|
90
|
+
for root, _dirs, files in _os.walk(base_path):
|
|
91
|
+
for name in files:
|
|
92
|
+
full = _os.path.join(root, name)
|
|
93
|
+
rel = _os.path.relpath(full, base_path)
|
|
94
|
+
if _fnmatch.fnmatch(rel, pattern):
|
|
95
|
+
results.append(rel)
|
|
96
|
+
except OSError:
|
|
97
|
+
pass
|
|
98
|
+
return results
|
|
99
|
+
|
|
100
|
+
def normalize(text: str) -> str:
|
|
101
|
+
"""Normalize whitespace and line endings in *text*."""
|
|
102
|
+
return text.replace("\r\n", "\n").strip()
|
|
103
|
+
|
|
104
|
+
def highlight_syntax(code: str, language: str = "") -> str:
|
|
105
|
+
"""Return *code* unchanged (no highlighting without Rust)."""
|
|
106
|
+
_ = language
|
|
107
|
+
return code
|
|
108
|
+
|
|
109
|
+
def strip_tags(html: str) -> str:
|
|
110
|
+
"""Strip HTML tags from *html*, returning plain text."""
|
|
111
|
+
return _re.sub(r"<[^>]+>", "", html)
|
|
112
|
+
|
|
113
|
+
# ---------------------------------------------------------------------------
|
|
114
|
+
# N-API Binding Registry (Task 5.2)
|
|
115
|
+
# ---------------------------------------------------------------------------
|
|
116
|
+
|
|
117
|
+
from omg_natives._bindings import ( # noqa: E402
|
|
118
|
+
REGISTRY,
|
|
119
|
+
BindingRegistry,
|
|
120
|
+
BindingSpec,
|
|
121
|
+
bind_function,
|
|
122
|
+
call_binding,
|
|
123
|
+
get_binding,
|
|
124
|
+
marshal_from_rust,
|
|
125
|
+
marshal_to_rust,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# ---------------------------------------------------------------------------
|
|
129
|
+
# Task 5.3: Import 12 module fallbacks (self-register via bind_function)
|
|
130
|
+
# Each module self-registers with REGISTRY at import time.
|
|
131
|
+
# Note: grep module imported without shadowing legacy grep(pattern, path)->List[str]
|
|
132
|
+
# ---------------------------------------------------------------------------
|
|
133
|
+
|
|
134
|
+
# Save legacy functions that module imports would shadow
|
|
135
|
+
_legacy_grep = grep # type: ignore[possibly-undefined] # noqa: E402
|
|
136
|
+
|
|
137
|
+
import omg_natives.grep as _grep_mod # noqa: E402, F401
|
|
138
|
+
from omg_natives.glob import glob as glob # noqa: E402
|
|
139
|
+
from omg_natives.shell import shell # noqa: E402
|
|
140
|
+
from omg_natives.text import text as text # noqa: E402
|
|
141
|
+
from omg_natives.keys import keys # noqa: E402
|
|
142
|
+
from omg_natives.highlight import highlight # noqa: E402
|
|
143
|
+
from omg_natives.task import task_run # noqa: E402
|
|
144
|
+
from omg_natives.ps import ps # noqa: E402
|
|
145
|
+
from omg_natives.prof import prof # noqa: E402
|
|
146
|
+
from omg_natives.image import image # noqa: E402
|
|
147
|
+
from omg_natives.clipboard import clipboard # noqa: E402
|
|
148
|
+
from omg_natives.html import html # noqa: E402
|
|
149
|
+
|
|
150
|
+
# Restore legacy grep (returns List[str] for backward compat)
|
|
151
|
+
grep = _legacy_grep # type: ignore[assignment] # noqa: E402
|
|
152
|
+
|
|
153
|
+
# ---------------------------------------------------------------------------
|
|
154
|
+
# Public API surface
|
|
155
|
+
# ---------------------------------------------------------------------------
|
|
156
|
+
|
|
157
|
+
__all__ = [
|
|
158
|
+
"OMG_RUST_ENABLED",
|
|
159
|
+
"RUST_AVAILABLE",
|
|
160
|
+
"grep",
|
|
161
|
+
"glob_match",
|
|
162
|
+
"normalize",
|
|
163
|
+
"highlight_syntax",
|
|
164
|
+
"strip_tags",
|
|
165
|
+
# N-API Binding Registry
|
|
166
|
+
"REGISTRY",
|
|
167
|
+
"BindingRegistry",
|
|
168
|
+
"BindingSpec",
|
|
169
|
+
"bind_function",
|
|
170
|
+
"call_binding",
|
|
171
|
+
"get_binding",
|
|
172
|
+
"marshal_from_rust",
|
|
173
|
+
"marshal_to_rust",
|
|
174
|
+
# Task 5.3: 12 Core Module Functions
|
|
175
|
+
"glob",
|
|
176
|
+
"shell",
|
|
177
|
+
"text",
|
|
178
|
+
"keys",
|
|
179
|
+
"highlight",
|
|
180
|
+
"task_run",
|
|
181
|
+
"ps",
|
|
182
|
+
"prof",
|
|
183
|
+
"image",
|
|
184
|
+
"clipboard",
|
|
185
|
+
"html",
|
|
186
|
+
]
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""N-API Binding Registry — maps function names to (rust_fn_spec, python_fallback) pairs.
|
|
2
|
+
|
|
3
|
+
Provides a registry for Rust↔Python bindings with marshalling utilities.
|
|
4
|
+
When Rust is not available, all calls transparently use the Python fallback.
|
|
5
|
+
|
|
6
|
+
This module is pure stdlib — no external dependencies.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from typing import Any, Callable, Dict, List, Optional
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# ---------------------------------------------------------------------------
|
|
16
|
+
# BindingSpec — describes a single Rust↔Python binding
|
|
17
|
+
# ---------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class BindingSpec:
|
|
21
|
+
"""Specification for a single Rust↔Python binding.
|
|
22
|
+
|
|
23
|
+
Attributes:
|
|
24
|
+
name: Logical name of the binding (e.g. ``"grep"``).
|
|
25
|
+
rust_symbol: Rust symbol path (e.g. ``"omg_natives::grep::grep"``).
|
|
26
|
+
python_fallback: Callable Python implementation used when Rust is unavailable.
|
|
27
|
+
type_hints: Optional mapping of parameter names to type strings for
|
|
28
|
+
documentation and marshalling guidance.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
name: str
|
|
32
|
+
rust_symbol: str
|
|
33
|
+
python_fallback: Callable[..., Any]
|
|
34
|
+
type_hints: Dict[str, str] = field(default_factory=dict)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# ---------------------------------------------------------------------------
|
|
38
|
+
# Marshalling utilities — Rust↔Python data type conversion
|
|
39
|
+
# ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
# Supported types for Rust↔Python marshalling.
|
|
42
|
+
_SUPPORTED_TYPES = (str, list, dict, int, float, bool, bytes, type(None))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def marshal_to_rust(value: Any) -> Any:
|
|
46
|
+
"""Convert a Python value to a Rust-compatible representation.
|
|
47
|
+
|
|
48
|
+
In the current pure-Python fallback mode this is an identity operation
|
|
49
|
+
for all supported types (str, list, dict, int, float, bool, bytes, None).
|
|
50
|
+
|
|
51
|
+
Raises:
|
|
52
|
+
TypeError: If *value* is not a supported type.
|
|
53
|
+
"""
|
|
54
|
+
if not isinstance(value, _SUPPORTED_TYPES):
|
|
55
|
+
raise TypeError(
|
|
56
|
+
f"Unsupported type for Rust marshalling: {type(value).__name__}. "
|
|
57
|
+
f"Supported: str, list, dict, int, float, bool, bytes, None"
|
|
58
|
+
)
|
|
59
|
+
return value
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def marshal_from_rust(value: Any) -> Any:
|
|
63
|
+
"""Convert a Rust-returned value back to a Python representation.
|
|
64
|
+
|
|
65
|
+
In pure-Python fallback mode this is always the identity function
|
|
66
|
+
because no actual FFI boundary is crossed.
|
|
67
|
+
"""
|
|
68
|
+
return value
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# ---------------------------------------------------------------------------
|
|
72
|
+
# BindingRegistry — central store for all registered bindings
|
|
73
|
+
# ---------------------------------------------------------------------------
|
|
74
|
+
|
|
75
|
+
class BindingRegistry:
|
|
76
|
+
"""Thread-safe registry mapping binding names to :class:`BindingSpec` instances.
|
|
77
|
+
|
|
78
|
+
Usage::
|
|
79
|
+
|
|
80
|
+
registry = BindingRegistry()
|
|
81
|
+
registry.register("grep", "omg_natives::grep::grep", _py_grep)
|
|
82
|
+
result = registry.call("grep", pattern, path)
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
def __init__(self) -> None:
|
|
86
|
+
self._bindings: Dict[str, BindingSpec] = {}
|
|
87
|
+
|
|
88
|
+
# -- mutators -----------------------------------------------------------
|
|
89
|
+
|
|
90
|
+
def register(
|
|
91
|
+
self,
|
|
92
|
+
name: str,
|
|
93
|
+
rust_symbol: str,
|
|
94
|
+
python_fallback: Callable[..., Any],
|
|
95
|
+
type_hints: Optional[Dict[str, str]] = None,
|
|
96
|
+
) -> None:
|
|
97
|
+
"""Register a new binding (or overwrite an existing one)."""
|
|
98
|
+
self._bindings[name] = BindingSpec(
|
|
99
|
+
name=name,
|
|
100
|
+
rust_symbol=rust_symbol,
|
|
101
|
+
python_fallback=python_fallback,
|
|
102
|
+
type_hints=type_hints or {},
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
# -- accessors ----------------------------------------------------------
|
|
106
|
+
|
|
107
|
+
def get(self, name: str) -> Optional[BindingSpec]:
|
|
108
|
+
"""Return the :class:`BindingSpec` for *name*, or ``None``."""
|
|
109
|
+
return self._bindings.get(name)
|
|
110
|
+
|
|
111
|
+
def list_names(self) -> List[str]:
|
|
112
|
+
"""Return a sorted list of all registered binding names."""
|
|
113
|
+
return sorted(self._bindings.keys())
|
|
114
|
+
|
|
115
|
+
def is_rust_available(self, name: str) -> bool:
|
|
116
|
+
"""Check whether the Rust implementation is available for *name*.
|
|
117
|
+
|
|
118
|
+
Always returns ``False`` in pure-Python fallback mode.
|
|
119
|
+
"""
|
|
120
|
+
# In a real Rust-enabled build this would probe the native extension.
|
|
121
|
+
return False
|
|
122
|
+
|
|
123
|
+
# -- invocation ---------------------------------------------------------
|
|
124
|
+
|
|
125
|
+
def call(self, __name: str, *args: Any, **kwargs: Any) -> Any:
|
|
126
|
+
"""Invoke the binding identified by *__name*.
|
|
127
|
+
|
|
128
|
+
In pure-Python fallback mode this delegates directly to the
|
|
129
|
+
registered ``python_fallback`` callable.
|
|
130
|
+
|
|
131
|
+
Raises:
|
|
132
|
+
KeyError: If no binding with *__name* is registered.
|
|
133
|
+
"""
|
|
134
|
+
spec = self._bindings.get(__name)
|
|
135
|
+
if spec is None:
|
|
136
|
+
raise KeyError(f"No binding registered with name: {__name!r}")
|
|
137
|
+
return spec.python_fallback(*args, **kwargs)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# ---------------------------------------------------------------------------
|
|
141
|
+
# Module-level singleton and convenience wrappers
|
|
142
|
+
# ---------------------------------------------------------------------------
|
|
143
|
+
|
|
144
|
+
REGISTRY = BindingRegistry()
|
|
145
|
+
"""Module-level singleton :class:`BindingRegistry` instance."""
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def bind_function(
|
|
149
|
+
name: str,
|
|
150
|
+
rust_symbol: str,
|
|
151
|
+
python_fallback: Callable[..., Any],
|
|
152
|
+
type_hints: Optional[Dict[str, str]] = None,
|
|
153
|
+
) -> None:
|
|
154
|
+
"""Convenience wrapper — register a binding in the global :data:`REGISTRY`."""
|
|
155
|
+
REGISTRY.register(name, rust_symbol, python_fallback, type_hints=type_hints)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def get_binding(name: str) -> Optional[BindingSpec]:
|
|
159
|
+
"""Convenience wrapper — look up a binding in the global :data:`REGISTRY`."""
|
|
160
|
+
return REGISTRY.get(name)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def call_binding(__name: str, *args: Any, **kwargs: Any) -> Any:
|
|
164
|
+
"""Convenience wrapper — invoke a binding via the global :data:`REGISTRY`."""
|
|
165
|
+
return REGISTRY.call(__name, *args, **kwargs)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""OMG Natives — clipboard: clipboard operation stubs.
|
|
2
|
+
|
|
3
|
+
Pure-Python stubs for clipboard operations.
|
|
4
|
+
No actual clipboard interaction — returns placeholder values.
|
|
5
|
+
|
|
6
|
+
Feature flag: ``OMG_RUST_ENGINE_ENABLED`` (default: False)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from typing import Optional
|
|
12
|
+
|
|
13
|
+
from omg_natives._bindings import bind_function
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def clipboard(operation: str = "get", text: Optional[str] = None) -> str:
|
|
17
|
+
"""Clipboard operation stubs.
|
|
18
|
+
|
|
19
|
+
- ``"get"``: returns ``""`` (stub — no actual clipboard access).
|
|
20
|
+
- ``"set"``: returns ``"ok"`` (stub — no actual clipboard access).
|
|
21
|
+
"""
|
|
22
|
+
if operation == "get":
|
|
23
|
+
return ""
|
|
24
|
+
elif operation == "set":
|
|
25
|
+
return "ok"
|
|
26
|
+
else:
|
|
27
|
+
return ""
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# Self-register with the global binding registry
|
|
31
|
+
bind_function(
|
|
32
|
+
name="clipboard",
|
|
33
|
+
rust_symbol="omg_natives::clipboard::clipboard",
|
|
34
|
+
python_fallback=clipboard,
|
|
35
|
+
type_hints={"operation": "str", "text": "str"},
|
|
36
|
+
)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""OMG Natives — glob: file path matching.
|
|
2
|
+
|
|
3
|
+
Pure-Python fallback for the Rust ``omg_natives::glob::glob_match`` function.
|
|
4
|
+
Uses ``pathlib.Path.glob`` for pattern matching.
|
|
5
|
+
|
|
6
|
+
Feature flag: ``OMG_RUST_ENGINE_ENABLED`` (default: False)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import List
|
|
13
|
+
|
|
14
|
+
from omg_natives._bindings import bind_function
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def glob(pattern: str, base: str = ".") -> list[str]:
|
|
18
|
+
"""Return file paths under *base* that match the glob *pattern*.
|
|
19
|
+
|
|
20
|
+
Uses ``pathlib.Path.glob`` for matching.
|
|
21
|
+
Returns relative paths as strings.
|
|
22
|
+
"""
|
|
23
|
+
results: List[str] = []
|
|
24
|
+
base_path = Path(base).resolve()
|
|
25
|
+
try:
|
|
26
|
+
for match in base_path.glob(pattern):
|
|
27
|
+
try:
|
|
28
|
+
results.append(str(match.relative_to(base_path)))
|
|
29
|
+
except ValueError:
|
|
30
|
+
results.append(str(match))
|
|
31
|
+
except OSError:
|
|
32
|
+
pass
|
|
33
|
+
return results
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# Self-register with the global binding registry
|
|
37
|
+
bind_function(
|
|
38
|
+
name="glob",
|
|
39
|
+
rust_symbol="omg_natives::glob::glob_match",
|
|
40
|
+
python_fallback=glob,
|
|
41
|
+
type_hints={"pattern": "str", "base": "str"},
|
|
42
|
+
)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""OMG Natives — grep: regex search in files.
|
|
2
|
+
|
|
3
|
+
Pure-Python fallback for the Rust ``omg_natives::grep::grep`` function.
|
|
4
|
+
Uses ``re`` and ``os.walk`` for recursive file searching.
|
|
5
|
+
|
|
6
|
+
Feature flag: ``OMG_RUST_ENGINE_ENABLED`` (default: False)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import re
|
|
13
|
+
from typing import List
|
|
14
|
+
|
|
15
|
+
from omg_natives._bindings import bind_function
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def grep(pattern: str, path: str, recursive: bool = False) -> list[dict]:
|
|
19
|
+
"""Search for *pattern* (regex) in files.
|
|
20
|
+
|
|
21
|
+
If *recursive* is False, searches only the single file at *path*.
|
|
22
|
+
If *recursive* is True and *path* is a directory, walks the directory tree.
|
|
23
|
+
|
|
24
|
+
Returns a list of ``{"file": path, "line": lineno, "text": line_content}``.
|
|
25
|
+
"""
|
|
26
|
+
results: List[dict] = []
|
|
27
|
+
try:
|
|
28
|
+
compiled = re.compile(pattern)
|
|
29
|
+
except re.error:
|
|
30
|
+
return results
|
|
31
|
+
|
|
32
|
+
def _search_file(filepath: str) -> None:
|
|
33
|
+
try:
|
|
34
|
+
with open(filepath, "r", encoding="utf-8", errors="ignore") as fh:
|
|
35
|
+
for lineno, line in enumerate(fh, start=1):
|
|
36
|
+
if compiled.search(line):
|
|
37
|
+
results.append({
|
|
38
|
+
"file": filepath,
|
|
39
|
+
"line": lineno,
|
|
40
|
+
"text": line.rstrip("\n"),
|
|
41
|
+
})
|
|
42
|
+
except OSError:
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
if recursive and os.path.isdir(path):
|
|
46
|
+
for root, _dirs, files in os.walk(path):
|
|
47
|
+
for name in files:
|
|
48
|
+
_search_file(os.path.join(root, name))
|
|
49
|
+
else:
|
|
50
|
+
_search_file(path)
|
|
51
|
+
|
|
52
|
+
return results
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# Self-register with the global binding registry
|
|
56
|
+
bind_function(
|
|
57
|
+
name="grep",
|
|
58
|
+
rust_symbol="omg_natives::grep::grep",
|
|
59
|
+
python_fallback=grep,
|
|
60
|
+
type_hints={"pattern": "str", "path": "str", "recursive": "bool"},
|
|
61
|
+
)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""OMG Natives — highlight: basic syntax highlighting.
|
|
2
|
+
|
|
3
|
+
Pure-Python fallback that returns code unchanged (no Pygments dependency).
|
|
4
|
+
Optionally wraps code with a language comment header.
|
|
5
|
+
|
|
6
|
+
Feature flag: ``OMG_RUST_ENGINE_ENABLED`` (default: False)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from omg_natives._bindings import bind_function
|
|
12
|
+
|
|
13
|
+
# Known language comment prefixes
|
|
14
|
+
_COMMENT_STYLES = {
|
|
15
|
+
"python": "#",
|
|
16
|
+
"javascript": "//",
|
|
17
|
+
"typescript": "//",
|
|
18
|
+
"rust": "//",
|
|
19
|
+
"go": "//",
|
|
20
|
+
"java": "//",
|
|
21
|
+
"c": "//",
|
|
22
|
+
"cpp": "//",
|
|
23
|
+
"ruby": "#",
|
|
24
|
+
"bash": "#",
|
|
25
|
+
"shell": "#",
|
|
26
|
+
"sh": "#",
|
|
27
|
+
"yaml": "#",
|
|
28
|
+
"toml": "#",
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def highlight(code: str, language: str = "") -> str:
|
|
33
|
+
"""Basic syntax highlighting — returns code unchanged (no Pygments).
|
|
34
|
+
|
|
35
|
+
If *language* is known, prepends a comment header indicating the language.
|
|
36
|
+
Otherwise returns *code* as-is.
|
|
37
|
+
"""
|
|
38
|
+
if not language:
|
|
39
|
+
return code
|
|
40
|
+
|
|
41
|
+
lang_lower = language.lower()
|
|
42
|
+
comment = _COMMENT_STYLES.get(lang_lower)
|
|
43
|
+
if comment:
|
|
44
|
+
return f"{comment} [{lang_lower}]\n{code}"
|
|
45
|
+
return code
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# Self-register with the global binding registry
|
|
49
|
+
bind_function(
|
|
50
|
+
name="highlight",
|
|
51
|
+
rust_symbol="omg_natives::highlight::highlight",
|
|
52
|
+
python_fallback=highlight,
|
|
53
|
+
type_hints={"code": "str", "language": "str"},
|
|
54
|
+
)
|