@newpeak/barista-cli 0.1.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.
Files changed (82) hide show
  1. package/.eslintrc.json +23 -0
  2. package/.prettierrc +9 -0
  3. package/.sisyphus/notepads/liberica-employees/learnings.md +73 -0
  4. package/AGENTS.md +270 -0
  5. package/CONTRIBUTING.md +291 -0
  6. package/README.md +707 -0
  7. package/bin/barista +6 -0
  8. package/bin/barista.js +3 -0
  9. package/docs/ARCHITECTURE.md +184 -0
  10. package/docs/COMMANDS.md +352 -0
  11. package/docs/COMMAND_DESIGN_SPEC.md +811 -0
  12. package/docs/INTEGRATION_NOTES.md +270 -0
  13. package/docs/commands/REFERENCE.md +297 -0
  14. package/docs/commands/arabica/auth/index.md +296 -0
  15. package/docs/commands/liberica/auth/index.md +133 -0
  16. package/docs/commands/liberica/context/index.md +60 -0
  17. package/docs/commands/liberica/employees/create.md +185 -0
  18. package/docs/commands/liberica/employees/disable.md +138 -0
  19. package/docs/commands/liberica/employees/enable.md +137 -0
  20. package/docs/commands/liberica/employees/get.md +153 -0
  21. package/docs/commands/liberica/employees/list.md +168 -0
  22. package/docs/commands/liberica/employees/update.md +180 -0
  23. package/docs/commands/liberica/orgs/list.md +62 -0
  24. package/docs/commands/liberica/positions/list.md +61 -0
  25. package/docs/commands/liberica/roles/list.md +67 -0
  26. package/docs/commands/liberica/users/create.md +170 -0
  27. package/docs/commands/liberica/users/get.md +151 -0
  28. package/docs/commands/liberica/users/list.md +175 -0
  29. package/package.json +37 -0
  30. package/src/commands/arabica/auth/index.ts +277 -0
  31. package/src/commands/arabica/auth/login.ts +5 -0
  32. package/src/commands/arabica/auth/logout.ts +5 -0
  33. package/src/commands/arabica/auth/register.ts +5 -0
  34. package/src/commands/arabica/auth/status.ts +5 -0
  35. package/src/commands/arabica/index.ts +23 -0
  36. package/src/commands/auth.ts +107 -0
  37. package/src/commands/context.ts +60 -0
  38. package/src/commands/liberica/auth/index.ts +170 -0
  39. package/src/commands/liberica/context/index.ts +43 -0
  40. package/src/commands/liberica/employees/create.ts +275 -0
  41. package/src/commands/liberica/employees/delete.ts +122 -0
  42. package/src/commands/liberica/employees/disable.ts +97 -0
  43. package/src/commands/liberica/employees/enable.ts +97 -0
  44. package/src/commands/liberica/employees/get.ts +115 -0
  45. package/src/commands/liberica/employees/index.ts +23 -0
  46. package/src/commands/liberica/employees/list.ts +131 -0
  47. package/src/commands/liberica/employees/update.ts +157 -0
  48. package/src/commands/liberica/index.ts +36 -0
  49. package/src/commands/liberica/orgs/index.ts +35 -0
  50. package/src/commands/liberica/positions/index.ts +30 -0
  51. package/src/commands/liberica/roles/index.ts +59 -0
  52. package/src/commands/liberica/users/create.ts +132 -0
  53. package/src/commands/liberica/users/delete.ts +49 -0
  54. package/src/commands/liberica/users/disable.ts +41 -0
  55. package/src/commands/liberica/users/enable.ts +30 -0
  56. package/src/commands/liberica/users/get.ts +46 -0
  57. package/src/commands/liberica/users/index.ts +27 -0
  58. package/src/commands/liberica/users/list.ts +68 -0
  59. package/src/commands/liberica/users/me.ts +42 -0
  60. package/src/commands/liberica/users/reset-password.ts +42 -0
  61. package/src/commands/liberica/users/update.ts +48 -0
  62. package/src/core/api/client.ts +825 -0
  63. package/src/core/auth/token-manager.ts +183 -0
  64. package/src/core/config/manager.ts +164 -0
  65. package/src/index.ts +37 -0
  66. package/src/types/employee.ts +102 -0
  67. package/src/types/index.ts +75 -0
  68. package/src/types/org.ts +25 -0
  69. package/src/types/position.ts +24 -0
  70. package/src/types/user.ts +64 -0
  71. package/tests/unit/commands/arabica/auth.test.ts +230 -0
  72. package/tests/unit/commands/liberica/auth.test.ts +175 -0
  73. package/tests/unit/commands/liberica/context.test.ts +98 -0
  74. package/tests/unit/commands/liberica/employees/create.test.ts +463 -0
  75. package/tests/unit/commands/liberica/employees/disable.test.ts +82 -0
  76. package/tests/unit/commands/liberica/employees/enable.test.ts +82 -0
  77. package/tests/unit/commands/liberica/employees/get.test.ts +111 -0
  78. package/tests/unit/commands/liberica/employees/list.test.ts +294 -0
  79. package/tests/unit/commands/liberica/employees/update.test.ts +210 -0
  80. package/tests/unit/config.test.ts +141 -0
  81. package/tests/unit/types.test.ts +195 -0
  82. package/tsconfig.json +20 -0
