ワンクリックで
go-project-main
CLI patterns with Cobra/Viper, profile configuration, and graceful shutdown with signal handling
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
CLI patterns with Cobra/Viper, profile configuration, and graceful shutdown with signal handling
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
This skill should be used when the user asks to generate or process images. Activates with phrases like generate image, create icon, make logo, design illustration, cut image, remove background. Provides image generation and processing capabilities via ComfyUI through n8n workflow service.
This skill should be used when the user asks to convert text to speech, generate audio, create TTS voice, or do voice synthesis. Activates with phrases like 语音合成, TTS, 文字转语音, 生成语音, 配音, 朗读. Provides text formatting, text splitting, TTS generation, and audio merging workflow.
Transform text content into professional Mermaid diagrams for presentations and documentation. Use when users ask to visualize concepts, create flowcharts, or make diagrams from text. Supports process flows, system architectures, comparisons, mindmaps, and more with built-in syntax error prevention.
This skill should be used when the user asks to understand new concepts or technologies. Activates with phrases like explain, teach, learn, concept, technology, how to, what is, understanding, tutorial, guide. Provides structured 5-step explanations following Problem-Based Learning principles: Scenario, Limitation, Concept, Core Mechanics, Implementation. Uses storytelling approach to create complete "problem-exploration-answer" cognitive loop with practical examples and code samples.
Automatically save chat conversations to individual markdown files with unique filenames containing timestamps. Each conversation is saved to /Users/pix/dev/code/ai/pixai/chat-history directory. Use when user wants to preserve chat history, save conversation logs, or maintain a record of discussions.
Automatically save chat conversations to individual markdown files with unique filenames containing timestamps. Each conversation is saved to /Users/pix/dev/code/ai/pixai/chat-history directory. Use when user wants to preserve chat history, save conversation logs, or maintain a record of discussions.
| name | go-project-main |
| description | CLI patterns with Cobra/Viper, profile configuration, and graceful shutdown with signal handling |
DO NOT put server code in main.go!
cmd/server/main.go should ONLY contain:
server.NewServer() and server.Start()All server logic belongs in server/server.go (see go-project-server).
cmd/server/
└── main.go # ONLY CLI entry point, 50-100 lines max
server/
├── server.go # Echo + cmux + service registration (200+ lines)
├── auth/ # Authentication logic
└── router/api/v1/ # Service implementations
WRONG (what you generated):
// cmd/server/main.go
func main() {
// ❌ Echo setup here
// ❌ Routes here
// ❌ Handlers here
// ❌ All business logic
}
CORRECT:
// cmd/server/main.go
func main() {
// ✓ Cobra CLI
// ✓ Profile validation
// ✓ Create server.NewServer()
// ✓ server.Start()
// ✓ Signal handling
}
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/myapp/internal/profile"
"github.com/myapp/server"
"github.com/myapp/store/db"
)
var rootCmd = &cobra.Command{
Use: "server",
Short: "Start API server",
RunE: func(cmd *cobra.Command, args []string) error {
prof := &profile.Profile{
Mode: viper.GetString("mode"),
Addr: viper.GetString("addr"),
Port: viper.GetInt("port"),
Data: viper.GetString("data"),
Driver: viper.GetString("driver"),
DSN: viper.GetString("dsn"),
}
return run(cmd.Context(), prof)
},
}
func init() {
rootCmd.Flags().String("mode", "dev", "dev|prod")
rootCmd.Flags().String("addr", "0.0.0.0", "bind address")
rootCmd.Flags().Int("port", 8081, "HTTP port")
rootCmd.Flags().String("data", "./data", "data directory")
rootCmd.Flags().String("driver", "sqlite", "database driver")
rootCmd.Flags().String("dsn", "", "database connection string")
viper.BindPFlags(rootCmd.Flags())
viper.SetEnvPrefix("myapp")
viper.AutomaticEnv()
}
func run(ctx context.Context, prof *profile.Profile) error {
if err := prof.Validate(); err != nil {
return err
}
dbDriver, err := db.NewDBDriver(prof)
if err != nil {
return err
}
storeInstance := store.New(dbDriver, prof)
if err := storeInstance.Migrate(ctx); err != nil {
return err
}
// ALL server logic in server/server.go
s, err := server.NewServer(ctx, prof, storeInstance)
if err != nil {
return err
}
if err := s.Start(ctx); err != nil {
return err
}
// Signal handling
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
<-c
return s.Shutdown(ctx)
}
func main() {
if err := rootCmd.Execute(); err != nil {
os.Exit(1)
}
}
func init() {
viper.SetDefault("mode", "dev")
viper.SetDefault("driver", "sqlite")
viper.SetDefault("port", 8081)
rootCmd.PersistentFlags().String("mode", "dev", "mode description")
rootCmd.PersistentFlags().String("addr", "", "address")
rootCmd.PersistentFlags().Int("port", 8081, "port")
rootCmd.PersistentFlags().String("data", "", "data directory")
rootCmd.PersistentFlags().String("driver", "sqlite", "database driver")
rootCmd.PersistentFlags().String("dsn", "", "database source name")
rootCmd.PersistentFlags().String("instance-url", "", "instance URL")
viper.BindPFlag("mode", rootCmd.PersistentFlags().Lookup("mode"))
viper.BindPFlag("addr", rootCmd.PersistentFlags().Lookup("addr"))
// ... bind other flags
viper.SetEnvPrefix("app")
viper.AutomaticEnv()
}
type Profile struct {
Mode string
Addr string
Port int
UNIXSock string
Data string
DSN string
Driver string
Version string
InstanceURL string
}
func (p *Profile) Validate() error {
if p.Mode != "demo" && p.Mode != "dev" && p.Mode != "prod" {
p.Mode = "demo"
}
if p.Mode == "prod" && p.Data == "" {
p.Data = "/var/opt/appname"
}
if _, err := os.Stat(p.Data); err != nil {
return err
}
if p.Driver == "sqlite" && p.DSN == "" {
p.DSN = filepath.Join(p.Data, fmt.Sprintf("appname_%s.db", p.Mode))
}
return nil
}