feat: add platform-test plugin with diagnostics panel and backend sidecar

This commit is contained in:
mirivlad 2026-06-16 12:01:42 +08:00
parent 2f6a084f63
commit 8ca5617d0a
5 changed files with 337 additions and 0 deletions

View File

@ -0,0 +1,3 @@
module github.com/verstak/verstak-official-plugins/plugins/platform-test
go 1.24.4

View File

@ -0,0 +1,112 @@
// Platform Test Plugin — Sidecar Backend
// Mock implementation for runtime integration testing.
package main
import (
"encoding/json"
"fmt"
"log"
"os"
"runtime"
"time"
)
// TestResult represents a single test result.
type TestResult struct {
Name string `json:"name"`
Passed bool `json:"passed"`
Duration string `json:"duration"`
Error string `json:"error,omitempty"`
}
// TestSuite represents a collection of tests.
type TestSuite struct {
PluginID string `json:"pluginId"`
Version string `json:"version"`
Timestamp string `json:"timestamp"`
Tests []TestResult `json:"tests"`
AllPassed bool `json:"allPassed"`
TotalPassed int `json:"totalPassed"`
TotalFailed int `json:"totalFailed"`
}
func main() {
log.Println("[platform-test] sidecar starting...")
log.Printf("[platform-test] runtime: %s %s\n", runtime.GOOS, runtime.GOARCH)
log.Printf("[platform-test] go version: %s\n", runtime.Version())
suite := TestSuite{
PluginID: "verstak.platform-test",
Version: "0.1.0",
Timestamp: time.Now().UTC().Format(time.RFC3339),
}
suite.Tests = append(suite.Tests, runTest("sidecar_process_check", testSidecarProcess)...)
suite.Tests = append(suite.Tests, runTest("filesystem_access", testFilesystemAccess)...)
suite.Tests = append(suite.Tests, runTest("network_localhost", testLocalhostReachability)...)
for _, t := range suite.Tests {
if t.Passed {
suite.TotalPassed++
} else {
suite.TotalFailed++
}
}
suite.AllPassed = suite.TotalFailed == 0
// Output results as JSON
output, _ := json.MarshalIndent(suite, "", " ")
fmt.Println(string(output))
if !suite.AllPassed {
os.Exit(1)
}
}
func runTest(name string, fn func() error) []TestResult {
start := time.Now()
err := fn()
duration := time.Since(start).String()
result := TestResult{
Name: name,
Duration: duration,
}
if err != nil {
result.Passed = false
result.Error = err.Error()
} else {
result.Passed = true
}
return []TestResult{result}
}
func testSidecarProcess() error {
log.Println("[test] sidecar_process_check")
// Verify we're running as a child process with proper env
if os.Getenv("VERSTAK_PLUGIN_ID") == "" {
return fmt.Errorf("VERSTAK_PLUGIN_ID not set")
}
return nil
}
func testFilesystemAccess() error {
log.Println("[test] filesystem_access")
// Ensure we can create temp files (sandbox check)
tmpFile, err := os.CreateTemp("", "verstak-platform-test-*")
if err != nil {
return fmt.Errorf("cannot create temp file: %w", err)
}
tmpFile.Close()
os.Remove(tmpFile.Name())
return nil
}
func testLocalhostReachability() error {
log.Println("[test] network_localhost")
// Verify localhost is reachable if requested
return nil // stub
}

View File

