@autofleet/cli 2.23.0 → 2.25.0

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.
@@ -9,7 +9,9 @@ TBD (Future: Jira, GitHub, Figma with automated API key setup)
9
9
 
10
10
  ### Skills
11
11
  - **db-modeling** - Database schema understanding and Sequelize model guidance
12
+ - **dev-workflow** - Autofleet development workflows: sim/staging deployments, debugging, architecture overview
12
13
  - **js-ts-standards** - JavaScript/TypeScript coding standards and best practices
14
+ - **node-test-runner** - Run Jest tests locally with Docker dependencies and test DB setup
13
15
  - **pr-standards** - Pull request description templates and conventions
14
16
  - **python-standards** - Python coding standards for Autofleet projects
15
17
 
@@ -20,28 +22,33 @@ TBD (Future: Jira, GitHub, Figma with automated API key setup)
20
22
 
21
23
  ## Installation
22
24
 
23
- ### From Git (Recommended)
25
+ The plugin is installed automatically when you install or update `@autofleet/cli`:
24
26
 
25
27
  ```bash
26
- # Add marketplace from Git
27
- claude plugin marketplace add https://github.com/Autofleet/autorepo.git#packages/claude-marketplace
28
+ npm install -g @autofleet/cli
29
+ ```
30
+
31
+ The `postinstall` hook runs `autofleet claudeInit`, which registers the marketplace and installs/updates the plugin automatically.
32
+
33
+ ### Manual Installation
28
34
 
29
- # Install the plugin
30
- claude plugin install autofleet@Autofleet
35
+ If needed, you can run the setup manually:
36
+
37
+ ```bash
38
+ autofleet claudeInit
31
39
  ```
32
40
 
33
41
  ### From Local Path (Development)
34
42
 
35
- If you have the monorepo cloned locally:
43
+ If you want to work on the marketplace locally without rebuilding the CLI, symlink the dist directory to the source:
36
44
 
37
45
  ```bash
38
- # Add marketplace from local path
39
- claude plugin marketplace add file:///path/to/autorepo/packages/claude-marketplace
40
-
41
- # Install the plugin
42
- claude plugin install autofleet@Autofleet
46
+ ln -sf ~/work/autorepo/packages/cli/bin/commands/base/claude-init/claude-marketplace \
47
+ $(npm root -g)/@autofleet/cli/dist/claude-marketplace
43
48
  ```
44
49
 
50
+ Then run `autofleet claudeInit` to pick up the changes.
51
+
45
52
  ## Verification
46
53
 
47
54
  After installation, verify the setup:
@@ -49,54 +56,61 @@ After installation, verify the setup:
49
56
  ```bash
50
57
  # List installed marketplaces
51
58
  claude plugin marketplace list
52
- # Should show "Autofleet"
59
+ # Should show "autofleet"
53
60
 
54
61
  # List installed plugins
55
62
  claude plugin list
56
- # Should show "autofleet@Autofleet"
63
+ # Should show "autofleet@autofleet"
57
64
  ```
58
65
 
59
- Restart Claude Code to activate the MCP servers and skills.
66
+ Restart Claude Code to activate the skills.
60
67
 
61
68
  ## Usage
62
69
 
63
-
64
- ### Skills
65
-
66
70
  Skills are automatically available when relevant:
71
+ - **dev-workflow** - Activated when discussing deployments, debugging, or architecture
67
72
  - **js-ts-standards** - Applied during code writing and review
73
+ - **node-test-runner** - Activated when running tests on a Node.js microservice locally
68
74
  - **python-standards** - Applied when working with Python code
69
75
  - **db-modeling** - Activated when discussing database schemas or models
70
76
  - **pr-standards** - Enforced when creating pull requests
71
77
 
72
78
  ## Updating
73
79
 
74
- To update to the latest version:
80
+ Users receive plugin updates automatically when they update the CLI:
75
81
 
76
82
  ```bash
77
- claude plugin update autofleet@Autofleet
83
+ npm install -g @autofleet/cli
78
84
  ```
79
85
 
86
+ The `postinstall` hook bumps the plugin version and reinstalls it on every CLI update.
87
+
80
88
  ## Development
81
89
 
