cue-ai 0.9.0 → 0.9.2

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 (310) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +82 -33
  3. package/bin/cue-review-progress +107 -0
  4. package/bin/cue-review-watch +98 -0
  5. package/dist/cue.js +7352 -3744
  6. package/package.json +16 -5
  7. package/profiles/_types.ts +9 -0
  8. package/profiles/backend/profile.yaml +2 -0
  9. package/profiles/blog-writer/profile.yaml +10 -0
  10. package/profiles/browser/profile.yaml +9 -2
  11. package/profiles/builder/profile.yaml +3 -6
  12. package/profiles/career/profile.yaml +13 -2
  13. package/profiles/claude-api/profile.yaml +1 -1
  14. package/profiles/commerce/profile.yaml +27 -3
  15. package/profiles/core/logo.png +0 -0
  16. package/profiles/core/profile.yaml +62 -2
  17. package/profiles/dash-merge-test/profile.yaml +109 -0
  18. package/profiles/designer/profile.yaml +2 -0
  19. package/profiles/designer-medusa-next/profile.yaml +4 -1
  20. package/profiles/designer-medusa-vite/profile.yaml +4 -1
  21. package/profiles/docs-writer/profile.yaml +3 -1
  22. package/profiles/eu-tender-research/README.md +48 -0
  23. package/profiles/eu-tender-research/logo.png +0 -0
  24. package/profiles/eu-tender-research/profile.yaml +108 -0
  25. package/profiles/finance/logo.png +0 -0
  26. package/profiles/finance/profile.yaml +46 -0
  27. package/profiles/frontend/profile.yaml +5 -9
  28. package/profiles/growth/profile.yaml +2 -3
  29. package/profiles/gstack/profile.yaml +15 -0
  30. package/profiles/higgsfield/profile.yaml +3 -0
  31. package/profiles/hyperframes/logo.png +0 -0
  32. package/profiles/hyperframes/profile.yaml +59 -0
  33. package/profiles/improver/profile.yaml +88 -0
  34. package/profiles/marketing/profile.yaml +0 -3
  35. package/profiles/medusa-dev/profile.yaml +2 -0
  36. package/profiles/medusa-next/profile.yaml +2 -3
  37. package/profiles/medusa-vite/profile.yaml +2 -3
  38. package/profiles/n8n/logo.png +0 -0
  39. package/profiles/n8n/profile.yaml +50 -0
  40. package/profiles/nextjs/profile.yaml +2 -3
  41. package/profiles/ops/profile.yaml +2 -0
  42. package/profiles/postizz/profile.yaml +13 -3
  43. package/profiles/python/profile.yaml +3 -0
  44. package/profiles/research/profile.yaml +3 -1
  45. package/profiles/schema.json +10 -0
  46. package/profiles/secops/profile.yaml +2 -0
  47. package/profiles/seo/profile.yaml +56 -0
  48. package/profiles/skill-writer/profile.yaml +8 -0
  49. package/profiles/ssh/profile.yaml +32 -0
  50. package/profiles/strapi/logo.png +0 -0
  51. package/profiles/strapi/profile.yaml +45 -0
  52. package/profiles/stripe/logo.png +0 -0
  53. package/profiles/stripe/profile.yaml +1 -0
  54. package/profiles/supabase/logo.png +0 -0
  55. package/profiles/supabase/profile.yaml +85 -0
  56. package/profiles/vercel/logo.png +0 -0
  57. package/profiles/vercel/profile.yaml +25 -1
  58. package/profiles/vite/profile.yaml +4 -3
  59. package/profiles/web-frontend-base/profile.yaml +5 -4
  60. package/profiles/webshop/profile.yaml +23 -5
  61. package/profiles/x-growth-bot/profile.yaml +44 -0
  62. package/resources/icons/generate-icons.py +128 -2
  63. package/resources/mcps/configs/claude.sanitized.json +42 -0
  64. package/resources/mcps/configs/codex.sanitized.json +7 -0
  65. package/resources/skills/skills/career/resume-version-manager/SKILL.md +351 -0
  66. package/resources/skills/skills/career/salary-negotiation-prep/SKILL.md +378 -0
  67. package/resources/skills/skills/content/pdf/SKILL.md +2 -0
  68. package/resources/skills/skills/content/postiz-cards/SKILL.md +48 -0
  69. package/resources/skills/skills/content/postiz-cards/scripts/analytics.sh +38 -0
  70. package/resources/skills/skills/content/postiz-cards/scripts/card.sh +42 -0
  71. package/resources/skills/skills/content/postiz-cards/scripts/lint.py +38 -0
  72. package/resources/skills/skills/design/headless-gif-demo/SKILL.md +1 -1
  73. package/resources/skills/skills/design/readme-svg-design/SKILL.md +1 -1
  74. package/resources/skills/skills/eu-funding/grant-outreach/SKILL.md +70 -0
  75. package/resources/skills/skills/eu-funding/hu-grant-finder/SKILL.md +114 -0
  76. package/resources/skills/skills/eu-funding/hu-grant-finder/evals.md +26 -0
  77. package/resources/skills/skills/eu-funding/ted-tender-search/SKILL.md +80 -0
  78. package/resources/skills/skills/eu-funding/ted-tender-search/evals.md +26 -0
  79. package/resources/skills/skills/eu-funding/ted-tender-search/scripts/ted-search.sh +46 -0
  80. package/resources/skills/skills/event-design/wedding-invitations/SKILL.md +1 -1
  81. package/resources/skills/skills/github/gx-agents/SKILL.md +96 -0
  82. package/resources/skills/skills/gstack/design-shotgun/SKILL.md +1 -1
  83. package/resources/skills/skills/marketing/ab-test-analyzer/SKILL.md +1 -1
  84. package/resources/skills/skills/marketing/ab-test-setup-and-analysis/SKILL.md +1 -1
  85. package/resources/skills/skills/marketing/account-structure-review/SKILL.md +1 -1
  86. package/resources/skills/skills/marketing/ad-copy-variant-generator/SKILL.md +1 -1
  87. package/resources/skills/skills/marketing/ad-extension-audit/SKILL.md +1 -1
  88. package/resources/skills/skills/marketing/ad-spend-allocator/SKILL.md +1 -1
  89. package/resources/skills/skills/marketing/anomaly-detection/SKILL.md +1 -1
  90. package/resources/skills/skills/marketing/attribution-model-comparison/SKILL.md +1 -1
  91. package/resources/skills/skills/marketing/audience-overlap-analysis/SKILL.md +7 -1
  92. package/resources/skills/skills/marketing/bid-strategy-recommendations/SKILL.md +7 -1
  93. package/resources/skills/skills/marketing/budget-scenario-planner/SKILL.md +6 -1
  94. package/resources/skills/skills/marketing/campaign-naming-convention-builder/SKILL.md +7 -1
  95. package/resources/skills/skills/marketing/channel-mix-optimizer/SKILL.md +7 -1
  96. package/resources/skills/skills/marketing/client-report-narratives/SKILL.md +6 -1
  97. package/resources/skills/skills/marketing/competitor-creative-analysis/SKILL.md +1 -1
  98. package/resources/skills/skills/marketing/competitor-teardown/SKILL.md +1 -1
  99. package/resources/skills/skills/marketing/content-repurposer/SKILL.md +1 -1
  100. package/resources/skills/skills/marketing/conversion-path-analysis/SKILL.md +1 -1
  101. package/resources/skills/skills/marketing/cpa-diagnostics/SKILL.md +1 -1
  102. package/resources/skills/skills/marketing/creative-fatigue-detection/SKILL.md +1 -1
  103. package/resources/skills/skills/marketing/day-hour-performance-breakdown/SKILL.md +1 -1
  104. package/resources/skills/skills/marketing/device-performance-split/SKILL.md +1 -1
  105. package/resources/skills/skills/marketing/e2e-seo-assistant/SKILL.md +1 -1
  106. package/resources/skills/skills/marketing/email-sequence-writer/SKILL.md +1 -1
  107. package/resources/skills/skills/marketing/frequency-cap-recommendations/SKILL.md +1 -1
  108. package/resources/skills/skills/marketing/geo-performance-analysis/SKILL.md +1 -1
  109. package/resources/skills/skills/marketing/google-ads-audit/SKILL.md +1 -1
  110. package/resources/skills/skills/marketing/icp-research-assistant/SKILL.md +1 -1
  111. package/resources/skills/skills/marketing/keyword-cannibalization-check/SKILL.md +1 -1
  112. package/resources/skills/skills/marketing/landing-page-audit/SKILL.md +1 -1
  113. package/resources/skills/skills/marketing/landing-page-audit-quick/SKILL.md +1 -1
  114. package/resources/skills/skills/marketing/linkedin-ads-audit/SKILL.md +1 -1
  115. package/resources/skills/skills/marketing/meta-ads-audit/SKILL.md +1 -1
  116. package/resources/skills/skills/marketing/pacing-monitor/SKILL.md +1 -1
  117. package/resources/skills/skills/marketing/performance-benchmarking/SKILL.md +1 -1
  118. package/resources/skills/skills/marketing/programmatic-seo-builder/SKILL.md +1 -1
  119. package/resources/skills/skills/marketing/quality-score-breakdown/SKILL.md +1 -1
  120. package/resources/skills/skills/marketing/reddit-ads-audit/SKILL.md +1 -1
  121. package/resources/skills/skills/marketing/retargeting-window-analysis/SKILL.md +1 -1
  122. package/resources/skills/skills/marketing/roas-forecasting/SKILL.md +1 -1
  123. package/resources/skills/skills/marketing/search-term-mining/SKILL.md +1 -1
  124. package/resources/skills/skills/marketing/utm-tracking-generator/SKILL.md +1 -1
  125. package/resources/skills/skills/marketing/wasted-spend-finder/SKILL.md +1 -1
  126. package/resources/skills/skills/marketing/weekly-account-summary/SKILL.md +1 -1
  127. package/resources/skills/skills/meta/awesome-list-submit/SKILL.md +4 -4
  128. package/resources/skills/skills/meta/cue-dashboard/SKILL.md +109 -0
  129. package/resources/skills/skills/meta/cue-developer/SKILL.md +161 -0
  130. package/resources/skills/skills/meta/cue-developer/evals/evals.json +57 -0
  131. package/resources/skills/skills/meta/cue-developer/references/architecture.md +65 -0
  132. package/resources/skills/skills/meta/cue-developer/references/build_and_test.md +72 -0
  133. package/resources/skills/skills/meta/cue-developer/references/contributing.md +75 -0
  134. package/resources/skills/skills/meta/cue-developer/references/conventions.md +57 -0
  135. package/resources/skills/skills/meta/cue-developer/references/first_time_setup.md +51 -0
  136. package/resources/skills/skills/meta/cue-developer/references/skill_and_mcp_authoring.md +84 -0
  137. package/resources/skills/skills/meta/cue-developer/references/troubleshooting.md +42 -0
  138. package/resources/skills/skills/meta/delegation-check/SKILL.md +148 -0
  139. package/resources/skills/skills/meta/delegation-check/specs/scan-algorithm.md +125 -0
  140. package/resources/skills/skills/meta/delegation-check/specs/separation-rules.md +190 -0
  141. package/resources/skills/skills/meta/focus/SKILL.md +62 -0
  142. package/resources/skills/skills/meta/help/SKILL.md +1 -1
  143. package/resources/skills/skills/meta/integrity-tags/SKILL.md +2 -0
  144. package/resources/skills/skills/meta/next-steps/SKILL.md +124 -0
  145. package/resources/skills/skills/meta/next-steps/evals/eval-set.json +92 -0
  146. package/resources/skills/skills/meta/profile-from-docs/SKILL.md +141 -0
  147. package/resources/skills/skills/meta/ralph-loop/SKILL.md +83 -0
  148. package/resources/skills/skills/meta/ralph-loop/scripts/loop.sh +73 -0
  149. package/resources/skills/skills/meta/skill-simplify/SKILL.md +136 -0
  150. package/resources/skills/skills/meta/skill-simplify/phases/01-analysis.md +173 -0
  151. package/resources/skills/skills/meta/skill-simplify/phases/02-optimize.md +104 -0
  152. package/resources/skills/skills/meta/skill-simplify/phases/03-check.md +145 -0
  153. package/resources/skills/skills/meta/smart-loader/scripts/smart-lookup.sh +13 -4
  154. package/resources/skills/skills/meta/verify-council/SKILL.md +182 -0
  155. package/resources/skills/skills/meta/verify-council/references/lane-prompts.md +103 -0
  156. package/resources/skills/skills/meta/verify-council/references/workflow.js +217 -0
  157. package/resources/skills/skills/nvidia/aiq-research/SKILL.md +1 -1
  158. package/resources/skills/skills/nvidia/cuopt-developer/SKILL.md +16 -1
  159. package/resources/skills/skills/nvidia/cuopt-developer/resources/contributing.md +2 -2
  160. package/resources/skills/skills/nvidia/cuopt-developer/resources/numerical_debugging.md +128 -0
  161. package/resources/skills/skills/nvidia/cuopt-developer/resources/python_bindings.md +2 -9
  162. package/resources/skills/skills/nvidia/cuopt-developer/resources/vrp_skills.md +166 -0
  163. package/resources/skills/skills/nvidia/cuopt-install/SKILL.md +2 -10
  164. package/resources/skills/skills/nvidia/cuopt-numerical-optimization-api-c/SKILL.md +3 -23
  165. package/resources/skills/skills/nvidia/cuopt-numerical-optimization-api-c/resources/examples.md +40 -20
  166. package/resources/skills/skills/nvidia/cuopt-numerical-optimization-api-python/SKILL.md +5 -1
  167. package/resources/skills/skills/nvidia/skill-evolution/SKILL.md +4 -5
  168. package/resources/skills/skills/research/trendradar/SKILL.md +1 -1
  169. package/resources/skills/skills/ssh/ssh-config/SKILL.md +94 -0
  170. package/resources/skills/skills/ssh/ssh-copy/SKILL.md +92 -0
  171. package/resources/skills/skills/ssh/ssh-harden/SKILL.md +108 -0
  172. package/resources/skills/skills/ssh/ssh-keys/SKILL.md +82 -0
  173. package/resources/skills/skills/ssh/ssh-paste-image/LICENSE +28 -0
  174. package/resources/skills/skills/ssh/ssh-paste-image/SKILL.md +149 -0
  175. package/resources/skills/skills/ssh/ssh-paste-image/scripts/build.sh +29 -0
  176. package/resources/skills/skills/ssh/ssh-paste-image/scripts/client/go.mod +3 -0
  177. package/resources/skills/skills/ssh/ssh-paste-image/scripts/client/main.go +79 -0
  178. package/resources/skills/skills/ssh/ssh-paste-image/scripts/daemon/ccimgd.service +12 -0
  179. package/resources/skills/skills/ssh/ssh-paste-image/scripts/daemon/com.ccimgd.plist +20 -0
  180. package/resources/skills/skills/ssh/ssh-paste-image/scripts/daemon/go.mod +3 -0
  181. package/resources/skills/skills/ssh/ssh-paste-image/scripts/daemon/main.go +98 -0
  182. package/resources/skills/skills/ssh/ssh-tunnel/SKILL.md +96 -0
  183. package/resources/skills/skills/strapi/building-with-strapi/SKILL.md +112 -0
  184. package/resources/skills/skills/strapi/strapi-cli/SKILL.md +93 -0
  185. package/resources/skills/skills/strapi/strapi-content-api/SKILL.md +115 -0
  186. package/resources/skills/skills/strapi/strapi-deploy/SKILL.md +89 -0
  187. package/resources/skills/skills/strapi/strapi-mcp-setup/SKILL.md +101 -0
  188. package/resources/skills/skills/strapi/strapi-plugins/SKILL.md +97 -0
  189. package/resources/skills/skills/tools/context7/SKILL.md +101 -0
  190. package/resources/skills/skills/tools/opensrc/SKILL.md +1 -1
  191. package/resources/skills/skills/tools/portless/SKILL.md +186 -0
  192. package/resources/skills/skills/xbot/operate/SKILL.md +229 -0
  193. package/src/commands/_index.ts +8 -0
  194. package/src/commands/ai-score.e2e.test.ts +11 -4
  195. package/src/commands/ai.ts +3 -4
  196. package/src/commands/auto-detect.ts +1 -1
  197. package/src/commands/cli.test.ts +1 -2
  198. package/src/commands/cli.ts +1 -1
  199. package/src/commands/cloud.ts +1 -1
  200. package/src/commands/current.ts +1 -4
  201. package/src/commands/dash.test.ts +110 -0
  202. package/src/commands/dash.ts +194 -0
  203. package/src/commands/dashboard.ts +26 -0
  204. package/src/commands/diff.ts +1 -1
  205. package/src/commands/discover.test.ts +1 -1
  206. package/src/commands/discover.ts +90 -40
  207. package/src/commands/doctor.test.ts +58 -0
  208. package/src/commands/doctor.ts +79 -3
  209. package/src/commands/eval-behavior.ts +1 -1
  210. package/src/commands/eval.ts +2 -2
  211. package/src/commands/evolve.ts +4 -3
  212. package/src/commands/failures.test.ts +1 -1
  213. package/src/commands/features-batch1.test.ts +6 -1
  214. package/src/commands/icon.ts +1 -5
  215. package/src/commands/import-profile.ts +1 -1
  216. package/src/commands/init.ts +50 -7
  217. package/src/commands/install-sh.e2e.test.ts +65 -0
  218. package/src/commands/launch-handoff.e2e.test.ts +88 -0
  219. package/src/commands/launch.e2e.test.ts +8 -1
  220. package/src/commands/launch.test.ts +29 -0
  221. package/src/commands/launch.ts +185 -131
  222. package/src/commands/lock.ts +0 -1
  223. package/src/commands/marketplace.ts +0 -4
  224. package/src/commands/materialize.ts +1 -1
  225. package/src/commands/mem.ts +341 -0
  226. package/src/commands/optimizer.ts +0 -3
  227. package/src/commands/playground.ts +1 -2
  228. package/src/commands/profile-draft-skill.ts +1 -1
  229. package/src/commands/replay-whatif.ts +1 -6
  230. package/src/commands/score.ts +2 -2
  231. package/src/commands/security.test.ts +88 -0
  232. package/src/commands/security.ts +74 -28
  233. package/src/commands/shell.test.ts +65 -4
  234. package/src/commands/shell.ts +67 -7
  235. package/src/commands/skills-test.ts +0 -1
  236. package/src/commands/skills.ts +28 -2
  237. package/src/commands/sources.ts +1 -2
  238. package/src/commands/status.ts +2 -6
  239. package/src/commands/submit-profile.ts +1 -1
  240. package/src/commands/suggest.ts +35 -10
  241. package/src/commands/trigger-gaps.test.ts +50 -0
  242. package/src/commands/trigger-gaps.ts +63 -29
  243. package/src/commands/update.ts +1 -1
  244. package/src/commands/validate.ts +16 -4
  245. package/src/commands/watch-live.ts +1 -1
  246. package/src/commands/workspace.ts +1 -1
  247. package/src/index.ts +26 -10
  248. package/src/lib/active-sessions.ts +1 -1
  249. package/src/lib/agent-adapters.test.ts +100 -0
  250. package/src/lib/agent-adapters.ts +2 -2
  251. package/src/lib/analytics.test.ts +88 -0
  252. package/src/lib/analytics.ts +82 -1
  253. package/src/lib/auto-detect.test.ts +10 -4
  254. package/src/lib/auto-detect.ts +19 -23
  255. package/src/lib/brand-icons.ts +0 -1
  256. package/src/lib/cache.ts +2 -3
  257. package/src/lib/claude-mem-env.test.ts +148 -0
  258. package/src/lib/claude-mem-env.ts +172 -0
  259. package/src/lib/combo-history.test.ts +53 -0
  260. package/src/lib/combo-history.ts +83 -0
  261. package/src/lib/companion-detect.test.ts +108 -0
  262. package/src/lib/companion-detect.ts +140 -0
  263. package/src/lib/companion-fetch.ts +4 -6
  264. package/src/lib/conditional-skills.test.ts +1 -1
  265. package/src/lib/config-paths.test.ts +53 -0
  266. package/src/lib/config-paths.ts +33 -0
  267. package/src/lib/dashboard-server.test.ts +351 -0
  268. package/src/lib/dashboard-server.ts +1476 -27
  269. package/src/lib/debug-log.test.ts +66 -0
  270. package/src/lib/debug-log.ts +45 -0
  271. package/src/lib/mcp-catalog.test.ts +102 -0
  272. package/src/lib/mcp-catalog.ts +193 -0
  273. package/src/lib/pair-suggestions.test.ts +111 -0
  274. package/src/lib/pair-suggestions.ts +98 -5
  275. package/src/lib/permissions.test.ts +76 -0
  276. package/src/lib/permissions.ts +125 -0
  277. package/src/lib/picker.test.ts +1106 -1
  278. package/src/lib/picker.ts +1230 -142
  279. package/src/lib/plugin-discovery.ts +126 -0
  280. package/src/lib/pr-poster.ts +1 -1
  281. package/src/lib/pr-throttle.ts +2 -6
  282. package/src/lib/profile-linter.test.ts +67 -1
  283. package/src/lib/profile-linter.ts +59 -14
  284. package/src/lib/profile-loader.test.ts +21 -0
  285. package/src/lib/profile-loader.ts +22 -3
  286. package/src/lib/profile-metrics.ts +2 -6
  287. package/src/lib/profile-names.test.ts +58 -0
  288. package/src/lib/repos.test.ts +57 -0
  289. package/src/lib/repos.ts +167 -0
  290. package/src/lib/resolver-npx.ts +10 -1
  291. package/src/lib/runtime-materializer.test.ts +200 -3
  292. package/src/lib/runtime-materializer.ts +129 -20
  293. package/src/lib/shared-profiles.ts +2 -3
  294. package/src/lib/skill-clis.test.ts +113 -0
  295. package/src/lib/skill-clis.ts +232 -0
  296. package/src/lib/skill-dependencies.ts +9 -1
  297. package/src/lib/skill-deps.ts +1 -1
  298. package/src/lib/skill-linter.ts +1 -1
  299. package/src/lib/skill-quality.ts +0 -1
  300. package/src/lib/skill-sandbox.test.ts +1 -1
  301. package/src/lib/skills-lock.test.ts +1 -1
  302. package/src/lib/telemetry-consent.ts +3 -5
  303. package/src/lib/telemetry-report.test.ts +2 -2
  304. package/src/lib/token-budget.ts +111 -0
  305. package/src/lib/trigger-gaps.test.ts +70 -0
  306. package/src/lib/trigger-gaps.ts +48 -6
  307. package/src/lib/tui/data.ts +1 -5
  308. package/src/lib/workflow-store.ts +150 -0
  309. package/src/lib/workspace-secrets.ts +0 -4
  310. package/src/lib/workspaces.ts +1 -1
