fix Windows Unicode crash on non-UTF-8 consoles (issue #992)
reconfigure stdout/stderr to UTF-8 at startup; replace → and — in all print statements with ASCII equivalents as belt-and-suspenders fallback Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
55d7dadb63
commit
31a608f73e
+16
-10
@@ -1118,7 +1118,7 @@ def _agents_install(project_dir: Path, platform: str) -> None:
|
||||
if platform not in ("codex", "opencode"):
|
||||
print()
|
||||
print("Note: unlike Claude Code, there is no PreToolUse hook equivalent for")
|
||||
print(f"{platform.capitalize()} — the AGENTS.md rules are the always-on mechanism.")
|
||||
print(f"{platform.capitalize()} - the AGENTS.md rules are the always-on mechanism.")
|
||||
|
||||
|
||||
def _project_install(platform_name: str, project_dir: Path | None = None) -> None:
|
||||
@@ -1399,7 +1399,7 @@ def _clone_repo(url: str, branch: str | None = None, out_dir: Path | None = None
|
||||
sys.exit(1)
|
||||
|
||||
if dest.exists():
|
||||
print(f"Repo already cloned at {dest} — pulling latest...", flush=True)
|
||||
print(f"Repo already cloned at {dest} - pulling latest...", flush=True)
|
||||
cmd = ["git", "-C", str(dest), "pull"]
|
||||
if branch:
|
||||
cmd += ["origin", "--", branch]
|
||||
@@ -1423,6 +1423,12 @@ def _clone_repo(url: str, branch: str | None = None, out_dir: Path | None = None
|
||||
|
||||
|
||||
def main() -> None:
|
||||
for _stream in (sys.stdout, sys.stderr):
|
||||
if _stream is not None and hasattr(_stream, "reconfigure"):
|
||||
try:
|
||||
_stream.reconfigure(encoding="utf-8", errors="replace")
|
||||
except Exception:
|
||||
pass
|
||||
# Check all known skill install locations for a stale version stamp.
|
||||
# Skip during install/uninstall (hook writes trigger a fresh check anyway).
|
||||
# Skip during hook-check — it runs on every editor tool use and must be silent.
|
||||
@@ -2364,7 +2370,7 @@ def main() -> None:
|
||||
watch_path = Path(".")
|
||||
graph_json = graph_override if graph_override is not None else watch_path / "graphify-out" / "graph.json"
|
||||
if not graph_json.exists():
|
||||
print(f"error: no graph found at {graph_json} — run /graphify first", file=sys.stderr)
|
||||
print(f"error: no graph found at {graph_json} - run /graphify first", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
from networkx.readwrite import json_graph as _jg
|
||||
from graphify.build import build_from_json
|
||||
@@ -2427,16 +2433,16 @@ def main() -> None:
|
||||
if no_viz:
|
||||
if html_target.exists():
|
||||
html_target.unlink()
|
||||
print(f"Done — {len(communities)} communities. GRAPH_REPORT.md and graph.json updated (--no-viz; graph.html removed).")
|
||||
print(f"Done - {len(communities)} communities. GRAPH_REPORT.md and graph.json updated (--no-viz; graph.html removed).")
|
||||
else:
|
||||
try:
|
||||
to_html(G, communities, str(html_target), community_labels=labels or None)
|
||||
print(f"Done — {len(communities)} communities. GRAPH_REPORT.md, graph.json and graph.html updated.")
|
||||
print(f"Done - {len(communities)} communities. GRAPH_REPORT.md, graph.json and graph.html updated.")
|
||||
except ValueError as viz_err:
|
||||
if html_target.exists():
|
||||
html_target.unlink()
|
||||
print(f"Skipped graph.html: {viz_err}")
|
||||
print(f"Done — {len(communities)} communities. GRAPH_REPORT.md and graph.json updated.")
|
||||
print(f"Done - {len(communities)} communities. GRAPH_REPORT.md and graph.json updated.")
|
||||
|
||||
elif cmd == "update":
|
||||
force = os.environ.get("GRAPHIFY_FORCE", "").lower() in ("1", "true", "yes")
|
||||
@@ -2487,7 +2493,7 @@ def main() -> None:
|
||||
):
|
||||
print("Tip: set GEMINI_API_KEY or GOOGLE_API_KEY to use Gemini for semantic extraction.")
|
||||
else:
|
||||
print("Nothing to update or rebuild failed — check output above.", file=sys.stderr)
|
||||
print("Nothing to update or rebuild failed - check output above.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
elif cmd == "hook-check":
|
||||
@@ -2981,7 +2987,7 @@ def main() -> None:
|
||||
try:
|
||||
result = _global_add(source, tag)
|
||||
if result["skipped"]:
|
||||
print(f"'{tag}' unchanged since last add — global graph not modified.")
|
||||
print(f"'{tag}' unchanged since last add - global graph not modified.")
|
||||
else:
|
||||
print(f"Added '{tag}' to global graph: +{result['nodes_added']} nodes, "
|
||||
f"-{result['nodes_removed']} pruned. Global: {_global_path()}")
|
||||
@@ -3458,7 +3464,7 @@ def main() -> None:
|
||||
try:
|
||||
result = _global_add(graphify_out / "graph.json", _tag)
|
||||
if result["skipped"]:
|
||||
print(f"[graphify global] '{_tag}' unchanged since last add — skipped.")
|
||||
print(f"[graphify global] '{_tag}' unchanged since last add - skipped.")
|
||||
else:
|
||||
print(f"[graphify global] '{_tag}' merged into global graph "
|
||||
f"(+{result['nodes_added']} nodes, -{result['nodes_removed']} pruned).")
|
||||
@@ -3520,7 +3526,7 @@ def main() -> None:
|
||||
try:
|
||||
result = _global_add(graphify_out / "graph.json", _tag)
|
||||
if result["skipped"]:
|
||||
print(f"[graphify global] '{_tag}' unchanged since last add — skipped.")
|
||||
print(f"[graphify global] '{_tag}' unchanged since last add - skipped.")
|
||||
else:
|
||||
print(f"[graphify global] '{_tag}' merged into global graph "
|
||||
f"(+{result['nodes_added']} nodes, -{result['nodes_removed']} pruned).")
|
||||
|
||||
+2
-2
@@ -86,11 +86,11 @@ def backup_if_protected(out_dir: Path) -> "Path | None":
|
||||
except Exception:
|
||||
pass
|
||||
if copied:
|
||||
print(f"[graphify] backed up {reason} graph ({copied} files) → {backup_dir.name}/")
|
||||
print(f"[graphify] backed up {reason} graph ({copied} files) -> {backup_dir.name}/")
|
||||
return backup_dir
|
||||
except Exception as exc:
|
||||
import sys
|
||||
print(f"[graphify] warning: backup failed ({exc}) — continuing with overwrite", file=sys.stderr)
|
||||
print(f"[graphify] warning: backup failed ({exc}) - continuing with overwrite", file=sys.stderr)
|
||||
return None
|
||||
|
||||
def _obsidian_tag(name: str) -> str:
|
||||
|
||||
+5
-5
@@ -471,7 +471,7 @@ def render_worktrees(prs: list[PRInfo], worktrees: dict[str, str]) -> None:
|
||||
if pr:
|
||||
status = _status_color(pr.status)
|
||||
print(f" {cyan(path)}")
|
||||
print(f" {dim('branch:')} {branch} → PR {bold(f'#{pr.number}')} [{status}] {_truncate(pr.title, 50)}")
|
||||
print(f" {dim('branch:')} {branch} -> PR {bold(f'#{pr.number}')} [{status}] {_truncate(pr.title, 50)}")
|
||||
else:
|
||||
print(f" {cyan(path)}")
|
||||
print(f" {dim('branch:')} {branch} {dim('(no open PR)')}")
|
||||
@@ -485,7 +485,7 @@ def render_conflicts(
|
||||
) -> None:
|
||||
actionable = [p for p in prs if p.base_branch == base and p.communities_touched]
|
||||
if not actionable:
|
||||
print(dim("\n No graph impact data — run with a valid graph.json to detect conflicts.\n"))
|
||||
print(dim("\n No graph impact data - run with a valid graph.json to detect conflicts.\n"))
|
||||
return
|
||||
|
||||
# Build community → [PRs] map
|
||||
@@ -496,7 +496,7 @@ def render_conflicts(
|
||||
|
||||
conflicts = {c: ps for c, ps in comm_to_prs.items() if len(ps) > 1}
|
||||
if not conflicts:
|
||||
print(green("\n No community overlap between open PRs — safe to merge in any order.\n"))
|
||||
print(green("\n No community overlap between open PRs - safe to merge in any order.\n"))
|
||||
return
|
||||
|
||||
print()
|
||||
@@ -518,7 +518,7 @@ def render_pr_detail(pr: PRInfo, repo: str | None = None) -> None:
|
||||
print(bold(f" PR #{pr.number} · {_status_color(pr.status)}"))
|
||||
print(f" {pr.title}")
|
||||
print()
|
||||
print(f" {dim('branch:')} {pr.branch} → {pr.base_branch}")
|
||||
print(f" {dim('branch:')} {pr.branch} -> {pr.base_branch}")
|
||||
print(f" {dim('author:')} {pr.author}")
|
||||
print(f" {dim('updated:')} {pr.days_old}d ago")
|
||||
print(f" {dim('CI:')} {_ci_icon(pr.ci_status)} {pr.ci_status}")
|
||||
@@ -579,7 +579,7 @@ def triage_with_opus(prs: list[PRInfo], base: str) -> None:
|
||||
try:
|
||||
from graphify.llm import BACKENDS, _get_backend_api_key
|
||||
except ImportError:
|
||||
print(red(" graphify.llm not available — cannot run triage."), file=sys.stderr)
|
||||
print(red(" graphify.llm not available - cannot run triage."), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
candidates = [p for p in prs if p.base_branch == base and p.status not in ("WRONG-BASE", "STALE")]
|
||||
|
||||
Reference in New Issue
Block a user