sassymcp 1.12.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 (237) hide show
  1. sassymcp-1.12.0/.claude/scheduled_tasks.lock +1 -0
  2. sassymcp-1.12.0/.claude/skills/sassymcp-shell.md +36 -0
  3. sassymcp-1.12.0/.claude/skills/sassymcp-update.md +65 -0
  4. sassymcp-1.12.0/.gitattributes +6 -0
  5. sassymcp-1.12.0/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
  6. sassymcp-1.12.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
  7. sassymcp-1.12.0/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
  8. sassymcp-1.12.0/.github/workflows/release.yml +415 -0
  9. sassymcp-1.12.0/.gitignore +106 -0
  10. sassymcp-1.12.0/.vscode/settings.json +3 -0
  11. sassymcp-1.12.0/CHANGELOG.md +500 -0
  12. sassymcp-1.12.0/IMPROVEMENT_NOTES_2026-04-30.md +219 -0
  13. sassymcp-1.12.0/LICENSE +21 -0
  14. sassymcp-1.12.0/MIGRATION.md +191 -0
  15. sassymcp-1.12.0/PKG-INFO +710 -0
  16. sassymcp-1.12.0/README.md +668 -0
  17. sassymcp-1.12.0/audits/mercury_sassymcp_core_report.md +136 -0
  18. sassymcp-1.12.0/audits/mercury_sassymcp_modules-a_report.md +16 -0
  19. sassymcp-1.12.0/audits/mercury_sassymcp_modules-b_report.md +147 -0
  20. sassymcp-1.12.0/autostart-bridge.bat +52 -0
  21. sassymcp-1.12.0/build-msi.ps1 +118 -0
  22. sassymcp-1.12.0/build.bat +39 -0
  23. sassymcp-1.12.0/build.sh +59 -0
  24. sassymcp-1.12.0/deploy/README.txt +88 -0
  25. sassymcp-1.12.0/deploy/claude_desktop_config.template.json +11 -0
  26. sassymcp-1.12.0/deploy/continue_mcp_config.template.json +14 -0
  27. sassymcp-1.12.0/deploy/cursor_mcp_config.template.json +12 -0
  28. sassymcp-1.12.0/deploy/grok_desktop_config.template.json +11 -0
  29. sassymcp-1.12.0/deploy/ssh_debug.txt +0 -0
  30. sassymcp-1.12.0/deploy/start-beta.bat +11 -0
  31. sassymcp-1.12.0/deploy/start-lan.bat +71 -0
  32. sassymcp-1.12.0/deploy/start-local.bat +22 -0
  33. sassymcp-1.12.0/deploy/start-tunnel.bat +92 -0
  34. sassymcp-1.12.0/deploy/windsurf_mcp_config.template.json +12 -0
  35. sassymcp-1.12.0/deploy.bat +141 -0
  36. sassymcp-1.12.0/docs/SassyWorks.md +153 -0
  37. sassymcp-1.12.0/docs/TUNNEL.md +196 -0
  38. sassymcp-1.12.0/docs/launch/00-RUNBOOK.md +121 -0
  39. sassymcp-1.12.0/docs/launch/01-positioning.md +69 -0
  40. sassymcp-1.12.0/docs/launch/02-product-hunt.md +75 -0
  41. sassymcp-1.12.0/docs/launch/03-show-hn.md +70 -0
  42. sassymcp-1.12.0/docs/launch/04-reddit.md +71 -0
  43. sassymcp-1.12.0/docs/launch/05-x-thread.md +58 -0
  44. sassymcp-1.12.0/docs/launch/06-devto-article.md +144 -0
  45. sassymcp-1.12.0/docs/launch/07-directories.md +111 -0
  46. sassymcp-1.12.0/docs/launch/08-assets-to-capture.md +64 -0
  47. sassymcp-1.12.0/docs/releases/_template.md +61 -0
  48. sassymcp-1.12.0/docs/releases/v1.1.1.md +110 -0
  49. sassymcp-1.12.0/docs/releases/v1.1.2.md +182 -0
  50. sassymcp-1.12.0/docs/releases/v1.1.3.md +124 -0
  51. sassymcp-1.12.0/docs/releases/v1.10.0.md +93 -0
  52. sassymcp-1.12.0/docs/releases/v1.2.0.md +98 -0
  53. sassymcp-1.12.0/docs/releases/v1.3.0.md +89 -0
  54. sassymcp-1.12.0/docs/releases/v1.3.1.md +54 -0
  55. sassymcp-1.12.0/docs/releases/v1.3.2.md +66 -0
  56. sassymcp-1.12.0/docs/releases/v1.3.3.md +89 -0
  57. sassymcp-1.12.0/docs/releases/v1.3.4.md +92 -0
  58. sassymcp-1.12.0/docs/releases/v1.4.0.md +90 -0
  59. sassymcp-1.12.0/docs/releases/v1.4.1.md +22 -0
  60. sassymcp-1.12.0/docs/releases/v1.4.2.md +91 -0
  61. sassymcp-1.12.0/docs/releases/v1.5.0.md +184 -0
  62. sassymcp-1.12.0/docs/releases/v1.7.2.md +76 -0
  63. sassymcp-1.12.0/docs/releases/v1.8.0.md +92 -0
  64. sassymcp-1.12.0/docs/superpowers/plans/2026-04-05-license-system.md +567 -0
  65. sassymcp-1.12.0/docs/superpowers/plans/2026-05-03-concurrency-hardening.md +1602 -0
  66. sassymcp-1.12.0/docs/superpowers/plans/2026-05-03-install-cli-and-dxt.md +660 -0
  67. sassymcp-1.12.0/docs/superpowers/specs/2026-04-05-sassymcp-product-design.md +191 -0
  68. sassymcp-1.12.0/docs/superpowers/specs/2026-05-03-install-cli-dxt-vscode-ext-design.md +206 -0
  69. sassymcp-1.12.0/docs/superpowers/specs/2026-05-03-multi-client-integration-design.md +303 -0
  70. sassymcp-1.12.0/docs/superpowers/specs/2026-06-06-sassy-brain-cockpit-design.md +104 -0
  71. sassymcp-1.12.0/hermes_node.py +292 -0
  72. sassymcp-1.12.0/installer.wxs +304 -0
  73. sassymcp-1.12.0/mcpb/README.md +35 -0
  74. sassymcp-1.12.0/mcpb/icon.png +0 -0
  75. sassymcp-1.12.0/mcpb/manifest.json +24 -0
  76. sassymcp-1.12.0/personal/.gitkeep +0 -0
  77. sassymcp-1.12.0/personal/README.md +43 -0
  78. sassymcp-1.12.0/pyproject.toml +77 -0
  79. sassymcp-1.12.0/sassymcp/__init__.py +12 -0
  80. sassymcp-1.12.0/sassymcp/__main__.py +7 -0
  81. sassymcp-1.12.0/sassymcp/_atomic.py +96 -0
  82. sassymcp-1.12.0/sassymcp/_audit_io.py +118 -0
  83. sassymcp-1.12.0/sassymcp/_brain_status.py +100 -0
  84. sassymcp-1.12.0/sassymcp/_cli_wizard.py +350 -0
  85. sassymcp-1.12.0/sassymcp/_db.py +40 -0
  86. sassymcp-1.12.0/sassymcp/_jobctl.py +300 -0
  87. sassymcp-1.12.0/sassymcp/_lemonsqueezy.py +308 -0
  88. sassymcp-1.12.0/sassymcp/_paths.py +76 -0
  89. sassymcp-1.12.0/sassymcp/_phone_status.py +57 -0
  90. sassymcp-1.12.0/sassymcp/_platform.py +306 -0
  91. sassymcp-1.12.0/sassymcp/auth.py +336 -0
  92. sassymcp-1.12.0/sassymcp/control_panel.py +835 -0
  93. sassymcp-1.12.0/sassymcp/desktop/__init__.py +10 -0
  94. sassymcp-1.12.0/sassymcp/desktop/__main__.py +3 -0
  95. sassymcp-1.12.0/sassymcp/desktop/app.py +147 -0
  96. sassymcp-1.12.0/sassymcp/desktop/bridge.py +141 -0
  97. sassymcp-1.12.0/sassymcp/install.py +559 -0
  98. sassymcp-1.12.0/sassymcp/license.py +568 -0
  99. sassymcp-1.12.0/sassymcp/modules/__init__.py +4 -0
  100. sassymcp-1.12.0/sassymcp/modules/_confirm.py +134 -0
  101. sassymcp-1.12.0/sassymcp/modules/_github_client.py +222 -0
  102. sassymcp-1.12.0/sassymcp/modules/_hooks.py +125 -0
  103. sassymcp-1.12.0/sassymcp/modules/_rate_limiter.py +157 -0
  104. sassymcp-1.12.0/sassymcp/modules/_security.py +731 -0
  105. sassymcp-1.12.0/sassymcp/modules/_tool_loader.py +717 -0
  106. sassymcp-1.12.0/sassymcp/modules/adb.py +214 -0
  107. sassymcp-1.12.0/sassymcp/modules/app_launcher.py +565 -0
  108. sassymcp-1.12.0/sassymcp/modules/audit.py +365 -0
  109. sassymcp-1.12.0/sassymcp/modules/bluetooth.py +69 -0
  110. sassymcp-1.12.0/sassymcp/modules/clipboard.py +132 -0
  111. sassymcp-1.12.0/sassymcp/modules/combos.py +356 -0
  112. sassymcp-1.12.0/sassymcp/modules/coordination.py +613 -0
  113. sassymcp-1.12.0/sassymcp/modules/crosslink.py +328 -0
  114. sassymcp-1.12.0/sassymcp/modules/editor.py +253 -0
  115. sassymcp-1.12.0/sassymcp/modules/eventlog.py +159 -0
  116. sassymcp-1.12.0/sassymcp/modules/fileops.py +522 -0
  117. sassymcp-1.12.0/sassymcp/modules/github_ops.py +1016 -0
  118. sassymcp-1.12.0/sassymcp/modules/github_quick.py +135 -0
  119. sassymcp-1.12.0/sassymcp/modules/linux.py +314 -0
  120. sassymcp-1.12.0/sassymcp/modules/memory.py +431 -0
  121. sassymcp-1.12.0/sassymcp/modules/meta.py +410 -0
  122. sassymcp-1.12.0/sassymcp/modules/network_audit.py +224 -0
  123. sassymcp-1.12.0/sassymcp/modules/observability.py +100 -0
  124. sassymcp-1.12.0/sassymcp/modules/persona.py +407 -0
  125. sassymcp-1.12.0/sassymcp/modules/phone_screen.py +784 -0
  126. sassymcp-1.12.0/sassymcp/modules/process_manager.py +161 -0
  127. sassymcp-1.12.0/sassymcp/modules/prompts.py +208 -0
  128. sassymcp-1.12.0/sassymcp/modules/registry.py +180 -0
  129. sassymcp-1.12.0/sassymcp/modules/runtime_config.py +391 -0
  130. sassymcp-1.12.0/sassymcp/modules/security_audit.py +274 -0
  131. sassymcp-1.12.0/sassymcp/modules/selfmod.py +948 -0
  132. sassymcp-1.12.0/sassymcp/modules/session.py +344 -0
  133. sassymcp-1.12.0/sassymcp/modules/setup_wizard.py +1044 -0
  134. sassymcp-1.12.0/sassymcp/modules/shell.py +668 -0
  135. sassymcp-1.12.0/sassymcp/modules/state_manager.py +94 -0
  136. sassymcp-1.12.0/sassymcp/modules/tools_manager.py +261 -0
  137. sassymcp-1.12.0/sassymcp/modules/ui_automation.py +249 -0
  138. sassymcp-1.12.0/sassymcp/modules/updater.py +365 -0
  139. sassymcp-1.12.0/sassymcp/modules/utility.py +482 -0
  140. sassymcp-1.12.0/sassymcp/modules/vision.py +673 -0
  141. sassymcp-1.12.0/sassymcp/modules/web_inspector.py +354 -0
  142. sassymcp-1.12.0/sassymcp/overlay/__init__.py +8 -0
  143. sassymcp-1.12.0/sassymcp/overlay/__main__.py +3 -0
  144. sassymcp-1.12.0/sassymcp/overlay/app.py +102 -0
  145. sassymcp-1.12.0/sassymcp/overlay/hotkey.py +23 -0
  146. sassymcp-1.12.0/sassymcp/overlay/launcher.py +174 -0
  147. sassymcp-1.12.0/sassymcp/overlay/mesh.py +104 -0
  148. sassymcp-1.12.0/sassymcp/overlay/tray.py +30 -0
  149. sassymcp-1.12.0/sassymcp/policy.py +268 -0
  150. sassymcp-1.12.0/sassymcp/server.py +1327 -0
  151. sassymcp-1.12.0/sassymcp/skills/sassymcp-tools.md +68 -0
  152. sassymcp-1.12.0/sassymcp/supervisor.py +585 -0
  153. sassymcp-1.12.0/sassymcp-billing/.gitignore +6 -0
  154. sassymcp-1.12.0/sassymcp-billing/package.json +14 -0
  155. sassymcp-1.12.0/sassymcp-billing/src/index.js +243 -0
  156. sassymcp-1.12.0/sassymcp-billing/wrangler.toml.example +45 -0
  157. sassymcp-1.12.0/sassymcp-oauth/package.json +14 -0
  158. sassymcp-1.12.0/sassymcp-oauth/src/index.js +449 -0
  159. sassymcp-1.12.0/sassymcp-oauth/wrangler.toml.example +37 -0
  160. sassymcp-1.12.0/sassymcp-vscode/.gitignore +5 -0
  161. sassymcp-1.12.0/sassymcp-vscode/.vscode/launch.json +13 -0
  162. sassymcp-1.12.0/sassymcp-vscode/.vscode/tasks.json +12 -0
  163. sassymcp-1.12.0/sassymcp-vscode/.vscodeignore +10 -0
  164. sassymcp-1.12.0/sassymcp-vscode/CHANGELOG.md +46 -0
  165. sassymcp-1.12.0/sassymcp-vscode/LICENSE +21 -0
  166. sassymcp-1.12.0/sassymcp-vscode/README.md +47 -0
  167. sassymcp-1.12.0/sassymcp-vscode/media/cockpit/cockpit.css +2 -0
  168. sassymcp-1.12.0/sassymcp-vscode/media/cockpit/cockpit.js +8 -0
  169. sassymcp-1.12.0/sassymcp-vscode/out/brain.js +123 -0
  170. sassymcp-1.12.0/sassymcp-vscode/out/brain.js.map +1 -0
  171. sassymcp-1.12.0/sassymcp-vscode/out/cockpit.js +203 -0
  172. sassymcp-1.12.0/sassymcp-vscode/out/cockpit.js.map +1 -0
  173. sassymcp-1.12.0/sassymcp-vscode/out/cockpitData.js +177 -0
  174. sassymcp-1.12.0/sassymcp-vscode/out/cockpitData.js.map +1 -0
  175. sassymcp-1.12.0/sassymcp-vscode/out/extension.js +150 -0
  176. sassymcp-1.12.0/sassymcp-vscode/out/extension.js.map +1 -0
  177. sassymcp-1.12.0/sassymcp-vscode/out/hermes.js +113 -0
  178. sassymcp-1.12.0/sassymcp-vscode/out/hermes.js.map +1 -0
  179. sassymcp-1.12.0/sassymcp-vscode/out/installer.js +135 -0
  180. sassymcp-1.12.0/sassymcp-vscode/out/installer.js.map +1 -0
  181. sassymcp-1.12.0/sassymcp-vscode/out/setupWizard.js +288 -0
  182. sassymcp-1.12.0/sassymcp-vscode/out/setupWizard.js.map +1 -0
  183. sassymcp-1.12.0/sassymcp-vscode/out/status.js +86 -0
  184. sassymcp-1.12.0/sassymcp-vscode/out/status.js.map +1 -0
  185. sassymcp-1.12.0/sassymcp-vscode/package-lock.json +4812 -0
  186. sassymcp-1.12.0/sassymcp-vscode/package.json +120 -0
  187. sassymcp-1.12.0/sassymcp-vscode/resources/icon.png +0 -0
  188. sassymcp-1.12.0/sassymcp-vscode/resources/icon.svg +16 -0
  189. sassymcp-1.12.0/sassymcp-vscode/src/brain.ts +98 -0
  190. sassymcp-1.12.0/sassymcp-vscode/src/cockpit.ts +190 -0
  191. sassymcp-1.12.0/sassymcp-vscode/src/cockpitData.ts +204 -0
  192. sassymcp-1.12.0/sassymcp-vscode/src/extension.ts +135 -0
  193. sassymcp-1.12.0/sassymcp-vscode/src/hermes.ts +84 -0
  194. sassymcp-1.12.0/sassymcp-vscode/src/installer.ts +106 -0
  195. sassymcp-1.12.0/sassymcp-vscode/src/setupWizard.ts +280 -0
  196. sassymcp-1.12.0/sassymcp-vscode/src/status.ts +54 -0
  197. sassymcp-1.12.0/sassymcp-vscode/tsconfig.json +16 -0
  198. sassymcp-1.12.0/sassymcp-vscode/vite.config.ts +35 -0
  199. sassymcp-1.12.0/sassymcp-vscode/webview/App.tsx +411 -0
  200. sassymcp-1.12.0/sassymcp-vscode/webview/cockpit.css +273 -0
  201. sassymcp-1.12.0/sassymcp-vscode/webview/main.tsx +8 -0
  202. sassymcp-1.12.0/sassymcp-vscode/webview/tsconfig.json +14 -0
  203. sassymcp-1.12.0/sassymcp-vscode/webview/types.ts +134 -0
  204. sassymcp-1.12.0/scripts/build-mcpb.ps1 +102 -0
  205. sassymcp-1.12.0/scripts/check-token.ps1 +9 -0
  206. sassymcp-1.12.0/scripts/gen-icons.py +104 -0
  207. sassymcp-1.12.0/scripts/get-auth-header.ps1 +8 -0
  208. sassymcp-1.12.0/scripts/mcp-init-body.ps1 +14 -0
  209. sassymcp-1.12.0/scripts/smoke-test.ps1 +40 -0
  210. sassymcp-1.12.0/scripts/verify-release.ps1 +96 -0
  211. sassymcp-1.12.0/server.json +22 -0
  212. sassymcp-1.12.0/start-lan.bat +71 -0
  213. sassymcp-1.12.0/start-local.bat +22 -0
  214. sassymcp-1.12.0/start-supervised.bat +47 -0
  215. sassymcp-1.12.0/start-tunnel.bat +92 -0
  216. sassymcp-1.12.0/tests/conftest.py +41 -0
  217. sassymcp-1.12.0/tests/test_atomic_write.py +112 -0
  218. sassymcp-1.12.0/tests/test_audit_io.py +77 -0
  219. sassymcp-1.12.0/tests/test_concurrency_integration.py +335 -0
  220. sassymcp-1.12.0/tests/test_concurrency_stress.py +94 -0
  221. sassymcp-1.12.0/tests/test_control_panel.py +230 -0
  222. sassymcp-1.12.0/tests/test_coordination.py +158 -0
  223. sassymcp-1.12.0/tests/test_db_helper.py +93 -0
  224. sassymcp-1.12.0/tests/test_discovery.py +97 -0
  225. sassymcp-1.12.0/tests/test_install.py +414 -0
  226. sassymcp-1.12.0/tests/test_intercept.py +805 -0
  227. sassymcp-1.12.0/tests/test_lemonsqueezy.py +455 -0
  228. sassymcp-1.12.0/tests/test_license_gating.py +241 -0
  229. sassymcp-1.12.0/tests/test_policy.py +152 -0
  230. sassymcp-1.12.0/tests/test_shell_auto_promote.py +100 -0
  231. sassymcp-1.12.0/tests/test_supervisor_lifecycle.py +327 -0
  232. sassymcp-1.12.0/tests/test_tool_loader_boost.py +160 -0
  233. sassymcp-1.12.0/tests/test_updater.py +52 -0
  234. sassymcp-1.12.0/tools/lemonsqueezy_setup.py +309 -0
  235. sassymcp-1.12.0/tools/mercury_audit_sassymcp.py +235 -0
  236. sassymcp-1.12.0/tools/verify_audit_fixes.py +479 -0
  237. sassymcp-1.12.0/uv.lock +1332 -0
