Skip to content

feat: scaffold JigAi v0.1.0 - #1

Merged
nafistiham merged 14 commits into
developfrom
feat/scaffold
Feb 26, 2026
Merged

feat: scaffold JigAi v0.1.0#1
nafistiham merged 14 commits into
developfrom
feat/scaffold

Conversation

@nafistiham

Copy link
Copy Markdown
Owner

Summary

  • Add transparent PTY proxy for wrapping any terminal-based AI tool
  • Add layered idle detection engine (pattern match + timeout + cooldown)
  • Add built-in patterns for Claude Code, Codex, Gemini CLI, Aider, OpenCode
  • Add macOS notifications via terminal-notifier with focus-aware skip logic
  • Add FastAPI WebSocket server with mDNS/Bonjour LAN discovery
  • Add full Typer CLI: watch, server, config, patterns, sessions
  • Add 46 unit tests across models, config, detector, and patterns
  • Add GitHub Actions CI (Python 3.10–3.12) and PyPI Trusted Publishing workflow
  • Add production README covering installation, caveats, architecture, roadmap

Commits

14 atomic commits — one logical unit each. No squash requested.

Test plan

  • pip install -e ".[dev]" && pytest — all 46 tests pass
  • jigai --version returns v0.1.0
  • jigai watch claude wraps Claude Code transparently with no UI disruption
  • Idle notification fires when Claude Code shows prompt
  • jigai server start starts FastAPI server on port 9384
  • jigai config test "> " correctly matches claude_code pattern

- Python 3.10+ support
- Full dependency list: typer, fastapi, uvicorn, websockets, zeroconf, pyyaml, rich, pydantic
- Dev extras: pytest, ruff, mypy
- Trusted publishing setup for PyPI
- GitHub URLs pointing to nafistiham/jigai
- Session tracks tool name, command, PID, status, working dir
- IdleEvent carries detection method, tool name, last output, session context
- SessionStatus enum: active / idle / stopped
- Pydantic v2 models with serialization support
- JigAiConfig with nested models: server, notifications, detection, sessions
- NotificationConfig includes sound, redact_patterns, only_when_away flag
- Auto-creates ~/.jigai/ directory on first use
- Safe YAML loading with fallback to defaults
- save_default_config() helper for jigai config init
…emini CLI, Aider, OpenCode

- Built-in patterns for all major AI coding tools
- PatternRegistry with match_any() and tool name lookup
- User-overridable via ~/.jigai/patterns.yaml
- detect_tool_from_command() auto-identifies tool from argv
- Invalid regex patterns are skipped gracefully
- 30s timeout fallback, 5s cooldown between notifications
- Forks child process inside a proper pseudo-terminal
- All I/O proxied unchanged — child behaves identically to direct launch
- Handles terminal resize (SIGWINCH) and passes through raw keystrokes
- on_output callback receives every byte of child stdout for detection
- Clean teardown on child exit or KeyboardInterrupt
…meout

- Strips ANSI escape codes before matching (handles rich TUI output)
- Layered detection: tool-hinted match first, then all-tool scan, then timeout
- Cooldown prevents notification floods on repeated idle patterns
- Output buffer (last 50 lines) for notification context
- Sensitive data redaction via configurable regex patterns
…ctor

- Watcher ties PTY proxy, idle detector, notifier, and server client together
- Accumulates partial lines (prompts without newline) for pattern matching
- _last_meaningful_line() strips box-drawing chars and finds real output text
- Background thread runs timeout checks every second
- Skips notification if terminal is focused (only_when_away config)
- Uses terminal-notifier when installed (banner popups)
- Falls back to osascript when terminal-notifier is not available
- is_terminal_focused() checks frontmost app via System Events
- only_when_away config skips notification if user is at a terminal
- Input sanitized to prevent osascript injection via quote/backslash escaping
- REST endpoints: /api/sessions, /api/events (register, unregister, push)
- WebSocket endpoint /ws broadcasts idle events to all connected clients
- ConnectionManager handles connect/disconnect and broadcast
- mDNS service registration so mobile clients auto-discover server on LAN
- get_local_ip() resolves machine's LAN IP for display at startup
- ServerClient wraps all REST calls to the local JigAi server
- is_server_running() used at startup to detect running server
- push_event() sends IdleEvent JSON to /api/events
- register_session() and unregister_session() for session lifecycle
- Silently ignores connection errors (server is optional)
…s commands

- jigai watch: wraps any command, connects to server if running
- jigai server start/status: manage LAN notification server
- jigai config init/show/test: config management and pattern testing
- jigai patterns: display all loaded patterns in a Rich table
- jigai sessions: list active sessions via server REST API
- Startup banner shown once before wrapped tool launches, then silent
- 46 tests covering core detection logic, pattern loading, config defaults
- TestStripAnsi verifies ANSI codes are stripped before matching
- TestDetector covers pattern detection, tool hints, cooldown, buffer, redaction
- TestTimeoutDetection covers idle trigger, re-trigger prevention, reset
- TestLoadPatterns verifies built-in patterns load and compile correctly
- All tests run on macOS CI via pytest-asyncio
- ci.yml: runs ruff lint + pytest on Python 3.10, 3.11, 3.12 on macos-latest
- publish.yml: builds and publishes to PyPI on GitHub Release via Trusted Publishing
- No API tokens stored — uses OIDC id-token for PyPI authentication
- Runs on push/PR to main and develop branches
- Installation steps for pip and terminal-notifier
- Notification setup walkthrough (terminal-notifier macOS config)
- Known caveats: Focus mode, Sequoia compatibility, display mirroring
- only_when_away config for suppressing notifications at terminal
- Full command reference, architecture diagram, project structure
- PyPI Trusted Publishing guide for maintainers
- Roadmap through v0.4
@nafistiham
nafistiham merged commit a451033 into develop Feb 26, 2026
0 of 3 checks passed
@nafistiham
nafistiham deleted the feat/scaffold branch February 26, 2026 23:21
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