Skip to content

Commit 70b62be

Browse files
committed
[ND-7649] - add pipeline logs command
1 parent 1bef09f commit 70b62be

9 files changed

Lines changed: 903 additions & 1 deletion

File tree

AGENTS.md

Lines changed: 372 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,372 @@
1+
# AI Agent Development Guide
2+
3+
This document provides instructions for AI assistants working on the Bunnyshell CLI codebase. It is maintained in an AI-agnostic format for use with any AI development assistant.
4+
5+
## Quick Start
6+
7+
**Project:** Bunnyshell CLI (`bns`)
8+
**Language:** Go 1.23
9+
**Development Environment:** Docker-based (required)
10+
11+
## Development Environment Setup
12+
13+
### Using Docker (Required for Go Commands)
14+
15+
All Go-related commands MUST be executed inside the Docker development container.
16+
17+
**1. Check if container is running:**
18+
```bash
19+
docker ps --filter "name=bunnyshell-cli"
20+
```
21+
22+
**2. Start container if needed:**
23+
```bash
24+
cd .dev && docker-compose up -d
25+
```
26+
27+
**3. Execute commands in container:**
28+
```bash
29+
docker exec -it bunnyshell-cli <command>
30+
```
31+
32+
**Common commands:**
33+
```bash
34+
# Build the project
35+
docker exec -it bunnyshell-cli make build-local
36+
37+
# Run go mod tidy
38+
docker exec -it bunnyshell-cli go mod tidy
39+
40+
# Run tests
41+
docker exec -it bunnyshell-cli go test ./...
42+
43+
# Access container shell
44+
docker exec -it bunnyshell-cli /bin/bash
45+
```
46+
47+
### Build Success Criteria
48+
49+
A build is considered **successful** when:
50+
- ✅ Linux binary is produced: `dist/bns_linux_amd64_v1/bns`
51+
- ✅ Darwin binary is produced: `dist/bns_darwin_arm64/bns` or `dist/bns_darwin_amd64_v1/bns`
52+
53+
A build may show errors for:
54+
- ❌ Docker image building (no Docker-in-Docker in dev container) - **THIS IS EXPECTED AND OK**
55+
56+
### Testing Builds
57+
58+
**From container:**
59+
```bash
60+
./dist/bns_linux_amd64_v1/bns --help
61+
```
62+
63+
**From host (macOS):**
64+
```bash
65+
./dist/bns_darwin_arm64/bns --help
66+
# or
67+
./dist/bns_darwin_amd64_v1/bns --help
68+
```
69+
70+
### Important Notes
71+
72+
- **DO NOT** rely on host machine Go installation
73+
- **DO NOT** run `go` commands directly on the host
74+
- **ALWAYS** use the Docker container for Go commands
75+
- The host may not have Go installed or may have a different version
76+
77+
## Project Structure
78+
79+
```
80+
/
81+
├── .dev/ # Docker development environment
82+
│ ├── docker-compose.yaml # Container setup
83+
│ ├── Dockerfile.dev # golang:1.23 with goreleaser
84+
│ └── Readme.md # Quick reference
85+
├── cmd/ # Command implementations
86+
│ └── [resource]/ # Command groups (environments, components, etc.)
87+
│ ├── root.go # Main command
88+
│ ├── list.go # List subcommand
89+
│ ├── show.go # Show subcommand
90+
│ └── action/ # Action subcommands (create, delete, etc.)
91+
├── pkg/ # Core packages
92+
│ ├── api/ # API client wrappers
93+
│ ├── config/ # Configuration management
94+
│ ├── formatter/ # Output formatters (stylish, JSON, YAML)
95+
│ ├── interactive/ # Interactive prompts
96+
│ └── ... # Other core packages
97+
├── main.go # Application entry point
98+
├── go.mod / go.sum # Go dependencies
99+
├── Makefile # Build targets
100+
├── .goreleaser.yaml # Release configuration
101+
└── AGENTS.md # This file
102+
```
103+
104+
## Adding a New Command
105+
106+
Follow this pattern when adding new commands:
107+
108+
### 1. Create API Layer
109+
110+
Location: `pkg/api/[resource]/`
111+
112+
```go
113+
// pkg/api/[resource]/list.go
114+
package resource
115+
116+
import (
117+
"bunnyshell.com/cli/pkg/api"
118+
"bunnyshell.com/cli/pkg/api/common"
119+
"bunnyshell.com/cli/pkg/lib"
120+
"bunnyshell.com/sdk"
121+
)
122+
123+
type ListOptions struct {
124+
common.ListOptions
125+
// Add your filters here
126+
}
127+
128+
func NewListOptions() *ListOptions {
129+
return &ListOptions{
130+
ListOptions: *common.NewListOptions(),
131+
}
132+
}
133+
134+
func List(options *ListOptions) (*sdk.PaginatedResourceCollection, error) {
135+
model, resp, err := ListRaw(options)
136+
if err != nil {
137+
return nil, api.ParseError(resp, err)
138+
}
139+
return model, nil
140+
}
141+
142+
func ListRaw(options *ListOptions) (*sdk.PaginatedResourceCollection, *http.Response, error) {
143+
profile := options.GetProfile()
144+
ctx, cancel := lib.GetContextFromProfile(profile)
145+
defer cancel()
146+
147+
request := lib.GetAPIFromProfile(profile).ResourceAPI.ResourceList(ctx)
148+
return applyOptions(request, options).Execute()
149+
}
150+
151+
func applyOptions(request sdk.ApiResourceListRequest, options *ListOptions) sdk.ApiResourceListRequest {
152+
if options == nil {
153+
return request
154+
}
155+
156+
if options.Page > 1 {
157+
request = request.Page(options.Page)
158+
}
159+
160+
// Add your filters here
161+
162+
return request
163+
}
164+
```
165+
166+
### 2. Create Command Implementation
167+
168+
Location: `cmd/[resource]/`
169+
170+
```go
171+
// cmd/[resource]/list.go
172+
package resource
173+
174+
import (
175+
"bunnyshell.com/cli/pkg/api/resource"
176+
"bunnyshell.com/cli/pkg/lib"
177+
"github.com/spf13/cobra"
178+
)
179+
180+
func init() {
181+
listOptions := resource.NewListOptions()
182+
183+
command := &cobra.Command{
184+
Use: "list",
185+
Short: "List resources",
186+
ValidArgsFunction: cobra.NoFileCompletions,
187+
188+
RunE: func(cmd *cobra.Command, args []string) error {
189+
return lib.ShowCollection(cmd, listOptions, func() (lib.ModelWithPagination, error) {
190+
return resource.List(listOptions)
191+
})
192+
},
193+
}
194+
195+
flags := command.Flags()
196+
// Add your flags here
197+
listOptions.UpdateFlagSet(flags)
198+
199+
mainCmd.AddCommand(command)
200+
}
201+
```
202+
203+
### 3. Add Formatter (if needed)
204+
205+
Location: `pkg/formatter/`
206+
207+
```go
208+
// pkg/formatter/stylish.resource.go
209+
package formatter
210+
211+
import (
212+
"fmt"
213+
"text/tabwriter"
214+
"bunnyshell.com/sdk"
215+
)
216+
217+
func tabulateResourceCollection(writer *tabwriter.Writer, data *sdk.PaginatedResourceCollection) {
218+
fmt.Fprintf(writer, "%v\t %v\t %v\n", "ID", "Name", "Status")
219+
220+
if data.Embedded != nil {
221+
for _, item := range data.Embedded.Item {
222+
fmt.Fprintf(writer, "%v\t %v\t %v\n",
223+
item.GetId(),
224+
item.GetName(),
225+
item.GetStatus(),
226+
)
227+
}
228+
}
229+
}
230+
```
231+
232+
Then add the case to `pkg/formatter/stylish.go`:
233+
234+
```go
235+
case *sdk.PaginatedResourceCollection:
236+
tabulateResourceCollection(writer, dataType)
237+
```
238+
239+
## Common Patterns
240+
241+
### Flag Conflicts to Avoid
242+
243+
These global flags are already registered:
244+
- `-t` = `--timeout`
245+
- `-d` = `--debug`
246+
- `-v` = `--verbose`
247+
- `-o` = `--output`
248+
249+
Do not use these shorthands for command-specific flags.
250+
251+
### Repeatable Flags
252+
253+
Use `StringArrayVar` for repeatable flags:
254+
255+
```go
256+
var statuses []string
257+
flags.StringArrayVar(&statuses, "status", statuses, "Filter by status (repeatable)")
258+
```
259+
260+
### Required Flags
261+
262+
```go
263+
flags.AddFlag(option.GetRequiredFlag("id"))
264+
```
265+
266+
### Optional Context-aware Flags
267+
268+
```go
269+
flags.AddFlag(options.Organization.GetFlag("organization"))
270+
```
271+
272+
## Testing Your Changes
273+
274+
### 1. Build the project
275+
276+
```bash
277+
docker exec -it bunnyshell-cli make build-local
278+
```
279+
280+
### 2. Verify build succeeded
281+
282+
Check for:
283+
- `dist/bns_linux_amd64_v1/bns` (Linux)
284+
- `dist/bns_darwin_arm64/bns` (macOS ARM)
285+
- `dist/bns_darwin_amd64_v1/bns` (macOS Intel)
286+
287+
### 3. Test the binary
288+
289+
From host (macOS):
290+
```bash
291+
./dist/bns_darwin_arm64/bns [your-command] --help
292+
```
293+
294+
From container (Linux):
295+
```bash
296+
./dist/bns_linux_amd64_v1/bns [your-command] --help
297+
```
298+
299+
## SDK Dependencies
300+
301+
The project depends on:
302+
- `bunnyshell.com/sdk` - Official Bunnyshell API client
303+
- `bunnyshell.com/dev` - Development utilities
304+
305+
If you need to test with local SDK changes:
306+
307+
1. Add to `go.mod`:
308+
```go
309+
replace bunnyshell.com/dev v0.7.0 => ../bunnyshellosi-dev/
310+
```
311+
312+
2. Ensure the path exists in both container and host (for IDE support)
313+
314+
3. The docker-compose.yaml already mounts this path
315+
316+
## Code Quality
317+
318+
### Before committing:
319+
320+
```bash
321+
# Format code
322+
docker exec -it bunnyshell-cli go fmt ./...
323+
324+
# Tidy dependencies
325+
docker exec -it bunnyshell-ci go mod tidy
326+
327+
# Run tests
328+
docker exec -it bunnyshell-cli go test ./...
329+
330+
# Build to verify
331+
docker exec -it bunnyshell-cli make build-local
332+
```
333+
334+
## Architecture Principles
335+
336+
1. **Separation of Concerns:**
337+
- `cmd/` = CLI interface and command handling
338+
- `pkg/api/` = Business logic and API interaction
339+
- `pkg/formatter/` = Output formatting
340+
- `pkg/lib/` = Shared utilities
341+
342+
2. **Configuration Management:**
343+
- Support multiple profiles
344+
- Store context (org, project, env, component)
345+
- Allow flag overrides
346+
- Interactive prompts for missing values
347+
348+
3. **User Experience:**
349+
- Provide interactive mode for missing parameters
350+
- Support non-interactive mode for automation
351+
- Multiple output formats (stylish, JSON, YAML)
352+
- Progress indicators for long operations
353+
354+
4. **Error Handling:**
355+
- Use domain-specific error types
356+
- Parse and format API errors
357+
- Provide helpful error messages
358+
359+
## Documentation
360+
361+
When adding features, update:
362+
- **AGENTS.md** (this file) - For AI-agnostic instructions
363+
- **CLAUDE.md** - For detailed codebase overview
364+
- **README.md** - For user-facing documentation
365+
- `.dev/Readme.md` - For development quick reference
366+
367+
## Getting Help
368+
369+
- Check **CLAUDE.md** for comprehensive codebase documentation
370+
- Look at existing commands for patterns (e.g., `cmd/pipeline/jobs.go`)
371+
- Examine API packages for SDK usage (e.g., `pkg/api/workflow_job/list.go`)
372+
- Review formatters for output patterns (e.g., `pkg/formatter/stylish.workflow_job.go`)

0 commit comments

Comments
 (0)