Added comprehensive session-based file logging to all 8 OpenCode plugins in .opencode/plugin/. Each plugin now logs every hook invocation, whether it triggered an action or was skipped.
.opencode/lib/logger.ts- Shared logging utility- All 8 plugins - Added
logTriggered()andlogSkipped()calls to every hook
Logs are written to .opencode/logs/<session-id>.log as JSON lines:
{"timestamp":"2026-01-12T02:18:59.890Z","plugin":"conventional-commit-reminder","hook":"tool.execute.after","sessionId":"abc-123","triggered":true,"message":"Tracked: code file modified: src/main.rs","details":{"tool":"edit","totalModifiedFiles":3}}
{"timestamp":"2026-01-12T02:19:01.123Z","plugin":"verification-gate","hook":"tool.execute.before","sessionId":"abc-123","triggered":false,"message":"Not a commit command","details":{"command":"cargo check"}}| Field | Description |
|---|---|
timestamp |
ISO 8601 timestamp |
plugin |
Plugin name (e.g., "conventional-commit-reminder") |
hook |
Hook name (e.g., "tool.execute.after", "stop", "event") |
sessionId |
OpenCode session ID for correlation |
triggered |
true if action was taken, false if skipped |
message |
Human-readable description |
details |
Optional object with additional context |
OpenCode loads ALL .ts files in the plugin/ directory as plugins.
This means:
- Every
.tsfile must export a valid Plugin as its default export - Utility modules (like our logger) must live in a different directory
- We moved
logger.tsto.opencode/lib/to fix this
TypeError: null is not an object (evaluating 'hook.config')
This cryptic error occurred because OpenCode tried to load logger.ts as a plugin, but it exported utility functions instead of a Plugin function.
.opencode/
├── lib/
│ └── logger.ts # Utility module (NOT a plugin)
├── logs/
│ └── <session-id>.log # Log files (gitignored)
└── plugin/
├── cargo-fmt-check.ts # Plugin
├── conventional-commit-reminder.ts
├── guideline-enforcer.ts
├── project-reminders.ts
├── screenshot-enforcer.ts
├── thoroughness-enforcer.ts
├── verification-gate.ts
└── visual-testing-reminder.ts
- Post-session debugging - Review what plugins did without watching console
- Verify enforcement - Confirm plugins are triggering when expected
- Understand behavior - See why a plugin did or didn't take action
- Session correlation - All logs for a session in one file
After an OpenCode session completes, check:
# List all session logs
ls -la .opencode/logs/
# View a specific session
cat .opencode/logs/<session-id>.log | jq .
# Find all triggered actions
grep '"triggered":true' .opencode/logs/*.log | jq .
# Find all commit-related logs
grep 'commit' .opencode/logs/*.log