@@ -0,0 +1 @@
1
+ {"sessionId":"c893b31e-4d63-4157-b42d-1247cac71aec","pid":21192,"acquiredAt":1782209316903}
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: sassymcp-shell
3
+ description: Use BEFORE calling sassy_shell, sassy_session_start, or sassy_session_send on a SassyMCP server. Establishes that the default shell is Windows PowerShell so commands are written in PowerShell syntax on the first try (no wasted retries on bash idioms). Also use when generating multi-line scripts to a SassyMCP target.
4
+ ---
5
+
6
+ # SassyMCP Shell Context
7
+
8
+ The SassyMCP server runs on **Windows**. `sassy_shell` defaults to `shell="powershell"`. Write commands in PowerShell syntax up front — don't reach for bash habits unless you've explicitly switched to `shell="wsl"` or `shell="cmd"`.
9
+
10
+ ## Quick translation
11
+
12
+ | bash / POSIX | PowerShell |
13
+ |---|---|
14
+ | `cd /d V:\foo` | `Set-Location V:\foo` |
15
+ | `cmd1 && cmd2` | `cmd1; cmd2` (or `if ($?) { cmd2 }`) |
16
+ | `cmd1 \|\| cmd2` | `if (-not $?) { cmd2 }` |
17
+ | `mkdir -p foo/bar` | `New-Item -ItemType Directory -Force foo/bar` |
18
+ | `cat foo` | `Get-Content foo` |
19
+ | `grep pat foo` | `Select-String pat foo` |
20
+ | `which X` | `Get-Command X` |
21
+ | `export FOO=bar` | `$env:FOO = "bar"` |
22
+ | `ls -la` | `Get-ChildItem -Force` |
23
+ | `rm -rf …` | intercepted — use `sassy_safe_delete` |
24
+ | escape with `\` | escape with backtick `` ` `` |
25
+
26
+ `sassy_shell` auto-rewrites `&&` → `;` and `cd /d` → `Set-Location` for the PowerShell shell, but writing it correctly the first time saves a round-trip.
27
+
28
+ ## Multi-line scripts and file content
29
+
30
+ - Don't try to embed multi-line PowerShell or here-strings inside a single `sassy_shell` argument — quoting collapses, and `Set-Content @'...'@` content gets keyword-scanned even when it's just data.
31
+ - **Use `sassy_write_file(path, content)` instead** — direct .NET write, bypasses all PowerShell quoting and the shell-keyword scanner. Then invoke the resulting file with `sassy_shell`.
32
+
33
+ ## When to switch shells
34
+
35
+ - `shell="cmd"`: `.bat` files, `tasklist`/`taskkill`, legacy CMD-only builtins.
36
+ - `shell="wsl"`: real bash — `grep`/`awk`/`sed` pipelines, Linux-native tools, anything where PowerShell equivalents are awkward. WSL receives the command verbatim, no PowerShell rewriting.
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: sassymcp-update
3
+ description: Use when the user wants to check, review, or apply a SassyMCP update — e.g. "is there a new version of sassymcp?", "update sassymcp", "what changed in the latest sassymcp release?", "show the sassymcp changelog". Walks through Kali-style apt-update / apt-show / apt-upgrade against this server's GitHub Releases (or the license-gated sassyconsultingllc.com endpoint when SASSYMCP_LICENSE_KEY is set). Never auto-installs — surfaces the asset, downloads to staging, and hands the user the run command.
4
+ ---
5
+
6
+ # SassyMCP Update Walkthrough
7
+
8
+ This skill walks through the four updater tools added in v1.3.0:
9
+
10
+ | Step | Tool | apt analogue |
11
+ |---|---|---|
12
+ | 1 | `sassy_update_check` | `apt update` — refresh remote state |
13
+ | 2 | `sassy_update_changelog` | `apt show <pkg>` — read release notes |
14
+ | 3 | `sassy_update_list` | `apt list --upgradable` — see assets |
15
+ | 4 | `sassy_update_apply` | `apt upgrade` (download phase) — stage the install |
16
+
17
+ ## When to invoke
18
+
19
+ Trigger when the user asks anything like:
20
+ - "check for sassymcp updates"
21
+ - "is there a new version?"
22
+ - "what's in the latest release?"
23
+ - "update sassymcp" / "upgrade sassymcp"
24
+ - "show me the changelog"
25
+ - "download the new MSI"
26
+
27
+ ## Workflow
28
+
29
+ 1. **Call `sassy_update_check`** with `force=False` (cached, 5 min TTL).
30
+ - If `upgradable: false` — tell the user they're on the latest, stop.
31
+ - If `upgradable: true` — surface the `summary` field (e.g. `1.2.0 → 1.3.0 available`).
32
+
33
+ 2. **Call `sassy_update_changelog`** with no `tag` (defaults to latest).
34
+ - Show the user the `name`, `published_at`, and `body` so they know what's
35
+ in the release before downloading 100+ MB.
36
+
37
+ 3. **Ask the user which asset they want**:
38
+ - Portable zip (`sassymcp-v*-portable.zip`, ~123 MB) — exe + tools + launchers.
39
+ Extract anywhere; delete the folder to remove. **Recommended.**
40
+ - Standalone exe (`sassymcp.exe`, ~35 MB) — no bundled tools.
41
+ - Or skip — they read the changelog and don't want to upgrade right now.
42
+
43
+ 4. **Call `sassy_update_apply`** with the chosen `asset_name`.
44
+ - Returns `downloaded_to` (a path under `%LOCALAPPDATA%\SassyMCP\updates\`)
45
+ and `next_step` — for a portable zip this is an `Expand-Archive`
46
+ command targeting `%LOCALAPPDATA%\SassyMCP\<tag>\`; for the standalone
47
+ exe it's the path to the exe.
48
+ - Echo the `next_step` to the user verbatim — **do not** auto-execute it.
49
+ Updates apply on next launch; this is an explicit user action by design.
50
+
51
+ ## License-aware download
52
+
53
+ If the env var `SASSYMCP_LICENSE_KEY` is set, `sassy_update_apply`
54
+ automatically rewrites the download URL to the gated
55
+ `https://sassyconsultingllc.com/download/sassymcp/windows/<asset>?key=...`
56
+ endpoint. The user gets the same file from the licensed mirror instead of
57
+ public GitHub Releases.
58
+
59
+ ## What this skill does NOT do
60
+
61
+ - **Never auto-runs the installer.** UAC + user intent. Always returns the
62
+ command for the user to run themselves.
63
+ - **Never modifies the running server.** Update applies on next launch.
64
+ - **Never blocks a downgrade.** If the user passes an older `tag` to
65
+ `sassy_update_apply`, that's their call.
@@ -0,0 +1,6 @@
1
+ # Shell scripts must stay LF — a CRLF shebang breaks them on macOS/Linux.
2
+ *.sh text eol=lf
3
+
4
+ # Windows batch/PowerShell scripts use CRLF.
5
+ *.bat text eol=crlf
6
+ *.ps1 text eol=crlf
@@ -0,0 +1,40 @@
1
+ <!--
2
+ Copyright (c) 2026 Shane Smith / Sassy Consulting LLC. All rights reserved.
3
+ Proprietary source. This notice is Copyright Management Information (17 U.S.C. 1202); removal or alteration prohibited.
4
+ CodeMark: SCLLC1-SassyMCP-Q3OSLI6ULAIQ
5
+ -->
6
+ ---
7
+ name: Bug Report
8
+ about: Something isn't working right
9
+ title: "[Bug] "
10
+ labels: bug
11
+ assignees: ''
12
+ ---
13
+
14
+ **What happened?**
15
+ A clear description of the bug.
16
+
17
+ **Steps to reproduce**
18
+ 1.
19
+ 2.
20
+ 3.
21
+
22
+ **Expected behavior**
23
+ What should have happened.
24
+
25
+ **Environment**
26
+ - SassyMCP version: v1.1.0
27
+ - MCP client: (Claude Desktop / Grok Desktop / Cursor / other)
28
+ - Transport mode: (stdio / HTTP / SSE)
29
+ - Windows version:
30
+ - Running from: (exe / source)
31
+
32
+ **Relevant logs**
33
+ Paste any error output or server logs here.
34
+
35
+ ```
36
+ (paste logs here)
37
+ ```
38
+
39
+ **Screenshots**
40
+ If applicable, add screenshots.
@@ -0,0 +1,8 @@
1
+ # Copyright (c) 2026 Shane Smith / Sassy Consulting LLC. All rights reserved.
2
+ # Proprietary source. This notice is Copyright Management Information (17 U.S.C. 1202); removal or alteration prohibited.
3
+ # CodeMark: SCLLC1-SassyMCP-TBNJIBENT44G
4
+ blank_issues_enabled: true
5
+ contact_links:
6
+ - name: Documentation
7
+ url: https://github.com/sassyconsultingllc/SassyMCP#readme
8
+ about: Check the README for setup and usage guides
@@ -0,0 +1,24 @@
1
+ <!--
2
+ Copyright (c) 2026 Shane Smith / Sassy Consulting LLC. All rights reserved.
3
+ Proprietary source. This notice is Copyright Management Information (17 U.S.C. 1202); removal or alteration prohibited.
4
+ CodeMark: SCLLC1-SassyMCP-O3YBHELD3QCV
5
+ -->
6
+ ---
7
+ name: Feature Request
8
+ about: Suggest a new tool or improvement
9
+ title: "[Feature] "
10
+ labels: enhancement
11
+ assignees: ''
12
+ ---
13
+
14
+ **What would you like?**
15
+ A clear description of the feature or improvement.
16
+
17
+ **Why?**
18
+ What problem does this solve or what workflow does it enable?
19
+
20
+ **Which module would this belong to?**
21
+ (e.g., core, android, system, github, new module)
22
+
23
+ **Alternatives considered**
24
+ Any workarounds you've tried or other approaches.
@@ -0,0 +1,415 @@
1
+ # Copyright (c) 2026 Shane Smith / Sassy Consulting LLC. All rights reserved.
2
+ # Proprietary source. This notice is Copyright Management Information (17 U.S.C. 1202); removal or alteration prohibited.
3
+ # CodeMark: SCLLC1-SassyMCP-G725NZONYF5R
4
+ name: Release
5
+
6
+ on:
7
+ push:
8
+ tags:
9
+ - "v*.*.*"
10
+ workflow_dispatch:
11
+ # Allow manual builds against any branch without tagging. The build jobs
12
+ # produce artifacts; the release/publish jobs only fire on real tag pushes.
13
+
14
+ permissions:
15
+ contents: write # needed for gh release create
16
+
17
+ env:
18
+ # Opt in to Node 24 for all JavaScript actions in this workflow. Github
19
+ # deprecated Node 20 in Sept 2025; node24 becomes the default June 2026.
20
+ # Setting this now silences the warnings and confirms forward-compat.
21
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
22
+
23
+ jobs:
24
+ build-exe:
25
+ name: Build sassymcp.exe (Windows)
26
+ runs-on: windows-latest
27
+ defaults:
28
+ run:
29
+ shell: pwsh # windows-latest defaults to pwsh; making it explicit
30
+ outputs:
31
+ version: ${{ steps.version.outputs.value }}
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+
35
+ - uses: actions/setup-python@v5
36
+ with:
37
+ python-version: "3.11"
38
+ cache: pip
39
+
40
+ - name: Read version from sassymcp/__init__.py
41
+ id: version
42
+ run: |
43
+ $content = Get-Content sassymcp/__init__.py -Raw
44
+ if ($content -match '__version__\s*=\s*"([^"]+)"') {
45
+ $v = $Matches[1]
46
+ "value=$v" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
47
+ Write-Host "Version: $v"
48
+ } else {
49
+ Write-Error "Could not parse __version__"
50
+ exit 1
51
+ }
52
+
53
+ - name: Verify tag matches __version__
54
+ if: startsWith(github.ref, 'refs/tags/')
55
+ run: |
56
+ $tagVersion = "${{ github.ref_name }}".TrimStart("v")
57
+ $sourceVersion = "${{ steps.version.outputs.value }}"
58
+ if ($tagVersion -ne $sourceVersion) {
59
+ Write-Error "Tag $tagVersion does not match __version__ $sourceVersion. Bump sassymcp/__init__.py before tagging."
60
+ exit 1
61
+ }
62
+
63
+ - name: Install dependencies + PyInstaller
64
+ # Install base deps only — the [all] extras (playwright,
65
+ # pytesseract, watchdog) are lazy-imported with graceful
66
+ # fallbacks, so excluding them keeps the shipped exe at ~35 MB
67
+ # instead of ~73 MB. Users who need OCR or playwright
68
+ # screenshots install those into their own Python.
69
+ run: |
70
+ python -m pip install --upgrade pip
71
+ python -m pip install pyinstaller
72
+ python -m pip install -e .
73
+
74
+ - name: Build sassymcp.exe via PyInstaller
75
+ run: |
76
+ pyinstaller --clean --noconfirm sassymcp.spec
77
+
78
+ - name: Verify exe exists
79
+ run: |
80
+ if (-not (Test-Path dist\sassymcp.exe)) {
81
+ Write-Error "PyInstaller did not produce dist\sassymcp.exe"
82
+ exit 1
83
+ }
84
+ $size = (Get-Item dist\sassymcp.exe).Length / 1MB
85
+ Write-Host "Built dist\sassymcp.exe ($([math]::Round($size, 1)) MB)"
86
+
87
+ - name: Smoke-test exe
88
+ run: |
89
+ # argparse exits 0 after printing --help, which is the success signal.
90
+ $output = & .\dist\sassymcp.exe --help 2>&1
91
+ if ($LASTEXITCODE -ne 0) {
92
+ Write-Error "sassymcp.exe --help exited $LASTEXITCODE; output: $output"
93
+ exit 1
94
+ }
95
+
96
+ - name: Upload exe artifact
97
+ uses: actions/upload-artifact@v4
98
+ with:
99
+ name: sassymcp-exe
100
+ path: dist/sassymcp.exe
101
+ if-no-files-found: error
102
+
103
+ build-dxt:
104
+ name: Build sassymcp.dxt
105
+ runs-on: windows-latest
106
+ needs: build-exe
107
+ defaults:
108
+ run:
109
+ shell: pwsh
110
+ steps:
111
+ - uses: actions/checkout@v4
112
+
113
+ - uses: actions/setup-node@v4
114
+ with:
115
+ node-version: "20"
116
+
117
+ - name: Download exe artifact
118
+ uses: actions/download-artifact@v4
119
+ with:
120
+ name: sassymcp-exe
121
+ path: .
122
+
123
+ - name: Build MCPB (+ byte-identical .dxt)
124
+ # build-mcpb.ps1 packs the bundle via the official @anthropic-ai/mcpb
125
+ # CLI (needs npx, hence setup-node above) and emits BOTH dist\*.mcpb and
126
+ # a byte-identical dist\*.dxt. It auto-syncs mcpb/manifest.json's version
127
+ # to sassymcp/__init__.py. Renamed from the old build-dxt.ps1 (now in
128
+ # scripts/_DELETE_/), which this job still referenced — so every release
129
+ # since the rename failed at "scripts/build-dxt.ps1 not recognized".
130
+ run: |
131
+ & scripts/build-mcpb.ps1
132
+
133
+ - name: Verify DXT exists
134
+ run: |
135
+ $dxt = Get-ChildItem dist\sassymcp-v*.dxt | Select-Object -First 1
136
+ if (-not $dxt) {
137
+ Write-Error "build-dxt.ps1 did not produce a DXT file"
138
+ exit 1
139
+ }
140
+ Write-Host "Built $($dxt.Name) ($([math]::Round($dxt.Length / 1MB, 1)) MB)"
141
+
142
+ - name: Upload DXT artifact
143
+ uses: actions/upload-artifact@v4
144
+ with:
145
+ name: sassymcp-dxt
146
+ path: dist/sassymcp-v*.dxt
147
+ if-no-files-found: error
148
+
149
+ build-vsix:
150
+ name: Build sassymcp-vscode-*.vsix
151
+ runs-on: ubuntu-latest
152
+ # No `needs:` — the VSIX doesn't depend on the .exe artifact. Build in
153
+ # parallel with build-exe to shave a few minutes off the pipeline.
154
+ steps:
155
+ - uses: actions/checkout@v4
156
+
157
+ - uses: actions/setup-node@v4
158
+ with:
159
+ node-version: "20"
160
+ cache: npm
161
+ cache-dependency-path: sassymcp-vscode/package-lock.json
162
+
163
+ - name: Sync sassymcp-vscode/package.json version with __init__.py
164
+ # The package.json version drives the produced .vsix filename. Keep
165
+ # it locked to the canonical __version__ so the VSIX, the DXT, and
166
+ # the GitHub release tag all carry the same string.
167
+ run: |
168
+ set -euo pipefail
169
+ version=$(python3 -c 'import re,sys; m=re.search(r"__version__\s*=\s*\"([^\"]+)\"", open("sassymcp/__init__.py").read()); print(m.group(1)) if m else sys.exit("could not parse __version__")')
170
+ echo "Syncing sassymcp-vscode/package.json to version $version"
171
+ # Update only the top-level "version" field. jq preserves formatting
172
+ # well enough for our purposes; install jq if not present (it is on
173
+ # ubuntu-latest by default but be explicit).
174
+ which jq >/dev/null || sudo apt-get update && sudo apt-get install -y jq
175
+ tmp=$(mktemp)
176
+ jq --arg v "$version" '.version = $v' sassymcp-vscode/package.json > "$tmp"
177
+ mv "$tmp" sassymcp-vscode/package.json
178
+ # Show the change for the run log
179
+ grep '"version"' sassymcp-vscode/package.json | head -1
180
+
181
+ - name: Install extension dependencies
182
+ working-directory: sassymcp-vscode
183
+ run: npm ci
184
+
185
+ - name: Compile TypeScript
186
+ working-directory: sassymcp-vscode
187
+ run: npm run compile
188
+
189
+ - name: Ensure dist/ exists
190
+ # vsce --out path must be a real directory or vsce errors. Repo root.
191
+ run: mkdir -p dist
192
+
193
+ - name: Package VSIX
194
+ working-directory: sassymcp-vscode
195
+ run: npx --yes @vscode/vsce package --out ../dist/
196
+
197
+ - name: Verify VSIX exists
198
+ run: |
199
+ ls -la dist/
200
+ if ! ls dist/sassymcp-*.vsix 1> /dev/null 2>&1; then
201
+ echo "vsce did not produce a VSIX"
202
+ exit 1
203
+ fi
204
+
205
+ - name: Upload VSIX artifact
206
+ uses: actions/upload-artifact@v4
207
+ with:
208
+ name: sassymcp-vsix
209
+ path: dist/sassymcp-*.vsix
210
+ if-no-files-found: error
211
+
212
+ build-macos:
213
+ name: Build sassymcp (macOS ${{ matrix.arch }})
214
+ runs-on: ${{ matrix.runner }}
215
+ # Build each arch on a native runner — PyInstaller can't cross-compile, and
216
+ # building x86_64 on an Intel runner + arm64 on an Apple Silicon runner is
217
+ # what lets us lipo a true universal2 binary in build-macos-universal.
218
+ strategy:
219
+ fail-fast: false
220
+ matrix:
221
+ include:
222
+ - runner: macos-13 # Intel (x86_64)
223
+ arch: x86_64
224
+ - runner: macos-14 # Apple Silicon (arm64)
225
+ arch: arm64
226
+ steps:
227
+ - uses: actions/checkout@v4
228
+
229
+ - uses: actions/setup-python@v5
230
+ with:
231
+ python-version: "3.11"
232
+ cache: pip
233
+
234
+ - name: Verify tag matches __version__
235
+ if: startsWith(github.ref, 'refs/tags/')
236
+ run: |
237
+ set -euo pipefail
238
+ tag="${GITHUB_REF_NAME#v}"
239
+ src=$(python3 -c 'import re,sys; m=re.search(r"__version__\s*=\s*\"([^\"]+)\"", open("sassymcp/__init__.py").read()); print(m.group(1)) if m else sys.exit("could not parse __version__")')
240
+ if [ "$tag" != "$src" ]; then
241
+ echo "Tag $tag does not match __version__ $src. Bump sassymcp/__init__.py before tagging."
242
+ exit 1
243
+ fi
244
+
245
+ - name: Install dependencies + PyInstaller
246
+ # Base deps only — the [all] extras (playwright/pytesseract/watchdog)
247
+ # are lazy-imported with graceful fallbacks, mirroring build-exe. The
248
+ # spec is platform-aware: pyobjc is pulled on macOS via sys_platform
249
+ # markers, pywinauto is excluded.
250
+ run: |
251
+ python -m pip install --upgrade pip
252
+ python -m pip install pyinstaller
253
+ python -m pip install -e .
254
+
255
+ - name: Confirm runner arch
256
+ run: |
257
+ set -euo pipefail
258
+ echo "uname -m: $(uname -m) (expected ${{ matrix.arch }})"
259
+ test "$(uname -m)" = "${{ matrix.arch }}"
260
+
261
+ - name: Build sassymcp via PyInstaller
262
+ run: pyinstaller --clean --noconfirm sassymcp.spec
263
+
264
+ - name: Verify + smoke-test
265
+ run: |
266
+ set -euo pipefail
267
+ test -f dist/sassymcp || { echo "PyInstaller did not produce dist/sassymcp"; exit 1; }
268
+ chmod +x dist/sassymcp
269
+ file dist/sassymcp
270
+ # argparse exits 0 after --help — the success signal.
271
+ ./dist/sassymcp --help >/dev/null
272
+ echo "OK (${{ matrix.arch }})"
273
+
274
+ - name: Upload per-arch artifact
275
+ uses: actions/upload-artifact@v4
276
+ with:
277
+ name: sassymcp-macos-${{ matrix.arch }}
278
+ path: dist/sassymcp
279
+ if-no-files-found: error
280
+
281
+ build-macos-universal:
282
+ name: Merge macOS universal2 binary
283
+ runs-on: macos-latest
284
+ needs: build-macos
285
+ steps:
286
+ - name: Download x86_64 build
287
+ uses: actions/download-artifact@v4
288
+ with:
289
+ name: sassymcp-macos-x86_64
290
+ path: x86_64
291
+
292
+ - name: Download arm64 build
293
+ uses: actions/download-artifact@v4
294
+ with:
295
+ name: sassymcp-macos-arm64
296
+ path: arm64
297
+
298
+ - name: lipo into a universal2 binary
299
+ run: |
300
+ set -euo pipefail
301
+ mkdir -p dist
302
+ lipo -create -output dist/sassymcp-macos x86_64/sassymcp arm64/sassymcp
303
+ chmod +x dist/sassymcp-macos
304
+ echo "=== archs ==="
305
+ lipo -archs dist/sassymcp-macos
306
+ file dist/sassymcp-macos
307
+ lipo -archs dist/sassymcp-macos | grep -q x86_64
308
+ lipo -archs dist/sassymcp-macos | grep -q arm64
309
+ echo "universal2 OK ($(du -h dist/sassymcp-macos | cut -f1))"
310
+
311
+ - name: Smoke-test universal binary
312
+ # macos-latest is arm64; the binary runs its arm64 slice natively.
313
+ run: |
314
+ set -euo pipefail
315
+ ./dist/sassymcp-macos --help >/dev/null
316
+ echo "universal --help OK"
317
+
318
+ # NOTE: this binary is UNSIGNED. On download, Gatekeeper quarantines it
319
+ # ("unidentified developer"); users clear it with `xattr -dr
320
+ # com.apple.quarantine sassymcp-macos` or right-click → Open. To ship
321
+ # signed+notarized, add an Apple Developer ID cert + notarytool step here
322
+ # (needs an Apple Developer account + secrets).
323
+ - name: Upload universal artifact
324
+ uses: actions/upload-artifact@v4
325
+ with:
326
+ name: sassymcp-macos
327
+ path: dist/sassymcp-macos
328
+ if-no-files-found: error
329
+
330
+ release:
331
+ name: GitHub Release
332
+ runs-on: ubuntu-latest
333
+ needs: [build-exe, build-dxt, build-vsix, build-macos-universal]
334
+ # Only fire on real tag pushes; workflow_dispatch builds the artifacts
335
+ # for verification but never publishes a release.
336
+ if: startsWith(github.ref, 'refs/tags/')
337
+ steps:
338
+ - uses: actions/checkout@v4
339
+
340
+ - name: Download all artifacts
341
+ uses: actions/download-artifact@v4
342
+ with:
343
+ path: release-artifacts
344
+
345
+ - name: List downloaded artifacts
346
+ run: find release-artifacts -type f
347
+
348
+ - name: Look up release notes for this version
349
+ id: notes
350
+ run: |
351
+ set -euo pipefail
352
+ version="${{ github.ref_name }}"
353
+ notes_file="docs/releases/${version}.md"
354
+ if [ -f "$notes_file" ]; then
355
+ echo "notes_file=$notes_file" >> "$GITHUB_OUTPUT"
356
+ echo "Using $notes_file"
357
+ else
358
+ echo "notes_file=" >> "$GITHUB_OUTPUT"
359
+ echo "No docs/releases/${version}.md — falling back to auto-generated notes"
360
+ fi
361
+
362
+ - name: Create GitHub Release with all artifacts
363
+ env:
364
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
365
+ run: |
366
+ set -euo pipefail
367
+ if [ -n "${{ steps.notes.outputs.notes_file }}" ]; then
368
+ gh release create "${{ github.ref_name }}" \
369
+ release-artifacts/sassymcp-exe/sassymcp.exe \
370
+ release-artifacts/sassymcp-macos/sassymcp-macos \
371
+ release-artifacts/sassymcp-dxt/*.dxt \
372
+ release-artifacts/sassymcp-vsix/*.vsix \
373
+ --title "${{ github.ref_name }}" \
374
+ --notes-file "${{ steps.notes.outputs.notes_file }}"
375
+ else
376
+ gh release create "${{ github.ref_name }}" \
377
+ release-artifacts/sassymcp-exe/sassymcp.exe \
378
+ release-artifacts/sassymcp-macos/sassymcp-macos \
379
+ release-artifacts/sassymcp-dxt/*.dxt \
380
+ release-artifacts/sassymcp-vsix/*.vsix \
381
+ --title "${{ github.ref_name }}" \
382
+ --generate-notes
383
+ fi
384
+
385
+ publish-vsix:
386
+ name: Publish VSIX to VS Code Marketplace
387
+ runs-on: ubuntu-latest
388
+ needs: build-vsix
389
+ # GitHub Actions does not allow `secrets.*` in job-level `if`. Gate this
390
+ # job on a repository VARIABLE (Settings -> Variables) instead. Set
391
+ # PUBLISH_VSIX=true once VSCE_PAT is configured in repo secrets. Also
392
+ # require a real tag — workflow_dispatch builds shouldn't auto-publish.
393
+ if: ${{ startsWith(github.ref, 'refs/tags/') && vars.PUBLISH_VSIX == 'true' }}
394
+ steps:
395
+ - uses: actions/checkout@v4
396
+
397
+ - uses: actions/setup-node@v4
398
+ with:
399
+ node-version: "20"
400
+
401
+ - name: Download VSIX
402
+ uses: actions/download-artifact@v4
403
+ with:
404
+ name: sassymcp-vsix
405
+ path: dist
406
+
407
+ - name: Publish to Marketplace
408
+ env:
409
+ VSCE_PAT: ${{ secrets.VSCE_PAT }}
410
+ run: |
411
+ if [ -z "$VSCE_PAT" ]; then
412
+ echo "VSCE_PAT secret is empty; cannot publish."
413
+ exit 1
414
+ fi
415
+ npx --yes @vscode/vsce publish --packagePath dist/sassymcp-*.vsix