osdlc-kit 0.3.0__tar.gz

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,20 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ day: "monday"
8
+ open-pull-requests-limit: 5
9
+ commit-message:
10
+ prefix: "fix"
11
+ prefix-development: "chore"
12
+
13
+ - package-ecosystem: "github-actions"
14
+ directory: "/"
15
+ schedule:
16
+ interval: "weekly"
17
+ day: "monday"
18
+ open-pull-requests-limit: 5
19
+ commit-message:
20
+ prefix: "chore"
@@ -0,0 +1,27 @@
1
+ name: CodeQL
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ schedule:
9
+ - cron: '0 12 * * 1'
10
+
11
+ jobs:
12
+ analyze:
13
+ name: Analyze
14
+ runs-on: ubuntu-latest
15
+ permissions:
16
+ actions: read
17
+ contents: read
18
+ security-events: write
19
+
20
+ steps:
21
+ - uses: actions/checkout@v6
22
+
23
+ - uses: github/codeql-action/init@v4
24
+
25
+ - uses: github/codeql-action/autobuild@v4
26
+
27
+ - uses: github/codeql-action/analyze@v4
@@ -0,0 +1,36 @@
1
+ name: Lint
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize]
6
+
7
+ permissions:
8
+ contents: read
9
+ pull-requests: write
10
+
11
+ jobs:
12
+ super-linter:
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v6
18
+ with:
19
+ fetch-depth: 0
20
+
21
+ - name: Super-Linter
22
+ uses: super-linter/super-linter@v8.6.0
23
+ env:
24
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
25
+ VALIDATE_ALL_CODEBASE: false
26
+ DEFAULT_BRANCH: main
27
+ VALIDATE_JAVA: true
28
+ VALIDATE_KOTLIN_KT_LINT: true
29
+ VALIDATE_KOTLIN_BIOME: true
30
+ VALIDATE_YAML: true
31
+ VALIDATE_JSON: true
32
+ VALIDATE_XML: true
33
+ VALIDATE_MARKDOWN: true
34
+ VALIDATE_PROPERTIES: true
35
+ VALIDATE_GITHUB_ACTIONS: true
36
+ FILTER_REGEX_EXCLUDE: \.jks$|\.jar$|\.keystore$
@@ -0,0 +1,235 @@
1
+ ---
2
+ name: opencode
3
+
4
+ on:
5
+ issue_comment:
6
+ types: [created]
7
+ pull_request_review:
8
+ types: [submitted]
9
+ workflow_run:
10
+ workflows: ["PR Check"]
11
+ types: [completed]
12
+
13
+ concurrency:
14
+ group: opencode-${{ github.event_name }}-${{
15
+ github.event.issue.number ||
16
+ github.event.pull_request.number ||
17
+ github.event.workflow_run.pull_requests[0].number ||
18
+ github.event.reply_to_id }}-${{
19
+ github.event_name == 'workflow_run' && 'auto' ||
20
+ contains(github.event.comment.body, '/oc') && 'cmd' ||
21
+ 'other' }}
22
+ cancel-in-progress: true
23
+
24
+ jobs:
25
+ opencode:
26
+ if: |
27
+ github.event_name != 'workflow_run' &&
28
+ github.event.comment != null &&
29
+ github.event.comment.author_association == 'OWNER' &&
30
+ github.actor == 'andreaschiona' &&
31
+ (
32
+ contains(github.event.comment.body, ' /oc') ||
33
+ startsWith(github.event.comment.body, '/oc') ||
34
+ contains(github.event.comment.body, ' /opencode') ||
35
+ startsWith(github.event.comment.body, '/opencode')
36
+ )
37
+ runs-on: ubuntu-latest
38
+ timeout-minutes: 180
39
+ permissions:
40
+ id-token: write
41
+ contents: write
42
+ pull-requests: write
43
+ issues: write
44
+ steps:
45
+ - name: Checkout repository
46
+ uses: actions/checkout@v6
47
+ with:
48
+ persist-credentials: false
49
+ fetch-depth: 0
50
+
51
+ - name: Install jq
52
+ shell: bash
53
+ run: sudo apt-get update -qq && sudo apt-get install -y -qq jq
54
+
55
+ - name: Setup Python
56
+ uses: actions/setup-python@v5
57
+ with:
58
+ python-version: '3.x'
59
+
60
+ - name: Get opencode version
61
+ id: version
62
+ shell: bash
63
+ run: |
64
+ VERSION=$(curl -sf https://api.github.com/repos/anomalyco/opencode/releases/latest |
65
+ grep -o '"tag_name": *"[^"]*"' | cut -d'"' -f4 || true)
66
+ echo "version=${VERSION:-v1.15.10}" >> "$GITHUB_OUTPUT"
67
+
68
+ - name: Cache opencode
69
+ id: cache
70
+ uses: actions/cache@v5
71
+ with:
72
+ path: ~/.opencode/bin
73
+ key: opencode-${{ runner.os }}-${{ runner.arch }}-${{ steps.version.outputs.version }}
74
+
75
+ - name: Install opencode
76
+ if: steps.cache.outputs.cache-hit != 'true'
77
+ shell: bash
78
+ run: curl -fsSL https://opencode.ai/install.sh | sh -s -- ${{ steps.version.outputs.version }}
79
+
80
+ - name: Add opencode to PATH
81
+ shell: bash
82
+ run: echo "$HOME/.opencode/bin" >> "$GITHUB_PATH"
83
+
84
+ - name: Determine model from comment
85
+ id: model_select
86
+ shell: bash
87
+ env:
88
+ COMMENT: ${{ github.event.comment.body }}
89
+ run: |
90
+ if echo "$COMMENT" | grep -qi "GEMINI"; then
91
+ echo "model=google/gemini-2.5-flash" >> "$GITHUB_OUTPUT"
92
+ elif echo "$COMMENT" | grep -qi "BIGPICKLE"; then
93
+ echo "model=opencode/big-pickle" >> "$GITHUB_OUTPUT"
94
+ elif echo "$COMMENT" | grep -qi "NEMOTRON"; then
95
+ echo "model=opencode/nemotron-3-super-free" >> "$GITHUB_OUTPUT"
96
+ else
97
+ echo "model=opencode/deepseek-v4-flash-free" >> "$GITHUB_OUTPUT"
98
+ fi
99
+
100
+ - name: Run opencode (with retry)
101
+ shell: bash
102
+ id: run_opencode
103
+ env:
104
+ MODEL: ${{ steps.model_select.outputs.model }}
105
+ OPENCODE_TELEMETRY: false
106
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
107
+ GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
108
+ run: |
109
+ echo "Selected model: $MODEL"
110
+
111
+ jq --arg model "$MODEL" '.model = $model' opencode.json > opencode.tmp.json && mv opencode.tmp.json opencode.json
112
+ echo "Injected model '$MODEL' into opencode.json"
113
+
114
+ MAX_RETRIES=3
115
+ RETRY_DELAY=15
116
+ for i in $(seq 1 "$MAX_RETRIES"); do
117
+ echo "opencode run attempt $i of $MAX_RETRIES"
118
+ if opencode github run; then
119
+ echo "opencode completed successfully"
120
+ exit 0
121
+ fi
122
+ exit_code=$?
123
+ echo "opencode exit code: $exit_code"
124
+ if [ "$i" -eq "$MAX_RETRIES" ]; then
125
+ echo "All $MAX_RETRIES attempts failed, last exit code: $exit_code"
126
+ exit 1
127
+ fi
128
+ echo "Attempt $i failed (exit code: $exit_code), retrying in ${RETRY_DELAY}s..."
129
+ sleep "$RETRY_DELAY"
130
+ done
131
+
132
+ auto-analyze-failure:
133
+ if: |
134
+ github.event_name == 'workflow_run' &&
135
+ github.event.workflow_run.conclusion == 'failure' &&
136
+ github.event.workflow_run.pull_requests[0] != null &&
137
+ github.event.workflow_run.head_repository.fork == false
138
+ runs-on: ubuntu-latest
139
+ timeout-minutes: 30
140
+ permissions:
141
+ contents: read
142
+ pull-requests: write
143
+ checks: read
144
+ steps:
145
+ - name: Checkout PR head
146
+ uses: actions/checkout@v6
147
+ with:
148
+ ref: ${{ github.event.workflow_run.head_sha }}
149
+ fetch-depth: 0
150
+ persist-credentials: false
151
+
152
+ - name: Get PR number
153
+ id: pr
154
+ shell: bash
155
+ run: |
156
+ {
157
+ echo "number=${{ github.event.workflow_run.pull_requests[0].number }}"
158
+ echo "head_branch=${{ github.event.workflow_run.head_branch }}"
159
+ echo "head_sha=${{ github.event.workflow_run.head_sha }}"
160
+ } >> "$GITHUB_OUTPUT"
161
+
162
+ - name: Collect failure context
163
+ shell: bash
164
+ run: |
165
+ mkdir -p /tmp/ci-context
166
+ URL="/repos/${{ github.repository }}/commits/${{ github.event.workflow_run.head_sha }}/check-runs"
167
+ gh api "$URL" --jq '
168
+ .check_runs[] | select(.conclusion == "failure") |
169
+ "## \(.name)\n\n**Title:** \(.output.title // "failed")\n\n**Summary:**\n\(.output.summary // "N/A")\n\n**Text:**\n\(.output.text // "N/A")\n"
170
+ ' > /tmp/ci-context/check-failures.md
171
+ gh pr diff ${{ steps.pr.outputs.number }} > /tmp/ci-context/pr-diff.diff
172
+ echo "Failure context collected ($(wc -l < /tmp/ci-context/check-failures.md) lines)"
173
+ env:
174
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
175
+
176
+ - name: Get opencode version
177
+ id: version
178
+ shell: bash
179
+ run: |
180
+ VERSION=$(curl -sf https://api.github.com/repos/anomalyco/opencode/releases/latest |
181
+ grep -o '"tag_name": *"[^"]*"' | cut -d'"' -f4 || true)
182
+ echo "version=${VERSION:-v1.15.10}" >> "$GITHUB_OUTPUT"
183
+
184
+ - name: Cache opencode
185
+ id: cache
186
+ uses: actions/cache@v5
187
+ with:
188
+ path: ~/.opencode/bin
189
+ key: opencode-auto-${{ runner.os }}-${{ runner.arch }}-${{ steps.version.outputs.version }}
190
+
191
+ - name: Install opencode
192
+ if: steps.cache.outputs.cache-hit != 'true'
193
+ shell: bash
194
+ run: curl -fsSL https://opencode.ai/install.sh | sh -s -- ${{ steps.version.outputs.version }}
195
+
196
+ - name: Add opencode to PATH
197
+ shell: bash
198
+ run: echo "$HOME/.opencode/bin" >> "$GITHUB_PATH"
199
+
200
+ - name: Analyze failures with opencode
201
+ shell: bash
202
+ continue-on-error: true
203
+ env:
204
+ OPENCODE_TELEMETRY: false
205
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
206
+ GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
207
+ run: |
208
+ opencode run --model opencode/deepseek-v4-flash-free \
209
+ --file /tmp/ci-context/check-failures.md \
210
+ --file /tmp/ci-context/pr-diff.diff \
211
+ "I CI check su questa PR (#${{ steps.pr.outputs.number }}) sono falliti. \
212
+ I file allegati contengono i dettagli dei check falliti e il diff della PR. \
213
+ Analizza i fallimenti e proponi correzioni specifiche. \
214
+ Fornisci un'analisi dettagliata in italiano." \
215
+ > /tmp/ci-context/analysis.md 2>&1
216
+
217
+ - name: Post analysis to PR
218
+ if: always() && steps.pr.outputs.number != ''
219
+ shell: bash
220
+ env:
221
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
222
+ run: |
223
+ {
224
+ echo '## Analisi automatica CI'
225
+ echo ''
226
+ if [ -s /tmp/ci-context/analysis.md ]; then
227
+ echo 'OpenCode ha analizzato i fallimenti dei check su questo PR.'
228
+ echo ''
229
+ cat /tmp/ci-context/analysis.md
230
+ else
231
+ echo "L'analisi automatica non ha prodotto risultati."
232
+ echo "Per analizzare manualmente, commenta con /oc analizza i fallimenti CI su questa PR."
233
+ fi
234
+ } > /tmp/ci-context/body.md
235
+ gh pr comment ${{ steps.pr.outputs.number }} --body-file /tmp/ci-context/body.md
@@ -0,0 +1,62 @@
1
+ name: PR Check
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize, reopened]
6
+ branches: [main]
7
+
8
+ permissions:
9
+ contents: read
10
+ pull-requests: write
11
+ checks: write
12
+
13
+ jobs:
14
+ check:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v6
18
+ with:
19
+ fetch-depth: 0
20
+
21
+ - name: Setup Python
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: '3.x'
25
+
26
+ - name: Install dependencies
27
+ run: pip install pytest pytest-cov
28
+
29
+ - name: Lint
30
+ run: python -m py_compile run.py src/osdlc/*.py
31
+
32
+ - name: Test with coverage
33
+ run: python -m pytest --cov=src/osdlc --cov-report=xml --cov-report=term-missing -v
34
+
35
+ - name: Build
36
+ run: python -m py_compile run.py src/osdlc/*.py
37
+
38
+ - name: Upload coverage artifact
39
+ if: always()
40
+ uses: actions/upload-artifact@v7
41
+ with:
42
+ name: coverage-report
43
+ path: coverage.xml
44
+ retention-days: 7
45
+
46
+ - name: PR comment with results
47
+ if: always() && github.event_name == 'pull_request'
48
+ uses: actions/github-script@v9
49
+ with:
50
+ script: |
51
+ const { data: checks } = await github.rest.checks.listForRef({
52
+ ...context.repo,
53
+ ref: context.sha,
54
+ });
55
+ const summary = checks.check_runs.map(c =>
56
+ `- **${c.name}**: ${c.conclusion || 'in_progress'}`
57
+ ).join('\n');
58
+ github.rest.issues.createComment({
59
+ ...context.repo,
60
+ issue_number: context.issue.number,
61
+ body: `## PR Check Results\n\n${summary}\n\n_Updated at ${new Date().toISOString()}_`,
62
+ });
@@ -0,0 +1,156 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths-ignore:
7
+ - '**.md'
8
+ - '.gitignore'
9
+ - '.github/**'
10
+
11
+ permissions:
12
+ contents: write
13
+ issues: write
14
+ id-token: write # needed for PyPI trusted publishing
15
+
16
+ jobs:
17
+ release:
18
+ runs-on: ubuntu-latest
19
+ outputs:
20
+ new_version: ${{ steps.resolve.outputs.new_version }}
21
+ steps:
22
+ - uses: actions/checkout@v6
23
+ with:
24
+ fetch-depth: 0
25
+
26
+ - name: Setup Python
27
+ uses: actions/setup-python@v5
28
+ with:
29
+ python-version: '3.x'
30
+
31
+ - name: Determine bump
32
+ id: bump
33
+ run: |
34
+ LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || true)
35
+ if [ -z "$LAST_TAG" ]; then
36
+ COMMITS=$(git log --format="%s")
37
+ else
38
+ COMMITS=$(git log "$LAST_TAG..HEAD" --format="%s")
39
+ fi
40
+ if echo "$COMMITS" | grep -q "BREAKING CHANGE"; then
41
+ echo "BUMP_TYPE=major" >> "$GITHUB_ENV"
42
+ elif echo "$COMMITS" | grep -q "^feat"; then
43
+ echo "BUMP_TYPE=minor" >> "$GITHUB_ENV"
44
+ else
45
+ echo "BUMP_TYPE=patch" >> "$GITHUB_ENV"
46
+ fi
47
+
48
+ - name: Bump version
49
+ id: version
50
+ shell: bash
51
+ run: |
52
+ OUTPUT=$(python src/osdlc/version.py update --root . 2>&1)
53
+ echo "update_output=$OUTPUT" >> "$GITHUB_OUTPUT"
54
+ NEW_VERSION=$(echo "$OUTPUT" | sed -n 's/.*-> \([0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p')
55
+ echo "new_version=$NEW_VERSION" >> "$GITHUB_OUTPUT"
56
+ echo "$OUTPUT"
57
+
58
+ - name: Install dependencies
59
+ run: pip install pytest
60
+
61
+ - name: Lint
62
+ run: python -m py_compile run.py src/osdlc/*.py
63
+
64
+ - name: Run tests
65
+ id: tests
66
+ continue-on-error: true
67
+ run: python -m pytest -v || test $? -eq 5
68
+
69
+ - name: Build
70
+ run: python -m py_compile run.py src/osdlc/*.py
71
+
72
+ - name: Create issue on test failure
73
+ if: steps.tests.outcome == 'failure'
74
+ uses: actions/github-script@v9
75
+ with:
76
+ script: |
77
+ github.rest.issues.create({
78
+ owner: context.repo.owner,
79
+ repo: context.repo.repo,
80
+ title: 'Release tests failed',
81
+ body: 'Tests failed during release for version ${{ steps.version.outputs.new_version }}. Check the release workflow run for details.',
82
+ labels: ['bug', 'auto-reported']
83
+ })
84
+
85
+ - name: Fail if tests failed
86
+ if: steps.tests.outcome == 'failure'
87
+ run: exit 1
88
+
89
+ - name: Resolve version (increment if tag exists)
90
+ id: resolve
91
+ run: |
92
+ VERSION_FILE="VERSION"
93
+ [ -f "pyproject.toml" ] && VERSION_FILE="pyproject.toml"
94
+ NEW_VERSION="${{ steps.version.outputs.new_version }}"
95
+ while git tag -l "v$NEW_VERSION" | grep -q .; do
96
+ echo "Tag v$NEW_VERSION already exists — incrementing"
97
+ IFS='.' read -r MAJOR MINOR PATCH <<< "$NEW_VERSION"
98
+ case "$BUMP_TYPE" in
99
+ major) MAJOR=$((MAJOR+1)); MINOR=0; PATCH=0 ;;
100
+ minor) MINOR=$((MINOR+1)); PATCH=0 ;;
101
+ patch) PATCH=$((PATCH+1)) ;;
102
+ esac
103
+ NEW_VERSION="$MAJOR.$MINOR.$PATCH"
104
+ done
105
+ echo "new_version=$NEW_VERSION" >> "$GITHUB_OUTPUT"
106
+ if [ -f "pyproject.toml" ]; then
107
+ sed -i "s/version = \"[0-9.]*\"/version = \"$NEW_VERSION\"/" pyproject.toml
108
+ else
109
+ echo "version=$NEW_VERSION" > "$VERSION_FILE"
110
+ fi
111
+
112
+ - name: Commit version bump
113
+ run: |
114
+ git config user.name "github-actions"
115
+ git config user.email "actions@github.com"
116
+ VERSION_FILE=$(python src/osdlc/version.py detect --root . | cut -d' ' -f1)
117
+ [ -z "$VERSION_FILE" ] && VERSION_FILE="VERSION"
118
+ git add "$VERSION_FILE"
119
+ git commit -m "chore: bump version to ${{ steps.resolve.outputs.new_version }} [skip ci]"
120
+ git tag v${{ steps.resolve.outputs.new_version }}
121
+
122
+ - name: Push changes
123
+ run: |
124
+ git push origin main
125
+ git push origin v${{ steps.resolve.outputs.new_version }}
126
+
127
+ - name: Create Release
128
+ uses: softprops/action-gh-release@v3
129
+ with:
130
+ tag_name: v${{ steps.resolve.outputs.new_version }}
131
+ generate_release_notes: true
132
+ make_latest: true
133
+
134
+ publish:
135
+ needs: release
136
+ runs-on: ubuntu-latest
137
+ permissions:
138
+ id-token: write
139
+ steps:
140
+ - uses: actions/checkout@v6
141
+ with:
142
+ ref: v${{ needs.release.outputs.new_version }}
143
+ fetch-depth: 0
144
+
145
+ - name: Setup Python
146
+ uses: actions/setup-python@v5
147
+ with:
148
+ python-version: '3.x'
149
+
150
+ - name: Build wheel
151
+ run: |
152
+ pip install hatchling
153
+ python -m hatchling build
154
+
155
+ - name: Publish to PyPI
156
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ .env
5
+ venv/
6
+ .venv/
7
+ .coverage
8
+ coverage.xml
9
+ .pytest_cache/
@@ -0,0 +1,67 @@
1
+ # AI Open SDLC Kit -- Agent Instructions
2
+
3
+ ## Project Overview
4
+
5
+ This project uses Python with a manual build system (manual).
6
+
7
+ ## Verified Commands
8
+
9
+ - **Build:** `python -m py_compile run.py src/osdlc/*.py`
10
+ - **Test:** `python -m pytest --cov=src/osdlc --cov-report=xml --cov-report=term-missing -v`
11
+ - **Lint:** `python -m py_compile run.py src/osdlc/*.py`
12
+
13
+ ## Environment
14
+
15
+ Python 3.x. Install dependencies with `pip install pytest pytest-cov`.
16
+
17
+ ## OpenCode Protocol
18
+
19
+ The agent MUST handle slash-commands found in issue or PR comments.
20
+
21
+ ### Parsing
22
+
23
+ When opencode is triggered by a comment:
24
+ 1. Read the comment body from the triggering event.
25
+ 2. If the comment starts with `/oc` or `/opencode`, extract the first whitespace-delimited token immediately following the prefix.
26
+ 3. The remainder of the comment (after the command token) is the **instruction payload**.
27
+ 4. Route to the appropriate behaviour based on the command token.
28
+
29
+ ### Commands
30
+
31
+ - **`/oc fix`** (Issue) - Apply a quick corrective change. Analyse the issue, create a throwaway fix branch from `main`, apply the fix, commit with `fix:`, and push. Do NOT create a PR. The payload may describe the fix intent.
32
+ - **`/oc analyze`** (Issue) - Read the issue body and all comments. Perform a critical analysis, then post a detailed functional requirement as a new issue comment. Include: problem statement, affected areas, acceptance criteria, and open questions.
33
+ - **`/oc plan`** (Issue) - Requires prior analyze. Read the analysed requirement, produce a technical implementation plan with file-level breakdown, and post it as a new issue comment.
34
+ - **`/oc implement`** (Issue) - Requires prior plan. Create branch `issue-{{number}}` from `main`. Implement file-by-file, commit each unit conventionally. Open a PR targeting `main` with `Closes #{{number}}`.
35
+ - **`/oc fixCheck`** (PR) - Read automated check results. For each failure, apply a fix, amend the PR branch, and re-trigger checks. Repeat up to 3 retries. Post a status comment when done.
36
+
37
+ ### Instruction Payload
38
+
39
+ Any text after the command token is the instruction payload. The agent MAY use it for additional context:
40
+ - `/oc fix add null guard` -> command `fix`, payload `add null guard`
41
+ - `/oc analyze` -> command `analyze`, payload empty
42
+
43
+ ### Model Overrides
44
+
45
+ The workflow sets the model based on keywords anywhere in the comment (case-insensitive):
46
+
47
+ - `GEMINI` -> `google/gemini-2.5-flash`
48
+ - `BIGPICKLE` -> `opencode/big-pickle`
49
+ - `NEMOTRON` -> `opencode/nemotron-3-super-free`
50
+ - (default) -> `opencode/deepseek-v4-flash-free`
51
+
52
+ ## Commit Convention
53
+
54
+ Every commit MUST follow the Conventional Commits specification:
55
+ - `feat: ...` -- a new feature
56
+ - `fix: ...` -- a bug fix
57
+ - `chore: ...` -- maintenance, dependencies, tooling
58
+ - `BREAKING CHANGE: ...` or `feat!: ...` -- incompatible API changes
59
+
60
+ ## Branch Naming
61
+
62
+ Feature branches MUST follow the pattern: `issue-{{number}}`
63
+ Always branch from `main`.
64
+
65
+ ## Version Configuration
66
+
67
+ Version is stored in: `VERSION`
Binary file