Skip to content

refactor(cli,ffi): relocate file_watcher to libgossamer with C-ABI exports#24

Merged
hyperpolymath merged 1 commit into
mainfrom
feat/cli-relocate-file-watcher
May 20, 2026
Merged

refactor(cli,ffi): relocate file_watcher to libgossamer with C-ABI exports#24
hyperpolymath merged 1 commit into
mainfrom
feat/cli-relocate-file-watcher

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

  • Moves cli/src/file_watcher.zigsrc/interface/ffi/src/file_watcher.zig so any libgossamer consumer (today's native Zig CLI, the planned Ephapax-wasm CLI behind a host launcher, third-party embedders) shares the same hot-reload path.
  • Adds two C-ABI exports: gossamer_watcher_start(handle, config_json, frontend_dist) -> opaque* and gossamer_watcher_stop(opaque*) -> void. The start path dupes both buffers into watcher-owned memory so callers may free their inputs on return.
  • Updates cli/src/main.zig to call the new exports via extern fn decls instead of importing the moved file.

Why

Phase 14a.2 of porting the gossamer CLI to typed-wasm Ephapax (umbrella issue forthcoming). The watcher is platform-coupled GTK-thread-marshalling code — it belongs in FFI/Zig per the architecture rule, not in the CLI's application code. Relocating it now means the future Ephapax port doesn't need to re-implement hot-reload from scratch.

Test plan

  • zig ast-check on all three touched files — zero parse errors.
  • Reviewer: confirm CI's GTK3/WebKitGTK build succeeds (local WSL env doesn't have the dev headers installed; CI does).
  • Reviewer: smoke-test gossamer dev against a real project — edit a watched file, confirm reload still fires.

Notes for reviewer

  • WatcherState gained two optional fields (owned_json, owned_frontend_dist) that store dupes of the caller's strings. The Zig-native start() path leaves both null for back-compat; only the new C-ABI gossamer_watcher_start populates them.
  • The hand-rolled JSON path-array parser in parseWatchConfig is unchanged. A real JSON parser belongs in libgossamer (planned in a follow-up: gossamer_conf_load).

🤖 Generated with Claude Code

…ports

Move cli/src/file_watcher.zig → src/interface/ffi/src/file_watcher.zig so
any libgossamer consumer can use the hot-reload watcher — the native Zig
CLI (today), the planned Ephapax-wasm CLI behind a host launcher, or
third-party embedders.

Changes:
  • git-mv the source file; update its header to reflect the new home.
  • Add two C-ABI exports at the bottom of the relocated file:
      - gossamer_watcher_start(handle, config_json, frontend_dist)
          dupes both buffers into watcher-owned memory so callers may free
          their inputs immediately on return.
      - gossamer_watcher_stop(opaque_handle)
          blocks on thread join, then frees the owned buffers + state.
  • Extend WatcherState with owned_json / owned_frontend_dist fields so
    the slices stored in WatchConfig outlive any caller-provided buffer
    when started via the C boundary. Zig-native start() leaves both null
    (back-compat — caller manages lifetime).
  • Wire src/interface/ffi/src/main.zig to pick up the new module via
    the existing comptime { _ = @import(...) } pattern.
  • cli/src/main.zig: drop the local @import("file_watcher.zig"), add
    extern decls for the two new exports, replace the call sites in
    cmdDev() with the C-ABI calls.

Verified:
  • zig ast-check on all 3 touched files — zero parse errors.
  • Compile-link to GTK3/WebKitGTK requires those system dev libs which
    aren't installed in this WSL env (pre-existing limitation, not a
    regression); CI will run the full build.

Phase 14a.2 of the gossamer cli (cli/) port from native Zig to typed-wasm
Ephapax. Unblocks task #15 by ensuring the watcher API is reachable from
any future wasm-host launcher.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 41 issues detected

Severity Count
🔴 Critical 21
🟠 High 4
🟡 Medium 16

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Issue in quality.yml",
    "type": "missing_workflow",
    "file": "quality.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in security-policy.yml",
    "type": "missing_workflow",
    "file": "security-policy.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Action actions/upload-artifact@v4 needs attention",
    "type": "unpinned_action",
    "file": "release.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action actions/download-artifact@v4 needs attention",
    "type": "unpinned_action",
    "file": "release.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/gossamer/gossamer/tests/unit/result_code_test.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/gossamer/gossamer/tests/unit/guard_mode_test.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/gossamer/gossamer/tests/unit/ipc_test.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/gossamer/gossamer/tests/unit/capability_test.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/gossamer/gossamer/tests/unit/dialog_test.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath merged commit abe1832 into main May 20, 2026
18 of 20 checks passed
@hyperpolymath hyperpolymath deleted the feat/cli-relocate-file-watcher branch May 20, 2026 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant