git clone https://github.com/Logiiiii/unity-agent-skills.git--- name: jahro-watcher description: > Analyzes C# fields and properties and generates [JahroWatch] attributes with groups and performance-safe patterns. Use when the user wants to monitor variables at runtime, add watchers, track game state, replace Debug.Log polling, or mentions JahroWatch, real-time inspection, or variable monitoring. --- # Jahro Watcher Help users monitor game variables in real-time using Jahro's `[JahroWatch]` attribute system. ## Workflow 1. **Analyze** the user's code — identify fields/properties worth monitoring 2. **Generate** correct `[JahroWatch]` attributes 3. **Add registration** if needed (instance members require `RegisterObject`) 4. **VERIFY** — "Enter Play Mode, open the Watcher tab, confirm values update" ## Analyzing Code for Watcher Candidates When the user shares a class, identify members worth monitoring: **Good candidates:** - Game state fields: health, score, level, currency, inventory counts - Physics values: velocity, position, rotation (especially via properties wrapping Rigidbody) - Performance metrics: FPS, memory, draw calls - Enum state fields: game state, player state, AI state - Key counters: enemy count, player count, item count **Skip these:** - Constants and readonly compile-time values - Private implementation details that change every frame with no debugging value - References to other objects (Transform, GameObject) — watch their properties instead - Collections and dictionaries (arrays are supported, but dictionaries are not) **Suggest replacing Debug.Log polling:** If the user has `Debug.Log($"Health: {health}")` in `Update()`, recommend `[JahroWatch]` instead — it eliminates log spam and provides a clean real-time dashboard. ## Attribute Syntax ```csharp [JahroWatch("Display Name", "GroupName", "Description for detail modal")] ``` Constructor: `[JahroWatch(string name, string group, string description)]` All parameters are optional. Defaults: name = member name (leading `_` stripped), group = "Default", description = "". ### Complete example ```csharp using JahroConsole; using UnityEngine; public class PlayerController : MonoBehaviour { [JahroWatch("Health", "Player", "Current hit points")] public float health = 100f; [JahroWatch("Stamina", "Player", "Current stamina")] public float stamina = 50f; [JahroWatch("Position", "Player", "World position")] public Vector3 Position => transform.position; [JahroWatch("Velocity", "Player", "Movement velocity")] public Vector3 Velocity => GetComponent<Rigidbody>().velocity; [JahroWatch("Is Grounded", "Player", "Touching ground")] public bool isGrounded; void OnEnable() => Jahro.RegisterObject(this); void OnDisable() => Jahro.UnregisterObject(this); } ``` ## Registration ### Instance members — require RegisterObject ```csharp void OnEnable() => Jahro.RegisterObject(this); void OnDisable() => Jahro.UnregisterObject(this); ``` This same call also registers `[JahroCommand]` attributes on the class. If the class already has `RegisterObject` for commands, do not add a second call — one call handles both. Read `references/common-patterns.md` for the canonical lifecycle pattern. ### Static members — no registration needed Static fields and properties with `[JahroWatch]` are discovered via assembly scanning: ```csharp public static class GameStats { [JahroWatch("Total Score", "Game")] public static int Score; [JahroWatch("Session Time", "Game")] public static float SessionTime => Time.realtimeSinceStartup; } ``` ### Adding watchers to a class that already has commands If the class already has `[JahroCommand]` attributes and `RegisterObject`, just add `[JahroWatch]` attributes — no registration changes: ```csharp public class GameManager : MonoBehaviour { // Existing command [JahroCommand("reset-game", "Game", "Reset game")] public void ResetGame() { /* ... */ } // New watchers — just add attributes [JahroWatch("Player Count", "Game")] public int playerCount; [JahroWatch("Game Time", "Game")] public float gameTime; // Already present — no changes needed void OnEnable() => Jahro.RegisterObject(this); void OnDisable() => Jahro.UnregisterObject(this); } ``` ## Supported Types | Type | List View Display | Detail Modal | |:-----|:-----------------|:-------------| | `int`, `float`, `double`, `bool` | Value as-is | Same | | `string` | Truncated | Full text | | `Vector2` | Compact coords | Coords + magnitude | | `Vector3` | Compact coords | Coords + magnitude | | `Quaternion` | Raw values | Raw + Euler angles | | `Transform` | Position | Position, rotation, scale, child count | | `Rigidbody` | Summary | Mass, kinematic, gravity, velocity, angular velocity | | `Collider` | Summary | Trigger status, material, bounds | | `AudioSource` | Summary | Clip, volume, loop, pitch, mute | | `Camera` | Summary | FOV, clip planes, aspect ratio | | Arrays (any `T[]`) | `TypeName[length]` | Full contents | For custom types not in this table, the watcher calls `.ToString()`. If you need rich display, consider watching individual primitive properties instead. Read `references/api-reference.md` for the full type display details. ## Performance Watchers are designed to be safe for development and testing: - **Values are only read when the Watcher UI tab is visible.** No continuous polling when the console is closed or on another tab. - **No overhead when disabled.** If Jahro is disabled via `JAHRO_DISABLE` or auto-disable, watchers are never evaluated. - **Be mindful of expensive property getters.** A property like `public int Count => expensiveList.Where(...).Count()` runs its getter every frame the Watcher is open. Cache expensive computations. ### Performance-safe property pattern ```csharp private float _cachedFps; private float _lastFpsUpdate; void Update() { if (Time.time - _lastFpsUpdate > 0.25f) { _cachedFps = 1f / Time.unscaledDeltaTime; _lastFpsUpdate = Time.time; } } [JahroWatch("FPS", "Performance")] public float FPS => _cachedFps; ``` ## Group Organization ### By system (recommended default) ``` "Player" — Health, Stamina, Position, Velocity "Physics" — Is Grounded, Angular Velocity, Collision Count "Performance" — FPS, Memory, Draw Calls "Game" — Game State, Level Progress, Player Count "AI" — AI State, Target, Path Length ``` ### By priority ``` "Critical" — Health, Frame Time (always need these) "Gameplay" — Enemy Count, Spawn Timer "Diagnostics" — GC Allocs, Memory ``` ### Watcher UI behavior - **Favorites** group always appears at top (user stars individual watchers) - Custom groups are alphabetically sorted - Groups are collapsible to reduce clutter - Tapping a watcher opens a detail modal with description and full type info ## Contextual Awareness | Pattern in code | Suggestion | |:---------------|:-----------| | `Debug.Log` in `Update()` logging variable values | Replace with `[JahroWatch]` — cleaner, no log spam | | `[JahroWatch]` already present | Suggest additional watchers, better groups, performance tips | | `[JahroCommand]` but no watchers | Suggest adding watchers for key state the commands modify | | Rigidbody or physics-heavy code | Suggest velocity, angular velocity, isGrounded watchers | | Game manager with state fields | Suggest watching game state enum, counts, timers | ## Verification After generating watchers, always include: > **Verify:** Enter Play Mode → press ~ → switch to the **Watcher** tab. Confirm your watched values appear in the correct groups and update in real-time as the game runs. Tap a watcher to see its detail modal. If watchers appear but don't update, or don't appear at all, suggest the jahro-troubleshooting skill — common causes: missing RegisterObject, Watcher tab not open, object destroyed without unregistering.
1. **Define Your Monitoring Scope**: Replace [COMPONENT/SYSTEM] with your specific Jahro component (e.g., 'Jahro API Gateway', 'Jahro Cache Layer'). Specify the environment (e.g., 'AWS EC2', 'Azure Kubernetes Service') in [ENVIRONMENT/PLATFORM]. 2. **Set Custom Thresholds**: Replace [THRESHOLD_1], [THRESHOLD_2], etc., with your critical metrics (e.g., 'CPU > 85%', 'Memory > 90%', 'Error Rate > 1%'). For security, use 'Unauthorized access attempts > 5/hour'. 3. **Choose Time Periods**: Replace [TIME_PERIOD] with your desired analysis window (e.g., 'last 7 days', 'last 24 hours'). For [METRICS/DATA], specify what to track (e.g., 'query latency', 'login failures', 'disk throughput'). 4. **Execute and Refine**: Run the prompt in your Jahro monitoring tool (e.g., Jahro Dashboard, Prometheus + Grafana, or custom scripts). Review alerts and adjust thresholds based on false positives/negatives. Use the suggested mitigation commands directly in your Jahro CLI or Kubernetes environment. 5. **Automate for Proactive Monitoring**: Integrate this prompt into a scheduled job (e.g., via cron or Azure Logic Apps) to run every 30 minutes. Pipe outputs to a Slack channel or email for real-time alerts. For advanced setups, use Jahro's webhook system to trigger automated responses (e.g., scaling resources).
No install command available. Check the GitHub repository for manual installation instructions.
git clone https://github.com/Logiiiii/unity-agent-skills/tree/main/skills/jahro-watcherCopy the install command above and run it in your terminal.
Launch Claude Code, Cursor, or your preferred AI coding agent.
Use the prompt template or examples below to test the skill.
Adapt the skill to your specific use case and workflow.
Act as a Jahro-Watcher monitoring system. Track the [COMPONENT/SYSTEM] in [ENVIRONMENT/PLATFORM] for anomalies, performance degradation, or security threats. Alert me if any of the following thresholds are breached: [THRESHOLD_1], [THRESHOLD_2], or [THRESHOLD_3]. Provide a root cause analysis for any critical issues and suggest immediate mitigation steps. Include a summary of recent [METRICS/DATA] trends over the last [TIME_PERIOD].
### Jahro-Watcher Alert Report - Generated: 2023-11-15 14:32:17 UTC
**Component Monitored:** Jahro Database Cluster (Primary Node: jahro-db-01)
**Environment:** Production Kubernetes Cluster (Cluster ID: prod-k8s-01)
**Alert Severity:** CRITICAL
**Detected Anomalies:**
1. **CPU Utilization Spike:** 92% (Threshold: 80%) - Sustained for 15 minutes
- Root Cause: Unauthorized query execution by user 'analytics_bot' consuming 85% of CPU resources
- Mitigation Steps:
- Terminate the rogue query via `kubectl exec jahro-db-01 -- psql -U admin -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE usename = 'analytics_bot';"`
- Restrict user permissions: `ALTER USER analytics_bot WITH CONNECTION LIMIT 5;`
- Scale up resources temporarily: `kubectl scale deployment jahro-db --replicas=3`
2. **Disk I/O Latency:** Avg. 450ms (Threshold: 200ms) - Spikes observed during backup window
- Root Cause: Concurrent backup process conflicting with production workload
- Mitigation Steps:
- Reschedule backups to off-peak hours (2-4 AM UTC)
- Enable storage tiering for backups: `kubectl patch pvc jahro-db-backup -p '{"spec":{"storageClassName":"ssd-tier"}}'`
**Recent Trends (Last 24 Hours):**
- Database queries: 12,450 (Peak: 1,800 concurrent at 14:00 UTC)
- Memory usage: 78% (Stable, no leaks detected)
- Failed login attempts: 12 (All from IP 192.168.45.12 - Blocked via firewall)
**Recommendations:**
1. Implement query timeouts: `ALTER SYSTEM SET statement_timeout = '30s';`
2. Enable Jahro's built-in monitoring dashboard for real-time visibility
3. Schedule a team review of user permission policies
**Next Steps:** Execute mitigation commands immediately. Monitor for 30 minutes post-fix. Schedule follow-up meeting with DevOps team to discuss long-term solutions.skills-collection
Take a free 3-minute scan and get personalized AI skill recommendations.
Take free scan