surveygo
Guides usage of the surveygo Go library (github.com/rendis/surveygo/v2) for building and managing surveys with validation, conditional logic, and output rendering, and tabular data extraction. Covers parsing surveys from JSON, creating surveys programmatically, adding questions and groups, answer validation and translation, DependsOn conditional visibility, grouped/repeatable answers, and output generation (CSV, HTML, JSON, TipTap). Use when working with surveygo imports, Survey structs, question types, answer review, schema construction, or the render package.
Best use case
surveygo is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Guides usage of the surveygo Go library (github.com/rendis/surveygo/v2) for building and managing surveys with validation, conditional logic, and output rendering, and tabular data extraction. Covers parsing surveys from JSON, creating surveys programmatically, adding questions and groups, answer validation and translation, DependsOn conditional visibility, grouped/repeatable answers, and output generation (CSV, HTML, JSON, TipTap). Use when working with surveygo imports, Survey structs, question types, answer review, schema construction, or the render package.
Teams using surveygo should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/surveygo/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How surveygo Compares
| Feature / Agent | surveygo | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Guides usage of the surveygo Go library (github.com/rendis/surveygo/v2) for building and managing surveys with validation, conditional logic, and output rendering, and tabular data extraction. Covers parsing surveys from JSON, creating surveys programmatically, adding questions and groups, answer validation and translation, DependsOn conditional visibility, grouped/repeatable answers, and output generation (CSV, HTML, JSON, TipTap). Use when working with surveygo imports, Survey structs, question types, answer review, schema construction, or the render package.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# surveygo
Go library for creating and managing surveys with validation, conditional logic, and rendering.
Import: `github.com/rendis/surveygo/v2`
## Quick Start
```go
// Parse survey from JSON
survey, err := surveygo.ParseFromJsonStr(jsonStr)
// Review answers
answers := surveygo.Answers{
"question1": {"answer_value"},
"choice_q": {"option_nameId"},
}
resume, err := survey.ReviewAnswers(answers)
// Translate choice nameIds to labels/values
translated, err := survey.TranslateAnswers(answers, false)
```
## Core Workflows
### Parse / Create Survey
```go
// From JSON string or bytes
survey, err := surveygo.ParseFromJsonStr(jsonStr)
survey, err := surveygo.ParseFromBytes(jsonBytes)
// Programmatically
survey, err := surveygo.NewSurvey("My Survey", "1.0", nil)
```
Parsing auto-validates struct, checks consistency, and assigns positions.
### Add Questions and Groups
```go
// Add question from JSON
err := survey.AddQuestionJson(`{
"nameId": "fav_color",
"visible": true,
"type": "single_select",
"label": "Favorite color?",
"value": {
"options": [
{"nameId": "red", "label": "Red"},
{"nameId": "blue", "label": "Blue"}
]
}
}`)
// Assign question to group (position -1 = append)
err = survey.AddQuestionToGroup("fav_color", "my_group", -1)
// Add group
err = survey.AddGroupJson(`{"nameId": "my_group"}`)
survey.UpdateGroupsOrder([]string{"my_group", "other_group"})
```
All Add/Update methods have variants: `*Question(q)`, `*QuestionJson(s)`, `*QuestionBytes(b)`, `*QuestionMap(m)`.
Same for groups. Also `AddOrUpdate*` variants that upsert.
### Review Answers
```go
resume, err := survey.ReviewAnswers(answers)
// Check completion
fmt.Println(resume.TotalRequiredQuestionsAnswered, "/", resume.TotalRequiredQuestions)
// Check invalid answers
for _, inv := range resume.InvalidAnswers {
fmt.Printf("%s: %s\n", inv.QuestionNameId, inv.Error)
}
// Per-group stats
groupResume := resume.GroupsResume["group_nameId"]
```
### Grouped (Repeatable) Answers
Groups with `AllowRepeat: true` accept multiple answer sets:
```go
answers := surveygo.Answers{
"repeatable_group": {
map[string][]any{"q1": {"a1"}, "q2": {"a2"}}, // set 1
map[string][]any{"q1": {"b1"}, "q2": {"b2"}}, // set 2
},
}
```
### DependsOn Conditional Logic
Questions/groups become visible only when referenced choice options are selected.
```json
{
"dependsOn": [
[{ "questionNameId": "q1", "optionNameId": "opt_a" }],
[
{ "questionNameId": "q2", "optionNameId": "opt_b" },
{ "questionNameId": "q3", "optionNameId": "opt_c" }
]
]
}
```
- Outer array = **OR** (any group matches = visible)
- Inner array = **AND** (all conditions must match)
- Referenced question must be a **choice type**
- Invisible questions are excluded from `SurveyResume` totals
### Rendering
```go
import "github.com/rendis/surveygo/v2/render"
csvBytes, err := render.AnswersToCSV(survey, answers)
card, err := render.AnswersToJSON(survey, answers)
htmlResult, err := render.AnswersToHTML(survey, answers)
tiptap, err := render.AnswersToTipTap(survey, answers)
// Multi-format single pass
result, err := render.AnswersTo(survey, answers, render.OutputOptions{
CSV: true, JSON: true, HTML: true, TipTap: true,
})
// HTMLResult has separate HTML + CSS
htmlResult.WithCSSPath("/static/card.css") // replace CSS href
// Tabular matrix (header row + data rows, same data as CSV but as Go types)
matrix, err := render.AnswersToRows(survey, answers)
```
See [references/render.md](references/render.md) for full render API and typesGotchas
- **Answers type**: always `map[string][]any` — values are arrays even for single answers
- **Choice answers**: stored as option **nameIds** (strings). Use `TranslateAnswers` to get labels/values
- **Asset MaxFiles/MinFiles**: `0` means default `1`, **not** unlimited/zero. The lib does NOT validate file counts — consuming apps must handle this
- **External questions**: use direct type assertion `q.Value.(*external.ExternalQuestion)` — no `CastToExternal` function exists
- **AnswerExpr**: expr-lang/expr expression. Environment: `ans` ([]any) + `options` (map[nameId]label for choice types). Silent fallback on error (nil, false). Never writes to stderr
- **Group.Title**: is `*string`, not `string`
- **NameId regex**: `^[a-zA-Z][a-zA-Z\d_-]{1,62}[a-zA-Z\d]$` (3-64 chars, start with letter, end with alphanumeric)
- **Position**: auto-calculated — do not set manually
- **Slider**: is a choice type (complex) with `Min`, `Max`, `Step`, `Default`, `Unit` — not `Options`
- **RemoveQuestion**: auto-cleans DependsOn references from other questions and groups
## References
- [references/api.md](references/api.md) — Full API: all exported structs, methods, and function signatures
- [references/question-types.md](references/question-types.md) — All question types with their specific fields and cast functions
- [references/render.md](references/render.md) — Render package: output functions, types, and formats