@@ -0,0 +1,149 @@
1
+ ---
2
+ name: ssh-paste-image
3
+ description: >-
4
+ Use when the user wants to paste a local clipboard image into Claude Code
5
+ running over SSH, says "paste image over ssh", "can't paste images on the
6
+ remote", "send screenshot to remote claude", or "/paste-image".
7
+ tags: [ssh, clipboard, image, remote, paste]
8
+ category: ssh
9
+ triggers: ["paste image over ssh", "can't paste images on the remote", "/paste-image", "send screenshot to remote claude", "paste clipboard image remote"]
10
+ allowed-tools: Bash(ccimg:*), Bash(go:*), Bash(systemctl:*), Bash(launchctl:*), Bash(scp:*), Read
11
+ ---
12
+
13
+ # SSH paste-image
14
+
15
+ Claude Code can't paste a clipboard image when you run it over SSH: the clipboard
16
+ lives on your local machine, the agent runs on the remote host. This skill bridges
17
+ the gap. A tiny daemon on your local machine reads the clipboard and serves the
18
+ PNG; a client on the remote pulls it through the SSH connection and writes a temp
19
+ file the agent can `Read`. The daemon and client are vendored under `scripts/`
20
+ (Go source, MIT, from AlexZeitler/claude-ssh-image-skill).
21
+
22
+ ## When to activate
23
+
24
+ - The user is in a Claude Code session on a remote SSH host and wants to share an image.
25
+ - The user says "paste image over ssh", "I can't paste a screenshot on the server", "/paste-image", or "send this image to the remote session".
26
+ - A task on the remote needs an image the user has on their local clipboard (a screenshot, a design, an error photo).
27
+
28
+ Do NOT use this for local sessions (paste works natively) or for copying image files that already exist on the remote (use `ssh-copy`).
29
+
30
+ ## How it works
31
+
32
+ ```
33
+ Local Machine Remote Server (SSH)
34
+ ┌──────────────────────┐ ┌──────────────────────────┐
35
+ │ Clipboard (PNG) │ │ Claude Code │
36
+ │ │ │ │ │ │
37
+ │ ▼ │ │ ▼ │
38
+ │ ccimgd (Port 9998) │◄────────────────│ ssh-paste-image skill │
39
+ │ - wl-paste/xclip │ SSH Reverse │ - TCP request to ccimgd │
40
+ │ - returns base64 │ Tunnel │ - receives base64 image │
41
+ │ image in response │ (Port 9998) │ - saves a temp PNG │
42
+ │ │ │ - Read → agent sees it │
43
+ └──────────────────────┘ └──────────────────────────┘
44
+ ```
45
+
46
+ 1. The skill runs `ccimg` on the remote, which opens a TCP request to `127.0.0.1:9998`.
47
+ 2. That port is forwarded over the SSH reverse tunnel to the local `ccimgd`.
48
+ 3. `ccimgd` reads the clipboard PNG (`wl-paste` on Wayland, `xclip` on X11, `pngpaste` on macOS) and returns base64 JSON.
49
+ 4. `ccimg` decodes it, writes `/tmp/clipboard-<pid>.png`, and prints the path.
50
+ 5. The skill uses `Read` on that path so the agent sees the image.
51
+
52
+ ## Prerequisites
53
+
54
+ - **Build (anywhere with Go):** `go` 1.26+ for `bash scripts/build.sh`.
55
+ - **Local machine, Linux Wayland:** `wl-paste` from `wl-clipboard` (apt: `sudo apt install -y wl-clipboard`).
56
+ - **Local machine, Linux X11:** `xclip` (apt: `sudo apt install -y xclip`).
57
+ - **Local machine, macOS:** `pngpaste` (brew: `brew install pngpaste`).
58
+ - **Remote host:** Claude Code, plus the `ccimg` client binary (installed in step 3 below).
59
+
60
+ ## Setup (one time)
61
+
62
+ ### 1. Build the binaries
63
+
64
+ From this skill's directory (where this SKILL.md lives):
65
+
66
+ ```bash
67
+ bash scripts/build.sh
68
+ ```
69
+
70
+ This writes static binaries for linux/amd64, linux/arm64, darwin/amd64, darwin/arm64 into `scripts/daemon/` and `scripts/client/`.
71
+
72
+ ### 2. Install the daemon on your LOCAL machine
73
+
74
+ Linux (systemd user service):
75
+
76
+ ```bash
77
+ cp scripts/daemon/ccimgd-linux-amd64 ~/.local/bin/ccimgd # or -linux-arm64
78
+ cp scripts/daemon/ccimgd.service ~/.config/systemd/user/
79
+ systemctl --user daemon-reload
80
+ systemctl --user enable --now ccimgd
81
+ ```
82
+
83
+ macOS (launchd agent):
84
+
85
+ ```bash
86
+ cp scripts/daemon/ccimgd-darwin-arm64 /usr/local/bin/ccimgd # or -darwin-amd64 on Intel
87
+ cp scripts/daemon/com.ccimgd.plist ~/Library/LaunchAgents/
88
+ launchctl load ~/Library/LaunchAgents/com.ccimgd.plist
89
+ ```
90
+
91
+ ### 3. Install the client on the REMOTE host
92
+
93
+ ```bash
94
+ scp scripts/client/ccimg-linux-amd64 your-server:~/.local/bin/ccimg # match the server arch
95
+ ssh your-server 'chmod +x ~/.local/bin/ccimg'
96
+ ```
97
+
98
+ To skip the per-call permission prompt, add to the remote `~/.claude/settings.json`:
99
+
100
+ ```json
101
+ { "permissions": { "allow": ["Bash(ccimg)"] } }
102
+ ```
103
+
104
+ ### 4. Open the SSH reverse tunnel
105
+
106
+ Connect with port 9998 forwarded back to your local daemon:
107
+
108
+ ```bash
109
+ ssh -R 9998:localhost:9998 your-server
110
+ ```
111
+
112
+ Or make it permanent in `~/.ssh/config` (see the `ssh-tunnel` skill for the pattern):
113
+
114
+ ```
115
+ Host your-server
116
+ RemoteForward 9998 localhost:9998
117
+ ```
118
+
119
+ ## Usage
120
+
121
+ On the remote session, copy an image to your LOCAL clipboard, then run the client and read the file it prints:
122
+
123
+ ```bash
124
+ ccimg
125
+ ```
126
+
127
+ Then `Read` the printed path (for example `/tmp/clipboard-12345.png`). The agent now sees the image.
128
+
129
+ ## Example
130
+
131
+ > User (in an SSH Claude Code session): "here's the broken layout, /paste-image"
132
+
133
+ 1. Run `ccimg` with Bash. It prints `/tmp/clipboard-4821.png`.
134
+ 2. `Read` `/tmp/clipboard-4821.png`.
135
+ 3. The screenshot renders in the session and you can act on it.
136
+
137
+ If `ccimg` prints `Failed to connect to ccimgd`, the reverse tunnel is not up (reconnect with `-R 9998:localhost:9998`). If it prints `Clipboard is empty or does not contain an image`, copy an image first (a file copy is not an image).
138
+
139
+ ## Rules
140
+
141
+ - The reverse tunnel (`-R 9998:localhost:9998`) is required. No tunnel, no image. This is the most common failure.
142
+ - `ccimgd` reads an IMAGE on the clipboard, not a file path. Copy the picture itself (screenshot tools do this).
143
+ - Port 9998 is chosen so it can run alongside sshimg.nvim (port 9999) on the same machine.
144
+ - The image crosses the existing SSH channel as base64. Nothing extra is exposed to the network.
145
+ - Rebuild and reinstall both binaries after editing the Go source; the daemon and client must agree on the protocol.
146
+
147
+ ## Credits
148
+
149
+ Daemon and client vendored from [claude-ssh-image-skill](https://github.com/AlexZeitler/claude-ssh-image-skill) by Alexander Zeitler, MIT licensed. See `LICENSE`. The `build.sh` adds a linux/arm64 target; the Go sources are otherwise unchanged.
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ cd "$(dirname "$0")"
5
+
6
+ # Faithful to upstream, plus linux/arm64 for ARM servers (Graviton, Hetzner ARM,
7
+ # Raspberry Pi). Each target is a static, CGO-free binary.
8
+ platforms=(
9
+ "linux/amd64"
10
+ "linux/arm64"
11
+ "darwin/amd64"
12
+ "darwin/arm64"
13
+ )
14
+
15
+ for platform in "${platforms[@]}"; do
16
+ os="${platform%/*}"
17
+ arch="${platform#*/}"
18
+ suffix="${os}-${arch}"
19
+
20
+ echo "Building for ${os}/${arch}..."
21
+
22
+ echo " ccimgd-${suffix}"
23
+ (cd daemon && CGO_ENABLED=0 GOOS="$os" GOARCH="$arch" go build -o "ccimgd-${suffix}" .)
24
+
25
+ echo " ccimg-${suffix}"
26
+ (cd client && CGO_ENABLED=0 GOOS="$os" GOARCH="$arch" go build -o "ccimg-${suffix}" .)
27
+ done
28
+
29
+ echo "Done."
@@ -0,0 +1,3 @@
1
+ module github.com/AlexZeitler/claude-ssh-image-skill/client
2
+
3
+ go 1.21
@@ -0,0 +1,79 @@
1
+ package main
2
+
3
+ import (
4
+ "encoding/base64"
5
+ "encoding/json"
6
+ "fmt"
7
+ "net"
8
+ "os"
9
+ "path/filepath"
10
+ )
11
+
12
+ const (
13
+ host = "127.0.0.1"
14
+ port = "9998"
15
+ )
16
+
17
+ type response struct {
18
+ OK bool `json:"ok"`
19
+ Image string `json:"image"`
20
+ Error string `json:"error"`
21
+ }
22
+
23
+ func main() {
24
+ conn, err := net.Dial("tcp", net.JoinHostPort(host, port))
25
+ if err != nil {
26
+ fmt.Fprintf(os.Stderr, "Failed to connect to ccimgd: %v\n", err)
27
+ os.Exit(1)
28
+ }
29
+ defer conn.Close()
30
+
31
+ _, err = conn.Write([]byte("{}\n"))
32
+ if err != nil {
33
+ fmt.Fprintf(os.Stderr, "Failed to send request: %v\n", err)
34
+ os.Exit(1)
35
+ }
36
+
37
+ var buf []byte
38
+ tmp := make([]byte, 65536)
39
+ for {
40
+ n, err := conn.Read(tmp)
41
+ if n > 0 {
42
+ buf = append(buf, tmp[:n]...)
43
+ }
44
+ if err != nil {
45
+ break
46
+ }
47
+ for _, b := range tmp[:n] {
48
+ if b == '\n' {
49
+ goto done
50
+ }
51
+ }
52
+ }
53
+ done:
54
+
55
+ var resp response
56
+ if err := json.Unmarshal(buf, &resp); err != nil {
57
+ fmt.Fprintf(os.Stderr, "Failed to parse response: %v\n", err)
58
+ os.Exit(1)
59
+ }
60
+
61
+ if !resp.OK {
62
+ fmt.Fprintf(os.Stderr, "Error: %s\n", resp.Error)
63
+ os.Exit(1)
64
+ }
65
+
66
+ imgData, err := base64.StdEncoding.DecodeString(resp.Image)
67
+ if err != nil {
68
+ fmt.Fprintf(os.Stderr, "Failed to decode image: %v\n", err)
69
+ os.Exit(1)
70
+ }
71
+
72
+ tmpFile := filepath.Join(os.TempDir(), fmt.Sprintf("clipboard-%d.png", os.Getpid()))
73
+ if err := os.WriteFile(tmpFile, imgData, 0644); err != nil {
74
+ fmt.Fprintf(os.Stderr, "Failed to write image: %v\n", err)
75
+ os.Exit(1)
76
+ }
77
+
78
+ fmt.Println(tmpFile)
79
+ }
@@ -0,0 +1,12 @@
1
+ [Unit]
2
+ Description=Clipboard image daemon for Claude Code over SSH
3
+ After=graphical-session.target
4
+
5
+ [Service]
6
+ Type=simple
7
+ ExecStart=%h/.local/bin/ccimgd
8
+ Restart=on-failure
9
+ RestartSec=5
10
+
11
+ [Install]
12
+ WantedBy=default.target
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>Label</key>
6
+ <string>com.ccimgd</string>
7
+ <key>ProgramArguments</key>
8
+ <array>
9
+ <string>/usr/local/bin/ccimgd</string>
10
+ </array>
11
+ <key>RunAtLoad</key>
12
+ <true/>
13
+ <key>KeepAlive</key>
14
+ <true/>
15
+ <key>StandardOutPath</key>
16
+ <string>/tmp/ccimgd.log</string>
17
+ <key>StandardErrorPath</key>
18
+ <string>/tmp/ccimgd.log</string>
19
+ </dict>
20
+ </plist>
@@ -0,0 +1,3 @@
1
+ module github.com/AlexZeitler/claude-ssh-image-skill/daemon
2
+
3
+ go 1.21
@@ -0,0 +1,98 @@
1
+ package main
2
+
3
+ import (
4
+ "encoding/base64"
5
+ "encoding/json"
6
+ "fmt"
7
+ "net"
8
+ "os"
9
+ "os/exec"
10
+ "os/signal"
11
+ "runtime"
12
+ "syscall"
13
+ )
14
+
15
+ const (
16
+ host = "127.0.0.1"
17
+ port = "9998"
18
+ )
19
+
20
+ type response struct {
21
+ OK bool `json:"ok"`
22
+ Image string `json:"image,omitempty"`
23
+ Error string `json:"error,omitempty"`
24
+ }
25
+
26
+ func getClipboardImage() ([]byte, error) {
27
+ var cmd *exec.Cmd
28
+ switch {
29
+ case runtime.GOOS == "darwin":
30
+ cmd = exec.Command("pngpaste", "-")
31
+ case os.Getenv("WAYLAND_DISPLAY") != "":
32
+ cmd = exec.Command("wl-paste", "--type", "image/png")
33
+ default:
34
+ cmd = exec.Command("xclip", "-selection", "clipboard", "-target", "image/png", "-o")
35
+ }
36
+ out, err := cmd.Output()
37
+ if err != nil || len(out) == 0 {
38
+ return nil, fmt.Errorf("Clipboard is empty or does not contain an image")
39
+ }
40
+ return out, nil
41
+ }
42
+
43
+ func handleConn(conn net.Conn) {
44
+ defer conn.Close()
45
+
46
+ buf := make([]byte, 4096)
47
+ for {
48
+ n, err := conn.Read(buf)
49
+ if err != nil || n == 0 {
50
+ return
51
+ }
52
+ for _, b := range buf[:n] {
53
+ if b == '\n' {
54
+ goto ready
55
+ }
56
+ }
57
+ }
58
+ ready:
59
+
60
+ var resp response
61
+ imgData, err := getClipboardImage()
62
+ if err != nil {
63
+ resp = response{OK: false, Error: err.Error()}
64
+ } else {
65
+ resp = response{OK: true, Image: base64.StdEncoding.EncodeToString(imgData)}
66
+ }
67
+
68
+ data, _ := json.Marshal(resp)
69
+ data = append(data, '\n')
70
+ conn.Write(data)
71
+ }
72
+
73
+ func main() {
74
+ listener, err := net.Listen("tcp", net.JoinHostPort(host, port))
75
+ if err != nil {
76
+ fmt.Fprintf(os.Stderr, "Failed to listen: %v\n", err)
77
+ os.Exit(1)
78
+ }
79
+ defer listener.Close()
80
+
81
+ fmt.Printf("ccimgd listening on %s:%s\n", host, port)
82
+
83
+ sig := make(chan os.Signal, 1)
84
+ signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT)
85
+ go func() {
86
+ <-sig
87
+ listener.Close()
88
+ os.Exit(0)
89
+ }()
90
+
91
+ for {
92
+ conn, err := listener.Accept()
93
+ if err != nil {
94
+ break
95
+ }
96
+ handleConn(conn)
97
+ }
98
+ }
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: ssh-tunnel
3
+ description: >-
4
+ Use when the user wants SSH port forwarding: a local tunnel (-L) to reach a
5
+ remote service, a reverse tunnel (-R) to expose a local one, or a dynamic
6
+ SOCKS proxy (-D). Triggers: "ssh tunnel", "forward a port", "reverse tunnel".
7
+ tags: [ssh, tunnel, port-forwarding, socks]
8
+ category: ssh
9
+ triggers: ["ssh tunnel", "forward a port", "reverse tunnel", "socks proxy", "port forward over ssh", "ssh -L", "ssh -R"]
10
+ allowed-tools: Bash(ssh:*), Bash(autossh:*)
11
+ ---
12
+
13
+ # SSH tunnel
14
+
15
+ SSH can forward TCP ports across the encrypted connection. Three directions cover
16
+ almost every case: pull a remote service to your machine (`-L`), push a local
17
+ service to the remote (`-R`), or send all traffic through the host as a proxy
18
+ (`-D`). This skill picks the right flag and keeps the tunnel alive.
19
+
20
+ ## When to activate
21
+
22
+ - The user wants to reach a remote-only service (a database, an admin UI) from their laptop.
23
+ - The user wants a remote host to reach a service running on their laptop (the paste-image daemon, a local API).
24
+ - The user wants to browse through a remote host as a SOCKS proxy.
25
+ - The user says "tunnel a port", "port forward over ssh", or "reverse tunnel".
26
+
27
+ ## Steps
28
+
29
+ ### Local forward (-L): reach a remote service locally
30
+
31
+ ```bash
32
+ ssh -L 5432:localhost:5432 user@dbhost
33
+ ```
34
+
35
+ Now `localhost:5432` on your machine reaches the database bound to `localhost:5432` on `dbhost`. The pattern is `-L <local_port>:<target_host>:<target_port>`, where the target is resolved FROM the remote side.
36
+
37
+ ### Reverse forward (-R): expose a local service on the remote
38
+
39
+ ```bash
40
+ ssh -R 9998:localhost:9998 user@server
41
+ ```
42
+
43
+ Now `localhost:9998` on `server` reaches port 9998 on your machine. This is exactly what the `ssh-paste-image` skill needs. To let other remote hosts (not just localhost) use it, set `GatewayPorts yes` in the server's sshd config.
44
+
45
+ ### Dynamic proxy (-D): SOCKS through the host
46
+
47
+ ```bash
48
+ ssh -D 1080 user@host
49
+ ```
50
+
51
+ Point a browser or tool at SOCKS5 `localhost:1080` to route its traffic through `host`.
52
+
53
+ ### Run a tunnel with no shell, in the background
54
+
55
+ ```bash
56
+ ssh -fN -L 5432:localhost:5432 user@dbhost
57
+ ```
58
+
59
+ `-N` means no remote command, `-f` backgrounds after auth. Find and stop it with `pgrep -af 'ssh -fN'` then `kill <pid>`.
60
+
61
+ ### Make it permanent in ~/.ssh/config
62
+
63
+ ```
64
+ Host dbhost
65
+ HostName db.example.com
66
+ User app
67
+ LocalForward 5432 localhost:5432
68
+ ```
69
+
70
+ ### Auto-reconnecting tunnel
71
+
72
+ ```bash
73
+ autossh -M 0 -fN -L 5432:localhost:5432 user@dbhost
74
+ ```
75
+
76
+ `autossh` restarts the tunnel if it drops. Pair with `ServerAliveInterval` from the `ssh-config` skill.
77
+
78
+ ## Prerequisites
79
+
80
+ - `ssh` (OpenSSH client). apt: `sudo apt install -y openssh-client`.
81
+ - `autossh` for auto-reconnect (optional). apt: `sudo apt install -y autossh` · brew: `brew install autossh`.
82
+
83
+ ## Example
84
+
85
+ > User: "I need to hit the staging Postgres on the bastion from my laptop with psql."
86
+
87
+ 1. `ssh -fN -L 5432:localhost:5432 user@bastion`.
88
+ 2. `psql -h localhost -p 5432 -U app staging` connects through the tunnel.
89
+ 3. To make it stick, add a `LocalForward 5432 localhost:5432` line to the `Host bastion` block.
90
+
91
+ ## Rules
92
+
93
+ - `-L` resolves the target from the REMOTE side; `-R` resolves it from YOUR side. Mixing these two up is the usual reason a tunnel "does nothing".
94
+ - Reverse forwards reach only `localhost` on the server unless `GatewayPorts yes` is set in sshd.
95
+ - A privileged local port (<1024) needs root; pick a high port instead.
96
+ - Background tunnels (`-fN`) are easy to forget. Track them with `pgrep -af ssh` and stop them when done.
@@ -0,0 +1,112 @@
1
+ ---
2
+ name: building-with-strapi
3
+ description: 'Use when building a Strapi v5 backend: project structure, content-types, components, dynamic zones, the Content-Type Builder, and Document Service queries in custom code.'
4
+ tags: [strapi, cms, content-types, document-service, backend]
5
+ ---
6
+
7
+ # Building With Strapi
8
+
9
+ Model content and customize the backend of a Strapi v5 project.
10
+
11
+ ## Use This Skill For
12
+
13
+ - Understanding the project layout and where code lives
14
+ - Creating content-types, components, and dynamic zones
15
+ - Querying and mutating content from custom code via the Document Service
16
+
17
+ ## Prerequisites
18
+
19
+ - A running Strapi v5 project in dev mode (`npm run develop`). See
20
+ `strapi-cli` to scaffold one.
21
+ - Content-Type Builder only works in `develop` mode (it writes schema files
22
+ and restarts the server).
23
+
24
+ ## Project Structure
25
+
26
+ ```
27
+ my-strapi-project/
28
+ ├── config/ server.ts, database.ts, admin.ts, api.ts, plugins.ts, middlewares.ts
29
+ ├── src/
30
+ │ ├── api/<name>/ content-types/, controllers/, services/, routes/
31
+ │ ├── components/ reusable field groups
32
+ │ ├── extensions/ overrides for installed plugins
33
+ │ ├── plugins/ local plugins
34
+ │ └── index.ts register() / bootstrap() lifecycle
35
+ ├── database/migrations/
36
+ └── public/uploads/ media library files
37
+ ```
38
+
39
+ Each entry under `src/api/<name>/` is one content-type with its schema,
40
+ controller, service, and routes.
41
+
42
+ ## Modeling Content
43
+
44
+ Build content-types in the admin **Content-Type Builder**
45
+ (`/admin/plugins/content-type-builder`):
46
+
47
+ - **Collection type**: many entries (e.g. `restaurant` → `/api/restaurants`).
48
+ - **Single type**: one entry (e.g. `homepage` → `/api/homepage`).
49
+ - **Component**: a reusable group of fields embedded in types.
50
+ - **Dynamic zone**: a slot that accepts a chosen list of components per entry.
51
+
52
+ The builder writes `schema.json` files under
53
+ `src/api/<name>/content-types/`. Commit those; they are your schema source
54
+ of truth.
55
+
56
+ ## documentId, Not id
57
+
58
+ Strapi 5 identifies every entry by a 24-character `documentId`, stable across
59
+ locales and draft/published versions. The numeric `id` is a physical record
60
+ detail and may disappear in future versions.
61
+
62
+ - Query and relate by `documentId`.
63
+ - Treat `id` as legacy; do not hardcode it in clients or relations.
64
+
65
+ ## Document Service API (in custom code)
66
+
67
+ Inside controllers, services, and plugins, use the Document Service. It sits
68
+ above the Query Engine and understands components, dynamic zones, draft &
69
+ publish, and i18n.
70
+
71
+ ```ts
72
+ // list (nothing populates by default — ask for it)
73
+ const articles = await strapi.documents('api::article.article').findMany({
74
+ filters: { title: { $containsi: 'strapi' } },
75
+ populate: { cover: true, author: { fields: ['name'] } },
76
+ sort: 'publishedAt:desc',
77
+ status: 'published',
78
+ });
79
+
80
+ // fetch one by documentId
81
+ const one = await strapi.documents('api::article.article').findOne({
82
+ documentId,
83
+ populate: ['cover'],
84
+ });
85
+
86
+ // create / update / delete
87
+ const created = await strapi.documents('api::article.article').create({ data });
88
+ await strapi.documents('api::article.article').update({ documentId, data });
89
+ await strapi.documents('api::article.article').delete({ documentId });
90
+
91
+ // draft & publish (when enabled on the type)
92
+ await strapi.documents('api::article.article').publish({ documentId });
93
+ await strapi.documents('api::article.article').unpublish({ documentId });
94
+ ```
95
+
96
+ Need raw DB access below the content model? Drop to the Query Engine
97
+ (`strapi.db.query(...)`), but prefer the Document Service for anything that
98
+ touches components, dynamic zones, or publication state.
99
+
100
+ ## Rules
101
+
102
+ - Model in `develop`; the builder is disabled in `start`.
103
+ - Always pass `populate`/`fields` explicitly; defaults return top-level
104
+ scalars only.
105
+ - Use the Document Service over the removed Entity Service path and over raw
106
+ Query Engine unless you specifically need lower-level access.
107
+ - Commit `schema.json` files; they define the data model.
108
+
109
+ ## Next Step
110
+
111
+ Expose this content over HTTP with `strapi-content-api`, or package custom
112
+ features as a plugin with `strapi-plugins`.