From b08594754762fdca810cad5d7ea943f1df844ccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Thu, 3 Sep 2026 01:17:26 -0400 Subject: [PATCH] chore(go): audit shared plugin helpers Drop unused expandHome and standardizeJSONC, share the runtime base URL validator between the guard and audit templates, and trim comments. Claude-Session: https://claude.ai/code/session_01Agoc9bRVE9KL7mmWtey9Vq --- .../plugins/droid_test_helpers_test.go | 9 ++++ cmd/elydora/plugins/guardtemplate.go | 24 +-------- cmd/elydora/plugins/hooktemplate.go | 49 ++----------------- cmd/elydora/plugins/jsonc.go | 9 ---- cmd/elydora/plugins/jsonutil.go | 19 ++----- cmd/elydora/plugins/legacy_hook_entries.go | 3 +- cmd/elydora/plugins/registry.go | 3 +- cmd/elydora/plugins/runtime_files.go | 6 +-- .../plugins/runtime_reader_template.go | 22 +++++++++ 9 files changed, 42 insertions(+), 102 deletions(-) diff --git a/cmd/elydora/plugins/droid_test_helpers_test.go b/cmd/elydora/plugins/droid_test_helpers_test.go index b6c55d4..6c41418 100644 --- a/cmd/elydora/plugins/droid_test_helpers_test.go +++ b/cmd/elydora/plugins/droid_test_helpers_test.go @@ -344,3 +344,12 @@ func requireNoDroidStagingFiles(t *testing.T, root string) { t.Fatalf("walk staging files: %v", err) } } + +func standardizeJSONC(source []byte, label string, allowTrailingCommas bool) ([]byte, error) { + value, err := parseJSONC(source, label, allowTrailingCommas) + if err != nil { + return nil, err + } + value.Standardize() + return value.Pack(), nil +} diff --git a/cmd/elydora/plugins/guardtemplate.go b/cmd/elydora/plugins/guardtemplate.go index 9bc9349..8ad6e92 100644 --- a/cmd/elydora/plugins/guardtemplate.go +++ b/cmd/elydora/plugins/guardtemplate.go @@ -146,30 +146,8 @@ function writeStatusCache(status) { }); } -function resolveBaseURL(config) { - const value = config.base_url || 'https://api.elydora.com'; - if (typeof value !== 'string' || /[\\\u0000-\u0020]/.test(value)) { - throw new Error('Agent config base_url must be an absolute HTTP or HTTPS URL'); - } - let parsed; - try { - parsed = new URL(value); - } catch (error) { - throw new Error('Agent config base_url must be an absolute HTTP or HTTPS URL'); - } - if (!['http:', 'https:'].includes(parsed.protocol) || !parsed.hostname) { - throw new Error('Agent config base_url must be an absolute HTTP or HTTPS URL'); - } - if (parsed.username || parsed.password || parsed.search || parsed.hash) { - throw new Error( - 'Agent config base_url must exclude credentials, query parameters, and fragments', - ); - } - return value.replace(/\/+$/, ''); -} - async function resolveRemoteStatus(config) { - const baseURL = resolveBaseURL(config); + const baseURL = resolveConfigBaseURL(config); const token = config.token || ''; if (typeof token !== 'string') throw new Error('Agent config token must be a string'); const controller = new AbortController(); diff --git a/cmd/elydora/plugins/hooktemplate.go b/cmd/elydora/plugins/hooktemplate.go index ff82f21..33b34c9 100644 --- a/cmd/elydora/plugins/hooktemplate.go +++ b/cmd/elydora/plugins/hooktemplate.go @@ -13,10 +13,7 @@ func buildHookScriptWithOutput( return fmt.Sprintf(`#!/usr/bin/env node 'use strict'; -// --------------------------------------------------------------------------- -// Self-contained Elydora audit hook for: %s -// Generated by @elydora/sdk — DO NOT EDIT -// --------------------------------------------------------------------------- +// Elydora audit hook for %s. Generated by Elydora SDK. const crypto = require('node:crypto'); const fs = require('node:fs'); @@ -53,10 +50,6 @@ function parsePrivateKey(raw) { return value; } -// --------------------------------------------------------------------------- -// Embedded crypto (from @elydora/sdk src/crypto.ts + src/utils.ts) -// --------------------------------------------------------------------------- - function base64urlEncode(data) { const buf = Buffer.isBuffer(data) ? data : Buffer.from(data); return buf.toString('base64url'); @@ -158,10 +151,6 @@ function generateNonce() { return base64urlEncode(crypto.randomBytes(16)); } -// --------------------------------------------------------------------------- -// Chain state persistence (atomic writes) -// --------------------------------------------------------------------------- - function readChainState() { let raw; try { @@ -265,10 +254,6 @@ function advanceChainState(fromHash, toHash) { }); } -// --------------------------------------------------------------------------- -// Error logging -// --------------------------------------------------------------------------- - function logError(err) { try { const ts = new Date().toISOString(); @@ -281,32 +266,6 @@ function logError(err) { } } -function resolveAuditBaseURL(config) { - const value = config.base_url || 'https://api.elydora.com'; - if (typeof value !== 'string' || /[\\\u0000-\u0020]/.test(value)) { - throw new Error('Agent config base_url must be an absolute HTTP or HTTPS URL'); - } - let parsed; - try { - parsed = new URL(value); - } catch (error) { - throw new Error('Agent config base_url must be an absolute HTTP or HTTPS URL'); - } - if (!['http:', 'https:'].includes(parsed.protocol) || !parsed.hostname) { - throw new Error('Agent config base_url must be an absolute HTTP or HTTPS URL'); - } - if (parsed.username || parsed.password || parsed.search || parsed.hash) { - throw new Error( - 'Agent config base_url must exclude credentials, query parameters, and fragments', - ); - } - return value.replace(/\/+$/, ''); -} - -// --------------------------------------------------------------------------- -// Main hook logic -// --------------------------------------------------------------------------- - async function postOperation(baseUrl, token, eor, deadline) { const remaining = deadline - performance.now(); if (remaining <= 0) throw new Error('Audit API retry budget exhausted'); @@ -344,7 +303,6 @@ async function postOperation(baseUrl, token, eor, deadline) { async function main() { try { - // Read JSON from stdin const chunks = []; for await (const chunk of process.stdin) { chunks.push(chunk); @@ -380,7 +338,6 @@ async function main() { hookData.conversation_id || hookData.session_id || hookData.sessionId || hookData.session || hookData.taskId || 'unknown'; - // Read agent config and private key let config; let privateKey; try { @@ -408,7 +365,7 @@ async function main() { const orgId = config.org_id; const agentId = config.agent_id; const kid = config.kid; - const baseUrl = resolveAuditBaseURL(config); + const baseUrl = resolveConfigBaseURL(config); const token = config.token || ''; if (typeof orgId !== 'string' || !orgId || typeof agentId !== 'string' || !agentId || typeof kid !== 'string' || !kid) { @@ -416,7 +373,7 @@ async function main() { } if (typeof token !== 'string') throw new Error('Agent config token must be a string'); - // Build and submit, retrying from the server chain head on PREV_HASH_MISMATCH + // Retry from the server chain head on PREV_HASH_MISMATCH. const payload = NATIVE_PAYLOAD ? hookData : { tool_name: toolName, tool_input: toolInput, diff --git a/cmd/elydora/plugins/jsonc.go b/cmd/elydora/plugins/jsonc.go index 2931616..199b7fc 100644 --- a/cmd/elydora/plugins/jsonc.go +++ b/cmd/elydora/plugins/jsonc.go @@ -17,15 +17,6 @@ type jsoncEditor struct { label string } -func standardizeJSONC(source []byte, label string, allowTrailingCommas bool) ([]byte, error) { - value, err := parseJSONC(source, label, allowTrailingCommas) - if err != nil { - return nil, err - } - value.Standardize() - return value.Pack(), nil -} - func parseJSONC(source []byte, label string, allowTrailingCommas bool) (hujson.Value, error) { value, err := hujson.Parse(source) if err != nil { diff --git a/cmd/elydora/plugins/jsonutil.go b/cmd/elydora/plugins/jsonutil.go index 729b391..1cbfccd 100644 --- a/cmd/elydora/plugins/jsonutil.go +++ b/cmd/elydora/plugins/jsonutil.go @@ -5,22 +5,9 @@ import ( "fmt" "os" "path/filepath" - "strings" ) -// expandHome replaces a leading ~ with the user's home directory. -func expandHome(p string) (string, error) { - if !strings.HasPrefix(p, "~") { - return p, nil - } - home, err := os.UserHomeDir() - if err != nil { - return "", fmt.Errorf("resolve home directory: %w", err) - } - return filepath.Join(home, p[1:]), nil -} - -// readJSONFile reads a JSON file into a map. Returns an empty map if the file does not exist. +// readJSONFile reads a JSON object; a missing file yields an empty map. func readJSONFile(path string) (map[string]interface{}, error) { data, err := os.ReadFile(path) if err != nil { @@ -53,7 +40,7 @@ func writeJSONFile(path string, data map[string]interface{}) error { return nil } -// hookScriptPath returns the default path for the hook script inside ~/.elydora//. +// hookScriptPath returns ~/.elydora//hook.js. func hookScriptPath(agentId string) (string, error) { agentDirectory, err := ResolveAgentRuntimeDirectory(agentId) if err != nil { @@ -62,7 +49,7 @@ func hookScriptPath(agentId string) (string, error) { return filepath.Join(agentDirectory, "hook.js"), nil } -// guardScriptPath returns the default path for the guard script inside ~/.elydora//. +// guardScriptPath returns ~/.elydora//guard.js. func guardScriptPath(agentId string) (string, error) { agentDirectory, err := ResolveAgentRuntimeDirectory(agentId) if err != nil { diff --git a/cmd/elydora/plugins/legacy_hook_entries.go b/cmd/elydora/plugins/legacy_hook_entries.go index 1fdd28d..1e68030 100644 --- a/cmd/elydora/plugins/legacy_hook_entries.go +++ b/cmd/elydora/plugins/legacy_hook_entries.go @@ -2,8 +2,7 @@ package plugins import "strings" -// extractElydoraScriptPath supports adapters that still use the legacy shared -// command-hook shape. Provider-specific adapters should define exact ownership. +// extractElydoraScriptPath reads the legacy shared command-hook shape. func extractElydoraScriptPath(hookArray any) string { entries, _ := hookArray.([]any) for _, entry := range entries { diff --git a/cmd/elydora/plugins/registry.go b/cmd/elydora/plugins/registry.go index ce6b1f5..947232f 100644 --- a/cmd/elydora/plugins/registry.go +++ b/cmd/elydora/plugins/registry.go @@ -26,8 +26,7 @@ var SupportedAgents = map[string]AgentRegistryEntry{ "qwen": {Name: "Qwen Code", ConfigDir: "~/.qwen", ConfigFile: "settings.json"}, } -// NewPlugin creates a plugin instance for the given agent name. -// Returns nil if the agent is not supported. +// NewPlugin returns the plugin for an agent name, or nil when unsupported. func NewPlugin(agentName string) AgentPlugin { switch agentName { case "augment": diff --git a/cmd/elydora/plugins/runtime_files.go b/cmd/elydora/plugins/runtime_files.go index cba6e08..3a1b59d 100644 --- a/cmd/elydora/plugins/runtime_files.go +++ b/cmd/elydora/plugins/runtime_files.go @@ -22,8 +22,7 @@ type agentRuntimeConfig struct { AgentName string `json:"agent_name"` } -// WriteRuntimeFileAtomic replaces one managed runtime file through a flushed, -// same-directory temporary file. +// WriteRuntimeFileAtomic replaces one managed runtime file atomically. func WriteRuntimeFileAtomic( path string, label string, @@ -40,8 +39,7 @@ func WriteRuntimeFileAtomic( return writeChanges([]*fileChange{change}, "write "+label, nil) } -// GenerateHookScript atomically commits the agent config, private key, and -// self-contained Node.js audit runtime. +// GenerateHookScript commits the config, private key, and audit runtime together. func GenerateHookScript(destPath string, config InstallConfig) error { return generateHookScriptWithRename(destPath, config, nil) } diff --git a/cmd/elydora/plugins/runtime_reader_template.go b/cmd/elydora/plugins/runtime_reader_template.go index 3fdf5e0..4241856 100644 --- a/cmd/elydora/plugins/runtime_reader_template.go +++ b/cmd/elydora/plugins/runtime_reader_template.go @@ -142,4 +142,26 @@ function writeProtectedJson(filePath, label, value) { } } } + +function resolveConfigBaseURL(config) { + const value = config.base_url || 'https://api.elydora.com'; + if (typeof value !== 'string' || /[\\\u0000-\u0020]/.test(value)) { + throw new Error('Agent config base_url must be an absolute HTTP or HTTPS URL'); + } + let parsed; + try { + parsed = new URL(value); + } catch (error) { + throw new Error('Agent config base_url must be an absolute HTTP or HTTPS URL'); + } + if (!['http:', 'https:'].includes(parsed.protocol) || !parsed.hostname) { + throw new Error('Agent config base_url must be an absolute HTTP or HTTPS URL'); + } + if (parsed.username || parsed.password || parsed.search || parsed.hash) { + throw new Error( + 'Agent config base_url must exclude credentials, query parameters, and fragments', + ); + } + return value.replace(/\/+$/, ''); +} `