packwise-skills 1.0.0
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.
- package/.cursorrules +23 -0
- package/CLAUDE.md +25 -0
- package/README.md +295 -0
- package/audit.md +224 -0
- package/bin/packwise.js +155 -0
- package/package.json +31 -0
- package/skill.md +719 -0
- package/sub-skills/ai/local-llm.md +183 -0
- package/sub-skills/ai/python-ml.md +164 -0
- package/sub-skills/backend/go-server.md +184 -0
- package/sub-skills/backend/java-spring.md +241 -0
- package/sub-skills/backend/node-server.md +164 -0
- package/sub-skills/backend/php-laravel.md +175 -0
- package/sub-skills/backend/python-server.md +164 -0
- package/sub-skills/backend/rust-backend.md +118 -0
- package/sub-skills/cli/python-cli.md +236 -0
- package/sub-skills/cli/sdk-library.md +497 -0
- package/sub-skills/cloud/ci-cd-pipelines.md +350 -0
- package/sub-skills/cloud/docker.md +191 -0
- package/sub-skills/cloud/kubernetes.md +277 -0
- package/sub-skills/cloud/payment-integration.md +307 -0
- package/sub-skills/cross-platform/multiplatform.md +252 -0
- package/sub-skills/desktop/electron.md +783 -0
- package/sub-skills/desktop/game-dev.md +443 -0
- package/sub-skills/desktop/native-app.md +123 -0
- package/sub-skills/desktop/scenarios.md +443 -0
- package/sub-skills/desktop/smart-platforms.md +324 -0
- package/sub-skills/desktop/tauri.md +428 -0
- package/sub-skills/desktop/vr-ar.md +252 -0
- package/sub-skills/desktop/web-to-desktop.md +153 -0
- package/sub-skills/embedded/car-infotainment.md +129 -0
- package/sub-skills/embedded/esp32.md +184 -0
- package/sub-skills/embedded/ros.md +150 -0
- package/sub-skills/embedded/stm32.md +160 -0
- package/sub-skills/mobile/android.md +322 -0
- package/sub-skills/mobile/capacitor.md +232 -0
- package/sub-skills/mobile/flutter-mobile.md +138 -0
- package/sub-skills/mobile/harmonyos.md +150 -0
- package/sub-skills/mobile/ios.md +245 -0
- package/sub-skills/mobile/react-native.md +443 -0
- package/sub-skills/mobile/wearables.md +230 -0
- package/sub-skills/plugins/browser-extension.md +308 -0
- package/sub-skills/plugins/jetbrains-plugin.md +226 -0
- package/sub-skills/plugins/vscode-extension.md +204 -0
- package/sub-skills/security/security-tools.md +174 -0
- package/sub-skills/web/monorepo.md +274 -0
- package/sub-skills/web/pwa.md +220 -0
- package/sub-skills/web/serverless-edge.md +295 -0
- package/sub-skills/web/spa.md +266 -0
- package/sub-skills/web/ssr.md +228 -0
- package/sub-skills/web/wasm.md +243 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
# Browser Extension Build Sub-Skill
|
|
2
|
+
|
|
3
|
+
Build and publish browser extensions for Chrome, Edge, Firefox, and Safari.
|
|
4
|
+
|
|
5
|
+
**Current version**: Manifest V3 (MV3) / Chrome 130+ / Firefox 130+ / Safari 18+ (2025-2026)
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
- Browser productivity tools (ad blockers, password managers, note-taking)
|
|
10
|
+
- Developer tools (API inspectors, debug panels)
|
|
11
|
+
- Content enhancement (readers, translators, UI overlays)
|
|
12
|
+
- Web scraping / data extraction tools
|
|
13
|
+
- AI-powered browser assistants
|
|
14
|
+
|
|
15
|
+
## Manifest V3 (Required for Chrome/Edge)
|
|
16
|
+
|
|
17
|
+
### Project Structure
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
my-extension/
|
|
21
|
+
├── manifest.json ← Core configuration (MV3)
|
|
22
|
+
├── background.js ← Service Worker (replaces background page)
|
|
23
|
+
├── content.js ← Content script (injected into pages)
|
|
24
|
+
├── popup/
|
|
25
|
+
│ ├── popup.html ← Popup page
|
|
26
|
+
│ └── popup.js
|
|
27
|
+
├── options/
|
|
28
|
+
│ ├── options.html ← Settings page
|
|
29
|
+
│ └── options.js
|
|
30
|
+
├── icons/
|
|
31
|
+
│ ├── icon16.png
|
|
32
|
+
│ ├── icon48.png
|
|
33
|
+
│ └── icon128.png
|
|
34
|
+
└── sidepanel/ ← Chrome Side Panel (optional)
|
|
35
|
+
├── panel.html
|
|
36
|
+
└── panel.js
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### manifest.json Template (MV3)
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"manifest_version": 3,
|
|
44
|
+
"name": "My Extension",
|
|
45
|
+
"version": "1.0.0",
|
|
46
|
+
"description": "Extension description",
|
|
47
|
+
"permissions": [
|
|
48
|
+
"activeTab",
|
|
49
|
+
"storage",
|
|
50
|
+
"scripting",
|
|
51
|
+
"sidePanel"
|
|
52
|
+
],
|
|
53
|
+
"host_permissions": ["https://*/*"],
|
|
54
|
+
"background": {
|
|
55
|
+
"service_worker": "background.js"
|
|
56
|
+
},
|
|
57
|
+
"content_scripts": [{
|
|
58
|
+
"matches": ["https://*/*"],
|
|
59
|
+
"js": ["content.js"],
|
|
60
|
+
"css": ["content.css"],
|
|
61
|
+
"run_at": "document_idle"
|
|
62
|
+
}],
|
|
63
|
+
"action": {
|
|
64
|
+
"default_popup": "popup/popup.html",
|
|
65
|
+
"default_icon": {
|
|
66
|
+
"16": "icons/icon16.png",
|
|
67
|
+
"48": "icons/icon48.png",
|
|
68
|
+
"128": "icons/icon128.png"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"side_panel": {
|
|
72
|
+
"default_path": "sidepanel/panel.html"
|
|
73
|
+
},
|
|
74
|
+
"icons": {
|
|
75
|
+
"16": "icons/icon16.png",
|
|
76
|
+
"48": "icons/icon48.png",
|
|
77
|
+
"128": "icons/icon128.png"
|
|
78
|
+
},
|
|
79
|
+
"minimum_chrome_version": "116"
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Background Service Worker (MV3)
|
|
84
|
+
|
|
85
|
+
```javascript
|
|
86
|
+
// background.js — runs as Service Worker (NOT persistent)
|
|
87
|
+
chrome.runtime.onInstalled.addListener(() => {
|
|
88
|
+
console.log('Extension installed');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Listen for messages from content script or popup
|
|
92
|
+
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
93
|
+
if (message.action === 'getData') {
|
|
94
|
+
chrome.storage.local.get(['data'], (result) => {
|
|
95
|
+
sendResponse(result.data);
|
|
96
|
+
});
|
|
97
|
+
return true; // Keep message channel open for async response
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Side Panel API
|
|
102
|
+
chrome.sidePanel.setOptions({ path: 'sidepanel/panel.html', enabled: true });
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Content Script
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
// content.js — runs in the context of web pages
|
|
109
|
+
// Can access DOM but NOT Chrome APIs directly
|
|
110
|
+
// Communicate with background via chrome.runtime.sendMessage
|
|
111
|
+
|
|
112
|
+
const data = document.title;
|
|
113
|
+
chrome.runtime.sendMessage({ action: 'pageTitle', data });
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Build Tools (Bundling with Vite/Webpack)
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npm install -D @crxjs/vite-plugin # For Vite projects
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
// vite.config.js
|
|
124
|
+
import { crx } from '@crxjs/vite-plugin';
|
|
125
|
+
import manifest from './manifest.json';
|
|
126
|
+
|
|
127
|
+
export default {
|
|
128
|
+
plugins: [crx({ manifest })],
|
|
129
|
+
build: {
|
|
130
|
+
rollupOptions: {
|
|
131
|
+
input: { background: 'background.js' },
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Firefox Extension (Manifest V3 Support)
|
|
140
|
+
|
|
141
|
+
Firefox now supports MV3. Add `browser_specific_settings` to manifest.json:
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"manifest_version": 3,
|
|
146
|
+
"browser_specific_settings": {
|
|
147
|
+
"gecko": {
|
|
148
|
+
"id": "my-extension@example.com",
|
|
149
|
+
"strict_min_version": "109.0"
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Firefox-Specific Differences
|
|
156
|
+
|
|
157
|
+
| Feature | Chrome MV3 | Firefox MV3 |
|
|
158
|
+
|---------|-----------|-------------|
|
|
159
|
+
| Background | Service Worker (ephemeral) | Event pages (can be persistent) |
|
|
160
|
+
| `browser` API | `chrome.*` | `browser.*` (promise-based) + `chrome.*` (compat) |
|
|
161
|
+
| Storage | `chrome.storage` | `browser.storage` |
|
|
162
|
+
| Side Panel | Supported | Not supported |
|
|
163
|
+
| `webRequest` blocking | Removed (use `declarativeNetRequest`) | Still supported |
|
|
164
|
+
|
|
165
|
+
### Cross-Browser Build (WXT Framework)
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
npm install -D wxt
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# Development
|
|
173
|
+
npx wxt dev
|
|
174
|
+
|
|
175
|
+
# Build for Chrome
|
|
176
|
+
npx wxt build --browser chrome
|
|
177
|
+
# Output: .output/chrome-mv3/
|
|
178
|
+
|
|
179
|
+
# Build for Firefox
|
|
180
|
+
npx wxt build --browser firefox
|
|
181
|
+
# Output: .output/firefox-mv2/
|
|
182
|
+
|
|
183
|
+
# Build for all browsers
|
|
184
|
+
npx wxt zip # Creates .zip for store upload
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Safari Extension
|
|
190
|
+
|
|
191
|
+
### Option 1: Web Extension (Recommended — share code with Chrome/Firefox)
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# In Xcode:
|
|
195
|
+
# File → New → Target → Safari Web Extension
|
|
196
|
+
# Import your Chrome MV3 extension
|
|
197
|
+
# Xcode converts it to Safari format
|
|
198
|
+
|
|
199
|
+
# Build
|
|
200
|
+
xcodebuild -scheme MyApp-Extension -configuration Release archive
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Option 2: Safari App Extension (Native Swift)
|
|
204
|
+
|
|
205
|
+
```swift
|
|
206
|
+
import SafariServices
|
|
207
|
+
|
|
208
|
+
class SafariExtensionHandler: SFSafariExtensionHandler {
|
|
209
|
+
override func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String: Any]?) {
|
|
210
|
+
page.dispatchMessageToScript(withName: "response", userInfo: ["data": "Hello from native!"])
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Safari-Specific Notes
|
|
216
|
+
|
|
217
|
+
- Safari uses Web Extension format (similar to MV3 but with limitations)
|
|
218
|
+
- Requires macOS + Xcode
|
|
219
|
+
- Distributed via App Store ($99/year developer account)
|
|
220
|
+
- Some Chrome APIs not available in Safari
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Packaging & Publishing
|
|
225
|
+
|
|
226
|
+
### Chrome Web Store
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# 1. Build production version
|
|
230
|
+
npm run build
|
|
231
|
+
|
|
232
|
+
# 2. Zip the extension
|
|
233
|
+
zip -r my-extension.zip manifest.json *.js *.css popup/ options/ icons/
|
|
234
|
+
|
|
235
|
+
# 3. Upload to Chrome Web Store
|
|
236
|
+
# chrome.google.com/webstore/devconsole
|
|
237
|
+
# - Pay $5 one-time registration fee
|
|
238
|
+
# - Upload .zip
|
|
239
|
+
# - Fill: description, screenshots (1280x800), privacy policy URL
|
|
240
|
+
# - Submit for review (1–7 days)
|
|
241
|
+
|
|
242
|
+
# Or: automated with GitHub Action
|
|
243
|
+
# wxtjs/wxt-builder-action
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Edge Add-ons
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
# Same .zip works for Edge
|
|
250
|
+
# partner.microsoft.com/dashboard
|
|
251
|
+
# Upload .zip → Submit for review (1–3 days)
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Firefox Add-ons
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# addons.mozilla.org/developers/
|
|
258
|
+
# Upload .zip → Submit for review (1–7 days, sometimes longer)
|
|
259
|
+
# No registration fee
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Safari Extensions
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
# App Store Connect → New App → macOS
|
|
266
|
+
# Upload .xcarchive via Xcode
|
|
267
|
+
# Requires Apple Developer account ($99/year)
|
|
268
|
+
# Review: 1–3 days
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Store Comparison
|
|
274
|
+
|
|
275
|
+
| Store | Fee | Review Time | User Base | Auto-Update |
|
|
276
|
+
|-------|-----|-------------|-----------|-------------|
|
|
277
|
+
| Chrome Web Store | $5 one-time | 1–7 days | 3B+ users | Yes |
|
|
278
|
+
| Edge Add-ons | Free | 1–3 days | 300M+ users | Yes |
|
|
279
|
+
| Firefox Add-ons | Free | 1–7 days | 200M+ users | Yes |
|
|
280
|
+
| Safari Extensions | $99/year | 1–3 days | 1B+ devices | Yes (via App Store) |
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## MV3 Migration Checklist (from MV2)
|
|
285
|
+
|
|
286
|
+
| MV2 Feature | MV3 Replacement |
|
|
287
|
+
|-------------|----------------|
|
|
288
|
+
| Background page | Service Worker |
|
|
289
|
+
| `chrome.browserAction` | `chrome.action` |
|
|
290
|
+
| `webRequest` blocking | `declarativeNetRequest` |
|
|
291
|
+
| Remote code execution | Bundled code only |
|
|
292
|
+
| `eval()` | Not allowed |
|
|
293
|
+
| Persistent background | Event-driven (non-persistent) |
|
|
294
|
+
| `chrome.extension.getURL` | `chrome.runtime.getURL` |
|
|
295
|
+
|
|
296
|
+
## Common Pitfalls
|
|
297
|
+
|
|
298
|
+
| Issue | Fix |
|
|
299
|
+
|-------|-----|
|
|
300
|
+
| V2 deprecated | Migrate to V3 (Service Worker replaces Background Page) |
|
|
301
|
+
| CSP restriction in MV3 | No remote code; bundle all dependencies |
|
|
302
|
+
| Too many permissions rejected | Minimize permissions; use `activeTab` instead of `<all_urls>` |
|
|
303
|
+
| Review rejected | Ensure privacy policy URL is valid; minimize data collection |
|
|
304
|
+
| Service Worker dies | MV3 Service Workers are ephemeral; use `chrome.alarms` for periodic tasks |
|
|
305
|
+
| Content script not injecting | Check `matches` pattern; verify `run_at` setting |
|
|
306
|
+
| `chrome.storage` not persisting | Use `chrome.storage.sync` for cross-device; `local` for device-only |
|
|
307
|
+
| Cross-browser compatibility | Use WXT or webextension-polyfill for unified API |
|
|
308
|
+
| Popup not showing | Check popup.html exists; verify `default_popup` in manifest |
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# JetBrains Plugin Build Sub-Skill
|
|
2
|
+
|
|
3
|
+
Develop and publish plugins for IntelliJ-based IDEs (IntelliJ IDEA, PyCharm, WebStorm, Android Studio, etc.).
|
|
4
|
+
|
|
5
|
+
**Current version**: Gradle IntelliJ Plugin 2.x / IntelliJ Platform 2024.3+ (2025-2026)
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
- Building plugins for IntelliJ IDEA, PyCharm, WebStorm, CLion, Android Studio, etc.
|
|
10
|
+
- Need deep IDE integration (refactoring, code analysis, tool windows)
|
|
11
|
+
- Want to distribute via JetBrains Marketplace
|
|
12
|
+
|
|
13
|
+
## Key Features
|
|
14
|
+
|
|
15
|
+
- **Gradle IntelliJ Plugin** — standard build tooling (replaced legacy Plugin DevKit)
|
|
16
|
+
- **Kotlin/Java** — both supported; Kotlin recommended for new plugins
|
|
17
|
+
- **Plugin Verifier** — automated compatibility checking across IDE versions
|
|
18
|
+
- **Dynamic plugins** — hot-reload without restarting IDE (since Platform 2020.1)
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# JDK 17+ (JBR — JetBrains Runtime recommended)
|
|
24
|
+
# Gradle 8.x (wrapper included in template)
|
|
25
|
+
# IntelliJ IDEA (for development and testing)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Project Setup
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Option 1: IntelliJ Plugin Template (recommended)
|
|
32
|
+
# File → New → Project → IntelliJ Platform Plugin
|
|
33
|
+
# Or clone from GitHub:
|
|
34
|
+
git clone https://github.com/JetBrains/intellij-platform-plugin-template.git my-plugin
|
|
35
|
+
cd my-plugin
|
|
36
|
+
|
|
37
|
+
# Option 2: Gradle init
|
|
38
|
+
# Use IntelliJ Plugin Generator: https://plugins.jetbrains.com/docs/intellij/generating-plugin.html
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Build Configuration
|
|
42
|
+
|
|
43
|
+
```kotlin
|
|
44
|
+
// build.gradle.kts
|
|
45
|
+
plugins {
|
|
46
|
+
id("java")
|
|
47
|
+
id("org.jetbrains.kotlin.jvm") version "2.0.21"
|
|
48
|
+
id("org.jetbrains.intellij.platform") version "2.2.1"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
intellijPlatform {
|
|
52
|
+
pluginConfiguration {
|
|
53
|
+
id = "com.example.myplugin"
|
|
54
|
+
name = "My Plugin"
|
|
55
|
+
version = "1.0.0"
|
|
56
|
+
description = "Plugin description"
|
|
57
|
+
ideaVersion {
|
|
58
|
+
sinceBuild = "243"
|
|
59
|
+
untilBuild = "253.*"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Target IDE(s)
|
|
64
|
+
intellijIdeaCommunity = "2024.3"
|
|
65
|
+
|
|
66
|
+
// Plugin dependencies
|
|
67
|
+
plugins = listOf(
|
|
68
|
+
"com.intellij.java", // Java support
|
|
69
|
+
"org.intellij.plugins.markdown:243.22562.64" // Markdown plugin
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
// Plugin Verifier
|
|
73
|
+
pluginVerifier {
|
|
74
|
+
ides = listOf(
|
|
75
|
+
intellijIdeaCommunity("2024.3"),
|
|
76
|
+
intellijIdeaCommunity("2025.1"),
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Required dependencies for IntelliJ Platform development
|
|
82
|
+
dependencies {
|
|
83
|
+
intellijPlatform {
|
|
84
|
+
intellijIdeaCommunity("2024.3")
|
|
85
|
+
instrumentationTools()
|
|
86
|
+
pluginVerifier()
|
|
87
|
+
zipSigner()
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Build & Test
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Build plugin ZIP
|
|
96
|
+
./gradlew buildPlugin
|
|
97
|
+
# Output: build/distributions/my-plugin-1.0.0.zip
|
|
98
|
+
|
|
99
|
+
# Run IDE with plugin installed (for testing)
|
|
100
|
+
./gradlew runIde
|
|
101
|
+
|
|
102
|
+
# Run unit tests
|
|
103
|
+
./gradlew test
|
|
104
|
+
|
|
105
|
+
# Run Plugin Verifier (compatibility check)
|
|
106
|
+
./gradlew runPluginVerifier
|
|
107
|
+
|
|
108
|
+
# Check for IntelliJ-specific lint issues
|
|
109
|
+
./gradlew verifyPlugin
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Publishing
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# 1. Get token from JetBrains Marketplace
|
|
116
|
+
# https://plugins.jetbrains.com/author/me → Upload Token
|
|
117
|
+
|
|
118
|
+
# 2. Publish
|
|
119
|
+
./gradlew publishPlugin
|
|
120
|
+
# Requires plugin signing (automatic with zipSigner)
|
|
121
|
+
|
|
122
|
+
# With token via environment variable:
|
|
123
|
+
export PUBLISH_TOKEN=your-token-here
|
|
124
|
+
./gradlew publishPlugin
|
|
125
|
+
|
|
126
|
+
# Or specify channel (beta/alpha):
|
|
127
|
+
./gradlew publishPlugin -Pchannel=beta
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Plugin Structure
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
my-plugin/
|
|
134
|
+
├── src/main/kotlin/com/example/myplugin/
|
|
135
|
+
│ ├── MyToolWindowFactory.kt # Tool window
|
|
136
|
+
│ ├── MyAction.kt # Menu/toolbar action
|
|
137
|
+
│ └── services/
|
|
138
|
+
│ └── MyService.kt # Application-level service
|
|
139
|
+
├── src/main/resources/
|
|
140
|
+
│ └── META-INF/
|
|
141
|
+
│ └── plugin.xml # Plugin descriptor (required)
|
|
142
|
+
├── build.gradle.kts
|
|
143
|
+
└── gradle.properties
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
```xml
|
|
147
|
+
<!-- src/main/resources/META-INF/plugin.xml -->
|
|
148
|
+
<idea-plugin>
|
|
149
|
+
<id>com.example.myplugin</id>
|
|
150
|
+
<name>My Plugin</name>
|
|
151
|
+
<vendor email="me@example.com">My Company</vendor>
|
|
152
|
+
|
|
153
|
+
<description><![CDATA[
|
|
154
|
+
Plugin description with <b>HTML</b> support.
|
|
155
|
+
]]></description>
|
|
156
|
+
|
|
157
|
+
<depends>com.intellij.modules.platform</depends>
|
|
158
|
+
<depends optional="true" config-file="my-java-ext.xml">com.intellij.java</depends>
|
|
159
|
+
|
|
160
|
+
<extensions defaultExtensionNs="com.intellij">
|
|
161
|
+
<toolWindow id="My Tool" factoryClass="com.example.myplugin.MyToolWindowFactory"/>
|
|
162
|
+
</extensions>
|
|
163
|
+
|
|
164
|
+
<actions>
|
|
165
|
+
<action id="MyPlugin.MyAction"
|
|
166
|
+
class="com.example.myplugin.MyAction"
|
|
167
|
+
text="My Action"
|
|
168
|
+
description="Does something useful">
|
|
169
|
+
<add-to-group group-id="ToolsMenu" anchor="last"/>
|
|
170
|
+
</action>
|
|
171
|
+
</actions>
|
|
172
|
+
</idea-plugin>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Common Pitfalls
|
|
176
|
+
|
|
177
|
+
| Issue | Fix |
|
|
178
|
+
|-------|-----|
|
|
179
|
+
| Plugin rejected on Marketplace | Ensure `plugin.xml` has all required fields (id, name, vendor, description, depends) |
|
|
180
|
+
| IDE version mismatch | Set `sinceBuild`/`untilBuild` carefully; test with Plugin Verifier |
|
|
181
|
+
| Build fails with SDK error | Clear Gradle cache (`~/.gradle/caches/modules-2`); verify JDK 17+ |
|
|
182
|
+
| Plugin not loaded in dev IDE | Check `plugin.xml` for syntax errors; check IDE log (`Help → Diagnostic Tools → Debug Log Settings`) |
|
|
183
|
+
| Tests fail with `NoClassDefFoundError` | Add required platform dependencies to `testImplementation` |
|
|
184
|
+
| Slow `runIde` startup | Use `buildSearchableOptions = false` for faster iteration |
|
|
185
|
+
| API deprecation warnings | Check IntelliJ Platform SDK changelog; migrate to new APIs |
|
|
186
|
+
| Memory issues in large projects | Use `ReadAction.runReadAction()` for thread-safe file access |
|
|
187
|
+
|
|
188
|
+
## CI/CD — GitHub Actions
|
|
189
|
+
|
|
190
|
+
```yaml
|
|
191
|
+
name: Build Plugin
|
|
192
|
+
on:
|
|
193
|
+
push:
|
|
194
|
+
branches: [main]
|
|
195
|
+
pull_request:
|
|
196
|
+
|
|
197
|
+
jobs:
|
|
198
|
+
build:
|
|
199
|
+
runs-on: ubuntu-latest
|
|
200
|
+
steps:
|
|
201
|
+
- uses: actions/checkout@v4
|
|
202
|
+
- uses: actions/setup-java@v4
|
|
203
|
+
with:
|
|
204
|
+
distribution: 'temurin'
|
|
205
|
+
java-version: '17'
|
|
206
|
+
- run: ./gradlew buildPlugin
|
|
207
|
+
- run: ./gradlew runPluginVerifier
|
|
208
|
+
- uses: actions/upload-artifact@v4
|
|
209
|
+
with:
|
|
210
|
+
name: plugin
|
|
211
|
+
path: build/distributions/*.zip
|
|
212
|
+
|
|
213
|
+
publish:
|
|
214
|
+
if: github.ref == 'refs/heads/main'
|
|
215
|
+
needs: build
|
|
216
|
+
runs-on: ubuntu-latest
|
|
217
|
+
steps:
|
|
218
|
+
- uses: actions/checkout@v4
|
|
219
|
+
- uses: actions/setup-java@v4
|
|
220
|
+
with:
|
|
221
|
+
distribution: 'temurin'
|
|
222
|
+
java-version: '17'
|
|
223
|
+
- run: ./gradlew publishPlugin
|
|
224
|
+
env:
|
|
225
|
+
PUBLISH_TOKEN: ${{ secrets.JETBRAINS_TOKEN }}
|
|
226
|
+
```
|