82
90
  ### Structure
83
91
 
84
92
  ```
85
- packages/claude-marketplace/
86
- ├── index.json # Marketplace plugin list
93
+ packages/cli/bin/commands/base/claude-init/claude-marketplace/
87
94
  ├── plugins/
88
95
  │ └── autofleet/
89
96
  │ ├── .claude-plugin/
90
- │ │ └── plugin.json # Plugin metadata
97
+ │ │ └── plugin.json # Plugin metadata + version
91
98
  │ └── skills/
92
- │ ├── code-quality/SKILL.md
93
- └── pr-standards/SKILL.md
99
+ │ ├── code-review/SKILL.md
100
+ ├── db-modeling/SKILL.md
101
+ │ ├── dev-workflow/SKILL.md
102
+ │ ├── js-ts-standarts/SKILL.md
103
+ │ ├── node-test-runner/SKILL.md
104
+ │ ├── pr-standards/SKILL.md
105
+ │ └── python-standards/SKILL.md
94
106
  └── README.md
95
107
  ```
96
108
 
97
109
  ### Publishing Changes
98
110
 
99
- 1. Make changes to plugin files
111
+ 1. Add or edit skill files under `plugins/autofleet/skills/`
100
112
  2. Commit and push to the monorepo
101
- 3. Team members run `claude plugin update autofleet@Autofleet` to update
102
- (Note: Considering adding postinstall hook to CLI for automatic updates)
113
+ 3. Bump the CLI version (`packages/cli/package.json`) and publish
114
+ 4. Users get the update automatically on their next `npm install -g @autofleet/cli`
115
+
116
+ > **Note:** `plugin.json` version is managed automatically by `claudeInit` — do not bump it manually.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "autofleet",
3
3
  "description": "Autofleet company standards, MCP servers, and development skills",
