4 files changed
+439
-44
.github/workflows/release.yml
new
+189
@@ -0,0 +1,189 @@
1
+name: Release
2
+
3
+on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+ workflow_dispatch:
8
+ inputs:
9
+ tag:
10
+ description: "Release tag (e.g. v0.1.0)"
11
+ required: true
12
+
13
+permissions:
14
+ contents: write
15
+
16
+env:
17
+ CARGO_TERM_COLOR: always
18
+
19
+jobs:
20
+ build:
21
+ name: Build ${{ matrix.artifact }}
22
+ runs-on: ${{ matrix.os }}
23
+ strategy:
24
+ fail-fast: false
25
+ matrix:
26
+ include:
27
+ - target: aarch64-apple-darwin
28
+ os: macos-latest
29
+ artifact: sigit-darwin-aarch64
30
+ binary: sigit
31
+ archive_ext: tar.gz
32
+
33
+ - target: x86_64-apple-darwin
34
+ os: macos-13
35
+ artifact: sigit-darwin-x86_64
36
+ binary: sigit
37
+ archive_ext: tar.gz
38
+
39
+ - target: x86_64-unknown-linux-gnu
40
+ os: ubuntu-latest
41
+ artifact: sigit-linux-x86_64
42
+ binary: sigit
43
+ archive_ext: tar.gz
44
+
45
+ - target: aarch64-unknown-linux-gnu
46
+ os: ubuntu-24.04-arm
47
+ artifact: sigit-linux-aarch64
48
+ binary: sigit
49
+ archive_ext: tar.gz
50
+
51
+ - target: x86_64-pc-windows-msvc
52
+ os: windows-latest
53
+ artifact: sigit-windows-x86_64
54
+ binary: sigit.exe
55
+ archive_ext: zip
56
+
57
+ steps:
58
+ - name: Checkout
59
+ uses: actions/checkout@v6
60
+ with:
61
+ ref: ${{ github.event.inputs.tag || github.ref }}
62
+
63
+ - name: Set release version
64
+ shell: bash
65
+ run: |
66
+ if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
67
+ release_version="${GITHUB_REF_NAME#v}"
68
+ else
69
+ release_version="${{ github.event.inputs.tag }}"
70
+ release_version="${release_version#v}"
71
+ fi
72
+
73
+ echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
74
+
75
+ - name: Verify Cargo.toml version matches tag
76
+ shell: bash
77
+ run: |
78
+ CARGO_VERSION=$(cargo metadata --no-deps --format-version 1 \
79
+ | jq -r '.packages[] | select(.name == "sigit") | .version')
80
+
81
+ echo "Cargo.toml version : ${CARGO_VERSION}"
82
+ echo "Release tag version: ${RELEASE_VERSION}"
83
+
84
+ if [[ "${CARGO_VERSION}" != "${RELEASE_VERSION}" ]]; then
85
+ echo "::error::Version mismatch — bump Cargo.toml version before tagging."
86
+ exit 1
87
+ fi
88
+
89
+ - name: Install Rust toolchain
90
+ uses: dtolnay/rust-toolchain@stable
91
+ with:
92
+ targets: ${{ matrix.target }}
93
+
94
+ - name: Setup Rust cache
95
+ uses: Swatinem/rust-cache@v2
96
+ with:
97
+ key: release-${{ matrix.target }}
98
+
99
+ - name: Build
100
+ shell: bash
101
+ run: cargo build --release --locked --target ${{ matrix.target }}
102
+
103
+ - name: Package (tar.gz)
104
+ if: matrix.archive_ext == 'tar.gz'
105
+ shell: bash
106
+ run: |
107
+ binary="target/${{ matrix.target }}/release/${{ matrix.binary }}"
108
+ archive="${{ matrix.artifact }}.tar.gz"
109
+
110
+ tar -czf "${archive}" -C "$(dirname "${binary}")" "${{ matrix.binary }}"
111
+
112
+ echo "ARCHIVE=${archive}" >> "$GITHUB_ENV"
113
+
114
+ - name: Package (zip)
115
+ if: matrix.archive_ext == 'zip'
116
+ shell: pwsh
117
+ run: |
118
+ $binary = "target\${{ matrix.target }}\release\${{ matrix.binary }}"
119
+ $archive = "${{ matrix.artifact }}.zip"
120
+
121
+ Compress-Archive -Path $binary -DestinationPath $archive
122
+
123
+ "ARCHIVE=$archive" | Out-File -FilePath $env:GITHUB_ENV -Append
124
+
125
+ - name: Upload archive
126
+ uses: actions/upload-artifact@v4
127
+ with:
128
+ name: ${{ matrix.artifact }}
129
+ path: ${{ env.ARCHIVE }}
130
+ if-no-files-found: error
131
+ retention-days: 1
132
+
133
+ release:
134
+ name: Publish GitHub Release
135
+ needs: build
136
+ runs-on: ubuntu-latest
137
+ permissions:
138
+ contents: write
139
+
140
+ steps:
141
+ - name: Checkout
142
+ uses: actions/checkout@v6
143
+ with:
144
+ ref: ${{ github.event.inputs.tag || github.ref }}
145
+
146
+ - name: Set release version and tag
147
+ shell: bash
148
+ run: |
149
+ if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
150
+ release_tag="${GITHUB_REF_NAME}"
151
+ release_version="${GITHUB_REF_NAME#v}"
152
+ else
153
+ release_tag="${{ github.event.inputs.tag }}"
154
+ release_version="${{ github.event.inputs.tag }}"
155
+ release_version="${release_version#v}"
156
+ fi
157
+
158
+ echo "RELEASE_TAG=${release_tag}" >> "$GITHUB_ENV"
159
+ echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
160
+
161
+ - name: Download all archives
162
+ uses: actions/download-artifact@v4
163
+ with:
164
+ path: archives
165
+ merge-multiple: true
166
+
167
+ - name: Check whether release already exists
168
+ id: release-check
169
+ shell: bash
170
+ run: |
171
+ if gh release view "${RELEASE_TAG}" --repo "${{ github.repository }}" >/dev/null 2>&1; then
172
+ echo "Release ${RELEASE_TAG} already exists — skipping."
173
+ echo "exists=true" >> "$GITHUB_OUTPUT"
174
+ else
175
+ echo "exists=false" >> "$GITHUB_OUTPUT"
176
+ fi
177
+ env:
178
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
179
+
180
+ - name: Create release and upload archives
181
+ if: steps.release-check.outputs.exists != 'true'
182
+ shell: bash
183
+ run: |
184
+ gh release create "${RELEASE_TAG}" \
185
+ --title "siGit ${RELEASE_TAG}" \
186
+ --generate-notes \
187
+ archives/*
188
+ env:
189
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Cargo.lock
+57
-41
@@ -1056,16 +1056,15 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
1056
1057
[[package]]
1058
name = "crossterm"
1059
-version = "0.28.1"
1059
+version = "0.25.0"
1060
source = "registry+https://github.com/rust-lang/crates.io-index"
1061
-checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
1061
+checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
1062
dependencies = [
1063
- "bitflags 2.11.0",
1063
+ "bitflags 1.3.2",
1064
"crossterm_winapi",
1065
- "futures-core",
1066
- "mio",
1065
+ "libc",
1066
+ "mio 0.8.11",
1067
"parking_lot",
1068
- "rustix 0.38.44",
1068
"signal-hook",
1069
"signal-hook-mio",
1070
"winapi",
@@ -1073,17 +1072,16 @@ dependencies = [
1072
1073
[[package]]
1074
name = "crossterm"
1076
-version = "0.29.0"
1075
+version = "0.28.1"
1076
source = "registry+https://github.com/rust-lang/crates.io-index"
1078
-checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
1077
+checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
1078
dependencies = [
1079
"bitflags 2.11.0",
1080
"crossterm_winapi",
1082
- "derive_more",
1083
- "document-features",
1084
- "mio",
1081
+ "futures-core",
1082
+ "mio 1.2.0",
1083
"parking_lot",
1086
- "rustix 1.1.4",
1084
+ "rustix 0.38.44",
1085
"signal-hook",
1086
"signal-hook-mio",
1087
"winapi",
@@ -1437,15 +1435,6 @@ version = "1.1.1"
1435
source = "registry+https://github.com/rust-lang/crates.io-index"
1436
checksum = "c2db04e74f0a9a93103b50e90b96024c9b2bdca8bce6a632ec71b88736d3d359"
1437
1440
-[[package]]
1441
-name = "document-features"
1442
-version = "0.2.12"
1443
-source = "registry+https://github.com/rust-lang/crates.io-index"
1444
-checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
1445
-dependencies = [
1446
- "litrs",
1447
-]
1448
-
1438
[[package]]
1439
name = "dtoa"
1440
version = "1.0.11"
@@ -3027,12 +3016,6 @@ version = "0.8.2"
3016
source = "registry+https://github.com/rust-lang/crates.io-index"
3017
checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
3018
3030
-[[package]]
3031
-name = "litrs"
3032
-version = "1.0.0"
3033
-source = "registry+https://github.com/rust-lang/crates.io-index"
3034
-checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
3035
-
3019
[[package]]
3020
name = "llguidance"
3021
version = "1.7.2"
@@ -3287,6 +3270,18 @@ dependencies = [
3270
"simd-adler32",
3271
]
3272
3273
+[[package]]
3274
+name = "mio"
3275
+version = "0.8.11"
3276
+source = "registry+https://github.com/rust-lang/crates.io-index"
3277
+checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
3278
+dependencies = [
3279
+ "libc",
3280
+ "log",
3281
+ "wasi",
3282
+ "windows-sys 0.48.0",
3283
+]
3284
+
3285
[[package]]
3286
name = "mio"
3287
version = "1.2.0"
@@ -3302,7 +3297,8 @@ dependencies = [
3297
[[package]]
3298
name = "mistralrs"
3299
version = "0.8.1"
3305
-source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#a27af8ea01123e5d5777120619413345989f4006"
3300
+source = "registry+https://github.com/rust-lang/crates.io-index"
3301
+checksum = "9bb0a83340b4492ebba9760ba6845364de369c7e10c1f91af8733d574c7405fa"
3302
dependencies = [
3303
"anyhow",
3304
"candle-core",
@@ -3329,7 +3325,8 @@ dependencies = [
3325
[[package]]
3326
name = "mistralrs-audio"
3327
version = "0.8.1"
3332
-source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#a27af8ea01123e5d5777120619413345989f4006"
3328
+source = "registry+https://github.com/rust-lang/crates.io-index"
3329
+checksum = "5ac5d36f634c7c20c45845bc995be3b6387ab01048410386a5b180cfeaf89c72"
3330
dependencies = [
3331
"anyhow",
3332
"apodize",
@@ -3340,7 +3337,8 @@ dependencies = [
3337
[[package]]
3338
name = "mistralrs-core"
3339
version = "0.8.1"
3343
-source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#a27af8ea01123e5d5777120619413345989f4006"
3340
+source = "registry+https://github.com/rust-lang/crates.io-index"
3341
+checksum = "a2b8b9e5c94491d9ceeded3a30291cb6af6ae74810a5776dd55e3bbb8b3429d4"
3342
dependencies = [
3343
"ahash",
3344
"akin",
@@ -3437,7 +3435,8 @@ dependencies = [
3435
[[package]]
3436
name = "mistralrs-macros"
3437
version = "0.8.1"
3440
-source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#a27af8ea01123e5d5777120619413345989f4006"
3438
+source = "registry+https://github.com/rust-lang/crates.io-index"
3439
+checksum = "5aa9b4794322d3f89fe61d21f33f67be494c16d5bd869604b111218f32544d32"
3440
dependencies = [
3441
"darling 0.23.0",
3442
"proc-macro2",
@@ -3448,7 +3447,8 @@ dependencies = [
3447
[[package]]
3448
name = "mistralrs-mcp"
3449
version = "0.8.1"
3451
-source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#a27af8ea01123e5d5777120619413345989f4006"
3450
+source = "registry+https://github.com/rust-lang/crates.io-index"
3451
+checksum = "4fa97d4e3189ed80ebbc730b7da5b2356df0ae004ab489066249340c33c089ab"
3452
dependencies = [
3453
"anyhow",
3454
"async-trait",
@@ -3468,7 +3468,8 @@ dependencies = [
3468
[[package]]
3469
name = "mistralrs-paged-attn"
3470
version = "0.8.1"
3471
-source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#a27af8ea01123e5d5777120619413345989f4006"
3471
+source = "registry+https://github.com/rust-lang/crates.io-index"
3472
+checksum = "6e53ddf1537426997b46abdadbe6ca8a7ce7668004ed2b7cf00115016558bae8"
3473
dependencies = [
3474
"anyhow",
3475
"candle-core",
@@ -3484,7 +3485,8 @@ dependencies = [
3485
[[package]]
3486
name = "mistralrs-quant"
3487
version = "0.8.1"
3487
-source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#a27af8ea01123e5d5777120619413345989f4006"
3488
+source = "registry+https://github.com/rust-lang/crates.io-index"
3489
+checksum = "980715493d252e9aaf0779c4c101576d67ef4dd9812bfd77a54987f6f17526f4"
3490
dependencies = [
3491
"byteorder",
3492
"candle-core",
@@ -3513,7 +3515,8 @@ dependencies = [
3515
[[package]]
3516
name = "mistralrs-vision"
3517
version = "0.8.1"
3516
-source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#a27af8ea01123e5d5777120619413345989f4006"
3518
+source = "registry+https://github.com/rust-lang/crates.io-index"
3519
+checksum = "10046a3da2de5b702d3e829b5ddef7aa829ad454819dcc4876dea481a6cb5456"
3520
dependencies = [
3521
"candle-core",
3522
"image",
@@ -3827,7 +3830,9 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
3830
3831
[[package]]
3832
name = "onde"
3830
-version = "0.1.3"
3833
+version = "0.1.4"
3834
+source = "registry+https://github.com/rust-lang/crates.io-index"
3835
+checksum = "939495589fec914220491600a00bddedcba437e5fd5e3926ca1af2e8da681bb0"
3836
dependencies = [
3837
"anyhow",
3838
"cc",
@@ -5292,7 +5297,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
5297
5298
[[package]]
5299
name = "sigit"
5295
-version = "0.1.0"
5300
+version = "0.1.1"
5301
dependencies = [
5302
"agent-client-protocol",
5303
"anyhow",
@@ -5325,7 +5330,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
5330
checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc"
5331
dependencies = [
5332
"libc",
5328
- "mio",
5333
+ "mio 0.8.11",
5334
+ "mio 1.2.0",
5335
"signal-hook",
5336
]
5337
@@ -6106,7 +6112,7 @@ checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c"
6112
dependencies = [
6113
"bytes",
6114
"libc",
6109
- "mio",
6115
+ "mio 1.2.0",
6116
"parking_lot",
6117
"pin-project-lite",
6118
"signal-hook-registry",
@@ -6286,10 +6292,11 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
6292
[[package]]
6293
name = "tqdm"
6294
version = "0.8.0"
6289
-source = "git+https://github.com/setoelkahfi/tqdm?branch=deps%2Fbump-crossterm#41e4182829136e6dadbdd1c36af824d19219147a"
6295
+source = "registry+https://github.com/rust-lang/crates.io-index"
6296
+checksum = "b316d5c2ac649ca856dacd487d0ebb94f3b746bada51355d93dd2c007ab62a2e"
6297
dependencies = [
6298
"anyhow",
6292
- "crossterm 0.29.0",
6299
+ "crossterm 0.25.0",
6300
"once_cell",
6301
]
6302
@@ -7266,6 +7273,15 @@ dependencies = [
7273
"windows-targets 0.42.2",
7274
]
7275
7276
+[[package]]
7277
+name = "windows-sys"
7278
+version = "0.48.0"
7279
+source = "registry+https://github.com/rust-lang/crates.io-index"
7280
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
7281
+dependencies = [
7282
+ "windows-targets 0.48.5",
7283
+]
7284
+
7285
[[package]]
7286
name = "windows-sys"
7287
version = "0.52.0"
Cargo.toml
+3
-3
@@ -1,10 +1,10 @@
1
[package]
2
name = "sigit"
3
-version = "0.1.0"
3
+version = "0.1.1"
4
edition = "2024"
5
description = "siGit Code — ACP-compatible AI coding agent for smbCloud platform."
6
documentation = "https://getsigit.5mb.app/"
7
-license = "MIT OR Apache-2.0"
7
+license = "Apache-2.0"
8
9
[[bin]]
10
name = "sigit"
@@ -15,7 +15,7 @@ path = "src/main.rs"
15
agent-client-protocol = "0.10.4"
16
17
# Onde Inference engine (local LLM)
18
-onde = { path = "../onde" }
18
+onde = { version = "0.1.4" }
19
20
# Async runtime
21
async-trait = "0.1"
LICENSE
new
+190
@@ -0,0 +1,190 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship made available under
36
+ the License, as indicated by a copyright notice that is included in
37
+ or attached to the work (an example is provided in the Appendix below).
38
+
39
+ "Derivative Works" shall mean any work, whether in Source or Object
40
+ form, that is based on (or derived from) the Work and for which the
41
+ editorial revisions, annotations, elaborations, or other modifications
42
+ represent, as a whole, an original work of authorship. For the purposes
43
+ of this License, Derivative Works shall not include works that remain
44
+ separable from, or merely link (or bind by name) to the interfaces of,
45
+ the Work and Derivative Works thereof.
46
+
47
+ "Contribution" shall mean, as defined by the copyright owner or by the
48
+ Legal Entity authorized to submit on behalf of the copyright owner, any
49
+ work of authorship, including the original version of the Work and any
50
+ modifications or additions to that Work or Derivative Works of the Work.
51
+
52
+ "Contributor" shall mean Licensor and any Legal Entity on behalf of
53
+ whom a Contribution has been received by the Licensor and subsequently
54
+ incorporated within the Work.
55
+
56
+ 2. Grant of Copyright License. Subject to the terms and conditions of
57
+ this License, each Contributor hereby grants to You a perpetual,
58
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
59
+ copyright license to reproduce, prepare Derivative Works of,
60
+ publicly display, publicly perform, sublicense, and distribute the
61
+ Work and such Derivative Works in Source or Object form.
62
+
63
+ 3. Grant of Patent License. Subject to the terms and conditions of
64
+ this License, each Contributor hereby grants to You a perpetual,
65
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
66
+ (except as stated in this section) patent license to make, have made,
67
+ use, offer to sell, sell, import, and otherwise transfer the Work,
68
+ where such license applies only to those patent claims licensable
69
+ by such Contributor that are necessarily infringed by their
70
+ Contribution(s) alone or by combination of their Contribution(s)
71
+ with the Work to which such Contribution(s) was submitted. If You
72
+ institute patent litigation against any entity (including a
73
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
74
+ or a Contribution incorporated within the Work constitutes direct
75
+ or contributory patent infringement, then any and all patent licenses
76
+ granted to You under this License for that Work shall terminate
77
+ as of the date such litigation is filed.
78
+
79
+ 4. Redistribution. You may reproduce and distribute copies of the
80
+ Work or Derivative Works thereof in any medium, with or without
81
+ modifications, and in Source or Object form, provided that You
82
+ meet the following conditions:
83
+
84
+ (a) You must give any other recipients of the Work or
85
+ Derivative Works a copy of this License; and
86
+
87
+ (b) You must cause any modified files to carry prominent notices
88
+ stating that You changed the files; and
89
+
90
+ (c) You must retain, in the Source form of any Derivative Works
91
+ that You distribute, all copyright, patent, trademark, and
92
+ attribution notices from the Source form of the Work,
93
+ excluding those notices that do not pertain to any part of
94
+ the Derivative Works; and
95
+
96
+ (d) If the Work includes a "NOTICE" text file as part of its
97
+ distribution, You must include a readable copy of the
98
+ attribution notices contained within such NOTICE file, in
99
+ at least one of the following places: within a NOTICE text
100
+ file distributed as part of the Derivative Works; within
101
+ the Source form or documentation, if provided along with the
102
+ Derivative Works; or, within a display generated by the
103
+ Derivative Works, if and wherever such third-party notices
104
+ normally appear. The contents of the NOTICE file are for
105
+ informational purposes only and do not modify the License.
106
+ You may add Your own attribution notices within Derivative
107
+ Works that You distribute, alongside or as an addendum to
108
+ the NOTICE text from the Work, provided that such additional
109
+ attribution notices cannot be construed as modifying the License.
110
+
111
+ You may add Your own license statement for Your modifications and
112
+ may provide additional grant of rights to use, copy, modify, merge,
113
+ publish, distribute, sublicense, and/or sell copies of the Work,
114
+ and to permit persons to whom the Work is furnished to do so,
115
+ subject to the following conditions:
116
+
117
+ The above copyright notice and this permission notice shall be
118
+ included in all copies or substantial portions of the Work.
119
+
120
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
121
+ any Contribution intentionally submitted for inclusion in the Work
122
+ by You to the Licensor shall be under the terms and conditions of
123
+ this License, without any additional terms or conditions.
124
+ Notwithstanding the above, nothing herein shall supersede or modify
125
+ the terms of any separate license agreement you may have executed
126
+ with Licensor regarding such Contributions.
127
+
128
+ 6. Trademarks. This License does not grant permission to use the trade
129
+ names, trademarks, service marks, or product names of the Licensor,
130
+ except as required for reasonable and customary use in describing the
131
+ origin of the Work and reproducing the content of the NOTICE file.
132
+
133
+ 7. Disclaimer of Warranty. Unless required by applicable law or
134
+ agreed to in writing, Licensor provides the Work (and each
135
+ Contributor provides its Contributions) on an "AS IS" BASIS,
136
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
137
+ implied, including, without limitation, any warranties or conditions
138
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
139
+ PARTICULAR PURPOSE. You are solely responsible for determining the
140
+ appropriateness of using or redistributing the Work and assume any
141
+ risks associated with Your exercise of permissions under this License.
142
+
143
+ 8. Limitation of Liability. In no event and under no legal theory,
144
+ whether in tort (including negligence), contract, or otherwise,
145
+ unless required by applicable law (such as deliberate and grossly
146
+ negligent acts) or agreed to in writing, shall any Contributor be
147
+ liable to You for damages, including any direct, indirect, special,
148
+ incidental, or exemplary damages of any character arising as a
149
+ result of this License or out of the use or inability to use the
150
+ Work (including but not limited to damages for loss of goodwill,
151
+ work stoppage, computer failure or malfunction, or all other
152
+ commercial damages or losses), even if such Contributor has been
153
+ advised of the possibility of such damages.
154
+
155
+ 9. Accepting Warranty or Additional Liability. While redistributing
156
+ the Work or Derivative Works thereof, You may choose to offer,
157
+ and charge a fee for, acceptance of support, warranty, indemnity,
158
+ or other liability obligations and/or rights consistent with this
159
+ License. However, in accepting such obligations, You may act only
160
+ on Your own behalf and on Your sole responsibility, not on behalf
161
+ of any other Contributor, and only if You agree to indemnify,
162
+ defend, and hold each Contributor harmless for any liability
163
+ incurred by, or claims asserted against, such Contributor by reason
164
+ of your accepting any such warranty or additional liability.
165
+
166
+ END OF TERMS AND CONDITIONS
167
+
168
+ APPENDIX: How to apply the Apache License to your work.
169
+
170
+ To apply the Apache License to your work, attach the following
171
+ boilerplate notice, with the fields enclosed by brackets "[]"
172
+ replaced with your own identifying information. (Don't include
173
+ the brackets!) The text should be enclosed in the appropriate
174
+ comment syntax for the file format in use. Also, it is recommended
175
+ that a file or directory name be given on the same line as the
176
+ copyright notice for easier identification within third-party archives.
177
+
178
+ Copyright 2026 Seto Elkahfi
179
+
180
+ Licensed under the Apache License, Version 2.0 (the "License");
181
+ you may not use this file except in compliance with the License.
182
+ You may obtain a copy of the License at
183
+
184
+ http://www.apache.org/licenses/LICENSE-2.0
185
+
186
+ Unless required by applicable law or agreed to in writing, software
187
+ distributed under the License is distributed on an "AS IS" BASIS,
188
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
189
+ See the License for the specific language governing permissions and
190
+ limitations under the License.