2 Commits

Author SHA1 Message Date
nauman73 e5f263ba98 fix(windows): unblock pipeline on Windows consoles + missing __main__ guards (#788)
Three independent Windows compatibility fixes shipped together because they
all surface during the same first /graphify run on Windows.

graphify/benchmark.py
  print_benchmark() unconditionally printed U+2500 (box-drawing) and U+2192
  (rightwards arrow), which UnicodeEncodeError'd on stdouts that can't encode
  them — most notably the legacy Windows console at cp1252. New _safe()
  helper falls back to ASCII when the active stdout encoding can't carry the
  glyph; _hr() uses it. Two regression tests cover both paths and prove
  print_benchmark survives a cp1252-strict stream.

graphify/extract.py
  ProcessPoolExecutor on Windows uses spawn, so worker subprocesses
  re-import the calling __main__. When the caller is `python -c "..."` or a
  script without an `if __name__ == "__main__":` guard, the workers
  recursively spawn themselves and the pool dies. The user-visible failure
  was a 290-line traceback ending in BrokenProcessPool, hiding the actual
  cause. _extract_parallel now catches BrokenProcessPool, prints a one-line
  warning that names the __main__-guard idiom, and returns False so the
  public extract() routes to the existing _extract_sequential fallback. Two
  tests cover the parallel-returns-False contract and the sequential
  fallback wiring.

graphify/skill-windows.md
  Every `python -c "..."` block (30 in total) is replaced with a
  Write+run+delete pattern using PowerShell's literal here-string @'...'@.
  The old form was a quote-escaping minefield: any double-quote inside the
  Python source had to be backslash-escaped for the shell, and PowerShell's
  parser ate them inconsistently — failing on f-strings like
  `f'AST: {len(result["nodes"])} nodes'`. The new form passes Python source
  to disk literally, so what the model writes is what Python sees. The AST
  step's script template now includes an explicit `if __name__ == "__main__":`
  guard so multi-core extraction works even before the runtime fallback above
  kicks in. All 31 resulting heredoc blocks parse cleanly under
  `ast.parse`.

Co-authored-by: Nauman Hameed <Nauman.Hameed@enghouse.com>
2026-05-09 12:59:38 +01:00
Safi 81a43f028f feat: 13-language AST support and token benchmark
Java, C, C++, Ruby, C#, Kotlin, Scala, PHP via tree-sitter (13 total)
benchmark.py measures BFS subgraph tokens vs corpus tokens
5 skill bug fixes (cohesion crash, dead step, missing MCP tool)
2026-04-04 18:56:38 +01:00