tool-compass 2.0.6__tar.gz → 2.2.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.
Files changed (87) hide show
  1. tool_compass-2.2.0/.github/dependabot.yml +24 -0
  2. tool_compass-2.2.0/.github/workflows/ci.yml +341 -0
  3. tool_compass-2.2.0/.github/workflows/publish.yml +178 -0
  4. {tool_compass-2.0.6 → tool_compass-2.2.0}/.gitignore +9 -0
  5. {tool_compass-2.0.6 → tool_compass-2.2.0}/CHANGELOG.md +77 -2
  6. {tool_compass-2.0.6 → tool_compass-2.2.0}/Dockerfile +4 -4
  7. tool_compass-2.2.0/Makefile +38 -0
  8. {tool_compass-2.0.6 → tool_compass-2.2.0}/PKG-INFO +75 -31
  9. tool_compass-2.2.0/README.es.md +324 -0
  10. tool_compass-2.2.0/README.fr.md +324 -0
  11. tool_compass-2.2.0/README.hi.md +323 -0
  12. {tool_compass-2.0.6 → tool_compass-2.2.0}/README.it.md +104 -62
  13. tool_compass-2.2.0/README.ja.md +322 -0
  14. {tool_compass-2.0.6 → tool_compass-2.2.0}/README.md +70 -28
  15. tool_compass-2.2.0/README.pt-BR.md +324 -0
  16. tool_compass-2.2.0/README.zh.md +324 -0
  17. tool_compass-2.2.0/SCORECARD.md +36 -0
  18. {tool_compass-2.0.6 → tool_compass-2.2.0}/SECURITY.md +3 -1
  19. tool_compass-2.2.0/SHIP_GATE.md +80 -0
  20. {tool_compass-2.0.6 → tool_compass-2.2.0}/analytics.py +382 -206
  21. {tool_compass-2.0.6 → tool_compass-2.2.0}/backend_client_simple.py +316 -55
  22. tool_compass-2.0.6/setup.py → tool_compass-2.2.0/bootstrap.py +4 -1
  23. {tool_compass-2.0.6 → tool_compass-2.2.0}/chain_indexer.py +10 -1
  24. tool_compass-2.2.0/cli.py +272 -0
  25. tool_compass-2.2.0/config.py +642 -0
  26. {tool_compass-2.0.6 → tool_compass-2.2.0}/docker-compose.yml +8 -7
  27. tool_compass-2.2.0/embedder.py +432 -0
  28. {tool_compass-2.0.6 → tool_compass-2.2.0}/gateway.py +560 -81
  29. tool_compass-2.2.0/indexer.py +870 -0
  30. {tool_compass-2.0.6 → tool_compass-2.2.0}/pyproject.toml +60 -9
  31. {tool_compass-2.0.6 → tool_compass-2.2.0}/requirements-dev.txt +2 -2
  32. {tool_compass-2.0.6 → tool_compass-2.2.0}/requirements.txt +1 -1
  33. tool_compass-2.2.0/site/astro.config.mjs +30 -0
  34. {tool_compass-2.0.6 → tool_compass-2.2.0}/site/package-lock.json +1866 -976
  35. {tool_compass-2.0.6 → tool_compass-2.2.0}/site/package.json +2 -1
  36. tool_compass-2.2.0/site/src/content/docs/handbook/architecture.md +140 -0
  37. tool_compass-2.2.0/site/src/content/docs/handbook/beginners.md +170 -0
  38. tool_compass-2.2.0/site/src/content/docs/handbook/configuration.md +137 -0
  39. tool_compass-2.2.0/site/src/content/docs/handbook/getting-started.md +157 -0
  40. tool_compass-2.2.0/site/src/content/docs/handbook/index.md +30 -0
  41. tool_compass-2.2.0/site/src/content/docs/handbook/operations.md +173 -0
  42. tool_compass-2.2.0/site/src/content/docs/handbook/tools.md +110 -0
  43. tool_compass-2.2.0/site/src/content.config.ts +7 -0
  44. tool_compass-2.2.0/site/src/site-config.ts +158 -0
  45. tool_compass-2.2.0/site/src/styles/starlight-custom.css +17 -0
  46. {tool_compass-2.0.6 → tool_compass-2.2.0}/sync_manager.py +110 -4
  47. {tool_compass-2.0.6 → tool_compass-2.2.0}/tool_manifest.py +66 -1
  48. {tool_compass-2.0.6 → tool_compass-2.2.0}/ui.py +197 -58
  49. tool_compass-2.0.6/.github/dependabot.yml +0 -29
  50. tool_compass-2.0.6/.github/workflows/ci.yml +0 -147
  51. tool_compass-2.0.6/.github/workflows/pages.yml +0 -50
  52. tool_compass-2.0.6/.github/workflows/publish.yml +0 -108
  53. tool_compass-2.0.6/README.es.md +0 -309
  54. tool_compass-2.0.6/README.fr.md +0 -284
  55. tool_compass-2.0.6/README.hi.md +0 -284
  56. tool_compass-2.0.6/README.ja.md +0 -299
  57. tool_compass-2.0.6/README.pt-BR.md +0 -289
  58. tool_compass-2.0.6/README.zh.md +0 -282
  59. tool_compass-2.0.6/config.py +0 -358
  60. tool_compass-2.0.6/embedder.py +0 -230
  61. tool_compass-2.0.6/indexer.py +0 -564
  62. tool_compass-2.0.6/pytest.ini +0 -31
  63. tool_compass-2.0.6/site/astro.config.mjs +0 -13
  64. tool_compass-2.0.6/site/src/site-config.ts +0 -89
  65. {tool_compass-2.0.6 → tool_compass-2.2.0}/.dockerignore +0 -0
  66. {tool_compass-2.0.6 → tool_compass-2.2.0}/.env.example +0 -0
  67. {tool_compass-2.0.6 → tool_compass-2.2.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  68. {tool_compass-2.0.6 → tool_compass-2.2.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  69. {tool_compass-2.0.6 → tool_compass-2.2.0}/AUDIT_REPORT.md +0 -0
  70. {tool_compass-2.0.6 → tool_compass-2.2.0}/CODE_OF_CONDUCT.md +0 -0
  71. {tool_compass-2.0.6 → tool_compass-2.2.0}/CONTRIBUTING.md +0 -0
  72. {tool_compass-2.0.6 → tool_compass-2.2.0}/LICENSE +0 -0
  73. {tool_compass-2.0.6 → tool_compass-2.2.0}/_version.py +0 -0
  74. {tool_compass-2.0.6 → tool_compass-2.2.0}/assets/logo.png +0 -0
  75. {tool_compass-2.0.6 → tool_compass-2.2.0}/backend_client_mcp.py +0 -0
  76. {tool_compass-2.0.6 → tool_compass-2.2.0}/compass_config.example.json +0 -0
  77. {tool_compass-2.0.6 → tool_compass-2.2.0}/docs/assets/social-preview.png +0 -0
  78. {tool_compass-2.0.6 → tool_compass-2.2.0}/docs/assets/social-preview.svg +0 -0
  79. {tool_compass-2.0.6 → tool_compass-2.2.0}/docs/assets/tool-compass-logo-dark-bg.jpg +0 -0
  80. {tool_compass-2.0.6 → tool_compass-2.2.0}/docs/index.md +0 -0
  81. {tool_compass-2.0.6 → tool_compass-2.2.0}/fly.toml +0 -0
  82. {tool_compass-2.0.6 → tool_compass-2.2.0}/llms.txt +0 -0
  83. {tool_compass-2.0.6 → tool_compass-2.2.0}/logo.png +0 -0
  84. {tool_compass-2.0.6 → tool_compass-2.2.0}/scripts/check-org-urls.sh +0 -0
  85. {tool_compass-2.0.6 → tool_compass-2.2.0}/site/src/pages/index.astro +0 -0
  86. {tool_compass-2.0.6 → tool_compass-2.2.0}/site/src/styles/global.css +0 -0
  87. {tool_compass-2.0.6 → tool_compass-2.2.0}/site/tsconfig.json +0 -0
@@ -0,0 +1,24 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "monthly"
7
+ open-pull-requests-limit: 3
8
+ groups:
9
+ # Minor + patch only so breaking majors open as SEPARATE PRs.
10
+ # (Avoids the ollama-intern PR #4 incident where 5 breaking majors
11
+ # shipped bundled under a wildcard group.)
12
+ all-pip:
13
+ patterns: ["*"]
14
+ update-types: ["minor", "patch"]
15
+
16
+ - package-ecosystem: "github-actions"
17
+ directory: "/"
18
+ schedule:
19
+ interval: "monthly"
20
+ open-pull-requests-limit: 3
21
+ groups:
22
+ all-github-actions:
23
+ patterns: ["*"]
24
+ update-types: ["minor", "patch"]
@@ -0,0 +1,341 @@
1
+ # Tool Compass CI Pipeline
2
+ # Runs tests on pushes and PRs that touch code or config.
3
+ # Also handles GitHub Pages deploy for site/** changes on main (folded in from
4
+ # the former pages.yml per the two-workflow-per-repo hard rule).
5
+
6
+ name: CI
7
+
8
+ on:
9
+ push:
10
+ branches: [main]
11
+ paths:
12
+ - '*.py'
13
+ - 'tests/**'
14
+ - 'scripts/**'
15
+ - 'requirements*.txt'
16
+ - 'pyproject.toml'
17
+ - 'Dockerfile'
18
+ - 'site/**'
19
+ - '.github/workflows/**'
20
+ pull_request:
21
+ branches: [main]
22
+ paths:
23
+ - '*.py'
24
+ - 'tests/**'
25
+ - 'scripts/**'
26
+ - 'requirements*.txt'
27
+ - 'pyproject.toml'
28
+ - 'Dockerfile'
29
+ - 'site/**'
30
+ - '.github/workflows/**'
31
+ # TST-FT-002: nightly-fuzz job runs Hypothesis in `nightly` profile
32
+ # Mon/Wed/Fri at 09:00 UTC. Kept in this file to preserve the
33
+ # two-workflow-per-repo limit.
34
+ schedule:
35
+ - cron: '0 9 * * 1,3,5'
36
+ workflow_dispatch:
37
+
38
+ concurrency:
39
+ group: ${{ github.workflow }}-${{ github.ref }}
40
+ cancel-in-progress: true
41
+
42
+ # Default least-privilege; individual jobs that need more elevate explicitly.
43
+ permissions:
44
+ contents: read
45
+
46
+ jobs:
47
+ lint:
48
+ name: Org URL sanity check
49
+ runs-on: ubuntu-latest
50
+ permissions:
51
+ contents: read
52
+ steps:
53
+ - name: Checkout repository
54
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
55
+
56
+ - name: Check for stale org/user URLs
57
+ run: bash scripts/check-org-urls.sh
58
+
59
+ # CDS-FT-001: SCORECARD drift guard. Soft-fail for now — shipcheck
60
+ # markdown output is still settling. Flip continue-on-error to false
61
+ # once the format stabilizes.
62
+ # TODO(swarm): enforce once shipcheck JSON format stabilizes
63
+ - name: Verify SCORECARD is in sync
64
+ continue-on-error: true
65
+ run: |
66
+ if [ -f Makefile ] && grep -q "^verify-scorecard:" Makefile; then
67
+ make verify-scorecard
68
+ else
69
+ echo "Makefile verify-scorecard target missing — skipping"
70
+ fi
71
+
72
+ test:
73
+ name: Python ${{ matrix.python-version }} on ${{ matrix.os }}
74
+ runs-on: ${{ matrix.os }}
75
+ permissions:
76
+ contents: read
77
+
78
+ strategy:
79
+ fail-fast: false
80
+ matrix:
81
+ os: [ubuntu-latest]
82
+ # Two versions per user's hard rule (max 2 Python versions). Covers
83
+ # current stable + latest supported, keeping requires-python honest.
84
+ # 3.13 dropped from CI matrix: hnswlib 0.8.0's cp313 wheel SIGILLs on
85
+ # GitHub ubuntu-latest runners (AVX instruction gap). pyproject still
86
+ # declares 3.13 support; once hnswlib ships a forgiving cp313 wheel
87
+ # or we switch to a pluggable vector backend (IDX-FT-001), re-add it.
88
+ python-version: ['3.11', '3.12']
89
+
90
+ steps:
91
+ - name: Checkout repository
92
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
93
+
94
+ - name: Set up Python ${{ matrix.python-version }}
95
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
96
+ with:
97
+ python-version: ${{ matrix.python-version }}
98
+ cache: 'pip'
99
+ cache-dependency-path: 'requirements*.txt'
100
+
101
+ - name: Install dependencies
102
+ run: |
103
+ python -m pip install --upgrade pip
104
+ pip install -r requirements.txt
105
+ pip install -r requirements-dev.txt
106
+
107
+ - name: Run tests
108
+ run: |
109
+ pytest -v --tb=short -m "not integration" \
110
+ --junitxml=junit-${{ matrix.python-version }}.xml
111
+
112
+ - name: Upload JUnit report
113
+ if: always()
114
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
115
+ with:
116
+ name: junit-reports-${{ matrix.python-version }}
117
+ path: junit-${{ matrix.python-version }}.xml
118
+ if-no-files-found: warn
119
+
120
+ - name: Run tests with coverage
121
+ if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
122
+ run: |
123
+ pytest --cov=. --cov-report=xml --cov-report=term -m "not integration"
124
+
125
+ - name: Upload coverage to Codecov
126
+ if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
127
+ uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v5
128
+ with:
129
+ file: coverage.xml
130
+ fail_ci_if_error: false
131
+
132
+ - name: Run pip-audit (report only)
133
+ if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
134
+ run: |
135
+ pip-audit -r requirements.txt --format json --output pip-audit-report.json || true
136
+ # Non-blocking: full output captured as artifact for reviewers.
137
+
138
+ - name: Upload pip-audit report
139
+ if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
140
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
141
+ with:
142
+ name: pip-audit-report
143
+ path: pip-audit-report.json
144
+ if-no-files-found: ignore
145
+
146
+ - name: Audit dependencies for vulnerabilities
147
+ if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
148
+ run: |
149
+ pip-audit -r requirements.txt
150
+ # TODO(swarm): enforce after CVE baseline reviewed — issue #TBD
151
+ continue-on-error: true # Warn-only until clean baseline established
152
+
153
+ # TST-FT-002: nightly Hypothesis fuzzing. Runs on schedule (Mon/Wed/Fri 09:00
154
+ # UTC) or manually via workflow_dispatch. Never runs on push/PR — nightly-only.
155
+ # On failure, opens a tracking issue via actions/github-script.
156
+ nightly-fuzz:
157
+ name: Nightly Hypothesis fuzz
158
+ if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
159
+ runs-on: ubuntu-latest
160
+ permissions:
161
+ contents: read
162
+ issues: write
163
+ steps:
164
+ - name: Checkout repository
165
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
166
+
167
+ - name: Set up Python
168
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
169
+ with:
170
+ python-version: '3.11'
171
+ cache: 'pip'
172
+ cache-dependency-path: 'requirements*.txt'
173
+
174
+ - name: Install dependencies
175
+ run: |
176
+ python -m pip install --upgrade pip
177
+ pip install -r requirements.txt
178
+ pip install -r requirements-dev.txt
179
+
180
+ - name: Run Hypothesis (nightly profile)
181
+ id: fuzz
182
+ run: |
183
+ HYPOTHESIS_PROFILE=nightly pytest -m "not integration"
184
+
185
+ - name: Open tracking issue on failure
186
+ if: failure() && steps.fuzz.conclusion == 'failure'
187
+ # TODO(swarm): pin actions/github-script to SHA once nightly-fuzz run
188
+ # history confirms the job shape is stable.
189
+ uses: actions/github-script@v7
190
+ with:
191
+ script: |
192
+ const title = `[nightly-fuzz] Hypothesis failures on ${context.sha}`;
193
+ const body = [
194
+ `Nightly Hypothesis run failed on commit \`${context.sha}\`.`,
195
+ ``,
196
+ `- Workflow: ${context.workflow}`,
197
+ `- Run: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
198
+ `- Triggered by: ${context.eventName}`,
199
+ ``,
200
+ `Investigate and either fix the underlying flake or narrow the strategy.`,
201
+ ].join('\n');
202
+ await github.rest.issues.create({
203
+ owner: context.repo.owner,
204
+ repo: context.repo.repo,
205
+ title,
206
+ body,
207
+ labels: ['nightly-fuzz', 'bug'],
208
+ });
209
+
210
+ # Integration tests (requires Ollama)
211
+ integration:
212
+ name: Integration Tests
213
+ runs-on: ubuntu-latest
214
+ needs: test # Only run after unit tests pass
215
+ permissions:
216
+ contents: read
217
+
218
+ steps:
219
+ - name: Checkout repository
220
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
221
+
222
+ - name: Set up Python
223
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
224
+ with:
225
+ python-version: '3.11'
226
+ cache: 'pip'
227
+ cache-dependency-path: 'requirements*.txt'
228
+
229
+ - name: Install dependencies
230
+ run: |
231
+ python -m pip install --upgrade pip
232
+ pip install -r requirements.txt
233
+ pip install -r requirements-dev.txt
234
+
235
+ - name: Install pinned Ollama
236
+ # Pinned to a specific Ollama release instead of piping `curl | sh`.
237
+ # Ollama's GitHub releases don't ship per-file .sha256 siblings, so
238
+ # we try to fetch one and fall back to a SHA-less pin. TODO(swarm):
239
+ # switch to attestation verification once Ollama publishes SLSA
240
+ # provenance, or hard-pin the known-good SHA-256 inline.
241
+ run: |
242
+ set -euo pipefail
243
+ OLLAMA_VERSION="v0.4.7"
244
+ BASE_URL="https://github.com/ollama/ollama/releases/download/${OLLAMA_VERSION}"
245
+ TARBALL="ollama-linux-amd64.tgz"
246
+ curl -fsSL "${BASE_URL}/${TARBALL}" -o "${TARBALL}"
247
+ if curl -fsSL "${BASE_URL}/${TARBALL}.sha256" -o "${TARBALL}.sha256" 2>/dev/null; then
248
+ sha256sum -c "${TARBALL}.sha256"
249
+ else
250
+ echo "::warning::Ollama ${OLLAMA_VERSION} release has no .sha256 file; proceeding without checksum verification (known upstream gap)."
251
+ fi
252
+ sudo tar -C /usr/local -xzf "${TARBALL}"
253
+ rm -f "${TARBALL}" "${TARBALL}.sha256"
254
+ ollama --version
255
+ ollama serve &
256
+ # Wait for the daemon to accept connections instead of a blind sleep.
257
+ for _ in $(seq 1 30); do
258
+ if curl -sf http://localhost:11434/api/version > /dev/null; then
259
+ break
260
+ fi
261
+ sleep 1
262
+ done
263
+ ollama pull nomic-embed-text
264
+
265
+ - name: Run integration tests
266
+ run: |
267
+ pytest -v -m integration
268
+ continue-on-error: true # Integration tests may be flaky
269
+
270
+ docker:
271
+ name: Docker Build
272
+ runs-on: ubuntu-latest
273
+ needs: test
274
+ permissions:
275
+ contents: read
276
+
277
+ steps:
278
+ - name: Checkout repository
279
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
280
+
281
+ - name: Set up Docker Buildx
282
+ uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
283
+
284
+ - name: Build Docker image
285
+ uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
286
+ with:
287
+ context: .
288
+ push: false
289
+ tags: tool-compass:test
290
+ cache-from: type=gha
291
+ cache-to: type=gha,mode=max
292
+
293
+ # ===========================================================================
294
+ # GitHub Pages build + deploy (folded in from former pages.yml)
295
+ # Only runs on pushes to main — never on PRs. Deploy job carries the
296
+ # elevated permissions; build job stays read-only.
297
+ # ===========================================================================
298
+ pages-build:
299
+ name: Build site
300
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
301
+ runs-on: ubuntu-latest
302
+ permissions:
303
+ contents: read
304
+ steps:
305
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
306
+
307
+ - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
308
+ with:
309
+ node-version: 22
310
+
311
+ - name: Install site dependencies
312
+ working-directory: site
313
+ run: npm ci
314
+
315
+ - name: Build site
316
+ working-directory: site
317
+ run: npm run build
318
+
319
+ - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
320
+ with:
321
+ path: site/dist
322
+
323
+ pages-deploy:
324
+ name: Deploy to GitHub Pages
325
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
326
+ needs: pages-build
327
+ runs-on: ubuntu-latest
328
+ # Dedicated concurrency group so a long deploy is never cancelled by a
329
+ # newer CI run (CDS-A-012).
330
+ concurrency:
331
+ group: pages
332
+ cancel-in-progress: false
333
+ permissions:
334
+ pages: write
335
+ id-token: write
336
+ environment:
337
+ name: github-pages
338
+ url: ${{ steps.deployment.outputs.page_url }}
339
+ steps:
340
+ - id: deployment
341
+ uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
@@ -0,0 +1,178 @@
1
+ # Tool Compass Release Pipeline
2
+ # Publishes to PyPI (trusted publishing) and GHCR on release
3
+
4
+ name: Publish
5
+
6
+ on:
7
+ release:
8
+ types: [published]
9
+ workflow_dispatch:
10
+
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ env:
16
+ REGISTRY: ghcr.io
17
+ IMAGE_NAME: ${{ github.repository }}
18
+
19
+ jobs:
20
+ build:
21
+ name: Build package
22
+ runs-on: ubuntu-latest
23
+
24
+ steps:
25
+ - name: Checkout repository
26
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
27
+
28
+ - name: Set up Python
29
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
30
+ with:
31
+ python-version: '3.11'
32
+
33
+ - name: Install build tools
34
+ run: |
35
+ python -m pip install --upgrade pip
36
+ pip install build twine
37
+
38
+ - name: Build package
39
+ run: python -m build
40
+
41
+ - name: Check package with twine
42
+ run: twine check dist/*
43
+
44
+ - name: Upload build artifacts
45
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
46
+ with:
47
+ name: dist
48
+ path: dist/
49
+
50
+ publish-pypi:
51
+ name: Publish to PyPI
52
+ runs-on: ubuntu-latest
53
+ needs: build
54
+ environment: pypi
55
+ permissions:
56
+ id-token: write
57
+
58
+ steps:
59
+ - name: Download build artifacts
60
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
61
+ with:
62
+ name: dist
63
+ path: dist/
64
+
65
+ - name: Publish to PyPI
66
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
67
+
68
+ docker:
69
+ name: Publish to GHCR
70
+ runs-on: ubuntu-latest
71
+ # PyPI ships first (CDS-B-005). If PyPI fails, Docker must not ship a
72
+ # half-release; if PyPI succeeds, Docker becomes the recoverable tail.
73
+ needs: publish-pypi
74
+ permissions:
75
+ contents: read
76
+ packages: write
77
+
78
+ steps:
79
+ - name: Checkout repository
80
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
81
+
82
+ - name: Log in to GHCR
83
+ uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
84
+ with:
85
+ registry: ${{ env.REGISTRY }}
86
+ username: ${{ github.actor }}
87
+ password: ${{ secrets.GITHUB_TOKEN }}
88
+
89
+ - name: Extract metadata
90
+ id: meta
91
+ uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
92
+ with:
93
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
94
+ tags: |
95
+ type=semver,pattern={{version}}
96
+ type=semver,pattern={{major}}.{{minor}}
97
+ type=sha
98
+ type=raw,value=latest,enable={{is_default_branch}}
99
+
100
+ # QEMU is required to cross-build linux/arm64 from an amd64 runner.
101
+ - name: Set up QEMU
102
+ # TODO(swarm): pin docker/setup-qemu-action by SHA on next dependabot sweep.
103
+ uses: docker/setup-qemu-action@v3
104
+
105
+ - name: Set up Docker Buildx
106
+ uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
107
+
108
+ - name: Build and push
109
+ uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
110
+ with:
111
+ context: .
112
+ push: true
113
+ platforms: linux/amd64,linux/arm64
114
+ tags: ${{ steps.meta.outputs.tags }}
115
+ labels: ${{ steps.meta.outputs.labels }}
116
+ cache-from: type=gha
117
+ cache-to: type=gha,mode=max
118
+
119
+ release-smoke:
120
+ name: Release smoke test
121
+ runs-on: ubuntu-latest
122
+ needs: [publish-pypi, docker]
123
+ permissions:
124
+ contents: read
125
+ packages: read
126
+ steps:
127
+ - name: Derive version (strip leading v)
128
+ id: ver
129
+ run: |
130
+ set -euo pipefail
131
+ TAG="${{ github.event.release.tag_name }}"
132
+ echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
133
+ echo "version=${TAG#v}" >> "$GITHUB_OUTPUT"
134
+
135
+ - name: Set up Python
136
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
137
+ with:
138
+ python-version: '3.11'
139
+
140
+ - name: PyPI smoke — install + --version matches tag
141
+ run: |
142
+ set -euo pipefail
143
+ VERSION="${{ steps.ver.outputs.version }}"
144
+ # PyPI propagation is fast but not instant; retry briefly.
145
+ for _ in $(seq 1 12); do
146
+ if pip install "tool-compass==${VERSION}"; then
147
+ break
148
+ fi
149
+ sleep 10
150
+ done
151
+ pip install "tool-compass==${VERSION}"
152
+ OUT="$(tool-compass --version 2>&1 || true)"
153
+ echo "tool-compass --version → $OUT"
154
+ echo "$OUT" | grep -Fq "${VERSION}" || {
155
+ echo "::error::PyPI smoke failed: --version output did not contain ${VERSION}"
156
+ exit 1
157
+ }
158
+
159
+ - name: Log in to GHCR (pull)
160
+ uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
161
+ with:
162
+ registry: ${{ env.REGISTRY }}
163
+ username: ${{ github.actor }}
164
+ password: ${{ secrets.GITHUB_TOKEN }}
165
+
166
+ - name: Docker smoke — pull + --version matches tag
167
+ run: |
168
+ set -euo pipefail
169
+ TAG="${{ steps.ver.outputs.tag }}"
170
+ VERSION="${{ steps.ver.outputs.version }}"
171
+ IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${VERSION}"
172
+ docker pull "$IMAGE"
173
+ OUT="$(docker run --rm --entrypoint tool-compass "$IMAGE" --version 2>&1 || true)"
174
+ echo "docker --version → $OUT"
175
+ echo "$OUT" | grep -Fq "${VERSION}" || {
176
+ echo "::error::Docker smoke failed: --version output did not contain ${VERSION}"
177
+ exit 1
178
+ }
@@ -98,3 +98,12 @@ tmpclaude-*
98
98
  archive/
99
99
  site/.astro/
100
100
  site/node_modules/
101
+
102
+ # forkctl / polyglot-mcp scratch
103
+ .artifact/
104
+ .polyglot-cache.json
105
+
106
+ # repo-knowledge scratch (init creates these; don't commit)
107
+ rk.config.json
108
+ data/knowledge.db*
109
+ data/artifacts/
@@ -5,7 +5,79 @@ All notable changes to Tool Compass will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [Unreleased]
8
+ ## [2.2.0] - 2026-04-23
9
+
10
+ Dogfood swarm release: Stage A bug/security health pass + Stage B/C humanization
11
+ + Feature Pass. Shipcheck 17/17 retained.
12
+
13
+ ### Added
14
+ - **Per-backend stdout reader** — isolated log streams per MCP backend so a noisy
15
+ child process can't crowd out siblings in the combined view
16
+ - **`/ready` + `/metrics` HTTP endpoints** — readiness probe + Prometheus-style
17
+ metrics surface for operators running the gateway behind a load balancer
18
+ - **Embedding cache** — LRU cache in `Embedder` so repeated identical queries
19
+ skip the Ollama round-trip
20
+ - **Diffing sync** — `SyncManager` now emits a structured diff (added / removed /
21
+ changed) instead of a full rebuild signal; downstream consumers can act on
22
+ partial changes
23
+ - **`tool-compass` CLI subcommand shell** (`cli.py`) — top-level entry point now
24
+ dispatches to `serve` (gateway), `ui` (Gradio), `doctor` (config health),
25
+ `sync`, `test`, and `config`. `python gateway.py` still works unchanged.
26
+ - **`deprecated_aliases` in tool manifest** — lets backends rename tools without
27
+ breaking old callers; the compass surfaces both names and marks legacy ones
28
+ - **`make scorecard` + `make verify-scorecard`** (CDS-FT-001) — regenerate
29
+ SCORECARD.md from shipcheck output; CI soft-fails on drift
30
+ - **`make dev` + `make dev-ui`** (CDS-FT-002) — one-shot install + run targets
31
+ for the fast local loop, with a warning if Ollama isn't reachable
32
+ - **Nightly Hypothesis fuzz job** (TST-FT-002) — `nightly-fuzz` runs Mon/Wed/Fri
33
+ at 09:00 UTC in `ci.yml` (no new workflow file), auto-opens a tracking issue
34
+ on failure
35
+ - **Coverage floor** (TST-FT-001) — `[tool.coverage.report] fail_under = 60`
36
+ and `--cov-fail-under=60` in `make test`; conservative first gate
37
+ - **Architecture Mermaid diagrams** (CDS-FT-005) — component graph + request
38
+ sequence diagrams in `site/src/content/docs/handbook/architecture.md`
39
+
40
+ ### Changed
41
+ - `tool-compass` console script now targets `cli:main` (was `gateway:main`).
42
+ `python gateway.py` remains fully supported for direct invocation.
43
+ - Wheel bundle includes `cli.py`
44
+
45
+ ### Fixed (Stage A — 23 HIGH bug/security)
46
+ - Misc security, bug, and error-shape fixes surfaced by the health pass
47
+
48
+ ### Humanized (Stage B/C — 15 HIGH + 14 MED)
49
+ - **Ollama-down lexical fallback** — compass returns keyword matches when the
50
+ embedding backend is unreachable, with a clear degraded-mode marker
51
+ - **`trace_id` correlation** — every request carries a trace ID end-to-end for
52
+ log stitching
53
+ - **Circuit breaker** on the embedder — opens after N consecutive failures,
54
+ half-opens after a cooldown
55
+ - **Corrupt-config recovery** — malformed `compass_config.json` no longer
56
+ crashes startup; loader falls back to defaults with a warning
57
+ - **`tool-compass doctor`** — diagnoses Ollama reachability, index presence,
58
+ backend health, and prints actionable fixes
59
+
60
+ ## [2.0.7] - 2026-03-25
61
+
62
+ ### Added
63
+ - 5 version consistency tests (semver, >= 1.0.0, CHANGELOG, pyproject parse, CLI)
64
+
65
+ ### Security
66
+ - SHA-pinned all GitHub Actions across 3 workflows (ci, pages, publish)
67
+
68
+ ## [2.0.6] - 2026-02-27
69
+
70
+ ### Added
71
+ - SHIP_GATE.md and SCORECARD.md (Shipcheck compliance)
72
+ - Makefile with `verify` target (lint + test + build)
73
+ - Security & Data Scope section and scorecard in README
74
+ - Standard email in SECURITY.md
75
+
76
+ ### Changed
77
+ - Removed redundant h1 heading (logo already contains name)
78
+ - Replaced footer with standard MCP Tool Shop link
79
+ - Scorecard 46/50 → 50/50
80
+ - Bumped to 2.0.6
9
81
 
10
82
  ## [2.0.3] - 2026-02-14
11
83
 
@@ -162,7 +234,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
162
234
  | 1.1.0 | 2026-01-16 | Workflows, analytics, sync |
163
235
  | 1.0.0 | 2026-01-15 | Initial release |
164
236
 
165
- [Unreleased]: https://github.com/mcp-tool-shop-org/tool-compass/compare/v2.0.3...HEAD
237
+ [Unreleased]: https://github.com/mcp-tool-shop-org/tool-compass/compare/v2.2.0...HEAD
238
+ [2.2.0]: https://github.com/mcp-tool-shop-org/tool-compass/compare/v2.0.7...v2.2.0
239
+ [2.0.7]: https://github.com/mcp-tool-shop-org/tool-compass/compare/v2.0.6...v2.0.7
240
+ [2.0.6]: https://github.com/mcp-tool-shop-org/tool-compass/compare/v2.0.3...v2.0.6
166
241
  [2.0.3]: https://github.com/mcp-tool-shop-org/tool-compass/compare/v2.0.2...v2.0.3
167
242
  [2.0.2]: https://github.com/mcp-tool-shop-org/tool-compass/compare/v2.0.1...v2.0.2
168
243
  [2.0.1]: https://github.com/mcp-tool-shop-org/tool-compass/compare/v2.0.0...v2.0.1
@@ -4,7 +4,7 @@
4
4
  # =============================================================================
5
5
  # Stage 1: Builder
6
6
  # =============================================================================
7
- FROM python:3.11-slim as builder
7
+ FROM python:3.11-slim AS builder
8
8
 
9
9
  WORKDIR /build
10
10
 
@@ -26,12 +26,12 @@ RUN pip install --no-cache-dir --upgrade pip && \
26
26
  # =============================================================================
27
27
  # Stage 2: Production
28
28
  # =============================================================================
29
- FROM python:3.11-slim as production
29
+ FROM python:3.11-slim AS production
30
30
 
31
31
  LABEL maintainer="Tool Compass <github.com/mcp-tool-shop-org/tool-compass>"
32
32
  LABEL description="Semantic search gateway for MCP tools"
33
33
  # Keep in sync with pyproject.toml [project] version
34
- LABEL version="2.0.3"
34
+ LABEL version="2.0.7"
35
35
 
36
36
  # Security: Run as non-root user
37
37
  RUN groupadd -r compass && useradd -r -g compass compass
@@ -76,7 +76,7 @@ CMD ["python", "ui.py"]
76
76
  # =============================================================================
77
77
  # Stage 3: MCP Gateway (alternative entrypoint)
78
78
  # =============================================================================
79
- FROM production as mcp-gateway
79
+ FROM production AS mcp-gateway
80
80
 
81
81
  # Override for HTTP mode (Fly.io / Smithery)
82
82
  ENV PORT=8080