3fe919e37c
Move SKILL.md + references/ scripts/ evals/ from skills/halcon/ up to the plugin root. Per Claude Code plugins-reference, a plugin with SKILL.md at its root and no skills/ subdir is auto-loaded as a single-skill plugin (v2.1.142+), so the invocation name = frontmatter name = halcon → clean /halcon. Bump plugin.json 2.0.0 → 2.0.1 so existing installs receive the update. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
41 lines
1.3 KiB
Python
Executable File
41 lines
1.3 KiB
Python
Executable File
"""Shared helpers for the HALCON runner scripts."""
|
|
import re
|
|
|
|
_INT_RE = re.compile(r"^[+-]?\d+$")
|
|
_FLOAT_RE = re.compile(r"^[+-]?(\d+\.\d*|\.\d+|\d+)([eE][+-]?\d+)?$")
|
|
|
|
|
|
def coerce(value: str):
|
|
"""Turn a CLI string into int/float/str, or a list for comma-separated input.
|
|
|
|
Absolute paths (C:/..., /mnt/...) and anything non-numeric stay strings.
|
|
Use a trailing comma or commas to force a tuple, e.g. '1,2,3' -> [1,2,3].
|
|
"""
|
|
if "," in value:
|
|
return [coerce(v) for v in value.split(",") if v != ""]
|
|
if _INT_RE.match(value):
|
|
return int(value)
|
|
if _FLOAT_RE.match(value) and not value.strip().startswith(("C:", "c:")):
|
|
return float(value)
|
|
return value
|
|
|
|
|
|
def jsonable(v):
|
|
"""Make a HALCON output control value JSON-serializable."""
|
|
if isinstance(v, (list, tuple)):
|
|
return [jsonable(x) for x in v]
|
|
if isinstance(v, (int, float, str, bool)) or v is None:
|
|
return v
|
|
return str(v)
|
|
|
|
|
|
def parse_set(pairs):
|
|
"""['Name=Value', ...] -> [(name, coerced_value), ...]."""
|
|
out = []
|
|
for p in pairs or []:
|
|
if "=" not in p:
|
|
raise SystemExit(f"--set expects Name=Value, got: {p!r}")
|
|
name, _, raw = p.partition("=")
|
|
out.append((name.strip(), coerce(raw)))
|
|
return out
|