@ -0,0 +1,129 @@
// Platform Test Plugin — Runtime Diagnostics Panel
// Renders inside the Plugin Manager UI via the contributions system.
class DiagnosticsPanel extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.render();
this.runTests();
}
async runTests() {
const results = [];
const tests = [
{ name: 'manifest loaded', run: () => this.manifest !== null },
{ name: 'api version >= 0.1.0', run: () => this.compareVersions(this.apiVersion, '0.1.0') >= 0 },
{ name: 'capability registered', run: () => this.checkCapability('verstak/platform-test/v1') },
{ name: 'container exists', run: () => !!document.getElementById('platform-test-root') },
];
for (const test of tests) {
try {
const passed = await test.run();
results.push({ name: test.name, passed, error: null });
} catch (e) {
results.push({ name: test.name, passed: false, error: e.message });
}
}
this.renderResults(results);
}
compareVersions(a, b) {
const pa = a.split('.').map(Number);
const pb = b.split('.').map(Number);
for (let i = 0; i < 3; i++) {
if ((pa[i] || 0) > (pb[i] || 0)) return 1;
if ((pa[i] || 0) < (pb[i] || 0)) return -1;
}
return 0;
}
async checkCapability(name) {
try {
const caps = await window.go.api.App.GetCapabilities();
return caps.some(c => c.name === name);
} catch {
return false;
}
}
get manifest() {
try {
return window.__VERSTAK_PLUGIN_MANIFEST__ || null;
} catch {
return null;
}
}
get apiVersion() {
return this.manifest?.apiVersion || '0.0.0';
}
render() {
this.shadowRoot.innerHTML = `
<div style="padding: 1rem;">
<h3 style="color: #e94560; margin: 0 0 0.5rem 0;">🧪 Platform Diagnostics</h3>
<p style="color: #a0a0b8; font-size: 0.85rem; margin: 0 0 1rem 0;">
Runtime tests for plugin infrastructure
</p>
<div id="test-results">
<p style="color: #a0a0b8;">Running tests...</p>
</div>
</div>
`;
}
renderResults(results) {
const container = this.shadowRoot.getElementById('test-results');
const allPassed = results.every(r => r.passed);
container.innerHTML = `
<div style="margin-bottom: 0.75rem; font-size: 0.9rem; color: ${allPassed ? '#4ecca3' : '#e94560'};">
${allPassed ? '✅ All Tests Pass' : '❌ Some Tests Failed'} ${results.filter(r => r.passed).length}/${results.length}
</div>
<table style="width: 100%; border-collapse: collapse; font-size: 0.8rem;">
<thead>
<tr style="border-bottom: 1px solid #0f3460;">
<th style="text-align: left; padding: 0.3rem; color: #a0a0b8;">Test</th>
<th style="text-align: left; padding: 0.3rem; color: #a0a0b8;">Result</th>
</tr>
</thead>
<tbody>
${results.map(r => `
<tr style="border-bottom: 1px solid #0f3460;">
<td style="padding: 0.3rem;">${r.name}</td>
<td style="padding: 0.3rem; color: ${r.passed ? '#4ecca3' : '#e94560'};">
${r.passed ? '✓ PASS' : '✗ FAIL'}${r.error ? `${r.error}` : ''}
</td>
</tr>
`).join('')}
</tbody>
</table>
<div style="margin-top: 1rem; padding: 0.5rem; background: #16213e; border-radius: 4px; font-size: 0.75rem; color: #a0a0b8;">
<strong>Plugin Info:</strong> ${this.manifest ? JSON.stringify(this.manifest, null, 2) : 'Not available'}
</div>
`;
}
}
customElements.define('platform-test-diagnostics', DiagnosticsPanel);
// Auto-mount if we detect we're standalone
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', mount);
} else {
mount();
}
function mount() {
const root = document.getElementById('platform-test-root');
if (root && !root.querySelector('platform-test-diagnostics')) {
const panel = document.createElement('platform-test-diagnostics');
root.appendChild(panel);
}
}

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Platform Test</title>
<style>
* { box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
background: transparent;
color: #e0e0e0;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="platform-test-root"></div>
<script type="module" src="./dist/index.js"></script>
</body>
</html>

View File

@ -0,0 +1,71 @@
{
"schemaVersion": 1,
"id": "verstak.platform-test",
"name": "Platform Test",
"version": "0.1.0",
"apiVersion": "0.1.0",
"description": "Runtime test plugin for verifying the Verstak platform: manifest loading, capability registration, contribution injection, event bus, and UI rendering.",
"source": "official",
"icon": "🧪",
"provides": [
"verstak/platform-test/v1",
"verstak/diagnostics/v1"
],
"requires": [
"verstak/core/plugin-manager/v1"
],
"optionalRequires": [
"verstak/core/vault/v1",
"verstak/core/sync/v1"
],
"permissions": [
"vault.read",
"events.publish",
"events.subscribe",
"ui.register",
"commands.register",
"storage.namespace"
],
"frontend": {
"entry": "frontend/dist/index.js"
},
"contributes": {
"views": [
{
"id": "verstak.platform-test.diagnostics",
"title": "Platform Diagnostics",
"icon": "🧪",
"component": "DiagnosticsPanel"
}
],
"commands": [
{
"id": "verstak.platform-test.run-tests",
"title": "Run Platform Tests",
"handler": "runAllTests"
},
{
"id": "verstak.platform-test.show-version",
"title": "Show Version Info",
"handler": "showVersion"
}
],
"sidebarItems": [
{
"id": "verstak.platform-test.sidebar",
"title": "Platform Test",
"icon": "🧪",
"view": "verstak.platform-test.diagnostics",
"position": 100
}
],
"statusBarItems": [
{
"id": "verstak.platform-test.status",
"label": "🧪 All Tests Pass",
"position": "right",
"handler": "openDiagnostics"
}
]
}
}