feat: generate brain tools skill from OpenAPI; rename db-yaml to postgres (#21)
Tests / Test (push) Skipped
Tests / Release (semver) (push) Skipped

Cursor skills stay in lockstep with serve handlers. CI checks every bin/
path named in SKILL.md exists.
This commit is contained in:
2026-08-13 21:32:57 +01:00
committed by GitHub
co-authored by GitHub
parent ff80359684
commit d894c6609f
10 changed files with 127 additions and 43 deletions
+18
View File
@@ -1,5 +1,7 @@
package httpapi
import "strings"
// Shared HTTP surface: OpenAPI paths and MCP tools are generated from Ops.
// ServeHTTP must keep the same path strings.
@@ -124,3 +126,19 @@ func MCPTools() []MCPTool {
}
return out
}
// SkillMarkdown is the Cursor skill fragment generated from Ops/MCPTools.
func SkillMarkdown() string {
var b strings.Builder
b.WriteString("# brain HTTP / MCP tools\n\n")
b.WriteString("Generated from `internal/httpapi.Ops`. Do not edit by hand.\n\n")
b.WriteString("Serve: `bin/brain/serve.go` (`GET /openapi.json`, `POST /mcp`).\n\n")
for _, t := range MCPTools() {
b.WriteString("- `")
b.WriteString(t.Name)
b.WriteString("` — ")
b.WriteString(t.Description)
b.WriteString("\n")
}
return b.String()
}
+13
View File
@@ -4,6 +4,8 @@ import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
)
@@ -76,6 +78,17 @@ func TestMCPToolsListAndCall(t *testing.T) {
}
}
func TestSkillMarkdownMatchesCommittedFile(t *testing.T) {
want, err := os.ReadFile(filepath.Join("..", "..", "skills", "brain", "tools.md"))
if err != nil {
t.Fatal(err)
}
got := SkillMarkdown()
if got != string(want) {
t.Fatalf("skills/brain/tools.md stale; regenerate from SkillMarkdown()\n--- got ---\n%s\n--- want ---\n%s", got, want)
}
}
func postJSON(t *testing.T, h http.Handler, path, raw string) (int, []byte) {
t.Helper()
req := httptest.NewRequest(http.MethodPost, path, strings.NewReader(raw))