bod-cli 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,274 @@
1
+ ---
2
+ name: using-bod-cli
3
+ description: Guide for AI agents to use the bod CLI to scaffold, deploy, manage, and operate apps on Bodify. Use when creating new projects, deploying code, managing environments, viewing logs, or operating deployed apps.
4
+ ---
5
+
6
+ # Using bod-cli
7
+
8
+ `bod` is the unified CLI for the Bod product family. Currently supports Bodify (self-hosted deployment platform).
9
+
10
+ ## Setup
11
+
12
+ ```bash
13
+ # Install globally (from the bod-cli directory)
14
+ bun link
15
+
16
+ # Or run directly
17
+ bun /path/to/bod-cli/src/cli.ts <command>
18
+
19
+ # First-run: authenticate with a Bodify instance
20
+ bod login https://your-bodify-server.com --key YOUR_API_KEY
21
+ ```
22
+
23
+ Config stored at `~/.bod/config.json`. Supports multiple instances.
24
+
25
+ ## End-to-End: New Project
26
+
27
+ ```bash
28
+ # 1. Create directory and init
29
+ mkdir my-api && cd my-api
30
+ bod init
31
+ # → Select template (caab / caab-db / static / server)
32
+ # → Enter app name
33
+ # → Auto: scaffolds files, git init, registers with Bodify, bun install
34
+
35
+ # 2. Deploy
36
+ bod deploy
37
+
38
+ # 3. Monitor
39
+ bod logs my-api -f
40
+ bod apps status my-api
41
+ ```
42
+
43
+ ## End-to-End: Existing Project
44
+
45
+ ```bash
46
+ cd my-existing-project
47
+ bod init
48
+ # → Auto-detects type (api.ts=caab, dist/=static, server.ts=server, packages/=mixed)
49
+ # → Creates bodify.yaml, registers with Bodify, sets up .claude/ config
50
+
51
+ bod deploy
52
+ ```
53
+
54
+ ## Command Reference
55
+
56
+ ### `bod login <url>`
57
+ Authenticate with a Bodify instance.
58
+
59
+ ```bash
60
+ bod login https://bodify.example.com # prompts for API key
61
+ bod login https://bodify.example.com --key=$KEY # non-interactive
62
+ bod login https://bodify.example.com --name=prod # custom alias
63
+ ```
64
+
65
+ Verifies connectivity (`/healthz`), fetches capabilities (`/config/public`), saves to config.
66
+
67
+ ### `bod init`
68
+ Initialize or connect a project to Bodify.
69
+
70
+ **Empty directory:** prompts for template, scaffolds complete project:
71
+ - Source files (api.ts / App.tsx / server.ts)
72
+ - `package.json`, `tsconfig.json`, `bodify.yaml`
73
+ - `.claude/CLAUDE.md` — project context for Claude agents
74
+ - `.claude/mcp_servers.json` — MCP connection to Bodify
75
+ - `.gitignore`, git init + initial commit
76
+ - Registers app with Bodify API
77
+ - `.npmrc` if registry enabled
78
+ - `bun install`
79
+
80
+ **Existing directory:** detects app type, creates `bodify.yaml`, registers, generates `.claude/` config.
81
+
82
+ ### `bod deploy [app] [--branch=...]`
83
+ Trigger deployment. Reads app name from positional arg or `bodify.yaml`. Auto-detects current git branch.
84
+
85
+ ```bash
86
+ bod deploy # from project dir with bodify.yaml
87
+ bod deploy my-api # explicit app name
88
+ bod deploy my-api --branch=lab # specific branch
89
+ ```
90
+
91
+ **Two deploy modes** (auto-detected):
92
+ - **Git-based**: if the app has a `repo` URL, Bodify clones from git (standard flow)
93
+ - **Upload-based**: if no repo URL, the CLI tars the local working directory and uploads it directly — no git remote needed
94
+
95
+ Polls for completion (up to 4 min), shows status updates.
96
+
97
+ ### `bod rollback [app] [--branch=...]`
98
+ Rollback to previous deployment.
99
+
100
+ ```bash
101
+ bod rollback my-api
102
+ bod rollback my-api --branch=lab
103
+ ```
104
+
105
+ ### `bod apps list`
106
+ List all registered apps with name, domain, branch, type, repo.
107
+
108
+ ### `bod apps status <app>`
109
+ Detailed view: app config, running instances, recent deployments.
110
+
111
+ ### `bod logs <app> [-f] [--lines=100]`
112
+ View application logs.
113
+
114
+ ```bash
115
+ bod logs my-api # last 100 lines
116
+ bod logs my-api --lines=500 # more lines
117
+ bod logs my-api -f # follow mode (polls every 2s)
118
+ ```
119
+
120
+ ### `bod open <app>`
121
+ Open an app in the default browser. Resolves the URL from the app's domain.
122
+
123
+ ```bash
124
+ bod open my-api # opens https://my-api.bodify.example.com
125
+ ```
126
+
127
+ ### `bod env list|set|unset <app>`
128
+ Manage environment variables.
129
+
130
+ ```bash
131
+ bod env list my-api
132
+ bod env set my-api DATABASE_URL=postgres://...
133
+ bod env set my-api -f .env # bulk set from .env file
134
+ bod env unset my-api OLD_VAR
135
+ ```
136
+
137
+ ### `bod add <pkg>` / `bod remove <pkg>`
138
+ Registry-aware package management. If Bodify registry is enabled, `bun add` uses it automatically.
139
+
140
+ ```bash
141
+ bod add @bod.ee/db # from Bodify registry
142
+ bod add lodash # falls through to npm
143
+ bod remove @bod.ee/db
144
+ ```
145
+
146
+ ## Multi-Instance Support
147
+
148
+ ```bash
149
+ # Add another instance
150
+ bod login https://staging.example.com --name=staging
151
+
152
+ # Use specific instance for a command
153
+ bod apps list --instance=staging
154
+
155
+ # Or via env var
156
+ BOD_INSTANCE=staging bod apps list
157
+ ```
158
+
159
+ ## Templates
160
+
161
+ | Template | Files | Use Case |
162
+ |----------|-------|----------|
163
+ | `caab` | `api.ts` with Resource convention | REST API, methods → endpoints |
164
+ | `caab-db` | `api.ts` + BodDB setup | API with embedded database |
165
+ | `static` | React + Vite + `vite.config.ts` | SPA, served from `dist/` |
166
+ | `server` | `server.ts` with `Bun.serve()` | Custom HTTP server |
167
+
168
+ ### CaaB Templates Use Resource Convention
169
+
170
+ ```typescript
171
+ abstract class Resource {
172
+ static readonly [Symbol.for('bodify.Resource')] = true;
173
+ }
174
+
175
+ class Items extends Resource {
176
+ async get() { ... } // GET /items
177
+ async getById(id: string) { ... } // GET /items/by-id/:id
178
+ async post(body: {...}) { ... } // POST /items
179
+ async delete(id: string) { ... } // DELETE /items/:id
180
+ }
181
+
182
+ export default class Api extends Resource {
183
+ items = new Items();
184
+ async getHealthz() { ... } // GET /healthz
185
+ }
186
+ ```
187
+
188
+ ### Server Template Requirements
189
+
190
+ - Read `PORT` from `process.env.PORT`
191
+ - Expose `GET /healthz` returning JSON
192
+ - Bodify health-checks this endpoint
193
+
194
+ ## AI-First: Generated `.claude/` Config
195
+
196
+ `bod init` generates two files for Claude Code integration:
197
+
198
+ **`.claude/CLAUDE.md`** — Project context with:
199
+ - Commands cheat sheet
200
+ - CaaB convention reference (for caab/caab-db templates)
201
+ - BodDB API reference (for database-enabled apps)
202
+ - Server requirements (for server template)
203
+ - MCP integration note
204
+
205
+ **`.claude/mcp_servers.json`** — MCP connection using `${BODIFY_API_KEY}` env var reference (not hardcoded keys). Users set the env var and Claude Code can manage the app via MCP tools.
206
+
207
+ ## Config File
208
+
209
+ `~/.bod/config.json`:
210
+ ```json
211
+ {
212
+ "instances": {
213
+ "my-server": {
214
+ "url": "https://bodify.example.com",
215
+ "apiKey": "$BODIFY_KEY",
216
+ "capabilities": {
217
+ "registryEnabled": true,
218
+ "baseDomain": "bodify.example.com",
219
+ "githubConfigured": true
220
+ }
221
+ }
222
+ },
223
+ "defaultInstance": "my-server"
224
+ }
225
+ ```
226
+
227
+ API key supports env var references: `$VAR_NAME` or `env:VAR_NAME`.
228
+
229
+ ## Common Agent Tasks
230
+
231
+ ### "Set up a new CaaB API"
232
+ ```bash
233
+ mkdir my-api && cd my-api
234
+ bod init # select caab or caab-db
235
+ # Edit api.ts to add your resources
236
+ bod deploy
237
+ ```
238
+
239
+ ### "Deploy a specific branch"
240
+ ```bash
241
+ bod deploy my-app --branch=feature-xyz
242
+ ```
243
+
244
+ ### "Deploy without a git remote"
245
+ ```bash
246
+ # Works from any local project — tars and uploads source directly
247
+ bod init # register app (no git remote needed)
248
+ bod deploy # auto-detects no repo, uploads tarball
249
+ ```
250
+
251
+ ### "Debug a failing deployment"
252
+ ```bash
253
+ bod apps status my-app # check deployment status
254
+ bod logs my-app -f # check logs
255
+ ```
256
+
257
+ ### "Add an env var and redeploy"
258
+ ```bash
259
+ bod env set my-app API_SECRET=xxx
260
+ bod deploy my-app
261
+ ```
262
+
263
+ ### "Bulk set env vars from .env file"
264
+ ```bash
265
+ bod env set my-app -f .env
266
+ bod deploy my-app
267
+ ```
268
+
269
+ ### "Connect an existing project"
270
+ ```bash
271
+ cd existing-project
272
+ bod init # auto-detects type, registers with Bodify
273
+ bod deploy
274
+ ```
@@ -0,0 +1,54 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ publish-npm:
10
+ if: "!contains(github.event.head_commit.message, '[skip ci]')"
11
+ runs-on: ubuntu-latest
12
+ permissions:
13
+ contents: write
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0
19
+
20
+ - uses: actions/setup-node@v4
21
+ with:
22
+ node-version: '20'
23
+ registry-url: 'https://registry.npmjs.org/'
24
+
25
+ - uses: oven-sh/setup-bun@v1
26
+
27
+ - name: Install dependencies
28
+ run: bun install --frozen-lockfile
29
+
30
+ - name: Build
31
+ run: bun run build
32
+
33
+ - name: Configure Git
34
+ run: |
35
+ git config user.name "GitHub Actions Bot"
36
+ git config user.email "actions@github.com"
37
+
38
+ - name: Bump version and commit
39
+ run: |
40
+ npm version patch --no-git-tag-version
41
+ VERSION=$(node -p "require('./package.json').version")
42
+ git add package.json
43
+ git commit -m "chore: release v${VERSION} [skip ci]"
44
+
45
+ - name: Publish to npm
46
+ run: npm publish --access public
47
+ env:
48
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
49
+
50
+ - name: Push tag
51
+ run: |
52
+ VERSION=$(node -p "require('./package.json').version")
53
+ git tag "v${VERSION}"
54
+ git push --follow-tags
package/CLAUDE.md ADDED
@@ -0,0 +1,50 @@
1
+ # bod-cli
2
+
3
+ Unified CLI for the Bod product family. Currently supports Bodify (self-hosted Vercel alternative).
4
+
5
+ ## Skill Path
6
+
7
+ See `.cursor/skills/using-bod-cli/SKILL.md` — full command reference, templates, AI integration, common tasks.
8
+
9
+ ## Quick Reference
10
+
11
+ - Runtime: Bun
12
+ - Framework: citty (defineCommand/runMain)
13
+ - Config: `~/.bod/config.json` (Zod-validated, multi-instance)
14
+ - Interactive prompts: @inquirer/prompts
15
+
16
+ ## Architecture
17
+
18
+ ```
19
+ src/
20
+ ├── cli.ts # citty entry + interactive menu
21
+ ├── config.ts # ~/.bod/config.json management
22
+ ├── client.ts # HTTP client (auth, JSON, errors)
23
+ ├── utils/
24
+ │ ├── logger.ts # component logger
25
+ │ ├── output.ts # printTable, printJson, printKv
26
+ │ └── resolve.ts # resolveAppId, readAppNameFromYaml
27
+ └── commands/
28
+ ├── login.ts # bod login <url>
29
+ ├── init/ # bod init (scaffold or connect)
30
+ │ ├── init.ts
31
+ │ └── templates.ts
32
+ ├── deploy.ts # bod deploy [app]
33
+ ├── rollback.ts # bod rollback [app]
34
+ ├── apps.ts # bod apps list|status
35
+ ├── logs.ts # bod logs <app> [-f]
36
+ ├── env.ts # bod env list|set|unset (set supports -f .env)
37
+ ├── open.ts # bod open <app>
38
+ ├── add.ts # bod add <pkg>
39
+ └── remove.ts # bod remove <pkg>
40
+ ```
41
+
42
+ ## Key Patterns
43
+
44
+ - Config supports env var references: `$VAR` or `env:VAR`
45
+ - Client auto-adds Bearer auth from config
46
+ - Commands use citty `defineCommand` with `args` and `run`
47
+ - First-run redirects to `bod login`
48
+ - Global `--instance` flag / `BOD_INSTANCE` env var for multi-instance
49
+ - `resolveAppId` in `utils/resolve.ts` — shared name→ID lookup
50
+ - Templates use proper CaaB Resource convention from bodify scaffolding docs