manifest.md - maoxiaoyue/hypgo GitHub Wiki

pkg/manifest — Project Manifest 自動生成

掃描 HypGo 應用程式的路由、中間件、伺服器設定,產出機器可讀的 YAML/JSON 描述,讓 AI 以最少 token 掌握專案全貌。

設計理念

AI 協作開發中最大的瓶頸是「理解專案」。傳統做法是讓 AI 逐一閱讀原始碼,消耗大量 token。Manifest 讓框架自動產出結構化的專案描述:

❌ AI 讀 20 個檔案才理解 API 結構(數千 token)
✅ AI 讀 1 個 manifest 就掌握全貌(數百 token)

快速上手

從程式碼中生成

import (
    "os"
    "github.com/maoxiaoyue/hypgo/pkg/manifest"
    "github.com/maoxiaoyue/hypgo/pkg/router"
    "github.com/maoxiaoyue/hypgo/pkg/config"
)

// 1. 建立 Collector(從 Router + Config 收集)
c := manifest.NewCollector(myRouter, myConfig)

// 2. 生成 Manifest
m := c.Collect()

// 3. 輸出 YAML 到 stdout
manifest.WriteYAML(os.Stdout, m)

// 4. 或儲存到檔案
manifest.SaveToFile(".hyp/manifest.yaml", m, "yaml")
manifest.SaveToFile(".hyp/manifest.json", m, "json")

從 Server 直接生成

srv := server.New(cfg, logger)

// 註冊路由後...
m := srv.Manifest()
manifest.WriteYAML(os.Stdout, m)

透過 CLI

# 輸出 YAML 到 stdout
hyp context

# 輸出 JSON 格式
hyp context -f json

# 儲存到檔案
hyp context -o .hyp/manifest.yaml
hyp context -o .hyp/manifest.json -f json

輸出範例

YAML

version: "1.0"
framework: HypGo
generated_at: 2026-03-26T20:00:00+08:00
server:
  addr: ":8080"
  protocol: http2
  tls: true
routes:
  - method: POST
    path: /api/users
    handler_names:
      - controllers.CreateUser
    summary: "建立使用者"
    tags:
      - users
    input_type: CreateUserRequest
    output_type: UserResponse
    responses:
      201: "User created"
      400: "Invalid input"
  - method: GET
    path: /api/users/:id
    handler_names:
      - controllers.GetUser
    summary: "依 ID 取得使用者"
    tags:
      - users
    output_type: UserResponse
  - method: GET
    path: /health
    handler_names:
      - main.healthHandler
database:
  driver: postgres
  has_replicas: true

JSON

{
  "version": "1.0",
  "framework": "HypGo",
  "server": {
    "addr": ":8080",
    "protocol": "http2",
    "tls": true
  },
  "routes": [
    {
      "method": "POST",
      "path": "/api/users",
      "handler_names": ["controllers.CreateUser"],
      "summary": "建立使用者",
      "tags": ["users"],
      "input_type": "CreateUserRequest",
      "output_type": "UserResponse",
      "responses": { "201": "User created" }
    }
  ]
}

核心型別

Manifest

type Manifest struct {
    Version     string          // 固定 "1.0"
    Framework   string          // 固定 "HypGo"
    GeneratedAt time.Time       // 生成時間
    Server      ServerInfo      // 伺服器配置
    Routes      []RouteManifest // 所有路由
    Middleware  []string        // 全域中間件
    Database    *DatabaseInfo   // 資料庫配置(可選)
}

RouteManifest

type RouteManifest struct {
    Method       string         // HTTP 方法
    Path         string         // 路由路徑
    HandlerNames []string       // handler 函式名(透過 runtime 反射)
    Summary      string         // 路由描述(來自 schema)
    Description  string         // 詳細描述(來自 schema)
    Tags         []string       // 分類標籤(來自 schema)
    InputType    string         // 請求型別名稱(來自 schema)
    OutputType   string         // 回應型別名稱(來自 schema)
    Responses    map[int]string // 狀態碼 → 描述(來自 schema)
}

資料來源

Collector 從三個來源收集資訊:

來源 提供資訊
Router.Routes() Method、Path、HandlerNames
schema.Global() Summary、Tags、InputType、OutputType、Responses
config.Config Server(addr、protocol、TLS)、Database(driver、replicas)

未使用 Schema() 註冊的路由仍會出現在 manifest 中,但不含 schema metadata。

Collector 流程

Router.Routes()
    │
    ├──→ 每個 RouteInfo
    │       │
    │       └──→ schema.Global().Get(method, path)
    │               │
    │               └──→ 合併為 RouteManifest
    │
    ├──→ sort by Path + Method
    │
config.Config ──→ ServerInfo + DatabaseInfo
    │
    └──→ 組裝 Manifest

Writer API

// 寫入 io.Writer
manifest.WriteYAML(w, m)   // YAML 格式,2 空格縮排
manifest.WriteJSON(w, m)   // JSON 格式,2 空格縮排

// 儲存到檔案(自動建立目錄)
manifest.SaveToFile(path, m, "yaml")
manifest.SaveToFile(path, m, "json")

架構

pkg/manifest/
├── manifest.go      Manifest、ServerInfo、RouteManifest、DatabaseInfo 型別
├── collector.go     Collector:從 Router + Config + Schema Registry 收集
├── writer.go        WriteYAML、WriteJSON、SaveToFile 輸出
└── manifest_test.go 8 個單元測試

依賴關係

pkg/manifest → pkg/router(Routes() 取得路由清單)
             → pkg/config(取得伺服器/資料庫設定)
             → pkg/schema(取得 schema metadata)
             → gopkg.in/yaml.v3(YAML 輸出)

AutoSync 自動同步

Server.Start() 啟動時自動呼叫 pkg/autosync,將 Manifest 寫入 .hyp/context.yaml,確保 AI 永遠有最新的專案結構:

// Server.Start() 內部自動執行:
sync := autosync.New(autosync.Config{Enabled: true}, router, config, logger)
sync.SyncSafe()  // 失敗不 panic,僅 log warning

特點:

  • 原子寫入:temp file + os.Rename() 防止中途損壞
  • 安全:不包含密碼、token、DSN 等敏感資訊
  • 零配置:Server 啟動即同步,無需手動操作

測試

go test ./pkg/manifest/... -v

涵蓋:Collector.Collect()、路由收集、schema 整合、Database 收集、nil config 處理、YAML/JSON 輸出、Group schema 整合。