[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7CWXK2WT52PBCZSWRWM7F2P":3,"skill-same:01M7CWXK2WT52PBCZSWRWM7F2P":65},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":38,"commitSha":39,"skillDirectory":40,"forksCount":41,"repositoryHtmlUrl":42,"repositoryHomepageUrl":6,"ownerHtmlUrl":43,"ownerBlogUrl":6,"ownerDescription":44,"updatedAt":45,"install":46,"resources":58},"01M7CWXK2WT52PBCZSWRWM7F2P","golang-spf13-viper",null,"Golang configuration library using spf13\u002Fviper — layered precedence (flag > env > file > KV > default), BindPFlag\u002FBindPFlags, SetEnvPrefix + SetEnvKeyReplacer + AutomaticEnv, ReadInConfig + ConfigFileNotFoundError, Unmarshal + mapstructure struct tags, Sub for sub-trees, WatchConfig + OnConfigChange for hot reload, viper.New() for test isolation, and remote KV integration. Apply when using or adopting spf13\u002Fviper, or when the codebase imports `github.com\u002Fspf13\u002Fviper`. For CLI command structure alongside viper, see the `samber\u002Fcc-skills-golang@golang-spf13-cobra` skill. For general CLI architecture, see `samber\u002Fcc-skills-golang@golang-cli`.","om-scogo\u002Fskillsh-scraper","om-scogo","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F160466840?v=4","01M79AWB6DFVCQ7RK70CS34B96","Om Achrekar","01M79AWB6ZM9SKR8KDH1WSSM22",0,"MIT","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fsamber-cc-skills-golang\u002Fgolang-spf13-viper\u002FSkill.md",[],[],"2026-11-15 14:19:17",false,"---\nname: golang-spf13-viper\ndescription: \"Golang configuration library using spf13\u002Fviper — layered precedence (flag > env > file > KV > default), BindPFlag\u002FBindPFlags, SetEnvPrefix + SetEnvKeyReplacer + AutomaticEnv, ReadInConfig + ConfigFileNotFoundError, Unmarshal + mapstructure struct tags, Sub for sub-trees, WatchConfig + OnConfigChange for hot reload, viper.New() for test isolation, and remote KV integration. Apply when using or adopting spf13\u002Fviper, or when the codebase imports `github.com\u002Fspf13\u002Fviper`. For CLI command structure alongside viper, see the `samber\u002Fcc-skills-golang@golang-spf13-cobra` skill. For general CLI architecture, see `samber\u002Fcc-skills-golang@golang-cli`.\"\nuser-invocable: true\nlicense: MIT\ncompatibility: Designed for Claude Code or similar AI coding agents, and for projects using Golang.\nmetadata:\n  author: samber\n  version: \"1.0.4\"\n  openclaw:\n    emoji: \"🔧\"\n    homepage: https:\u002F\u002Fgithub.com\u002Fsamber\u002Fcc-skills-golang\n    requires:\n      bins:\n        - go\n    install: []\n    skill-library-version: \"1.21.0\"\nallowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent WebFetch mcp__context7__resolve-library-id mcp__context7__query-docs Bash(godig:*) Bash(gopls:*) LSP mcp__gopls__*\n---\n\n**Persona:** You are a Go engineer who treats configuration as a layered system. Flag beats env beats file beats default — and you bind every key so all four layers stay reachable through one API.\n\n# Using spf13\u002Fviper for layered configuration in Go\n\nViper resolves configuration values from multiple sources in a fixed precedence order. It has no user-facing surface — it doesn't define commands or flags. Its job is to answer \"what is the value of key X right now?\" by walking its source layers from highest to lowest priority.\n\n**Official Resources:**\n\n- [pkg.go.dev\u002Fgithub.com\u002Fspf13\u002Fviper](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fspf13\u002Fviper)\n- [github.com\u002Fspf13\u002Fviper](https:\u002F\u002Fgithub.com\u002Fspf13\u002Fviper)\n\nThis skill is not exhaustive. Please refer to library documentation and code examples for more information. For Go package docs, symbols, versions, importers, and known vulnerabilities, → See `samber\u002Fcc-skills-golang@golang-pkg-go-dev` skill (`godig`) — prefer it over Context7 for Go package facts. To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See `samber\u002Fcc-skills-golang@golang-gopls` skill (`gopls`). Context7 remains a fallback for docs not indexed on pkg.go.dev.\n\n```bash\ngo get github.com\u002Fspf13\u002Fviper@latest\n```\n\n## Viper vs. cobra\n\nCobra owns the command tree — subcommands, flags, arg validation, completions. Viper owns configuration resolution — it answers \"what is the value of key X?\" by walking its source layers. Viper has no user-facing surface; it is purely a key-value resolver. Use cobra alone for flag-only CLIs; viper alone for config-file daemons; both when you need both, binding flags at `PersistentPreRunE` via `BindPFlag`.\n\n→ See `samber\u002Fcc-skills-golang@golang-spf13-cobra` for the cobra side of this integration.\n\n## The precedence pipeline\n\nViper resolves a key by walking sources in this order (first set value wins):\n\n```\n1. explicit Set()      — viper.Set(\"key\", val)    highest priority\n2. flag                — bound pflag.Flag\n3. env var             — BindEnv \u002F AutomaticEnv\n4. config file         — ReadInConfig \u002F MergeInConfig\n5. KV remote           — etcd \u002F Consul\n6. default             — viper.SetDefault(\"key\", val)   lowest priority\n```\n\nThis pipeline is fixed and cannot be reordered. Understanding it prevents most viper bugs: a key that \"should\" come from a config file may be shadowed by an env var or a flag with a default value.\n\n## Sources and config files\n\n```go\nviper.SetConfigName(\"config\")\nviper.AddConfigPath(\"$HOME\u002F.myapp\")\nif err := viper.ReadInConfig(); err != nil {\n    var notFound *viper.ConfigFileNotFoundError\n    if !errors.As(err, &notFound) {\n        return fmt.Errorf(\"reading config: %w\", err) \u002F\u002F propagate real errors only\n    }\n}\n```\n\n`ConfigFileNotFoundError` must be handled gracefully — config files are usually optional. An unhandled error from a missing file crashes programs that are perfectly valid when run with only flags or env vars.\n\nFor supported formats (JSON, TOML, YAML, HCL, INI, properties), `MergeInConfig`, and remote KV, see [sources-and-formats.md](references\u002Fsources-and-formats.md).\n\n## Env binding and key replacers\n\nThis is the highest-bug-density area in viper. All three settings must be wired together — missing any one breaks nested key resolution:\n\n```go\n\u002F\u002F ✓ Good — all three wired together at startup\nviper.SetEnvPrefix(\"MYAPP\")                             \u002F\u002F prevent collisions: PORT → MYAPP_PORT\nviper.SetEnvKeyReplacer(strings.NewReplacer(\".\", \"_\"))  \u002F\u002F database.host → MYAPP_DATABASE_HOST\nviper.AutomaticEnv()\n\n\u002F\u002F ✗ Bad — without SetEnvKeyReplacer, viper looks for MYAPP_DATABASE.HOST (dot preserved)\n```\n\nFor `BindEnv`, `AllowEmptyEnv`, and env-vs-default interaction, see [binding-and-env.md](references\u002Fbinding-and-env.md).\n\n## Flag binding (the cobra seam)\n\nBind cobra flags to viper in `init()` or `PersistentPreRunE` — never in `RunE` (config loading in `PersistentPreRunE` already ran before `RunE`, so bindings set in `RunE` are missed):\n\n```go\nfunc init() {\n    rootCmd.PersistentFlags().Int(\"port\", 8080, \"listen port\")\n    viper.BindPFlag(\"port\", rootCmd.PersistentFlags().Lookup(\"port\"))\n    \u002F\u002F viper.BindPFlags(cmd.Flags()) — bind an entire FlagSet at once\n}\n```\n\nFor `AllowEmptyEnv` and flag\u002Fenv interaction details, see [binding-and-env.md](references\u002Fbinding-and-env.md).\n\n## Unmarshaling into structs\n\n`viper.Unmarshal` maps the resolved configuration into a struct using `mapstructure`:\n\n```go\ntype Config struct {\n    Port     int `mapstructure:\"port\"`\n    Database struct {\n        MaxConn int `mapstructure:\"max_conn\"` \u002F\u002F explicit tag: mapstructure won't convert underscore→camelCase\n    } `mapstructure:\"database\"`\n}\nvar cfg Config\nviper.Unmarshal(&cfg)\n```\n\n**Always use `mapstructure` tags** — implicit mapping is fragile for nested structs and underscore-named fields. Prefer `UnmarshalKey(\"database\", &dbCfg)` over `Sub(\"database\").Unmarshal` — it avoids the nil-check `Sub` requires when the key is missing.\n\nFor `time.Duration` \u002F `net.IP` \u002F slice decoders and custom `DecodeHook` registration, see [unmarshal.md](references\u002Funmarshal.md).\n\n## Sub-trees\n\n`viper.Sub(\"database\")` returns a new `*viper.Viper` scoped to the prefix, or **nil** if the key does not exist — always nil-check before calling methods on the result. Prefer `UnmarshalKey(\"database\", &dbCfg)` which avoids the nil risk entirely.\n\n## Hot reload\n\n```go\nviper.WatchConfig()\nviper.OnConfigChange(func(e fsnotify.Event) { \u002F* re-apply changed values *\u002F })\n```\n\n`WatchConfig` uses fsnotify and watches inodes. Editors that write atomically via rename (vim, neovim) replace the inode — the callback may not fire. Test hot-reload with `echo >> config.yaml`, not editor saves. For race-safe reload patterns, see [watch-and-reload.md](references\u002Fwatch-and-reload.md).\n\n## Test isolation\n\n**Never use the global viper in tests** — state leaks across test cases. Use `viper.New()` per test so each instance is isolated:\n\n```go\nv := viper.New()\nv.SetConfigFile(\"testdata\u002Fconfig.yaml\")\nrequire.NoError(t, v.ReadInConfig())\n```\n\nFor `t.Setenv` interactions and `Reset()` limitations, see [testing-and-isolation.md](references\u002Ftesting-and-isolation.md).\n\n## Best Practices\n\n1. **Set prefix + key replacer + AutomaticEnv together** — missing any one causes nested env keys to silently not resolve (`database.host` → `DATABASE.HOST` instead of `DATABASE_HOST`).\n2. **Handle `ConfigFileNotFoundError` gracefully** — a missing config file should not crash a service that runs with only flags and env vars.\n3. **Always use `mapstructure` tags on config structs** — implicit mapping silently misses nested and underscore-named fields.\n4. **Use `viper.New()` in tests, never the global** — the global accumulates state across test runs; per-test instances are isolated.\n5. **Bind flags before `Execute()`** — binding in `RunE` is too late; cobra parses flags before `RunE` runs.\n\n## Common Mistakes\n\n| Mistake | Why it fails | Fix |\n| --- | --- | --- |\n| `AutomaticEnv` without `SetEnvKeyReplacer` | `database.host` looks for `MYAPP_DATABASE.HOST` (dot preserved) — never matches | Add `SetEnvKeyReplacer(strings.NewReplacer(\".\", \"_\"))` before `AutomaticEnv` |\n| No `mapstructure` tags on struct fields | Silently misses nested and underscore-named fields | Add `mapstructure:\"key_name\"` to every field |\n| Using global viper in tests | State from one test contaminates the next, causing flaky ordering | Create `viper.New()` per test |\n| Missing `ConfigFileNotFoundError` check | Missing config file crashes a service that should run on flags\u002Fenv alone | `errors.As(err, &notFound)` — only propagate non-not-found errors |\n\n## Further Reading\n\n- [sources-and-formats.md](references\u002Fsources-and-formats.md) — supported file formats, multi-path search, MergeInConfig, remote KV (etcd\u002FConsul)\n- [binding-and-env.md](references\u002Fbinding-and-env.md) — BindEnv, AutomaticEnv, SetEnvPrefix, SetEnvKeyReplacer, AllowEmptyEnv, timing rules\n- [unmarshal.md](references\u002Funmarshal.md) — Unmarshal, UnmarshalKey, mapstructure tags, custom DecodeHooks (Duration, IP, slice)\n- [watch-and-reload.md](references\u002Fwatch-and-reload.md) — WatchConfig, OnConfigChange, fsnotify caveats, atomic-rename trap, race-safe patterns\n- [testing-and-isolation.md](references\u002Ftesting-and-isolation.md) — viper.New() per test, t.Setenv interactions, Reset() limitations, snapshot\u002Frestore\n\n## Cross-References\n\n- → See `samber\u002Fcc-skills-golang@golang-cli` skill for general CLI architecture — project layout, exit codes, signal handling, cobra+viper integration\n- → See `samber\u002Fcc-skills-golang@golang-spf13-cobra` skill for the cobra side of this integration (flag definition and binding)\n- → See `samber\u002Fcc-skills-golang@golang-testing` skill for general Go testing patterns\n\nIf you encounter a bug or unexpected behavior in spf13\u002Fviper, open an issue at \u003Chttps:\u002F\u002Fgithub.com\u002Fspf13\u002Fviper\u002Fissues>.\n","**Persona:** You are a Go engineer who treats configuration as a layered system. Flag beats env beats file beats default — and you bind every key so all four layers stay reachable through one API.\n\n# Using spf13\u002Fviper for layered configuration in Go\n\nViper resolves configuration values from multiple sources in a fixed precedence order. It has no user-facing surface — it doesn't define commands or flags. Its job is to answer \"what is the value of key X right now?\" by walking its source layers from highest to lowest priority.\n\n**Official Resources:**\n\n- [pkg.go.dev\u002Fgithub.com\u002Fspf13\u002Fviper](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fspf13\u002Fviper)\n- [github.com\u002Fspf13\u002Fviper](https:\u002F\u002Fgithub.com\u002Fspf13\u002Fviper)\n\nThis skill is not exhaustive. Please refer to library documentation and code examples for more information. For Go package docs, symbols, versions, importers, and known vulnerabilities, → See `samber\u002Fcc-skills-golang@golang-pkg-go-dev` skill (`godig`) — prefer it over Context7 for Go package facts. To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See `samber\u002Fcc-skills-golang@golang-gopls` skill (`gopls`). Context7 remains a fallback for docs not indexed on pkg.go.dev.\n\n```bash\ngo get github.com\u002Fspf13\u002Fviper@latest\n```\n\n## Viper vs. cobra\n\nCobra owns the command tree — subcommands, flags, arg validation, completions. Viper owns configuration resolution — it answers \"what is the value of key X?\" by walking its source layers. Viper has no user-facing surface; it is purely a key-value resolver. Use cobra alone for flag-only CLIs; viper alone for config-file daemons; both when you need both, binding flags at `PersistentPreRunE` via `BindPFlag`.\n\n→ See `samber\u002Fcc-skills-golang@golang-spf13-cobra` for the cobra side of this integration.\n\n## The precedence pipeline\n\nViper resolves a key by walking sources in this order (first set value wins):\n\n```\n1. explicit Set()      — viper.Set(\"key\", val)    highest priority\n2. flag                — bound pflag.Flag\n3. env var             — BindEnv \u002F AutomaticEnv\n4. config file         — ReadInConfig \u002F MergeInConfig\n5. KV remote           — etcd \u002F Consul\n6. default             — viper.SetDefault(\"key\", val)   lowest priority\n```\n\nThis pipeline is fixed and cannot be reordered. Understanding it prevents most viper bugs: a key that \"should\" come from a config file may be shadowed by an env var or a flag with a default value.\n\n## Sources and config files\n\n```go\nviper.SetConfigName(\"config\")\nviper.AddConfigPath(\"$HOME\u002F.myapp\")\nif err := viper.ReadInConfig(); err != nil {\n    var notFound *viper.ConfigFileNotFoundError\n    if !errors.As(err, &notFound) {\n        return fmt.Errorf(\"reading config: %w\", err) \u002F\u002F propagate real errors only\n    }\n}\n```\n\n`ConfigFileNotFoundError` must be handled gracefully — config files are usually optional. An unhandled error from a missing file crashes programs that are perfectly valid when run with only flags or env vars.\n\nFor supported formats (JSON, TOML, YAML, HCL, INI, properties), `MergeInConfig`, and remote KV, see [sources-and-formats.md](references\u002Fsources-and-formats.md).\n\n## Env binding and key replacers\n\nThis is the highest-bug-density area in viper. All three settings must be wired together — missing any one breaks nested key resolution:\n\n```go\n\u002F\u002F ✓ Good — all three wired together at startup\nviper.SetEnvPrefix(\"MYAPP\")                             \u002F\u002F prevent collisions: PORT → MYAPP_PORT\nviper.SetEnvKeyReplacer(strings.NewReplacer(\".\", \"_\"))  \u002F\u002F database.host → MYAPP_DATABASE_HOST\nviper.AutomaticEnv()\n\n\u002F\u002F ✗ Bad — without SetEnvKeyReplacer, viper looks for MYAPP_DATABASE.HOST (dot preserved)\n```\n\nFor `BindEnv`, `AllowEmptyEnv`, and env-vs-default interaction, see [binding-and-env.md](references\u002Fbinding-and-env.md).\n\n## Flag binding (the cobra seam)\n\nBind cobra flags to viper in `init()` or `PersistentPreRunE` — never in `RunE` (config loading in `PersistentPreRunE` already ran before `RunE`, so bindings set in `RunE` are missed):\n\n```go\nfunc init() {\n    rootCmd.PersistentFlags().Int(\"port\", 8080, \"listen port\")\n    viper.BindPFlag(\"port\", rootCmd.PersistentFlags().Lookup(\"port\"))\n    \u002F\u002F viper.BindPFlags(cmd.Flags()) — bind an entire FlagSet at once\n}\n```\n\nFor `AllowEmptyEnv` and flag\u002Fenv interaction details, see [binding-and-env.md](references\u002Fbinding-and-env.md).\n\n## Unmarshaling into structs\n\n`viper.Unmarshal` maps the resolved configuration into a struct using `mapstructure`:\n\n```go\ntype Config struct {\n    Port     int `mapstructure:\"port\"`\n    Database struct {\n        MaxConn int `mapstructure:\"max_conn\"` \u002F\u002F explicit tag: mapstructure won't convert underscore→camelCase\n    } `mapstructure:\"database\"`\n}\nvar cfg Config\nviper.Unmarshal(&cfg)\n```\n\n**Always use `mapstructure` tags** — implicit mapping is fragile for nested structs and underscore-named fields. Prefer `UnmarshalKey(\"database\", &dbCfg)` over `Sub(\"database\").Unmarshal` — it avoids the nil-check `Sub` requires when the key is missing.\n\nFor `time.Duration` \u002F `net.IP` \u002F slice decoders and custom `DecodeHook` registration, see [unmarshal.md](references\u002Funmarshal.md).\n\n## Sub-trees\n\n`viper.Sub(\"database\")` returns a new `*viper.Viper` scoped to the prefix, or **nil** if the key does not exist — always nil-check before calling methods on the result. Prefer `UnmarshalKey(\"database\", &dbCfg)` which avoids the nil risk entirely.\n\n## Hot reload\n\n```go\nviper.WatchConfig()\nviper.OnConfigChange(func(e fsnotify.Event) { \u002F* re-apply changed values *\u002F })\n```\n\n`WatchConfig` uses fsnotify and watches inodes. Editors that write atomically via rename (vim, neovim) replace the inode — the callback may not fire. Test hot-reload with `echo >> config.yaml`, not editor saves. For race-safe reload patterns, see [watch-and-reload.md](references\u002Fwatch-and-reload.md).\n\n## Test isolation\n\n**Never use the global viper in tests** — state leaks across test cases. Use `viper.New()` per test so each instance is isolated:\n\n```go\nv := viper.New()\nv.SetConfigFile(\"testdata\u002Fconfig.yaml\")\nrequire.NoError(t, v.ReadInConfig())\n```\n\nFor `t.Setenv` interactions and `Reset()` limitations, see [testing-and-isolation.md](references\u002Ftesting-and-isolation.md).\n\n## Best Practices\n\n1. **Set prefix + key replacer + AutomaticEnv together** — missing any one causes nested env keys to silently not resolve (`database.host` → `DATABASE.HOST` instead of `DATABASE_HOST`).\n2. **Handle `ConfigFileNotFoundError` gracefully** — a missing config file should not crash a service that runs with only flags and env vars.\n3. **Always use `mapstructure` tags on config structs** — implicit mapping silently misses nested and underscore-named fields.\n4. **Use `viper.New()` in tests, never the global** — the global accumulates state across test runs; per-test instances are isolated.\n5. **Bind flags before `Execute()`** — binding in `RunE` is too late; cobra parses flags before `RunE` runs.\n\n## Common Mistakes\n\n| Mistake | Why it fails | Fix |\n| --- | --- | --- |\n| `AutomaticEnv` without `SetEnvKeyReplacer` | `database.host` looks for `MYAPP_DATABASE.HOST` (dot preserved) — never matches | Add `SetEnvKeyReplacer(strings.NewReplacer(\".\", \"_\"))` before `AutomaticEnv` |\n| No `mapstructure` tags on struct fields | Silently misses nested and underscore-named fields | Add `mapstructure:\"key_name\"` to every field |\n| Using global viper in tests | State from one test contaminates the next, causing flaky ordering | Create `viper.New()` per test |\n| Missing `ConfigFileNotFoundError` check | Missing config file crashes a service that should run on flags\u002Fenv alone | `errors.As(err, &notFound)` — only propagate non-not-found errors |\n\n## Further Reading\n\n- [sources-and-formats.md](references\u002Fsources-and-formats.md) — supported file formats, multi-path search, MergeInConfig, remote KV (etcd\u002FConsul)\n- [binding-and-env.md](references\u002Fbinding-and-env.md) — BindEnv, AutomaticEnv, SetEnvPrefix, SetEnvKeyReplacer, AllowEmptyEnv, timing rules\n- [unmarshal.md](references\u002Funmarshal.md) — Unmarshal, UnmarshalKey, mapstructure tags, custom DecodeHooks (Duration, IP, slice)\n- [watch-and-reload.md](references\u002Fwatch-and-reload.md) — WatchConfig, OnConfigChange, fsnotify caveats, atomic-rename trap, race-safe patterns\n- [testing-and-isolation.md](references\u002Ftesting-and-isolation.md) — viper.New() per test, t.Setenv interactions, Reset() limitations, snapshot\u002Frestore\n\n## Cross-References\n\n- → See `samber\u002Fcc-skills-golang@golang-cli` skill for general CLI architecture — project layout, exit codes, signal handling, cobra+viper integration\n- → See `samber\u002Fcc-skills-golang@golang-spf13-cobra` skill for the cobra side of this integration (flag definition and binding)\n- → See `samber\u002Fcc-skills-golang@golang-testing` skill for general Go testing patterns\n\nIf you encounter a bug or unexpected behavior in spf13\u002Fviper, open an issue at \u003Chttps:\u002F\u002Fgithub.com\u002Fspf13\u002Fviper\u002Fissues>.\n",{"name":5,"license":15,"metadata":24,"description":7,"allowed-tools":35,"compatibility":36,"user-invocable":37},{"author":25,"version":26,"openclaw":27},"samber","1.0.4",{"emoji":28,"install":29,"homepage":30,"requires":31,"skill-library-version":34},"🔧",[],"https:\u002F\u002Fgithub.com\u002Fsamber\u002Fcc-skills-golang",{"bins":32},[33],"go","1.21.0","Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent WebFetch mcp__context7__resolve-library-id mcp__context7__query-docs Bash(godig:*) Bash(gopls:*) LSP mcp__gopls__*","Designed for Claude Code or similar AI coding agents, and for projects using Golang.",true,"main","8859218955d9504cd18b59e7892100718039d3b4","data\u002Fskills\u002Fsamber-cc-skills-golang\u002Fgolang-spf13-viper",1,"https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper","https:\u002F\u002Fgithub.com\u002Fom-scogo","SDE-1 @ Scogo ","2026-07-18 12:22:46",{"source":8,"skillName":5,"commands":47,"prompt":57,"zipAvailable":37},[48,51,54],{"tool":49,"command":50},"npx","npx skills add om-scogo\u002Fskillsh-scraper --skill golang-spf13-viper",{"tool":52,"command":53},"bunx","bunx skills add om-scogo\u002Fskillsh-scraper --skill golang-spf13-viper",{"tool":55,"command":56},"pnpm","pnpm dlx skills add om-scogo\u002Fskillsh-scraper --skill golang-spf13-viper","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fsamber-cc-skills-golang\u002Fgolang-spf13-viper\u002FSkill.md",[59],{"path":60,"resourceType":61,"resourceTypeDesc":62,"sizeBytes":63,"sourceHtmlUrl":64},"metadata.json","REFERENCE","参考文档",473,"https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fsamber-cc-skills-golang\u002Fgolang-spf13-viper\u002Fmetadata.json",[66,73,78,85,90,97],{"skillNo":67,"name":68,"nameZh":6,"description":69,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":70,"categories":71,"keywords":72,"publishedAt":19},"01M7D6MC9FAAEV4CMNYX8W7JTG","arxiv-search","Search arXiv physics, math, and computer science preprints using natural language queries. Powered by Valyu semantic search.","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fyorkeccak-scientific-skills\u002Farxiv-search\u002Fskills\u002Farxiv-search\u002FSKILL.md",[],[],{"skillNo":74,"name":68,"nameZh":6,"description":69,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":77,"publishedAt":19},"01M7D6M85CKKN87TA98VCQV4H7","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fyorkeccak-scientific-skills\u002Farxiv-search\u002FSkill.md",[],[],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":19},"01M7D4ZTCS4DR3CE4JY06X84T2","working-with-legacy-code","Safely change and test untested codebases using Feathers' \"Working Effectively with Legacy Code\". Use when the user mentions \"legacy code\", \"no tests\", \"untested codebase\", \"how do I test this\", \"seams\", \"characterization tests\", \"golden master\", \"sprout method\", \"afraid to change this code\", \"monster method\", \"dependency breaking\", or \"inherited a messy codebase\". Also trigger when changing code without tests safely, getting a class under test when constructors, statics, or singletons block it, adding features to tangled modules, or planning incremental test coverage for an old codebase. Covers the legacy-code change algorithm, seams, characterization tests, sprout\u002Fwrap, and dependency-breaking techniques. For refactoring code that already has tests, see refactoring-patterns. For day-to-day code quality, see clean-code.","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fwondelai-skills\u002Fworking-with-legacy-code\u002Fworking-with-legacy-code\u002FSKILL.md",[],[],{"skillNo":86,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":87,"categories":88,"keywords":89,"publishedAt":19},"01M7D4ZHZKJD2RSNGAF63V14P4","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fwondelai-skills\u002Fworking-with-legacy-code\u002FSkill.md",[],[],{"skillNo":91,"name":92,"nameZh":6,"description":93,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":94,"categories":95,"keywords":96,"publishedAt":19},"01M7D4ZB4CJBFW5JE67CPH2QRV","web-typography","Select, pair, and implement typefaces for web projects. Use when the user mentions \"font pairing\", \"which typeface\", \"line height\", \"responsive typography\", \"web font loading\", \"type hierarchy\", \"variable fonts\", \"FOUT\u002FFOIT\", \"typographic scale\", or \"the text is hard to read\". Also trigger when choosing between system fonts and web fonts, optimizing font-loading performance, or designing readable long-form content. Covers readability evaluation, CSS implementation, and performance optimization. For overall UI design systems, see refactoring-ui. For dramatic typographic experiences, see top-design.","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fwondelai-skills\u002Fweb-typography\u002Fweb-typography\u002FSKILL.md",[],[],{"skillNo":98,"name":92,"nameZh":6,"description":93,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":99,"categories":100,"keywords":101,"publishedAt":19},"01M7D4Z4MVYVY3NMJ18BNV6WNA","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fwondelai-skills\u002Fweb-typography\u002FSkill.md",[],[]]