@aaronshaf/ger 1.2.11 → 2.0.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.
- package/.ast-grep/rules/no-as-casting.yml +13 -0
- package/.claude-plugin/plugin.json +22 -0
- package/.github/workflows/ci-simple.yml +53 -0
- package/.github/workflows/ci.yml +171 -0
- package/.github/workflows/claude-code-review.yml +83 -0
- package/.github/workflows/claude.yml +50 -0
- package/.github/workflows/dependency-update.yml +84 -0
- package/.github/workflows/release.yml +166 -0
- package/.github/workflows/security-scan.yml +113 -0
- package/.github/workflows/security.yml +96 -0
- package/.husky/pre-commit +16 -0
- package/.husky/pre-push +25 -0
- package/.lintstagedrc.json +6 -0
- package/.tool-versions +1 -0
- package/CLAUDE.md +105 -0
- package/DEVELOPMENT.md +361 -0
- package/EXAMPLES.md +457 -0
- package/README.md +831 -16
- package/bin/ger +3 -18
- package/biome.json +36 -0
- package/bun.lock +678 -0
- package/bunfig.toml +8 -0
- package/docs/adr/0001-use-effect-for-side-effects.md +65 -0
- package/docs/adr/0002-use-bun-runtime.md +64 -0
- package/docs/adr/0003-store-credentials-in-home-directory.md +75 -0
- package/docs/adr/0004-use-commander-for-cli.md +76 -0
- package/docs/adr/0005-use-effect-schema-for-validation.md +93 -0
- package/docs/adr/0006-use-msw-for-api-mocking.md +89 -0
- package/docs/adr/0007-git-hooks-for-quality.md +94 -0
- package/docs/adr/0008-no-as-typecasting.md +83 -0
- package/docs/adr/0009-file-size-limits.md +82 -0
- package/docs/adr/0010-llm-friendly-xml-output.md +93 -0
- package/docs/adr/0011-ai-tool-strategy-pattern.md +102 -0
- package/docs/adr/0012-build-status-message-parsing.md +94 -0
- package/docs/adr/0013-git-subprocess-integration.md +98 -0
- package/docs/adr/0014-group-management-support.md +95 -0
- package/docs/adr/0015-batch-comment-processing.md +111 -0
- package/docs/adr/0016-flexible-change-identifiers.md +94 -0
- package/docs/adr/0017-git-worktree-support.md +102 -0
- package/docs/adr/0018-auto-install-commit-hook.md +103 -0
- package/docs/adr/0019-sdk-package-exports.md +95 -0
- package/docs/adr/0020-code-coverage-enforcement.md +105 -0
- package/docs/adr/0021-typescript-isolated-declarations.md +83 -0
- package/docs/adr/0022-biome-oxlint-tooling.md +124 -0
- package/docs/adr/README.md +30 -0
- package/docs/prd/README.md +12 -0
- package/docs/prd/architecture.md +325 -0
- package/docs/prd/commands.md +425 -0
- package/docs/prd/data-model.md +349 -0
- package/docs/prd/overview.md +124 -0
- package/index.ts +219 -0
- package/oxlint.json +24 -0
- package/package.json +82 -15
- package/scripts/check-coverage.ts +69 -0
- package/scripts/check-file-size.ts +38 -0
- package/scripts/fix-test-mocks.ts +55 -0
- package/skills/gerrit-workflow/SKILL.md +247 -0
- package/skills/gerrit-workflow/examples.md +572 -0
- package/skills/gerrit-workflow/reference.md +728 -0
- package/src/api/gerrit.ts +696 -0
- package/src/cli/commands/abandon.ts +65 -0
- package/src/cli/commands/add-reviewer.ts +156 -0
- package/src/cli/commands/build-status.ts +282 -0
- package/src/cli/commands/checkout.ts +422 -0
- package/src/cli/commands/comment.ts +460 -0
- package/src/cli/commands/comments.ts +85 -0
- package/src/cli/commands/diff.ts +71 -0
- package/src/cli/commands/extract-url.ts +266 -0
- package/src/cli/commands/groups-members.ts +104 -0
- package/src/cli/commands/groups-show.ts +169 -0
- package/src/cli/commands/groups.ts +137 -0
- package/src/cli/commands/incoming.ts +226 -0
- package/src/cli/commands/init.ts +164 -0
- package/src/cli/commands/mine.ts +115 -0
- package/src/cli/commands/open.ts +57 -0
- package/src/cli/commands/projects.ts +68 -0
- package/src/cli/commands/push.ts +430 -0
- package/src/cli/commands/rebase.ts +52 -0
- package/src/cli/commands/remove-reviewer.ts +123 -0
- package/src/cli/commands/restore.ts +50 -0
- package/src/cli/commands/review.ts +486 -0
- package/src/cli/commands/search.ts +162 -0
- package/src/cli/commands/setup.ts +286 -0
- package/src/cli/commands/show.ts +491 -0
- package/src/cli/commands/status.ts +35 -0
- package/src/cli/commands/submit.ts +108 -0
- package/src/cli/commands/vote.ts +119 -0
- package/src/cli/commands/workspace.ts +200 -0
- package/src/cli/index.ts +53 -0
- package/src/cli/register-commands.ts +659 -0
- package/src/cli/register-group-commands.ts +88 -0
- package/src/cli/register-reviewer-commands.ts +97 -0
- package/src/prompts/default-review.md +86 -0
- package/src/prompts/system-inline-review.md +135 -0
- package/src/prompts/system-overall-review.md +206 -0
- package/src/schemas/config.test.ts +245 -0
- package/src/schemas/config.ts +84 -0
- package/src/schemas/gerrit.ts +681 -0
- package/src/services/commit-hook.ts +314 -0
- package/src/services/config.test.ts +150 -0
- package/src/services/config.ts +250 -0
- package/src/services/git-worktree.ts +342 -0
- package/src/services/review-strategy.ts +292 -0
- package/src/test-utils/mock-generator.ts +138 -0
- package/src/utils/change-id.test.ts +98 -0
- package/src/utils/change-id.ts +63 -0
- package/src/utils/comment-formatters.ts +153 -0
- package/src/utils/diff-context.ts +103 -0
- package/src/utils/diff-formatters.ts +141 -0
- package/src/utils/formatters.ts +85 -0
- package/src/utils/git-commit.test.ts +277 -0
- package/src/utils/git-commit.ts +122 -0
- package/src/utils/index.ts +55 -0
- package/src/utils/message-filters.ts +26 -0
- package/src/utils/review-formatters.ts +89 -0
- package/src/utils/review-prompt-builder.ts +110 -0
- package/src/utils/shell-safety.ts +117 -0
- package/src/utils/status-indicators.ts +100 -0
- package/src/utils/url-parser.test.ts +271 -0
- package/src/utils/url-parser.ts +118 -0
- package/tests/abandon.test.ts +230 -0
- package/tests/add-reviewer.test.ts +579 -0
- package/tests/build-status-watch.test.ts +344 -0
- package/tests/build-status.test.ts +789 -0
- package/tests/change-id-formats.test.ts +268 -0
- package/tests/checkout/integration.test.ts +653 -0
- package/tests/checkout/parse-input.test.ts +55 -0
- package/tests/checkout/validation.test.ts +178 -0
- package/tests/comment-batch-advanced.test.ts +431 -0
- package/tests/comment-gerrit-api-compliance.test.ts +414 -0
- package/tests/comment.test.ts +708 -0
- package/tests/comments.test.ts +323 -0
- package/tests/config-service-simple.test.ts +100 -0
- package/tests/diff.test.ts +419 -0
- package/tests/extract-url.test.ts +517 -0
- package/tests/groups-members.test.ts +256 -0
- package/tests/groups-show.test.ts +323 -0
- package/tests/groups.test.ts +334 -0
- package/tests/helpers/build-status-test-setup.ts +83 -0
- package/tests/helpers/config-mock.ts +27 -0
- package/tests/incoming.test.ts +357 -0
- package/tests/init.test.ts +70 -0
- package/tests/integration/commit-hook.test.ts +246 -0
- package/tests/interactive-incoming.test.ts +173 -0
- package/tests/mine.test.ts +285 -0
- package/tests/mocks/msw-handlers.ts +80 -0
- package/tests/open.test.ts +233 -0
- package/tests/projects.test.ts +259 -0
- package/tests/rebase.test.ts +271 -0
- package/tests/remove-reviewer.test.ts +357 -0
- package/tests/restore.test.ts +237 -0
- package/tests/review.test.ts +135 -0
- package/tests/search.test.ts +712 -0
- package/tests/setup.test.ts +63 -0
- package/tests/show-auto-detect.test.ts +324 -0
- package/tests/show.test.ts +813 -0
- package/tests/status.test.ts +145 -0
- package/tests/submit.test.ts +316 -0
- package/tests/unit/commands/push.test.ts +194 -0
- package/tests/unit/git-branch-detection.test.ts +82 -0
- package/tests/unit/git-worktree.test.ts +55 -0
- package/tests/unit/patterns/push-patterns.test.ts +148 -0
- package/tests/unit/schemas/gerrit.test.ts +85 -0
- package/tests/unit/services/commit-hook.test.ts +132 -0
- package/tests/unit/services/review-strategy.test.ts +349 -0
- package/tests/unit/test-utils/mock-generator.test.ts +154 -0
- package/tests/unit/utils/comment-formatters.test.ts +415 -0
- package/tests/unit/utils/diff-context.test.ts +171 -0
- package/tests/unit/utils/diff-formatters.test.ts +165 -0
- package/tests/unit/utils/formatters.test.ts +411 -0
- package/tests/unit/utils/message-filters.test.ts +227 -0
- package/tests/unit/utils/shell-safety.test.ts +230 -0
- package/tests/unit/utils/status-indicators.test.ts +137 -0
- package/tests/vote.test.ts +317 -0
- package/tests/workspace.test.ts +295 -0
- package/tsconfig.json +36 -5
- package/src/commands/branch.ts +0 -196
- package/src/ger.ts +0 -22
- package/src/types.d.ts +0 -35
- package/src/utils.ts +0 -130
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# ADR - Architecture Decision Records
|
|
2
|
+
|
|
3
|
+
Records of significant architectural decisions with context and rationale. Each ADR captures the why behind technical choices.
|
|
4
|
+
|
|
5
|
+
## Records
|
|
6
|
+
|
|
7
|
+
| ADR | Decision |
|
|
8
|
+
|-----|----------|
|
|
9
|
+
| [0001](0001-use-effect-for-side-effects.md) | Effect-TS for all side effects |
|
|
10
|
+
| [0002](0002-use-bun-runtime.md) | Bun as the JavaScript runtime |
|
|
11
|
+
| [0003](0003-store-credentials-in-home-directory.md) | `~/.ger/config.json` for credentials |
|
|
12
|
+
| [0004](0004-use-commander-for-cli.md) | Commander.js for CLI framework |
|
|
13
|
+
| [0005](0005-use-effect-schema-for-validation.md) | Effect Schema for data validation |
|
|
14
|
+
| [0006](0006-use-msw-for-api-mocking.md) | MSW for HTTP mocking in tests |
|
|
15
|
+
| [0007](0007-git-hooks-for-quality.md) | Pre-commit hooks for code quality |
|
|
16
|
+
| [0008](0008-no-as-typecasting.md) | Prohibit `as` type casting |
|
|
17
|
+
| [0009](0009-file-size-limits.md) | Enforce file size limits |
|
|
18
|
+
| [0010](0010-llm-friendly-xml-output.md) | `--xml` flag for LLM consumption |
|
|
19
|
+
| [0011](0011-ai-tool-strategy-pattern.md) | Pluggable AI tool strategies |
|
|
20
|
+
| [0012](0012-build-status-message-parsing.md) | Parse messages for build status |
|
|
21
|
+
| [0013](0013-git-subprocess-integration.md) | Shell out to git instead of library |
|
|
22
|
+
| [0014](0014-group-management-support.md) | Full Gerrit group management |
|
|
23
|
+
| [0015](0015-batch-comment-processing.md) | JSON array input for bulk comments |
|
|
24
|
+
| [0016](0016-flexible-change-identifiers.md) | Accept both numeric and Change-ID formats |
|
|
25
|
+
| [0017](0017-git-worktree-support.md) | Full git worktree compatibility |
|
|
26
|
+
| [0018](0018-auto-install-commit-hook.md) | Auto-install Gerrit commit-msg hook |
|
|
27
|
+
| [0019](0019-sdk-package-exports.md) | Export SDK for programmatic usage |
|
|
28
|
+
| [0020](0020-code-coverage-enforcement.md) | 80% coverage threshold in pre-commit |
|
|
29
|
+
| [0021](0021-typescript-isolated-declarations.md) | Explicit return types on exports |
|
|
30
|
+
| [0022](0022-biome-oxlint-tooling.md) | Biome formatter + oxlint linter |
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# PRD - Product Requirements Documents
|
|
2
|
+
|
|
3
|
+
Product specifications defining what the software should do, its goals, and design decisions.
|
|
4
|
+
|
|
5
|
+
## Documents
|
|
6
|
+
|
|
7
|
+
| File | Description |
|
|
8
|
+
|------|-------------|
|
|
9
|
+
| [overview.md](overview.md) | Project overview, goals, design decisions |
|
|
10
|
+
| [architecture.md](architecture.md) | Technical architecture and component design |
|
|
11
|
+
| [commands.md](commands.md) | CLI command specifications |
|
|
12
|
+
| [data-model.md](data-model.md) | Data structures, schemas, API models |
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## System Overview
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
7
|
+
│ CLI Layer │
|
|
8
|
+
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
9
|
+
│ │ show │ │ comment │ │ push │ │ review │ ... │
|
|
10
|
+
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
|
|
11
|
+
└───────┼───────────┼───────────┼───────────┼─────────────────┘
|
|
12
|
+
│ │ │ │
|
|
13
|
+
┌───────┴───────────┴───────────┴───────────┴─────────────────┐
|
|
14
|
+
│ Service Layer │
|
|
15
|
+
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
16
|
+
│ │ GerritApi │ │ ConfigService│ │ ReviewStrategy│ │
|
|
17
|
+
│ │ Service │ │ │ │ │ │
|
|
18
|
+
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
|
19
|
+
└───────┬───────────────────────────────────────────────────────┘
|
|
20
|
+
│
|
|
21
|
+
┌───────┴─────────────────────────────────────────────────────┐
|
|
22
|
+
│ External Systems │
|
|
23
|
+
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
24
|
+
│ │ Gerrit API │ │ Git (spawn) │ │ AI Tools │ │
|
|
25
|
+
│ │ │ │ │ │ (claude/llm) │ │
|
|
26
|
+
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
|
27
|
+
└─────────────────────────────────────────────────────────────┘
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Directory Structure
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
src/
|
|
34
|
+
├── cli/ # CLI interface layer
|
|
35
|
+
│ ├── index.ts # Entry point, command registration
|
|
36
|
+
│ ├── register-commands.ts # Main command setup
|
|
37
|
+
│ ├── register-group-commands.ts # Group commands
|
|
38
|
+
│ └── commands/ # Individual commands
|
|
39
|
+
│ ├── show.ts
|
|
40
|
+
│ ├── comment.ts
|
|
41
|
+
│ ├── push.ts
|
|
42
|
+
│ └── ... (27 commands)
|
|
43
|
+
│
|
|
44
|
+
├── api/ # External API clients
|
|
45
|
+
│ └── gerrit.ts # Gerrit REST API service
|
|
46
|
+
│
|
|
47
|
+
├── services/ # Business logic services
|
|
48
|
+
│ ├── config.ts # Configuration management
|
|
49
|
+
│ ├── review-strategy.ts # AI tool strategies
|
|
50
|
+
│ ├── git-worktree.ts # Git worktree operations
|
|
51
|
+
│ └── commit-hook.ts # Gerrit hook installation
|
|
52
|
+
│
|
|
53
|
+
├── schemas/ # Data validation schemas
|
|
54
|
+
│ ├── gerrit.ts # Gerrit API types
|
|
55
|
+
│ └── config.ts # Config file schema
|
|
56
|
+
│
|
|
57
|
+
├── utils/ # Shared utilities
|
|
58
|
+
│ ├── change-id.ts # Change identifier parsing
|
|
59
|
+
│ ├── git-commit.ts # Git operations
|
|
60
|
+
│ ├── formatters.ts # Output formatting
|
|
61
|
+
│ ├── shell-safety.ts # XML/CDATA handling
|
|
62
|
+
│ └── ... (diff, comment, review utils)
|
|
63
|
+
│
|
|
64
|
+
├── prompts/ # AI review prompts
|
|
65
|
+
│ ├── default-review.md
|
|
66
|
+
│ ├── system-inline-review.md
|
|
67
|
+
│ └── system-overall-review.md
|
|
68
|
+
│
|
|
69
|
+
└── i18n/ # Internationalization (planned)
|
|
70
|
+
|
|
71
|
+
tests/
|
|
72
|
+
├── unit/ # Pure function tests
|
|
73
|
+
├── integration/ # API + command tests
|
|
74
|
+
├── mocks/ # MSW handlers
|
|
75
|
+
└── helpers/ # Test utilities
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Dependency Injection
|
|
79
|
+
|
|
80
|
+
Effect Layers provide dependency injection:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// Define service interface
|
|
84
|
+
interface GerritApiService {
|
|
85
|
+
readonly getChange: (id: string) => Effect.Effect<ChangeInfo, ApiError>
|
|
86
|
+
readonly listChanges: (query?: string) => Effect.Effect<ChangeInfo[], ApiError>
|
|
87
|
+
// ...
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Create service tag
|
|
91
|
+
const GerritApiService = Context.GenericTag<GerritApiService>('GerritApiService')
|
|
92
|
+
|
|
93
|
+
// Implement live service
|
|
94
|
+
const GerritApiServiceLive = Layer.succeed(GerritApiService, {
|
|
95
|
+
getChange: (id) => Effect.gen(function* () {
|
|
96
|
+
const config = yield* ConfigService
|
|
97
|
+
const response = yield* fetchJson(`${config.host}/a/changes/${id}`)
|
|
98
|
+
return yield* Schema.decodeUnknown(ChangeInfo)(response)
|
|
99
|
+
}),
|
|
100
|
+
// ...
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
// Use in commands
|
|
104
|
+
const showCommand = Effect.gen(function* () {
|
|
105
|
+
const api = yield* GerritApiService
|
|
106
|
+
const change = yield* api.getChange(changeId)
|
|
107
|
+
console.log(formatChange(change))
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
// Provide layers at runtime
|
|
111
|
+
Effect.runPromise(
|
|
112
|
+
showCommand.pipe(
|
|
113
|
+
Effect.provide(GerritApiServiceLive),
|
|
114
|
+
Effect.provide(ConfigServiceLive)
|
|
115
|
+
)
|
|
116
|
+
)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Error Handling
|
|
120
|
+
|
|
121
|
+
Tagged errors with Effect Schema:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// Define error types
|
|
125
|
+
export class ApiError extends Schema.TaggedError<ApiError>()('ApiError', {
|
|
126
|
+
message: Schema.String,
|
|
127
|
+
statusCode: Schema.Number,
|
|
128
|
+
url: Schema.String,
|
|
129
|
+
}) {}
|
|
130
|
+
|
|
131
|
+
export class ConfigError extends Schema.TaggedError<ConfigError>()('ConfigError', {
|
|
132
|
+
message: Schema.String,
|
|
133
|
+
}) {}
|
|
134
|
+
|
|
135
|
+
// Handle by tag
|
|
136
|
+
Effect.catchTag('ApiError', (error) => {
|
|
137
|
+
console.error(`API Error: ${error.message} (${error.statusCode})`)
|
|
138
|
+
return Effect.succeed(null)
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
// Or let errors propagate
|
|
142
|
+
Effect.runPromise(effect).catch((error) => {
|
|
143
|
+
if (error._tag === 'ApiError') {
|
|
144
|
+
console.error(`API failed: ${error.message}`)
|
|
145
|
+
}
|
|
146
|
+
})
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Data Flow
|
|
150
|
+
|
|
151
|
+
### Read Operation (show command)
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
User: ger show 12345
|
|
155
|
+
│
|
|
156
|
+
▼
|
|
157
|
+
┌─────────────────────┐
|
|
158
|
+
│ Parse arguments │
|
|
159
|
+
│ Normalize change ID │
|
|
160
|
+
└─────────┬───────────┘
|
|
161
|
+
│
|
|
162
|
+
▼
|
|
163
|
+
┌─────────────────────┐
|
|
164
|
+
│ Load config │
|
|
165
|
+
│ (~/.ger/config.json)│
|
|
166
|
+
└─────────┬───────────┘
|
|
167
|
+
│
|
|
168
|
+
▼
|
|
169
|
+
┌─────────────────────┐
|
|
170
|
+
│ API: GET /changes │
|
|
171
|
+
│ Validate response │
|
|
172
|
+
└─────────┬───────────┘
|
|
173
|
+
│
|
|
174
|
+
▼
|
|
175
|
+
┌─────────────────────┐
|
|
176
|
+
│ Format output │
|
|
177
|
+
│ (text/xml/json) │
|
|
178
|
+
└─────────┬───────────┘
|
|
179
|
+
│
|
|
180
|
+
▼
|
|
181
|
+
Console
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Write Operation (comment command)
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
User: echo '...' | ger comment 12345
|
|
188
|
+
│
|
|
189
|
+
▼
|
|
190
|
+
┌─────────────────────┐
|
|
191
|
+
│ Parse stdin (JSON) │
|
|
192
|
+
│ Validate schema │
|
|
193
|
+
└─────────┬───────────┘
|
|
194
|
+
│
|
|
195
|
+
▼
|
|
196
|
+
┌─────────────────────┐
|
|
197
|
+
│ Load config │
|
|
198
|
+
└─────────┬───────────┘
|
|
199
|
+
│
|
|
200
|
+
▼
|
|
201
|
+
┌─────────────────────┐
|
|
202
|
+
│ API: POST /review │
|
|
203
|
+
│ (batch comments) │
|
|
204
|
+
└─────────┬───────────┘
|
|
205
|
+
│
|
|
206
|
+
▼
|
|
207
|
+
Success/Error
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## AI Integration Flow
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
User: ger review 12345
|
|
214
|
+
│
|
|
215
|
+
▼
|
|
216
|
+
┌─────────────────────┐
|
|
217
|
+
│ Fetch change diff │
|
|
218
|
+
│ (API: GET /patch) │
|
|
219
|
+
└─────────┬───────────┘
|
|
220
|
+
│
|
|
221
|
+
▼
|
|
222
|
+
┌─────────────────────┐
|
|
223
|
+
│ Detect AI tool │
|
|
224
|
+
│ (claude/llm/etc) │
|
|
225
|
+
└─────────┬───────────┘
|
|
226
|
+
│
|
|
227
|
+
▼
|
|
228
|
+
┌─────────────────────┐ ┌─────────────────────┐
|
|
229
|
+
│ Stage 1: Inline │────►│ AI: Generate inline │
|
|
230
|
+
│ comments │ │ comments JSON │
|
|
231
|
+
└─────────┬───────────┘ └─────────────────────┘
|
|
232
|
+
│
|
|
233
|
+
▼
|
|
234
|
+
┌─────────────────────┐ ┌─────────────────────┐
|
|
235
|
+
│ Stage 2: Overall │────►│ AI: Generate │
|
|
236
|
+
│ review │ │ summary │
|
|
237
|
+
└─────────┬───────────┘ └─────────────────────┘
|
|
238
|
+
│
|
|
239
|
+
▼
|
|
240
|
+
┌─────────────────────┐
|
|
241
|
+
│ API: POST /review │
|
|
242
|
+
│ (all comments) │
|
|
243
|
+
└─────────────────────┘
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Configuration Architecture
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
Priority: File > Environment > Error
|
|
250
|
+
|
|
251
|
+
┌─────────────────────────────────────┐
|
|
252
|
+
│ ~/.ger/config.json │
|
|
253
|
+
│ { │
|
|
254
|
+
│ "host": "https://gerrit.com", │
|
|
255
|
+
│ "username": "user", │
|
|
256
|
+
│ "password": "token", │
|
|
257
|
+
│ "aiTool": "claude", │
|
|
258
|
+
│ "aiAutoDetect": true │
|
|
259
|
+
│ } │
|
|
260
|
+
└─────────────────────────────────────┘
|
|
261
|
+
│
|
|
262
|
+
▼ (file not found)
|
|
263
|
+
┌─────────────────────────────────────┐
|
|
264
|
+
│ Environment Variables │
|
|
265
|
+
│ GERRIT_HOST │
|
|
266
|
+
│ GERRIT_USERNAME │
|
|
267
|
+
│ GERRIT_PASSWORD │
|
|
268
|
+
└─────────────────────────────────────┘
|
|
269
|
+
│
|
|
270
|
+
▼ (not set)
|
|
271
|
+
┌─────────────────────────────────────┐
|
|
272
|
+
│ ConfigError: No credentials found │
|
|
273
|
+
└─────────────────────────────────────┘
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Testing Architecture
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
280
|
+
│ Test Runner (Bun) │
|
|
281
|
+
└─────────────────────────────────────────────────────────────┘
|
|
282
|
+
│
|
|
283
|
+
┌─────────────────────┼─────────────────────┐
|
|
284
|
+
▼ ▼ ▼
|
|
285
|
+
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
|
286
|
+
│ Unit Tests │ │ Integration │ │ E2E Tests │
|
|
287
|
+
│ │ │ Tests │ │ (manual) │
|
|
288
|
+
│ - Schemas │ │ - Commands │ │ │
|
|
289
|
+
│ - Utilities │ │ - API flows │ │ - Full CLI │
|
|
290
|
+
│ - Formatters │ │ - Services │ │ - Real Gerrit │
|
|
291
|
+
└───────────────┘ └───────┬───────┘ └───────────────┘
|
|
292
|
+
│
|
|
293
|
+
▼
|
|
294
|
+
┌───────────────────┐
|
|
295
|
+
│ MSW Handlers │
|
|
296
|
+
│ │
|
|
297
|
+
│ Mock HTTP at │
|
|
298
|
+
│ network level │
|
|
299
|
+
└───────────────────┘
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Security Model
|
|
303
|
+
|
|
304
|
+
```
|
|
305
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
306
|
+
│ Credential Storage │
|
|
307
|
+
│ - File: ~/.ger/config.json (mode 0600) │
|
|
308
|
+
│ - Never logged or printed in errors │
|
|
309
|
+
│ - Basic auth over HTTPS only │
|
|
310
|
+
└─────────────────────────────────────────────────────────────┘
|
|
311
|
+
|
|
312
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
313
|
+
│ Input Validation │
|
|
314
|
+
│ - Schema validation on all external data │
|
|
315
|
+
│ - Git subprocess (no shell=true, no string interpolation) │
|
|
316
|
+
│ - CDATA wrapping for XML output │
|
|
317
|
+
└─────────────────────────────────────────────────────────────┘
|
|
318
|
+
|
|
319
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
320
|
+
│ Output Sanitization │
|
|
321
|
+
│ - Credentials never in output │
|
|
322
|
+
│ - Error messages sanitized │
|
|
323
|
+
│ - XML special chars handled via CDATA │
|
|
324
|
+
└─────────────────────────────────────────────────────────────┘
|
|
325
|
+
```
|