feat(plugin): add plugin discovery, management, and run tracking
- internal/plugin/types.go: Plugin type definitions with TOML frontmatter schema - internal/plugin/scanner.go: Discover plugins from town and rig directories - internal/plugin/recording.go: Record plugin runs as ephemeral beads - internal/cmd/plugin.go: `gt plugin list` and `gt plugin show` commands Plugin locations: ~/gt/plugins/ (town-level), <rig>/plugins/ (rig-level). Rig-level plugins override town-level by name. Closes: gt-h8k4z, gt-rsejc, gt-n08ix.3 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
50
internal/plugin/recording_test.go
Normal file
50
internal/plugin/recording_test.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPluginRunRecord(t *testing.T) {
|
||||
record := PluginRunRecord{
|
||||
PluginName: "test-plugin",
|
||||
RigName: "gastown",
|
||||
Result: ResultSuccess,
|
||||
Body: "Test run completed successfully",
|
||||
}
|
||||
|
||||
if record.PluginName != "test-plugin" {
|
||||
t.Errorf("expected plugin name 'test-plugin', got %q", record.PluginName)
|
||||
}
|
||||
if record.RigName != "gastown" {
|
||||
t.Errorf("expected rig name 'gastown', got %q", record.RigName)
|
||||
}
|
||||
if record.Result != ResultSuccess {
|
||||
t.Errorf("expected result 'success', got %q", record.Result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunResultConstants(t *testing.T) {
|
||||
if ResultSuccess != "success" {
|
||||
t.Errorf("expected ResultSuccess to be 'success', got %q", ResultSuccess)
|
||||
}
|
||||
if ResultFailure != "failure" {
|
||||
t.Errorf("expected ResultFailure to be 'failure', got %q", ResultFailure)
|
||||
}
|
||||
if ResultSkipped != "skipped" {
|
||||
t.Errorf("expected ResultSkipped to be 'skipped', got %q", ResultSkipped)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewRecorder(t *testing.T) {
|
||||
recorder := NewRecorder("/tmp/test-town")
|
||||
if recorder == nil {
|
||||
t.Fatal("NewRecorder returned nil")
|
||||
}
|
||||
if recorder.townRoot != "/tmp/test-town" {
|
||||
t.Errorf("expected townRoot '/tmp/test-town', got %q", recorder.townRoot)
|
||||
}
|
||||
}
|
||||
|
||||
// Integration tests for RecordRun, GetLastRun, GetRunsSince require
|
||||
// a working beads installation and are skipped in unit tests.
|
||||
// These functions shell out to `bd` commands.
|
||||
Reference in New Issue
Block a user