vision-squeezer 0.6.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 (114) hide show
  1. vision_squeezer-0.6.0/.claude-plugin/marketplace.json +28 -0
  2. vision_squeezer-0.6.0/.claude-plugin/plugin.json +13 -0
  3. vision_squeezer-0.6.0/.github/FUNDING.yml +1 -0
  4. vision_squeezer-0.6.0/.github/ISSUE_TEMPLATE/bug_report.yml +60 -0
  5. vision_squeezer-0.6.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  6. vision_squeezer-0.6.0/.github/ISSUE_TEMPLATE/feature_request.yml +25 -0
  7. vision_squeezer-0.6.0/.github/PULL_REQUEST_TEMPLATE.md +17 -0
  8. vision_squeezer-0.6.0/.github/workflows/ci.yml +44 -0
  9. vision_squeezer-0.6.0/.github/workflows/python.yml +123 -0
  10. vision_squeezer-0.6.0/.github/workflows/release.yml +161 -0
  11. vision_squeezer-0.6.0/.gitignore +20 -0
  12. vision_squeezer-0.6.0/.npmignore +31 -0
  13. vision_squeezer-0.6.0/CHANGELOG.md +288 -0
  14. vision_squeezer-0.6.0/CLAUDE.md +137 -0
  15. vision_squeezer-0.6.0/CODE_OF_CONDUCT.md +27 -0
  16. vision_squeezer-0.6.0/CONTRIBUTING.md +37 -0
  17. vision_squeezer-0.6.0/Cargo.lock +1819 -0
  18. vision_squeezer-0.6.0/Cargo.toml +38 -0
  19. vision_squeezer-0.6.0/LICENSE +30 -0
  20. vision_squeezer-0.6.0/Makefile +21 -0
  21. vision_squeezer-0.6.0/PKG-INFO +73 -0
  22. vision_squeezer-0.6.0/README.md +654 -0
  23. vision_squeezer-0.6.0/assets/favicon.png +0 -0
  24. vision_squeezer-0.6.0/assets/logo.png +0 -0
  25. vision_squeezer-0.6.0/benches/pipeline.rs +45 -0
  26. vision_squeezer-0.6.0/bin/install.js +304 -0
  27. vision_squeezer-0.6.0/bin/run.js +34 -0
  28. vision_squeezer-0.6.0/bin/vision-squeezer-mcp +0 -0
  29. vision_squeezer-0.6.0/data/istanbul.jpg +0 -0
  30. vision_squeezer-0.6.0/data/istanbul2.jpg +0 -0
  31. vision_squeezer-0.6.0/docs/.editorconfig +13 -0
  32. vision_squeezer-0.6.0/docs/.env.example +2 -0
  33. vision_squeezer-0.6.0/docs/.gitignore +27 -0
  34. vision_squeezer-0.6.0/docs/app/app.config.ts +67 -0
  35. vision_squeezer-0.6.0/docs/app/app.vue +56 -0
  36. vision_squeezer-0.6.0/docs/app/assets/css/main.css +26 -0
  37. vision_squeezer-0.6.0/docs/app/components/AppFooter.vue +23 -0
  38. vision_squeezer-0.6.0/docs/app/components/AppHeader.vue +72 -0
  39. vision_squeezer-0.6.0/docs/app/components/AppLogo.vue +40 -0
  40. vision_squeezer-0.6.0/docs/app/components/CookieConsent.vue +55 -0
  41. vision_squeezer-0.6.0/docs/app/components/OgImage/Docs.takumi.vue +64 -0
  42. vision_squeezer-0.6.0/docs/app/components/PageHeaderLinks.vue +80 -0
  43. vision_squeezer-0.6.0/docs/app/components/TemplateMenu.vue +49 -0
  44. vision_squeezer-0.6.0/docs/app/components/content/HeroBackground.vue +88 -0
  45. vision_squeezer-0.6.0/docs/app/components/content/InstallSelector.vue +96 -0
  46. vision_squeezer-0.6.0/docs/app/components/content/SavingsCalculator.vue +159 -0
  47. vision_squeezer-0.6.0/docs/app/components/content/StarsBg.vue +183 -0
  48. vision_squeezer-0.6.0/docs/app/components/content/VersionBadge.vue +32 -0
  49. vision_squeezer-0.6.0/docs/app/error.vue +42 -0
  50. vision_squeezer-0.6.0/docs/app/layouts/docs.vue +22 -0
  51. vision_squeezer-0.6.0/docs/app/pages/[...slug].vue +112 -0
  52. vision_squeezer-0.6.0/docs/app/pages/index.vue +48 -0
  53. vision_squeezer-0.6.0/docs/content/1.getting-started/.navigation.yml +2 -0
  54. vision_squeezer-0.6.0/docs/content/1.getting-started/1.index.md +69 -0
  55. vision_squeezer-0.6.0/docs/content/1.getting-started/2.installation.md +65 -0
  56. vision_squeezer-0.6.0/docs/content/1.getting-started/3.mcp-setup.md +102 -0
  57. vision_squeezer-0.6.0/docs/content/2.cli/.navigation.yml +2 -0
  58. vision_squeezer-0.6.0/docs/content/2.cli/1.usage.md +65 -0
  59. vision_squeezer-0.6.0/docs/content/2.cli/2.options.md +50 -0
  60. vision_squeezer-0.6.0/docs/content/2.cli/3.batch-json.md +66 -0
  61. vision_squeezer-0.6.0/docs/content/3.providers/.navigation.yml +2 -0
  62. vision_squeezer-0.6.0/docs/content/3.providers/1.claude.md +45 -0
  63. vision_squeezer-0.6.0/docs/content/3.providers/2.gpt.md +57 -0
  64. vision_squeezer-0.6.0/docs/content/3.providers/3.gemini.md +36 -0
  65. vision_squeezer-0.6.0/docs/content/3.providers/4.llama.md +60 -0
  66. vision_squeezer-0.6.0/docs/content/3.providers/5.qwen.md +51 -0
  67. vision_squeezer-0.6.0/docs/content/3.providers/6.deepseek.md +60 -0
  68. vision_squeezer-0.6.0/docs/content/4.guides/.navigation.yml +2 -0
  69. vision_squeezer-0.6.0/docs/content/4.guides/1.python-bindings.md +65 -0
  70. vision_squeezer-0.6.0/docs/content/4.guides/2.sandbox.md +43 -0
  71. vision_squeezer-0.6.0/docs/content/4.guides/3.crawler-integration.md +49 -0
  72. vision_squeezer-0.6.0/docs/content/index.md +214 -0
  73. vision_squeezer-0.6.0/docs/content.config.ts +25 -0
  74. vision_squeezer-0.6.0/docs/eslint.config.mjs +6 -0
  75. vision_squeezer-0.6.0/docs/nuxt.config.ts +134 -0
  76. vision_squeezer-0.6.0/docs/package.json +45 -0
  77. vision_squeezer-0.6.0/docs/pnpm-lock.yaml +14614 -0
  78. vision_squeezer-0.6.0/docs/pnpm-workspace.yaml +8 -0
  79. vision_squeezer-0.6.0/docs/public/android-chrome-192x192.png +0 -0
  80. vision_squeezer-0.6.0/docs/public/android-chrome-512x512.png +0 -0
  81. vision_squeezer-0.6.0/docs/public/apple-touch-icon.png +0 -0
  82. vision_squeezer-0.6.0/docs/public/favicon-16x16.png +0 -0
  83. vision_squeezer-0.6.0/docs/public/favicon-32x32.png +0 -0
  84. vision_squeezer-0.6.0/docs/public/favicon.ico +0 -0
  85. vision_squeezer-0.6.0/docs/public/logo.png +0 -0
  86. vision_squeezer-0.6.0/docs/public/site.webmanifest +21 -0
  87. vision_squeezer-0.6.0/docs/server/mcp/tools/get-page.ts +60 -0
  88. vision_squeezer-0.6.0/docs/server/mcp/tools/list-pages.ts +50 -0
  89. vision_squeezer-0.6.0/docs/server/routes/raw/[...slug].md.get.ts +27 -0
  90. vision_squeezer-0.6.0/docs/tsconfig.json +4 -0
  91. vision_squeezer-0.6.0/llms-full.txt +46 -0
  92. vision_squeezer-0.6.0/llms.txt +20 -0
  93. vision_squeezer-0.6.0/netlify.toml +39 -0
  94. vision_squeezer-0.6.0/package.json +34 -0
  95. vision_squeezer-0.6.0/plugins/vision-squeezer-mcp/.claude-plugin/plugin.json +13 -0
  96. vision_squeezer-0.6.0/plugins/vision-squeezer-mcp/.mcp.json +8 -0
  97. vision_squeezer-0.6.0/plugins/vision-squeezer-mcp/skills/vision-doctor/SKILL.md +161 -0
  98. vision_squeezer-0.6.0/plugins/vision-squeezer-mcp/skills/vision-stats/SKILL.md +40 -0
  99. vision_squeezer-0.6.0/plugins/vision-squeezer-mcp/skills/vision-upgrade/SKILL.md +176 -0
  100. vision_squeezer-0.6.0/postinstall.js +98 -0
  101. vision_squeezer-0.6.0/pyproject.toml +29 -0
  102. vision_squeezer-0.6.0/python/Cargo.lock +1587 -0
  103. vision_squeezer-0.6.0/python/Cargo.toml +18 -0
  104. vision_squeezer-0.6.0/python/README.md +55 -0
  105. vision_squeezer-0.6.0/python/examples/basic.py +40 -0
  106. vision_squeezer-0.6.0/python/src/lib.rs +207 -0
  107. vision_squeezer-0.6.0/scripts/postinstall.js +44 -0
  108. vision_squeezer-0.6.0/server.json +20 -0
  109. vision_squeezer-0.6.0/smithery.yaml +22 -0
  110. vision_squeezer-0.6.0/src/lib.rs +1481 -0
  111. vision_squeezer-0.6.0/src/main.rs +918 -0
  112. vision_squeezer-0.6.0/src/mcp_server.rs +534 -0
  113. vision_squeezer-0.6.0/tests/cli.rs +232 -0
  114. vision_squeezer-0.6.0/tests/mcp.rs +175 -0