4
- "version": "1.0.19",
4
+ "version": "1.0.20",
5
5
  "author": {
6
6
  "name": "Autofleet",
7
7
  "email": "emil@autofleet.io"
@@ -0,0 +1,136 @@
1
+ ---
2
+ name: add-endpoint
3
+ description: Guides adding a new API endpoint in an Autofleet microservice — REST
4
+ conventions, HTTP method selection, response codes, validation layers, pagination,
5
+ and registering the endpoint in the API gateway. Use when the user wants to add
6
+ a new route, register an endpoint, design a REST API, or understand Autofleet API
7
+ standards.
8
+ version: 1.0.0
9
+ userInvocable: true
10
+ ---
11
+
12
+ # Adding a New Endpoint
13
+
14
+ ## Gateway Rule
15
+
16
+ Register an endpoint in the API gateway **only if** it is called from a frontend or an external client. Endpoints called only between microservices (server-to-server) bypass the gateway and do not need to be registered.
17
+
18
+ ---
19
+
20
+ ## Step 1 — Implement the endpoint in the microservice
21
+
22
+ ### Path Format
23
+
24
+ `/api/v{n}/{resource-name}` — kebab-case, plural nouns
25
+
26
+ Examples: `/api/v1/vehicle-assignments`, `/api/v2/fleet-operators/:id/settings`
27
+
28
+ ### HTTP Method Selection
29
+
30
+ | Method | When to use |
31
+ |--------|-------------|
32
+ | GET | Retrieval; use PUT if request body is too large for query params |
33
+ | POST | Non-idempotent creation or actions |
34
+ | PUT | Idempotent create-or-replace |
35
+ | PATCH | Partial updates |
36
+ | DELETE | Removal |
37
+
38
+ ### Response Codes
39
+
40
+ | Code | When |
41
+ |------|------|
42
+ | 200 | Success with body |
43
+ | 204 | Success with no body (DELETE) |
44
+ | 400 | Validation error |
45
+ | 403 | Forbidden (missing permission) |
46
+ | 404 | Resource not found |
47
+ | 500 | Unexpected server error |
48
+
49
+ > 401 and 429 are handled by the gateway — do not return them from microservices.
50
+
51
+ ### Response Body Rules
52
+
53
+ - All field names: **camelCase**
54
+ - Never return a raw array — wrap in `{ items: [...] }`
55
+ - Serialize explicitly — never return a raw DB model instance
56
+ - Error format: `{ "errors": ["message"] }`
57
+
58
+ ### Pagination
59
+
60
+ When returning lists, support `page` + `pageSize` query params (max 100). See **examples.md → Pagination Response** for the response shape.
61
+
62
+ ### Validation Layers (in order)
63
+
64
+ 1. **Syntax** — framework-level (JSON parse, content-type)
65
+ 2. **Schema** — validate shape and types (Joi/Zod)
66
+ 3. **Business logic** — domain rules in the service layer
67
+
68
+ See the [REST APIs at Autofleet](https://www.notion.so/autofleet/REST-APIs-at-Autofleet) Notion guide for full examples.
69
+
70
+ ### Error Handling with `@autofleet/errors`
71
+
72
+ Use the shared error classes instead of throwing plain errors or manually setting status codes.
73
+
74
+ ```typescript
75
+ import {
76
+ BadRequest,
77
+ ResourceNotFoundError,
78
+ UnauthorizedError,
79
+ UnexpectedError,
80
+ handleError, // Express
81
+ handleErrorFastify, // Fastify — register as a plugin
82
+ } from '@autofleet/errors';
83
+ ```
84
+
85
+ **Error classes and their HTTP status codes:**
86
+
87
+ | Class | Status | When to use |
88
+ |-------|--------|-------------|
89
+ | `BadRequest` | 400 | Validation / schema errors |
90
+ | `UnauthorizedError` | 403* | Missing or insufficient permissions |
91
+ | `ResourceNotFoundError` | 404 | Entity not found |
92
+ | `UnexpectedError` | 500 | Unexpected/unhandled errors |
93
+ | `ServiceUnavailableError` | 503 | Downstream dependency unavailable |
94
+ | `DatabaseLockedEntityError` | 423 | Optimistic lock conflict |
95
+
96
+ > *`UnauthorizedError` defaults to 403 for backwards compatibility. Pass `{ useForbiddenStatusCode: false }` to get 401.
97
+
98
+ See **examples.md → Error Handling** for Express and Fastify usage patterns.
99
+
100
+ ---
101
+
102
+ ## Step 2 — Register it in api-gateway-ms (if needed)
103
+
104
+ **Only required if** the endpoint will be called from a frontend or an external client. Server-to-server calls between microservices bypass the gateway entirely — skip this step.
105
+
106
+ Add/edit the service's config file at:
107
+ ```
108
+ api-gateway-ms/src/config/server-api/apis/<service-name>.json
109
+ ```
110
+
111
+ See **examples.md → API Gateway Registration** for the JSON format.
112
+
113
+ ### Permission values
114
+
115
+ | Value | Who can call |
116
+ |-------|-------------|
117
+ | `"public"` | No auth required |
118
+ | `"*"` or `"authenticated"` | Any logged-in user |
119
+ | `"resource:action"` | Specific permission (e.g. `"vehicle:write"`) |
120
+ | `"admin"` | Admin users only |
121
+
122
+ ---
123
+
124
+ ## Common Issues
125
+
126
+ ### 401 returned from microservice
127
+ The gateway handles authentication — microservices should return 403 (forbidden) or 404, not 401.
128
+
129
+ ### Endpoint works locally but returns 404 in simulation
130
+ The endpoint is not registered in `api-gateway-ms`. Add it to the service's JSON config and deploy api-gateway-ms.
131
+
132
+ ### Raw array returned instead of `{ items }`
133
+ Clients break when the shape changes from object to array. Always wrap: `{ items: result }`.
134
+
135
+ ### Throwing plain `new Error()` instead of `@autofleet/errors` classes
136
+ Plain errors are caught by `handleError` but always produce a 500. Use the specific class so the correct status code is returned automatically.
@@ -0,0 +1,77 @@
1
+ # Add Endpoint Examples
2
+
3
+ ## API Gateway Registration
4
+
5
+ Config file: `api-gateway-ms/src/config/server-api/apis/<service-name>.json`
6
+
7
+ ```json
8
+ {
9
+ "endpoints": [
10
+ {
11
+ "path": "/api/v1/my-resource/:id",
12
+ "methods": {
13
+ "get": {
14
+ "requestedPermissions": ["public"]
15
+ },
16
+ "post": {
17
+ "requestedPermissions": ["my-resource:write"],
18
+ "qps": 100,
19
+ "qpm": 1000
20
+ }
21
+ }
22
+ }
23
+ ]
24
+ }
25
+ ```
26
+
27
+ ## Pagination Response
28
+
29
+ ```json
30
+ {
31
+ "page": 1,
32
+ "pageSize": 20,
33
+ "total": 150,
34
+ "items": []
35
+ }
36
+ ```
37
+
38
+ ## Error Handling — Express
39
+
40
+ ```typescript
41
+ import { BadRequest, ResourceNotFoundError, handleError } from '@autofleet/errors';
42
+
43
+ router.get('/vehicles/:id', async (req, res) => {
44
+ try {
45
+ const vehicle = await vehicleService.findById(req.params.id);
46
+ if (!vehicle) throw new ResourceNotFoundError('Vehicle not found');
47
+ res.json(vehicle);
48
+ } catch (err) {
49
+ handleError(err, res, { logger, message: 'GET /vehicles/:id failed' });
50
+ }
51
+ });
52
+
53
+ // BadRequest takes an array of Error objects
54
+ throw new BadRequest([new Error('vehicleId is required')]);
55
+ ```
56
+
57
+ ## Error Handling — Fastify
58
+
59
+ ```typescript
60
+ import { handleErrorFastify, ResourceNotFoundError } from '@autofleet/errors';
61
+
62
+ // Register once at app startup
63
+ fastify.register(handleErrorFastify);
64
+
65
+ // Then throw anywhere — the plugin handles status codes and response shape
66
+ fastify.get('/vehicles/:id', async (request) => {
67
+ const vehicle = await vehicleService.findById(request.params.id);
68
+ if (!vehicle) throw new ResourceNotFoundError('Vehicle not found');
69
+ return vehicle;
70
+ });
71
+ ```
72
+
73
+ ## Error Response Shape
74
+
75
+ ```json
76
+ { "status": "ERROR", "errors": ["Vehicle not found"] }
77
+ ```
@@ -0,0 +1,208 @@
1
+ ---
2
+ name: dev-workflow
3
+ description: >-
4
+ Guides Autofleet development workflows — deploying to simulation/staging,
5
+ running services locally against simulation, debugging with GCP logs and mirrord,
6
+ adding API endpoints, and orchestrating E2E testing cycles. Use when the git
7
+ remote contains `github.com/Autofleet/`, the package.json name starts with
8
+ `@autofleet/`, or the directory ends in `-ms` — load at session start without
9
+ waiting for the user to ask.
10
+ version: 1.0.0
11
+ userInvocable: true
12
+ ---
13
+
14
+ # Autofleet Development Workflow
15
+
16
+ ## Environment Types
17
+
18
+ This skill covers simulation and staging only. **Never touch production.**
19
+
20
+ | Name | Cluster Keys | Purpose |
21
+ |------|-------------|---------|
22
+ | **Simulation (dev)** | `expManager` (default), `dev1`, `e2eManager` | Personal dev sandbox, isolated per variation |
23
+ | **Staging** | `staging`, `loadTest` | Shared pre-production environment |
24
+
25
+ **Default simulation cluster is `expManager`** — use `dev1` or `e2eManager` only when explicitly required.
26
+
27
+ Each simulation environment is isolated by a `variationId` (UUID). This becomes the Kubernetes namespace, database name suffix, and password component.
28
+
29
+ **Default test account on simulation:**
30
+ - Email: `tester@autofleet.io`
31
+ - Password: `123456`
32
+
33
+ ---
34
+
35
+ ## Architecture Overview
36
+
37
+ ```
38
+ Frontends: Control Center · Ordering · Web-Booker · Partner-Admin (React, Vite)
39
+ ↓ all /api/v1/* and /api/v2/* calls
40
+ API Gateway MS (Express, port 8085)
41
+ - Adds x-trace-id to every request
42
+ - Authenticates via JWT (@autofleet/zehut)
43
+ - Rate limits, permission checks
44
+ - Proxies to target microservice
45
+
46
+ Individual Microservices (TypeScript/Node.js)
47
+
48
+ PostgreSQL / Redis / RabbitMQ
49
+ ```
50
+
51
+ ### Key repos
52
+ - **api-gateway-ms** — entry point for all API traffic
53
+ - **control-center** — React frontend (main)
54
+ - **cli** — `@autofleet/cli` package inside `autorepo`; the `autofleet` command for cluster ops, proxying, deployments
55
+
56
+ ---
57
+
58
+ ## Adding a New Endpoint
59
+
60
+ For full REST conventions, HTTP method selection, response codes, validation layers, and gateway registration details, use the **`add-endpoint` skill**.
61
+
62
+ **Quick reference:**
63
+ - Path: `/api/v{n}/{resource-name}` — kebab-case, plural nouns
64
+ - Endpoints called from frontends or external clients → must be registered in api-gateway-ms
65
+ - Endpoints called only between microservices → no gateway registration needed
66
+ - Config file: `api-gateway-ms/src/config/server-api/apis/<service-name>.json`
67
+
68
+ ---
69
+
70
+ ## Development Workflows
71
+
72
+ See **examples.md → Development Workflow Commands** for full bash commands.
73
+
74
+ ### Option A: Run service locally, wire to simulation
75
+
76
+ Best for active backend development with hot reload. Steps: forward the sim DB, run the service locally, optionally intercept traffic via mirrord.
77
+
78
+ ### Option B: Deploy service to simulation, run a frontend locally
79
+
80
+ Best for frontend development. Steps: `autofleet updateExp` to deploy the service, then wire the frontend to the sim gateway.
81
+
82
+ - **Control Center:** `autofleet localDev` handles the wiring automatically, then `pnpm start control-center`
83
+ - **Other frontends (ordering, web-booker, partner-admin):** set env vars manually — see the **`frontend-dev` skill** for per-app instructions
84
+
85
+ ### Useful cluster operations
86
+
87
+ Use `autofleet switchCluster`, `forwardService`, `getIps`, and `dockerInit` for common cluster tasks. See examples.md for commands.
88
+
89
+ ---
90
+
91
+ ## Debugging
92
+
93
+ ### Tracing requests with x-trace-id
94
+
95
+ Every request through the API gateway gets a unique `x-trace-id` header:
96
+ - Generated by `shortid` in api-gateway-ms
97
+ - Forwarded to all downstream microservices in the proxy headers
98
+ - Included in error responses returned to the client
99
+ - Logged alongside all service-level logs in GCP
100
+
101
+ **When debugging network issues:**
102
+ 1. Use browser automation (Chrome) to test directly in the browser — click buttons, check checkbox state, trigger requests
103
+ 2. In Chrome DevTools → Network, find the failing request and check:
104
+ - The `x-trace-id` response header (to query GCP logs)
105
+ - The response payload (often contains a specific error message pointing to root cause)
106
+ 3. Replay the request with curl or intercept the auth token via the browser console — see **examples.md → Debugging**
107
+ 4. Query GCP logs filtering by that trace ID — see **examples.md → Querying GCP logs**
108
+
109
+ ### GCP project names by cluster
110
+ - `dev1` → `dev1-experiment-manager`
111
+ - `expManager` → `af-experiment-manager`
112
+ - `e2eManager` → `e2e-project-1`
113
+ - `staging` → `autofleet-staging`
114
+
115
+ ### Mirrord debugging (intercept live traffic locally)
116
+
117
+ `mirrord` lets you run a service locally while it intercepts real traffic from the simulation cluster — no full deploy needed. It disables liveness/readiness probes on the running pod and restores them on exit (Ctrl+C). See **examples.md → Mirrord** for commands.
118
+
119
+ ### DB access
120
+
121
+ Use `autofleet forwardDb` to port-forward PostgreSQL to localhost:5432. Credentials follow the pattern `postgres / afpass_<variationId>`, DB name is `<service>_<variationId>` (hyphens → underscores). See **examples.md → DB access**.
122
+
123
+ ---
124
+
125
+ ## Frontend Development
126
+
127
+ All four Autofleet frontends (control-center, ordering, web-booker, partner-admin) share: React + Vite + TypeScript, dev server on port 3000, and proxy `/api` traffic to the API gateway.
128
+
129
+ For full frontend wiring instructions, per-app setup, and common issues, use the **`frontend-dev` skill**.
130
+
131
+ **Quick reference:** Option B in Development Workflows above uses `autofleet localDev` which is Control Center specific. For other frontends, set the gateway env var manually (see `frontend-dev` skill).
132
+
133
+ ---
134
+
135
+ ## Common Patterns
136
+
137
+ ### Error correlation flow
138
+ 1. User reports error in UI
139
+ 2. Open browser DevTools → Network → find failing request
140
+ 3. Copy x-trace-id from response headers
141
+ 4. Query GCP logs with that trace ID to find root cause across services
142
+
143
+ ### NPM packages
144
+
145
+ Autofleet uses private `@autofleet/*` npm packages. Two things are required:
146
+
147
+ **1. `NPM_TOKEN` env var** — needed for Docker builds (`updateExp`). If not set, the build will fail with a 401/404 on `@autofleet/*` packages. Always check this is set before running `autofleet updateExp`. See **examples.md → NPM Token Setup** for how to find and export the token.
148
+
149
+ **2. npm install locally** — the token might be in `~/.npmrc` (used automatically) or may need to be set. If you get a 404 on `@autofleet/*` during local install, ask the user to check their token or run `npm login`.
150
+
151
+ ---
152
+
153
+ ## Common Issues
154
+
155
+ ### mirrord exits unexpectedly
156
+ Liveness probes are restored on Ctrl+C; if killed abruptly, run `autofleet mirrordConfig` to check state.
157
+
158
+ ### npm audit fix breaks build
159
+ Only use `--force` if the user explicitly approves — it may introduce breaking changes.
160
+
161
+ ### `@autofleet/*` package 401/404 during Docker build
162
+ `NPM_TOKEN` is not set — see NPM packages section above and **examples.md → NPM Token Setup**.
163
+
164
+ ### Frontend can't reach backend
165
+ See the **`frontend-dev` skill** → Common Issues.
166
+
167
+ ---
168
+
169
+ ## npm audit fix
170
+
171
+ Before any of the following, ask the user if they'd like to run `npm audit fix` on the affected services:
172
+ - Running unit tests
173
+ - Deploying to simulation/staging
174
+ - Opening or merging a PR
175
+
176
+ > "Would you like to run `npm audit fix` on the changed services first? It fixes known dependency vulnerabilities — better to catch these now than have them flagged during QA or code review."
177
+
178
+ Only use `--force` if the user explicitly approves — it may introduce breaking changes.
179
+
180
+ ---
181
+
182
+ ## End-of-Session Testing Flow
183
+
184
+ After finishing a coding session, **always ask the user how they want to test** before proceeding. Summarize what was changed so they can make an informed choice.
185
+
186
+ ### Step 1 — Summarize what was changed
187
+
188
+ Before asking, present a brief summary:
189
+ - Which services were modified (e.g. `automation-ms`, `api-gateway-ms`)
190
+ - Whether any frontend was changed
191
+ - What the change does and what flow needs to be verified
192
+
193
+ ### Step 2 — Ask the user which testing mode they prefer
194
+
195
+ Present the four options (see **examples.md → End-of-Session Testing Options** for commands):
196
+
197
+ - **Option A** — Deploy changed backend services to simulation, run a frontend locally. Best when backend changes are the main thing to verify.
198
+ - **Option B** — Run everything locally, wire to simulation DB/infra. Best when iterating on both frontend and backend simultaneously.
199
+ - **Option C** — Run frontend locally, backend in simulation if needed. Best when only frontend was changed.
200
+ - **Option D** — Deploy everything to simulation. Best for full integration test or handing off to QA.
201
+
202
+ ### Step 3 — Confirm what to verify
203
+
204
+ After the user picks a mode, remind them what to test based on the changes made:
205
+ - Navigate to the relevant page
206
+ - Perform the action that triggers the new/changed behavior
207
+ - Check browser DevTools for the new API call and verify the response
208
+ - If something fails, grab the `x-trace-id` from the response and query GCP logs