package/.eslintrc.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "env": {
3
+ "node": true,
4
+ "es2022": true
5
+ },
6
+ "extends": [
7
+ "eslint:recommended",
8
+ "plugin:@typescript-eslint/recommended"
9
+ ],
10
+ "parser": "@typescript-eslint/parser",
11
+ "parserOptions": {
12
+ "ecmaVersion": 2022,
13
+ "sourceType": "module"
14
+ },
15
+ "plugins": ["@typescript-eslint"],
16
+ "rules": {
17
+ "no-console": "off",
18
+ "@typescript-eslint/no-explicit-any": "warn",
19
+ "@typescript-eslint/explicit-function-return-type": "off",
20
+ "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
21
+ },
22
+ "ignorePatterns": ["dist/", "node_modules/", "*.js"]
23
+ }
package/.prettierrc ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "semi": true,
3
+ "singleQuote": true,
4
+ "tabWidth": 2,
5
+ "trailingComma": "es5",
6
+ "printWidth": 100,
7
+ "arrowParens": "always",
8
+ "endOfLine": "lf"
9
+ }
@@ -0,0 +1,73 @@
1
+ # Liberica Employees - Learnings
2
+
3
+ ## API Patterns Observed
4
+
5
+ - API expects token WITHOUT "Bearer " prefix
6
+ - API prefix: /api
7
+ - Pagination is 0-based on backend
8
+ - Response fields: rows, pageNo, pageSize, totalRows
9
+ - Backend error format: {success, code, message} directly (not nested under error object)
10
+ - organizationId is `string` (was BigInteger), positionId is `string`
11
+
12
+ ## CRITICAL: BigInteger IDs
13
+
14
+ **Backend returns BigInteger for all ID fields, which exceeds JavaScript number range.**
15
+
16
+ ```typescript
17
+ // WRONG - Precision loss for IDs > 9007199254740991
18
+ employeeId: number
19
+
20
+ // CORRECT
21
+ employeeId: string
22
+ ```
23
+
24
+ **Affected interfaces:**
25
+ - Employee.employeeId
26
+ - Employee.organizationId
27
+ - UpdateEmployeeRequest.employeeId
28
+ - OrgListItem.id (for cached org/position lookups)
29
+
30
+ ## CRITICAL: Do NOT Use X-TENANT-ID Header
31
+
32
+ The tenant is embedded in the JWT token. Passing `X-TENANT-ID` with string tenant name causes:
33
+ ```
34
+ NumberFormatException: For input string: "shanghai"
35
+ ```
36
+
37
+ Backend expects numeric tenant ID or no header at all.
38
+
39
+ ## HTTP Methods Matter
40
+
41
+ | Endpoint | Method | Common Error |
42
+ |----------|--------|--------------|
43
+ | `/master/org/tree` | POST (not GET!) | A1504: 当前接口不支持GET方式请求 |
44
+ | `/master/position/list` | GET | - |
45
+ | `/employee/delete` | POST | - |
46
+
47
+ ## Error Response Normalization
48
+
49
+ Backend returns errors in two formats - must normalize in handleApiError:
50
+
51
+ ```typescript
52
+ // Format 1: Error at top level
53
+ { success: false, code: "A150001", message: "查询结果不存在" }
54
+
55
+ // Format 2: Nested under error
56
+ { success: false, error: { code: "01001150001", message: "职员不存在" } }
57
+ ```
58
+
59
+ ## Implementation Decisions
60
+
61
+ - In-memory cache (Map) for org/position lists with 5-minute TTL
62
+ - Cache key: `${environment}:${tenant}`
63
+ - Generic lookup types (OrgListItem, PositionListItem) with `id` + `name` for reuse across modules
64
+ - Create command resolves names to IDs before building request; exits with descriptive error if not found
65
+ - Position ID stays as string (backend contract)
66
+ - All IDs use string type to handle BigInteger without precision loss
67
+
68
+ ## Debugging Tips
69
+
70
+ 1. Add `console.error('[DEBUG]', ...)` to see raw API responses
71
+ 2. Use `--json` flag to get full response data with IDs
72
+ 3. Token stored in `~/.barista/.barista-tokens` (binary format)
73
+ 4. Config stored in `~/.barista/config.yaml`
package/AGENTS.md ADDED
@@ -0,0 +1,270 @@
1
+ # AGENTS.md - Barista CLI
2
+
3
+ **Project**: Node.js CLI (TypeScript) for Liberica & Arabica services
4
+ **Updated**: 2025-04-13
5
+
6
+ ## Quick Commands
7
+
8
+ ```bash
9
+ cd coffee-barista-cli
10
+
11
+ npm run build # Build TypeScript
12
+ npm run dev # Watch mode
13
+ npm run test:unit # Run tests (single run)
14
+ npm test # Watch mode
15
+ npm run lint # ESLint check
16
+ npm run lint -- --fix # Auto-fix
17
+
18
+ # Run CLI directly
19
+ node ./bin/barista.js --help
20
+ ```
21
+
22
+ ## Project Structure
23
+
24
+ ```
25
+ src/
26
+ ├── index.ts # Main entry - Commander setup
27
+ ├── commands/
28
+ │ ├── context.ts # Context management
29
+ │ ├── auth.ts # Auth commands
30
+ │ ├── liberica/
31
+ │ │ ├── index.ts # Liberica service entry
32
+ │ │ ├── auth/index.ts # Liberica auth
33
+ │ │ ├── context/index.ts # Liberica context
34
+ │ │ └── employees/ # Employee CRUD commands
35
+ │ └── arabica/
36
+ │ └── auth/ # Arabica auth commands
37
+ ├── core/
38
+ │ ├── auth/token-manager.ts # Keychain token storage
39
+ │ ├── config/manager.ts # YAML config (~/.barista/config.yaml)
40
+ │ └── api/client.ts # API client (axios wrapper)
41
+ └── types/
42
+ ├── index.ts
43
+ ├── employee.ts
44
+ ├── org.ts
45
+ └── position.ts
46
+ ```
47
+
48
+ ## CRITICAL: API Integration Rules
49
+
50
+ **These rules are hard-won. Breaking them causes silent failures.**
51
+
52
+ ### 1. BigInteger IDs → Use String Type
53
+
54
+ Backend returns BigInteger for all ID fields, exceeding JS `number` range (max: 9007199254740991).
55
+
56
+ ```typescript
57
+ // WRONG - precision loss
58
+ employeeId: number
59
+
60
+ // CORRECT
61
+ employeeId: string
62
+ ```
63
+
64
+ **All ID fields from backend MUST be `string`.**
65
+
66
+ ### 2. Do NOT Use X-TENANT-ID Header
67
+
68
+ Tenant is embedded in JWT token. Passing `X-TENANT-ID` causes:
69
+ ```
70
+ NumberFormatException: For input string: "shanghai"
71
+ ```
72
+
73
+ ```typescript
74
+ // WRONG
75
+ { headers: { 'X-TENANT-ID': tenant } }
76
+
77
+ // CORRECT - omit header entirely
78
+ ```
79
+
80
+ ### 3. Authorization: No "Bearer " Prefix
81
+
82
+ ```typescript
83
+ // WRONG
84
+ 'Authorization': `Bearer ${token}`
85
+
86
+ // CORRECT
87
+ 'Authorization': token
88
+ ```
89
+
90
+ ### 4. HTTP Methods Vary by Endpoint
91
+
92
+ Always check the backend controller for correct method:
93
+
94
+ | Endpoint | Method | Notes |
95
+ |----------|--------|-------|
96
+ | `/employee/page` | GET | Paginated list |
97
+ | `/employee/detail` | GET | Single item |
98
+ | `/employee/add\|edit\|delete` | POST | Write operations |
99
+ | `/master/org/tree` | POST | NOT GET |
100
+ | `/master/position/list` | GET | - |
101
+
102
+ ### 5. Error Response Has Two Formats
103
+
104
+ Backend returns errors in different structures:
105
+
106
+ ```typescript
107
+ // Format 1: Top-level error (common)
108
+ { success: false, code: "A150001", message: "查询结果不存在" }
109
+
110
+ // Format 2: Nested under 'error'
111
+ { success: false, error: { code: "01001150001", message: "职员不存在" } }
112
+ ```
113
+
114
+ Must normalize in `handleApiError()`.
115
+
116
+ ### 6. Pagination: 0-Based, Use pageNo/pageSize
117
+
118
+ ```typescript
119
+ // CLI page 1 → API page 0
120
+ const pageNo = parseInt(options.page) - 1;
121
+ // Query: /employee/page?pageNo=0&pageSize=20
122
+ ```
123
+
124
+ ### 7. Response Field Names Differ
125
+
126
+ | Backend | Common Mistake |
127
+ |---------|---------------|
128
+ | `rows` | `records` |
129
+ | `pageNo` | `current` |
130
+ | `pageSize` | `size` |
131
+ | `totalRows` | `total` |
132
+
133
+ ## Common Issues & Fixes
134
+
135
+ | Error | Cause | Fix |
136
+ |-------|-------|-----|
137
+ | `A1504: 不支持GET方式` | Wrong HTTP method | Use POST for `/org/tree` |
138
+ | `NumberFormatException` | Using `X-TENANT-ID` header | Remove header |
139
+ | Precision loss on IDs | Using `number` for BigInteger | Use `string` |
140
+ | "not found" for valid ID | ID truncated due to precision loss | Use string type |
141
+ | Empty data despite records | Field name mismatch | Check `rows` not `records` |
142
+
143
+ ## CLI Conventions
144
+
145
+ ### Command Structure
146
+ - Factory functions: `createXxxCommand(): Command`
147
+ - Subcommands via `.addCommand()`
148
+ - Commander.js 12 (not oclif/yargs)
149
+
150
+ ### Output Formatting
151
+ - TTY auto-detection: tables for humans, JSON for scripts
152
+ - `--json` flag forces JSON output
153
+ - `chalk` for colors, `cli-table3` for tables
154
+
155
+ ### Imports
156
+ - Use `.js` extension even in TypeScript: `'../../core/config/manager.js'`
157
+ - Async parse: `program.parseAsync()` not `parse()`
158
+
159
+ ## Token & Config
160
+
161
+ - Tokens: System keychain only (keytar), NOT files
162
+ - Key: `{service}:{environment}:{tenant}` (e.g., `liberica:dev:shanghai`)
163
+ - Config: `~/.barista/config.yaml`
164
+ - First run creates config with defaults
165
+
166
+ ## Adding Commands (MANDATORY: Design First)
167
+
168
+ 1. Read `docs/COMMAND_DESIGN_SPEC.md`
169
+ 2. Find backend Controller endpoints (check facade modules)
170
+ 3. Create design doc at `docs/commands/{service}/{resource}/{action}.md`
171
+ 4. Implement following existing patterns
172
+ 5. Write unit tests
173
+ 6. Verify: `npm run build && npm run test:unit`
174
+
175
+ ## Functional Verification Workflow
176
+
177
+ **Always verify new commands against the real API before committing.**
178
+
179
+ ### Standard Test Environment
180
+
181
+ ```bash
182
+ # Environment: dev
183
+ # Tenant: shanghai
184
+ # User: admin@shanghai.newpeaksh.com
185
+ # Password: 123456
186
+ ```
187
+
188
+ ### Workflow
189
+
190
+ ```bash
191
+ cd coffee-barista-cli
192
+
193
+ # 1. Build
194
+ npm run build
195
+
196
+ # 2. Login to Liberica
197
+ node ./bin/barista.js liberica auth login dev shanghai admin@shanghai.newpeaksh.com 123456
198
+
199
+ # 3. Verify login
200
+ node ./bin/barista.js context show
201
+
202
+ # 4. Test command (use --json to see full IDs)
203
+ node ./bin/barista.js liberica employees list --json
204
+
205
+ # 5. Test specific operations
206
+ node ./bin/barista.js liberica employees get <id>
207
+ node ./bin/barista.js liberica employees create -n "测试" --no "9999"
208
+ node ./bin/barista.js liberica employees delete <id> --force
209
+
210
+ # 6. For create with org/position:
211
+ node ./bin/barista.js liberica employees create \
212
+ -n "测试员工" \
213
+ -p "13300000000" \
214
+ -e "test@example.com" \
215
+ -s M \
216
+ --org "销售部" \
217
+ --position "经理" \
218
+ --no "TEST001"
219
+ ```
220
+
221
+ ### Why This Matters
222
+
223
+ - Unit tests mock the API but don't catch real integration issues
224
+ - BigInteger ID precision only shows with actual API responses
225
+ - Backend may return different error formats than mocks
226
+ - HTTP method issues only appear with real calls
227
+
228
+ ### Troubleshooting
229
+
230
+ ```bash
231
+ # Check current context
232
+ node ./bin/barista.js context show
233
+
234
+ # Re-login if token expired
235
+ node ./bin/barista.js liberica auth login dev shanghai admin@shanghai.newpeaksh.com 123456
236
+
237
+ # Debug: use --json to see full response
238
+ node ./bin/barista.js liberica employees list --json
239
+
240
+ # Debug: check API calls
241
+ # Add to client.ts temporarily:
242
+ console.error('[DEBUG]', JSON.stringify(response.data));
243
+ ```
244
+
245
+ ## Testing
246
+
247
+ - Vitest with TypeScript
248
+ - Mock `keytar` and `axios`
249
+ - Tests co-located: `tests/unit/commands/...`
250
+
251
+ ## Key Files Reference
252
+
253
+ | Purpose | File |
254
+ |---------|------|
255
+ | API client | `src/core/api/client.ts` |
256
+ | Types | `src/types/employee.ts`, `org.ts`, `position.ts` |
257
+ | Commands | `src/commands/liberica/employees/*.ts` |
258
+ | Integration lessons | `docs/INTEGRATION_NOTES.md` |
259
+ | Command design | `docs/COMMAND_DESIGN_SPEC.md` |
260
+
261
+ ## Environment URLs
262
+
263
+ ```
264
+ Liberica: https://{tenant}-{env}.newpeaksh.com
265
+ dev: https://{tenant}-dev.newpeaksh.com
266
+ prod-jp: https://{tenant}.newpeakjp.com
267
+
268
+ Arabica: https://arabica-{env}.newpeaksh.com
269
+ prod: https://www.newpeaksh.com
270
+ ```
@@ -0,0 +1,291 @@
1
+ # Contributing to Barista CLI
2
+
3
+ Thank you for your interest in contributing to Barista CLI! This document provides guidelines and instructions for contributing.
4
+
5
+ ## Development Setup
6
+
7
+ ### Prerequisites
8
+
9
+ - Node.js 18+
10
+ - npm 9+
11
+
12
+ ### Initial Setup
13
+
14
+ ```bash
15
+ # Clone the repository
16
+ git clone https://gitlab.newpeaksh.com/coffee/coffee-barista-cli.git
17
+ cd coffee-barista-cli
18
+
19
+ # Install dependencies
20
+ npm install
21
+
22
+ # Link CLI for local development
23
+ npm link
24
+
25
+ # Verify installation
26
+ barista --version
27
+ ```
28
+
29
+ ### VS Code Setup
30
+
31
+ Recommended extensions:
32
+ - ESLint
33
+ - Prettier
34
+ - TypeScript Vue Plugin (Volar)
35
+
36
+ ## Development Workflow
37
+
38
+ ### ⚠️ IMPORTANT: Design First, Code Later
39
+
40
+ **Before writing ANY code, you MUST complete the design phase.**
41
+
42
+ Skipping design leads to:
43
+ - Wrong API endpoints (like Arabica register using `/api/member/user/register` instead of `/member/user/register`)
44
+ - Missing required parameters
45
+ - Inconsistent command structures
46
+ - Rework and wasted time
47
+
48
+ ### 1. Design Phase (MANDATORY)
49
+
50
+ 1. Read `docs/COMMAND_DESIGN_SPEC.md`
51
+ 2. Find backend Controller:
52
+ ```bash
53
+ # Example: Find the register endpoint
54
+ grep -r "register" --include="*.java" ../coffee-arabica-end/facade/
55
+ ```
56
+ 3. Document the command design:
57
+ - API endpoint and HTTP method
58
+ - All parameters (required vs optional)
59
+ - Request/Response DTOs
60
+ - Error codes and handling
61
+ 4. Create design document: `docs/commands/{service}/{resource}/{action}/index.md`
62
+ 5. **Get design reviewed** before coding
63
+
64
+ ### 2. Create a Branch
65
+
66
+ ```bash
67
+ git checkout -b feature/my-feature
68
+ # or
69
+ git checkout -b fix/bug-description
70
+ ```
71
+
72
+ ### 3. Implement Changes (After Design Approved)
73
+
74
+ - Write TypeScript code following the approved design
75
+ - Follow existing command patterns
76
+ - Add or update tests
77
+ - Update documentation if needed
78
+
79
+ ### 4. Run Tests
80
+
81
+ ```bash
82
+ # Run all tests
83
+ npm test
84
+
85
+ # Run unit tests only
86
+ npm run test:unit
87
+
88
+ # Run tests in watch mode
89
+ npm test -- --watch
90
+ ```
91
+
92
+ ### 5. Lint and Format
93
+
94
+ ```bash
95
+ # Check code style
96
+ npm run lint
97
+
98
+ # Auto-fix linting issues
99
+ npm run lint -- --fix
100
+
101
+ # Format code with Prettier
102
+ npm run format
103
+ ```
104
+
105
+ ### 6. Build
106
+
107
+ ```bash
108
+ # Build TypeScript
109
+ npm run build
110
+
111
+ # Watch mode for development
112
+ npm run dev
113
+ ```
114
+
115
+ ### 7. Commit Changes
116
+
117
+ Follow commit message conventions (see below).
118
+
119
+ ### 8. Push and Create PR
120
+
121
+ ```bash
122
+ git push origin feature/my-feature
123
+ # Then create PR via GitLab UI
124
+ ```
125
+
126
+ ## Code Style
127
+
128
+ We use ESLint and Prettier for code formatting:
129
+
130
+ - **TypeScript**: Strict mode enabled
131
+ - **ESM**: All code uses ES modules with `.js` extensions in imports
132
+ - **Semicolons**: Required
133
+ - **Quotes**: Single quotes for strings
134
+ - **Indentation**: 2 spaces
135
+
136
+ ### Import Order
137
+
138
+ ```typescript
139
+ // 1. Node.js built-ins
140
+ import fs from 'fs';
141
+ import path from 'path';
142
+
143
+ // 2. External packages
144
+ import chalk from 'chalk';
145
+ import { Command } from 'commander';
146
+
147
+ // 3. Internal packages (relative)
148
+ import { configManager } from '../core/config/manager.js';
149
+ import { tokenManager } from '../core/auth/token-manager.js';
150
+ import type { Context, Config } from '../types/index.js';
151
+ ```
152
+
153
+ ## Commit Message Conventions
154
+
155
+ We follow [Conventional Commits](https://www.conventionalcommits.org/):
156
+
157
+ ```
158
+ <type>(<scope>): <subject>
159
+
160
+ [optional body]
161
+
162
+ [optional footer]
163
+ ```
164
+
165
+ ### Types
166
+
167
+ | Type | Description |
168
+ |------|-------------|
169
+ | feat | New feature |
170
+ | fix | Bug fix |
171
+ | docs | Documentation changes |
172
+ | style | Formatting, missing semicolons, etc. |
173
+ | refactor | Code refactoring |
174
+ | test | Adding tests |
175
+ | chore | Maintenance tasks |
176
+
177
+ ### Examples
178
+
179
+ ```bash
180
+ # Feature
181
+ git commit -m "feat(liberica): add orders cancel command"
182
+
183
+ # Bug fix
184
+ git commit -m "fix(auth): handle token expiration gracefully"
185
+
186
+ # Documentation
187
+ git commit -m "docs: update README with new command examples"
188
+
189
+ # Refactoring
190
+ git commit -m "refactor(config): extract environment validation"
191
+ ```
192
+
193
+ ## Testing
194
+
195
+ ### Test Structure
196
+
197
+ ```typescript
198
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
199
+
200
+ describe('module name', () => {
201
+ beforeEach(() => {
202
+ vi.clearAllMocks();
203
+ });
204
+
205
+ it('should do something specific', () => {
206
+ // Arrange
207
+ const input = 'test';
208
+
209
+ // Act
210
+ const result = functionUnderTest(input);
211
+
212
+ // Assert
213
+ expect(result).toBe('expected');
214
+ });
215
+ });
216
+ ```
217
+
218
+ ### Running Specific Tests
219
+
220
+ ```bash
221
+ # Run tests matching a pattern
222
+ npm test -- orders
223
+
224
+ # Run with coverage
225
+ npm test -- --coverage
226
+
227
+ # Run in watch mode for specific file
228
+ npm test -- src/commands/context.test.ts --watch
229
+ ```
230
+
231
+ ## Project Structure
232
+
233
+ ```
234
+ coffee-barista-cli/
235
+ ├── bin/
236
+ │ └── barista # CLI entry point
237
+ ├── src/
238
+ │ ├── index.ts # Main entry
239
+ │ ├── commands/ # Command implementations
240
+ │ │ ├── context.ts
241
+ │ │ ├── auth.ts
242
+ │ │ ├── liberica/
243
+ │ │ │ ├── orders.ts
244
+ │ │ │ ├── products.ts
245
+ │ │ │ └── index.ts
246
+ │ │ └── arabica/
247
+ │ │ └── index.ts
248
+ │ ├── core/ # Core functionality
249
+ │ │ ├── config/
250
+ │ │ │ └── manager.ts
251
+ │ │ └── auth/
252
+ │ │ └── token-manager.ts
253
+ │ ├── types/
254
+ │ │ └── index.ts
255
+ │ └── utils/
256
+ ├── tests/
257
+ │ ├── unit/ # Unit tests
258
+ │ ├── integration/ # Integration tests
259
+ │ └── fixtures/ # Test fixtures
260
+ ├── docs/ # Documentation
261
+ └── package.json
262
+ ```
263
+
264
+ ## Documentation
265
+
266
+ When adding new features, update relevant docs:
267
+
268
+ - **New command**:
269
+ 1. **必须先**阅读 [命令设计规范](./docs/COMMAND_DESIGN_SPEC.md)
270
+ 2. 编写设计文档(按规范模板)
271
+ 3. 更新 `docs/COMMANDS.md`
272
+ - **Architecture changes**: Update `docs/ARCHITECTURE.md`
273
+ - **README.md**: Update if CLI interface changes
274
+
275
+ ## Pull Request Checklist
276
+
277
+ - [ ] Code follows style guidelines (lint passes)
278
+ - [ ] Tests added/updated and passing
279
+ - [ ] Documentation updated
280
+ - [ ] Commit messages follow conventions
281
+ - [ ] Build succeeds (`npm run build`)
282
+
283
+ ## Questions?
284
+
285
+ For questions or discussions:
286
+ - Open an issue in the repository
287
+ - Contact the development team
288
+
289
+ ## License
290
+
291
+ By contributing, you agree that your contributions will be licensed under the MIT License.