@@ -0,0 +1,28 @@
1
+ {
2
+ "$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
3
+ "name": "vision-squeezer",
4
+ "owner": {
5
+ "name": "Eralp Özcan",
6
+ "email": "quarentin@gmail.com"
7
+ },
8
+ "metadata": {
9
+ "description": "LLM-native image optimization tools for Claude Code"
10
+ },
11
+ "plugins": [
12
+ {
13
+ "name": "vision-squeezer-mcp",
14
+ "source": "./plugins/vision-squeezer-mcp",
15
+ "description": "VisionSqueezer for Claude Code — MCP server (optimize_image / sandbox_execute / get_savings_stats) bundled with the vision-doctor, vision-upgrade, and vision-stats skills. One install brings everything.",
16
+ "version": "0.6.0",
17
+ "author": {
18
+ "name": "Eralp Özcan",
19
+ "url": "https://github.com/eralpozcan"
20
+ },
21
+ "homepage": "https://visionsqueezer.com",
22
+ "repository": "https://github.com/eralpozcan/vision-squeezer",
23
+ "license": "Elastic-2.0",
24
+ "keywords": ["vision", "tokens", "llm", "mcp", "image", "optimization"],
25
+ "category": "productivity"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "vision-squeezer",
3
+ "description": "LLM-native image optimization tools for Claude Code — analytics and health check skills.",
4
+ "author": {
5
+ "name": "Eralp Özcan",
6
+ "url": "https://github.com/eralpozcan"
7
+ },
8
+ "homepage": "https://visionsqueezer.com",
9
+ "repository": "https://github.com/eralpozcan/vision-squeezer",
10
+ "version": "0.6.0",
11
+ "license": "Elastic-2.0",
12
+ "keywords": ["vision", "tokens", "llm", "optimization", "mcp", "image"]
13
+ }
@@ -0,0 +1 @@
1
+ github: [eralpozcan]
@@ -0,0 +1,60 @@
1
+ name: Bug Report
2
+ description: Something is broken or behaving unexpectedly
3
+ labels: ["bug"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thanks for taking the time to report a bug. Please fill out the sections below.
9
+
10
+ - type: textarea
11
+ id: description
12
+ attributes:
13
+ label: Description
14
+ description: What happened? What did you expect?
15
+ validations:
16
+ required: true
17
+
18
+ - type: textarea
19
+ id: reproduction
20
+ attributes:
21
+ label: Steps to Reproduce
22
+ description: Commands or code to reproduce the issue
23
+ placeholder: |
24
+ cargo run -- data/image.jpg
25
+ # or MCP call...
26
+ validations:
27
+ required: true
28
+
29
+ - type: textarea
30
+ id: output
31
+ attributes:
32
+ label: Actual Output / Error
33
+ render: shell
34
+ validations:
35
+ required: true
36
+
37
+ - type: input
38
+ id: version
39
+ attributes:
40
+ label: vision-squeezer version
41
+ placeholder: "0.1.0"
42
+ validations:
43
+ required: true
44
+
45
+ - type: dropdown
46
+ id: os
47
+ attributes:
48
+ label: OS
49
+ options:
50
+ - macOS
51
+ - Linux
52
+ - Windows
53
+ validations:
54
+ required: true
55
+
56
+ - type: input
57
+ id: rust
58
+ attributes:
59
+ label: Rust version
60
+ placeholder: "rustc 1.78.0"
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Discussions
4
+ url: https://github.com/eralpozcan/vision-squeezer/discussions
5
+ about: Questions, ideas, and general discussion
@@ -0,0 +1,25 @@
1
+ name: Feature Request
2
+ description: Suggest a new feature or improvement
3
+ labels: ["enhancement"]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: Problem / Motivation
9
+ description: What problem does this solve? What use case drives it?
10
+ validations:
11
+ required: true
12
+
13
+ - type: textarea
14
+ id: solution
15
+ attributes:
16
+ label: Proposed Solution
17
+ description: How should it work?
18
+ validations:
19
+ required: true
20
+
21
+ - type: textarea
22
+ id: alternatives
23
+ attributes:
24
+ label: Alternatives Considered
25
+ description: Other approaches you thought about
@@ -0,0 +1,17 @@
1
+ ## Summary
2
+
3
+ <!-- What does this PR do? -->
4
+
5
+ ## Type
6
+
7
+ - [ ] Bug fix
8
+ - [ ] New feature
9
+ - [ ] Refactor
10
+ - [ ] Docs / tests
11
+
12
+ ## Checklist
13
+
14
+ - [ ] `cargo test` passes
15
+ - [ ] `cargo clippy` clean
16
+ - [ ] `cargo fmt` applied
17
+ - [ ] Tests added / updated where relevant
@@ -0,0 +1,44 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths-ignore:
7
+ - '**.md'
8
+ - 'docs/**'
9
+ - 'assets/**'
10
+ - 'LICENSE'
11
+ - '.github/ISSUE_TEMPLATE/**'
12
+ pull_request:
13
+ paths-ignore:
14
+ - '**.md'
15
+ - 'docs/**'
16
+ - 'assets/**'
17
+ - 'LICENSE'
18
+ - '.github/ISSUE_TEMPLATE/**'
19
+
20
+ # Cancel superseded runs on the same ref (PR push amends, branch force-push, etc.)
21
+ # Main-branch runs are kept (each commit on main should produce a status check).
22
+ concurrency:
23
+ group: ${{ github.workflow }}-${{ github.ref }}
24
+ cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
25
+
26
+ env:
27
+ CARGO_TERM_COLOR: always
28
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
29
+
30
+ jobs:
31
+ # Single job — lint + test share the same checkout, toolchain, and cache.
32
+ # Saves ~1 runner-minute per push vs running them as separate jobs.
33
+ check:
34
+ name: Lint & Test
35
+ runs-on: ubuntu-latest
36
+ steps:
37
+ - uses: actions/checkout@v4
38
+ - uses: dtolnay/rust-toolchain@stable
39
+ with:
40
+ components: clippy, rustfmt
41
+ - uses: Swatinem/rust-cache@v2
42
+ - run: cargo fmt --check
43
+ - run: cargo clippy -- -D warnings
44
+ - run: cargo test --all
@@ -0,0 +1,123 @@
1
+ name: Python wheels
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+ workflow_dispatch:
7
+
8
+ # Cancel queued/running wheel jobs if a newer tag supersedes them.
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ linux:
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ matrix:
18
+ target: [x86_64, aarch64]
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.11"
24
+ - name: Build wheels
25
+ uses: PyO3/maturin-action@v1
26
+ with:
27
+ target: ${{ matrix.target }}
28
+ # Python 3.8 + 3.9 dropped: both are EOL and rarely used in modern
29
+ # vision stacks. Trims the per-platform wheel count from 6 → 4.
30
+ args: --release --out dist --manifest-path python/Cargo.toml --interpreter 3.10 3.11 3.12 3.13
31
+ sccache: "true"
32
+ manylinux: 2_28
33
+ - uses: actions/upload-artifact@v4
34
+ with:
35
+ name: wheels-linux-${{ matrix.target }}
36
+ path: dist
37
+ retention-days: 14
38
+
39
+ macos:
40
+ runs-on: macos-latest
41
+ # Intel macOS dropped: macos-latest is arm64 only since 2024 (Intel runs
42
+ # would be billed at 10× and Apple has EOL'd Intel Macs). Users on Intel
43
+ # Macs can install via Rosetta or `pip install --no-binary`.
44
+ steps:
45
+ - uses: actions/checkout@v4
46
+ - uses: actions/setup-python@v5
47
+ with:
48
+ python-version: "3.11"
49
+ - name: Build wheels
50
+ uses: PyO3/maturin-action@v1
51
+ with:
52
+ target: aarch64
53
+ args: --release --out dist --manifest-path python/Cargo.toml
54
+ sccache: "true"
55
+ - uses: actions/upload-artifact@v4
56
+ with:
57
+ name: wheels-macos-aarch64
58
+ path: dist
59
+ retention-days: 14
60
+
61
+ windows:
62
+ runs-on: windows-latest
63
+ steps:
64
+ - uses: actions/checkout@v4
65
+ - uses: actions/setup-python@v5
66
+ with:
67
+ python-version: "3.11"
68
+ - name: Build wheels
69
+ uses: PyO3/maturin-action@v1
70
+ with:
71
+ target: x64
72
+ args: --release --out dist --manifest-path python/Cargo.toml
73
+ sccache: "true"
74
+ - uses: actions/upload-artifact@v4
75
+ with:
76
+ name: wheels-windows-x64
77
+ path: dist
78
+ retention-days: 14
79
+
80
+ sdist:
81
+ runs-on: ubuntu-latest
82
+ steps:
83
+ - uses: actions/checkout@v4
84
+ - name: Build sdist
85
+ uses: PyO3/maturin-action@v1
86
+ with:
87
+ command: sdist
88
+ args: --out dist --manifest-path python/Cargo.toml
89
+ - uses: actions/upload-artifact@v4
90
+ with:
91
+ name: wheels-sdist
92
+ path: dist
93
+ retention-days: 14
94
+
95
+ # PyPI publish via Trusted Publishing (OIDC) — no API token/secret. The
96
+ # `id-token: write` permission lets pypa/gh-action-pypi-publish mint the
97
+ # short-lived token PyPI exchanges against the registered trusted publisher.
98
+ # Requires (one-time, in the PyPI + GitHub UIs):
99
+ # - PyPI trusted publisher for project "vision-squeezer": owner eralpozcan,
100
+ # repo vision-squeezer, workflow python.yml, environment pypi.
101
+ # - GitHub environment named "pypi".
102
+ # Runs on a v* tag or a manual dispatch. The first successful upload creates
103
+ # the project on PyPI and flips the pending publisher to active.
104
+ release:
105
+ name: Publish to PyPI
106
+ runs-on: ubuntu-latest
107
+ if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v')
108
+ needs: [linux, macos, windows, sdist]
109
+ environment:
110
+ name: pypi
111
+ url: https://pypi.org/p/vision-squeezer
112
+ permissions:
113
+ id-token: write
114
+ steps:
115
+ - uses: actions/download-artifact@v4
116
+ with:
117
+ pattern: wheels-*
118
+ merge-multiple: true
119
+ path: dist
120
+ - name: Publish to PyPI
121
+ uses: pypa/gh-action-pypi-publish@release/v1
122
+ with:
123
+ skip-existing: true
@@ -0,0 +1,161 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ # A tag is immutable, so a re-tag should cancel any in-flight build for the
9
+ # same ref instead of running both to completion.
10
+ concurrency:
11
+ group: ${{ github.workflow }}-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
14
+ env:
15
+ CARGO_TERM_COLOR: always
16
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
17
+
18
+ jobs:
19
+ build:
20
+ name: Build ${{ matrix.target }}
21
+ runs-on: ${{ matrix.os }}
22
+ strategy:
23
+ matrix:
24
+ include:
25
+ - os: macos-latest
26
+ target: aarch64-apple-darwin
27
+ binary: vision-squeezer-mcp
28
+ asset: vision-squeezer-mcp-macos-arm64
29
+ - os: ubuntu-latest
30
+ target: x86_64-unknown-linux-gnu
31
+ binary: vision-squeezer-mcp
32
+ asset: vision-squeezer-mcp-linux-x86_64
33
+ - os: ubuntu-latest
34
+ target: aarch64-unknown-linux-gnu
35
+ binary: vision-squeezer-mcp
36
+ asset: vision-squeezer-mcp-linux-arm64
37
+ - os: windows-latest
38
+ target: x86_64-pc-windows-msvc
39
+ binary: vision-squeezer-mcp.exe
40
+ asset: vision-squeezer-mcp-windows-x86_64.exe
41
+
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+ - uses: dtolnay/rust-toolchain@stable
45
+ with:
46
+ targets: ${{ matrix.target }}
47
+ - uses: Swatinem/rust-cache@v2
48
+
49
+ - name: Install cross-compiler (Linux arm64)
50
+ if: matrix.target == 'aarch64-unknown-linux-gnu'
51
+ run: |
52
+ sudo apt-get update
53
+ sudo apt-get install -y gcc-aarch64-linux-gnu
54
+
55
+ - name: Build
56
+ env:
57
+ CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
58
+ run: cargo build --release --bin vision-squeezer-mcp --target ${{ matrix.target }}
59
+
60
+ - name: Upload artifact
61
+ uses: actions/upload-artifact@v4
62
+ with:
63
+ name: ${{ matrix.asset }}
64
+ path: target/${{ matrix.target }}/release/${{ matrix.binary }}
65
+ if-no-files-found: error
66
+ # Artifacts are only needed long enough for the `release` job to pull
67
+ # them and attach to the GitHub Release. The default 90-day retention
68
+ # wastes storage quota — 7 days is well past any retry window.
69
+ retention-days: 7
70
+
71
+ # GitHub Release + crates.io + npm in a single runner. Each individual
72
+ # publish step is well under a minute; running them in one job saves the
73
+ # ~30s × 2 runner spin-ups vs the old three-job split, and lets npm's
74
+ # postinstall safely find the freshly-attached GH release binaries
75
+ # (npm publish only happens after `gh release` attaches assets).
76
+ #
77
+ # Step order matters: cargo publish runs BEFORE artifact download so its
78
+ # dirty-tree check sees a clean working directory. Downloading artifacts
79
+ # first leaves `artifacts/` and `dist/` as untracked files and cargo
80
+ # refuses to publish without `--allow-dirty`.
81
+ publish:
82
+ name: Publish (GitHub Release + crates.io + npm)
83
+ needs: build
84
+ runs-on: ubuntu-latest
85
+ permissions:
86
+ contents: write
87
+ id-token: write # OIDC token for mcp-publisher (io.github.* namespace auth)
88
+ steps:
89
+ - uses: actions/checkout@v4
90
+
91
+ - uses: dtolnay/rust-toolchain@stable
92
+ - uses: Swatinem/rust-cache@v2
93
+
94
+ - name: Publish to crates.io (skip if version exists)
95
+ env:
96
+ CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
97
+ # `--locked` forbids cargo from regenerating Cargo.lock during
98
+ # publish (which would dirty the working tree and trip the
99
+ # built-in cleanliness check). The lockfile must be committed
100
+ # in sync with Cargo.toml — bump both in every version commit.
101
+ run: |
102
+ set +e
103
+ OUTPUT=$(cargo publish --locked 2>&1)
104
+ STATUS=$?
105
+ echo "$OUTPUT"
106
+ if [ $STATUS -ne 0 ] && echo "$OUTPUT" | grep -q "already exists"; then
107
+ echo "Version already on crates.io — skipping."
108
+ exit 0
109
+ fi
110
+ exit $STATUS
111
+
112
+ - uses: actions/setup-node@v4
113
+ with:
114
+ node-version: '24'
115
+ registry-url: 'https://registry.npmjs.org'
116
+
117
+ - name: Download all artifacts
118
+ uses: actions/download-artifact@v4
119
+ with:
120
+ path: artifacts/
121
+
122
+ - name: Rename binaries
123
+ run: |
124
+ mkdir -p dist
125
+ for dir in artifacts/*/; do
126
+ name=$(basename "$dir")
127
+ src="${dir}vision-squeezer-mcp.exe"
128
+ [ -f "$src" ] || src="${dir}vision-squeezer-mcp"
129
+ cp "$src" "dist/${name}"
130
+ done
131
+
132
+ - name: Extract changelog for this version
133
+ id: changelog
134
+ run: |
135
+ VERSION="${GITHUB_REF_NAME#v}"
136
+ BODY=$(awk "/^## \[${VERSION}\]/{found=1; next} found && /^## \[/{exit} found{print}" CHANGELOG.md)
137
+ echo "body<<EOF" >> "$GITHUB_OUTPUT"
138
+ echo "$BODY" >> "$GITHUB_OUTPUT"
139
+ echo "EOF" >> "$GITHUB_OUTPUT"
140
+
141
+ - name: Upload to GitHub Release
142
+ uses: softprops/action-gh-release@v2
143
+ with:
144
+ files: dist/vision-squeezer-mcp-*
145
+ body: ${{ steps.changelog.outputs.body }}
146
+
147
+ - name: Publish to npm
148
+ run: npm publish --access public
149
+ env:
150
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
151
+
152
+ # MCP registry (registry.modelcontextprotocol.io) listing. Auth is GitHub
153
+ # OIDC — the `io.github.eralpozcan/*` namespace is proven by this repo's
154
+ # id-token, so no secret is needed. Replaces the old manual mcp-publisher
155
+ # step that left server.json stale at 0.1.1 through 0.3.x.
156
+ - name: Publish to MCP Registry
157
+ run: |
158
+ curl -fsSL "https://github.com/modelcontextprotocol/registry/releases/download/v1.7.9/mcp-publisher_linux_amd64.tar.gz" | tar -xz mcp-publisher
159
+ ./mcp-publisher login github-oidc
160
+ ./mcp-publisher publish
161
+
@@ -0,0 +1,20 @@
1
+ /target
2
+ **/target/
3
+ node_modules
4
+ .DS_Store
5
+ .claude/
6
+ *.optimized.*
7
+
8
+ # Release build outputs (downloaded artifacts + renamed binaries)
9
+ /artifacts/
10
+ /dist/
11
+
12
+ # Python build artifacts
13
+ python/dist/
14
+ python/build/
15
+ python/*.egg-info/
16
+ __pycache__/
17
+ *.pyc
18
+ *.so
19
+ *.pyd
20
+ *.dylib
@@ -0,0 +1,31 @@
1
+ # Source & build
2
+ src/
3
+ target/
4
+ Cargo.toml
5
+ Cargo.lock
6
+ Makefile
7
+
8
+ # Dev assets & test data
9
+ assets/
10
+ data/
11
+ docs/
12
+
13
+ # GitHub / CI
14
+ .github/
15
+ scripts/
16
+
17
+ # Claude / editor
18
+ .claude/
19
+ CLAUDE.md
20
+
21
+ # Native binaries (downloaded by postinstall, not bundled)
22
+ bin/vision-squeezer-mcp
23
+ bin/vision-squeezer-mcp.exe
24
+
25
+ # Skills (Claude Code specific)
26
+ skills/
27
+
28
+ # Misc
29
+ llms.txt
30
+ llms-full.txt
31
+ .DS_Store