@maccesar/aiskills 1.12.0 → 1.15.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.
Files changed (59) hide show
  1. package/README.md +42 -7
  2. package/lib/cleanup.js +29 -0
  3. package/lib/commands/skills.js +110 -9
  4. package/lib/config.js +17 -9
  5. package/lib/installer.js +5 -3
  6. package/lib/symlink.js +45 -3
  7. package/lib/utils.js +41 -0
  8. package/package.json +1 -1
  9. package/skills/audit-codebase/SKILL.md +70 -0
  10. package/skills/audit-codebase/agents/openai.yaml +4 -0
  11. package/skills/audit-codebase/references/comprehensive-audit.md +220 -0
  12. package/skills/audit-codebase/references/report-format.md +119 -0
  13. package/skills/humaniza/SKILL.md +55 -4
  14. package/skills/humaniza/references/ai-patterns-es.md +40 -0
  15. package/skills/humaniza/references/checklist.md +9 -0
  16. package/skills/humaniza/references/examples.md +16 -0
  17. package/skills/humaniza/references/lexicon-es-mx.md +18 -0
  18. package/skills/humaniza/references/structures-es.md +132 -0
  19. package/skills/humaniza/scripts/check_ai_patterns.py +216 -0
  20. package/skills/refactoring-ui/SKILL.md +65 -29
  21. package/skills/refactoring-ui/references/05-motion.md +124 -0
  22. package/skills/refactoring-ui/references/06-dark-mode.md +117 -0
  23. package/skills/refactoring-ui/references/07-component-patterns.md +181 -0
  24. package/skills/stitch-showcase/SKILL.md +24 -232
  25. package/skills/stitch-showcase/references/07-theme-system.md +12 -0
  26. package/skills/stitch-showcase/references/08-type-detection.md +9 -1
  27. package/skills/stitch-showcase/references/10-component-standardization.md +25 -0
  28. package/skills/stitch-showcase/references/12-video-embedding.md +113 -0
  29. package/skills/stitch-showcase/references/13-language-detection.md +82 -0
  30. package/skills/stitch-showcase/references/14-troubleshooting-known-issues.md +122 -0
  31. package/skills/stitch-showcase/references/15-build-flags.md +71 -0
  32. package/skills/stitch-showcase/references/16-design-md-format.md +107 -0
  33. package/skills/stitch-showcase/references/index.html +25 -19
  34. package/skills/stitch-showcase/references/viewer.html +24 -12
  35. package/skills/stitch-showcase/scripts/__pycache__/build_showcase.cpython-314.pyc +0 -0
  36. package/skills/stitch-showcase/scripts/__pycache__/component_utils.cpython-314.pyc +0 -0
  37. package/skills/stitch-showcase/scripts/__pycache__/detect_components.cpython-314.pyc +0 -0
  38. package/skills/stitch-showcase/scripts/__pycache__/extract_catalog.cpython-314.pyc +0 -0
  39. package/skills/stitch-showcase/scripts/__pycache__/extract_text.cpython-314.pyc +0 -0
  40. package/skills/stitch-showcase/scripts/__pycache__/extract_zips.cpython-314.pyc +0 -0
  41. package/skills/stitch-showcase/scripts/__pycache__/parse_design_md.cpython-314.pyc +0 -0
  42. package/skills/stitch-showcase/scripts/__pycache__/slug_demangle.cpython-314.pyc +0 -0
  43. package/skills/stitch-showcase/scripts/build_showcase.py +150 -10
  44. package/skills/stitch-showcase/scripts/parse_design_md.py +145 -12
  45. package/skills/stitch-showcase/scripts/slug_demangle.py +209 -0
  46. package/skills/vscode-extension-dev/SKILL.md +90 -41
  47. package/skills/vscode-extension-dev/references/api-additional.md +168 -0
  48. package/skills/vscode-extension-dev/references/api-progress.md +55 -0
  49. package/skills/vscode-extension-dev/references/api-quickpick.md +75 -0
  50. package/skills/vscode-extension-dev/references/api-secretstorage.md +57 -0
  51. package/skills/vscode-extension-dev/references/api-statusbar.md +38 -0
  52. package/skills/vscode-extension-dev/references/api-treeview.md +78 -0
  53. package/skills/vscode-extension-dev/references/api-webview.md +149 -0
  54. package/skills/vscode-extension-dev/references/architecture.md +67 -0
  55. package/skills/vscode-extension-dev/references/debugger.md +179 -0
  56. package/skills/vscode-extension-dev/references/lsp.md +175 -0
  57. package/skills/vscode-extension-dev/references/notebooks.md +208 -0
  58. package/skills/vscode-extension-dev/references/testing.md +208 -0
  59. package/skills/vscode-extension-dev/references/api-patterns.md +0 -625
@@ -0,0 +1,209 @@
1
+ """
2
+ slug_demangle.py — Reverses Stitch's accent stripping in screen filenames.
3
+
4
+ Google Stitch replaces accented characters (á, é, í, ó, ú, ñ, ü) with `_`
5
+ when exporting screens, so "Configuración" becomes "configuraci_n" and
6
+ "Membresías" becomes "membres_as".
7
+
8
+ This module exposes a single function `demangle_to_title(slug)` that infers
9
+ the readable display title for a Stitch-style mangled slug, using a
10
+ dictionary of common Spanish words with their accent positions.
11
+
12
+ For slugs the dictionary doesn't cover, the user can still override the
13
+ title explicitly via `Title | Description` in DESIGN.md.
14
+ """
15
+ import re
16
+
17
+
18
+ # Mangled → fixed (lowercase). Longer entries are applied first so that
19
+ # composites like "men_m_s" beat the standalone "men_".
20
+ WORD_REPLACEMENTS: dict[str, str] = {
21
+ # -ción / -sión nouns
22
+ "acci_n": "acción",
23
+ "aceptaci_n": "aceptación",
24
+ "activaci_n": "activación",
25
+ "actualizaci_n": "actualización",
26
+ "administraci_n": "administración",
27
+ "aplicaci_n": "aplicación",
28
+ "asignaci_n": "asignación",
29
+ "autenticaci_n": "autenticación",
30
+ "calificaci_n": "calificación",
31
+ "cancelaci_n": "cancelación",
32
+ "clasificaci_n": "clasificación",
33
+ "comunicaci_n": "comunicación",
34
+ "configuraci_n": "configuración",
35
+ "confirmaci_n": "confirmación",
36
+ "conexi_n": "conexión",
37
+ "creaci_n": "creación",
38
+ "descripci_n": "descripción",
39
+ "direcci_n": "dirección",
40
+ "discusi_n": "discusión",
41
+ "donaci_n": "donación",
42
+ "duraci_n": "duración",
43
+ "edici_n": "edición",
44
+ "educaci_n": "educación",
45
+ "elecci_n": "elección",
46
+ "evaluaci_n": "evaluación",
47
+ "exclusi_n": "exclusión",
48
+ "facturaci_n": "facturación",
49
+ "geolocalizaci_n": "geolocalización",
50
+ "habitaci_n": "habitación",
51
+ "identificaci_n": "identificación",
52
+ "informaci_n": "información",
53
+ "inscripci_n": "inscripción",
54
+ "instalaci_n": "instalación",
55
+ "introducci_n": "introducción",
56
+ "modificaci_n": "modificación",
57
+ "navegaci_n": "navegación",
58
+ "notificaci_n": "notificación",
59
+ "opci_n": "opción",
60
+ "operaci_n": "operación",
61
+ "organizaci_n": "organización",
62
+ "personalizaci_n": "personalización",
63
+ "posici_n": "posición",
64
+ "publicaci_n": "publicación",
65
+ "recuperaci_n": "recuperación",
66
+ "registraci_n": "registración",
67
+ "relaci_n": "relación",
68
+ "reservaci_n": "reservación",
69
+ "revisi_n": "revisión",
70
+ "secci_n": "sección",
71
+ "selecci_n": "selección",
72
+ "soluci_n": "solución",
73
+ "suscripci_n": "suscripción",
74
+ "transacci_n": "transacción",
75
+ "ubicaci_n": "ubicación",
76
+ "validaci_n": "validación",
77
+ "verificaci_n": "verificación",
78
+ "visualizaci_n": "visualización",
79
+ # composite phrases (must beat their standalone parts)
80
+ "men_m_s": "menú más",
81
+ "men_principal": "menú principal",
82
+ # standalone words with accents
83
+ "men_": "menú",
84
+ "caf_": "café",
85
+ "p_gina": "página",
86
+ "p_ginas": "páginas",
87
+ "art_culo": "artículo",
88
+ "art_culos": "artículos",
89
+ "categor_a": "categoría",
90
+ "categor_as": "categorías",
91
+ "membres_a": "membresía",
92
+ "membres_as": "membresías",
93
+ "pol_tica": "política",
94
+ "pol_ticas": "políticas",
95
+ "m_s": "más",
96
+ "qu_": "qué",
97
+ "c_mo": "cómo",
98
+ "d_a": "día",
99
+ "d_as": "días",
100
+ # words with ñ
101
+ "esc_ner": "escáner",
102
+ "rese_a": "reseña",
103
+ "rese_as": "reseñas",
104
+ "espa_a": "españa",
105
+ "espa_ol": "español",
106
+ "peque_o": "pequeño",
107
+ "peque_a": "pequeña",
108
+ "compa_a": "compañía",
109
+ "compa_as": "compañías",
110
+ "se_al": "señal",
111
+ "se_ales": "señales",
112
+ "ma_ana": "mañana",
113
+ "due_o": "dueño",
114
+ "ni_o": "niño",
115
+ "ni_a": "niña",
116
+ "a_o": "año",
117
+ "a_os": "años",
118
+ # other common standalone
119
+ "_xito": "éxito",
120
+ "_rea": "área",
121
+ "_reas": "áreas",
122
+ "_ltimo": "último",
123
+ "_ltima": "última",
124
+ "_nico": "único",
125
+ "_nica": "única",
126
+ "_til": "útil",
127
+ "_tiles": "útiles",
128
+ "tel_fono": "teléfono",
129
+ "n_mero": "número",
130
+ "n_meros": "números",
131
+ "c_digo": "código",
132
+ "c_digos": "códigos",
133
+ "m_dico": "médico",
134
+ "m_dica": "médica",
135
+ "p_blico": "público",
136
+ "p_blica": "pública",
137
+ "f_cil": "fácil",
138
+ "r_pido": "rápido",
139
+ "r_pida": "rápida",
140
+ "_ndice": "índice",
141
+ "_xitos": "éxitos",
142
+ }
143
+
144
+
145
+ def demangle_word(token: str) -> str:
146
+ """
147
+ Try to recover the accented form of a single mangled token (no separators).
148
+ Returns the token unchanged if no entry matches.
149
+ """
150
+ return WORD_REPLACEMENTS.get(token.lower(), token)
151
+
152
+
153
+ def demangle_to_title(slug: str) -> str:
154
+ """
155
+ Convert a (possibly mangled) snake-case slug into a readable display title.
156
+
157
+ Examples:
158
+ "configuraci_n_oscuro" → "Configuración Oscuro"
159
+ "membres_as_y_pagos" → "Membresías Y Pagos"
160
+ "home_screen" → "Home Screen"
161
+ "men_m_s" → "Menú Más"
162
+ """
163
+ if not slug:
164
+ return ""
165
+
166
+ s = slug.strip().lower()
167
+
168
+ # Apply dictionary replacements, longest first to handle composites correctly.
169
+ # We anchor each match to slug-token boundaries (start, end, or non-mangled `_`
170
+ # separator) so a short entry like "men_" does not eat into "menma".
171
+ for mangled in sorted(WORD_REPLACEMENTS.keys(), key=len, reverse=True):
172
+ fixed = WORD_REPLACEMENTS[mangled]
173
+ pattern = re.compile(
174
+ rf"(?:^|(?<=[^a-záéíóúñü\d]))"
175
+ rf"{re.escape(mangled)}"
176
+ rf"(?=$|[^a-záéíóúñü\d])",
177
+ re.IGNORECASE,
178
+ )
179
+ s = pattern.sub(fixed, s)
180
+
181
+ # Replace remaining separators and apply Title Case.
182
+ return s.replace("_", " ").replace("-", " ").title()
183
+
184
+
185
+ def slug_to_title(slug: str) -> str:
186
+ """
187
+ Canonical slug → display title for the showcase pipeline.
188
+
189
+ Strips a leading numeric ordering prefix (``01_splash_screen`` →
190
+ ``splash_screen``) and then delegates to :func:`demangle_to_title`.
191
+ Falls back to ``slug.title()`` only in the edge case where the entire
192
+ slug is digits/underscores.
193
+
194
+ This is the single source of truth used by both ``parse_design_md`` and
195
+ ``build_showcase``.
196
+ """
197
+ if not slug:
198
+ return ""
199
+ stripped = re.sub(r"^[\d_]+", "", slug)
200
+ return demangle_to_title(stripped) or slug.title()
201
+
202
+
203
+ if __name__ == "__main__":
204
+ import sys
205
+
206
+ if len(sys.argv) < 2:
207
+ print("Usage: python slug_demangle.py <slug>", file=sys.stderr)
208
+ sys.exit(1)
209
+ print(slug_to_title(sys.argv[1]))
@@ -1,34 +1,73 @@
1
1
  ---
2
2
  name: vscode-extension-dev
3
- description: Guide for building VS Code extensions from scratch. Use when the user is creating, scaffolding, designing, debugging, testing, bundling, or publishing a VS Code extension. Covers all major API patterns — TreeView, QuickPick, Webview, StatusBar, commands, configuration, SecretStorage, progress indicators, and esbuild bundling.
4
- when_to_use: >
5
- - User wants to create a new VS Code extension
6
- - User asks about VS Code extension APIs (TreeView, Webview, QuickPick, etc.)
7
- - User needs help with package.json contributes, activationEvents, or keybindings
8
- - User is debugging extension activation, disposables, or memory leaks
9
- - User asks about bundling extensions with esbuild or webpack
10
- - User wants to publish an extension to the VS Code Marketplace or Open VSX
11
- - User asks about Webview CSP, nonce, or postMessage communication
12
- - User asks about SecretStorage or credential management in extensions
13
- - User needs help with extension testing (@vscode/test-electron)
14
- source: "VS Code Extension API documentation (https://code.visualstudio.com/api)"
15
- anti_hallucination_note: >
16
- ALL guidance in this skill comes from the official VS Code Extension API docs
17
- and established community patterns. Do NOT invent API methods, event names,
18
- or configuration keys. If unsure whether an API exists, say so explicitly.
19
- Always verify imports come from the 'vscode' module.
3
+ description: 'Use when the user is creating, scaffolding, designing, debugging, testing, bundling, or publishing a VS Code extension. Covers TreeView, QuickPick, Webview, StatusBar, commands, configuration, SecretStorage, progress indicators, and esbuild bundling. Triggers: "create a VS Code extension", VS Code Extension APIs, package.json contributes/activationEvents/keybindings, debugging activation/disposables/memory leaks, bundling with esbuild/webpack, publishing to Marketplace or Open VSX, Webview CSP/nonce/postMessage, SecretStorage, extension testing (@vscode/test-electron).'
20
4
  ---
21
5
 
22
6
  # VS Code Extension Development Skill
23
7
 
24
8
  You are a VS Code extension development advisor. Base ALL guidance on the reference files below — not training data.
25
9
 
26
- ## How to Use This Skill
10
+ ## Required workflow (read before responding)
27
11
 
28
- 1. Read the relevant reference file(s) before answering
29
- 2. Base ALL code on the reference content not training data
30
- 3. Use real TypeScript imports and correct `vscode` API signatures
31
- 4. Do not invent API methods, events, or configuration keys not in the references
12
+ The SKILL.md alone is an **index** of references. The detail you need
13
+ to give accurate answers lives in the reference files. **Reading this
14
+ SKILL.md is not enough.**
15
+
16
+ ### Step 1 — Open the relevant reference files
17
+
18
+ | Task involves | Required reading |
19
+ |---|---|
20
+ | TreeView, TreeDataProvider, sidebar trees | [references/api-treeview.md](references/api-treeview.md) |
21
+ | Webview Panel, CSP, postMessage, nonce | [references/api-webview.md](references/api-webview.md) |
22
+ | QuickPick (simple or async with debounce) | [references/api-quickpick.md](references/api-quickpick.md) |
23
+ | StatusBarItem, codicons, status bar UI | [references/api-statusbar.md](references/api-statusbar.md) |
24
+ | SecretStorage, credential management | [references/api-secretstorage.md](references/api-secretstorage.md) |
25
+ | withProgress, cancellation tokens | [references/api-progress.md](references/api-progress.md) |
26
+ | FileSystemWatcher, Diagnostics, OutputChannel, ContextKeys, TextDocumentContentProvider, disposable lifecycle | [references/api-additional.md](references/api-additional.md) |
27
+ | Activation events, project structure, layered architecture, testing | [references/architecture.md](references/architecture.md) |
28
+ | `contributes`, `activationEvents`, `engines`, `scripts`, `keybindings`, esbuild config | [references/package-json-schema.md](references/package-json-schema.md) |
29
+ | Marketplace publishing, vsce, Open VSX, CI/CD, `.vscodeignore`, versioning | [references/publishing.md](references/publishing.md) |
30
+ | Language Server Protocol, `vscode-languageclient`, language servers | [references/lsp.md](references/lsp.md) |
31
+ | Notebook serializers, controllers, renderers | [references/notebooks.md](references/notebooks.md) |
32
+ | Debug Adapter Protocol, `DebugAdapterDescriptorFactory`, `DebugConfigurationProvider` | [references/debugger.md](references/debugger.md) |
33
+ | Advanced testing — multi-suite `.vscode-test.mjs`, fixtures, mocking, CI, coverage | [references/testing.md](references/testing.md) |
34
+
35
+ ### Step 2 — Output contract
36
+
37
+ Every API symbol, configuration key, command, or behavior you cite MUST
38
+ be backed by a citation in the form:
39
+
40
+ `[source: references/<file>.md]`
41
+
42
+ Example: *"Push all subscriptions to `context.subscriptions` so they are disposed on deactivation [source: references/api-additional.md]"*
43
+
44
+ ### Step 3 — If you must answer from memory
45
+
46
+ If you write a claim without having read the reference that backs it,
47
+ prepend `FROM_MEMORY (unverified):` to that claim. Do not hide it.
48
+
49
+ ### Banned behaviors
50
+
51
+ - ❌ Inventing API methods, event names, or configuration keys not in the references
52
+ - ❌ Importing from anywhere other than the `'vscode'` module
53
+ - ❌ Suggesting deprecated APIs (e.g. `vscode.workspace.rootPath`) without flagging them as deprecated
54
+ - ❌ Marking the answer complete without listing which reference files you read
55
+
56
+ ## When to use
57
+
58
+ - User wants to create a new VS Code extension
59
+ - User asks about VS Code extension APIs (TreeView, Webview, QuickPick, etc.)
60
+ - User needs help with package.json contributes, activationEvents, or keybindings
61
+ - User is debugging extension activation, disposables, or memory leaks
62
+ - User asks about bundling extensions with esbuild or webpack
63
+ - User wants to publish an extension to the VS Code Marketplace or Open VSX
64
+ - User asks about Webview CSP, nonce, or postMessage communication
65
+ - User asks about SecretStorage or credential management in extensions
66
+ - User needs help with extension testing (@vscode/test-electron)
67
+
68
+ ## Source
69
+
70
+ VS Code Extension API documentation (https://code.visualstudio.com/api)
32
71
 
33
72
  ## Scaffolding Workflow
34
73
 
@@ -37,7 +76,7 @@ You are a VS Code extension development advisor. Base ALL guidance on the refere
37
76
  3. **Choose bundler**: esbuild (recommended) or webpack
38
77
  4. **Project structure** created — see `references/architecture.md` for layout
39
78
  5. **Configure** `package.json` — see `references/package-json-schema.md`
40
- 6. **Implement** — see `references/api-patterns.md` for working examples
79
+ 6. **Implement** — pick the right reference from the Step 1 table (TreeView, Webview, QuickPick, StatusBar, SecretStorage, withProgress, or api-additional)
41
80
  7. **Test** — see `references/architecture.md` for testing strategy
42
81
  8. **Publish** — see `references/publishing.md` for full workflow
43
82
 
@@ -65,24 +104,24 @@ You are a VS Code extension development advisor. Base ALL guidance on the refere
65
104
  - Push ALL subscriptions to `context.subscriptions` in `activate()`
66
105
  - Use `deactivate()` only for async cleanup (closing connections, stopping servers)
67
106
  - Never rely on garbage collection — always dispose explicitly
68
- - See `references/api-patterns.md` for the cleanup pattern
107
+ - See `references/api-additional.md` for the cleanup pattern
69
108
 
70
109
  ### withProgress for Async Operations
71
110
  - Use `ProgressLocation.Notification` for user-facing tasks
72
111
  - Use `ProgressLocation.Window` for status bar progress
73
112
  - Support cancellation via `CancellationToken`
74
- - See `references/api-patterns.md` for working examples
113
+ - See `references/api-progress.md` for working examples
75
114
 
76
115
  ### SecretStorage for Credentials
77
116
  - Use `context.secrets` (SecretStorage API) — never store tokens in settings
78
117
  - Fires `onDidChange` event when secrets change
79
- - See `references/api-patterns.md` for the credential manager pattern
118
+ - See `references/api-secretstorage.md` for the credential manager pattern
80
119
 
81
120
  ### Webview CSP and PostMessage
82
121
  - Always set a Content Security Policy with nonce
83
122
  - Use `webview.asWebviewUri()` for local resources
84
123
  - Bidirectional communication via `postMessage` / `onDidReceiveMessage`
85
- - See `references/api-patterns.md` for the full Webview pattern
124
+ - See `references/api-webview.md` for the full Webview pattern
86
125
 
87
126
  ### esbuild Bundling
88
127
  - Bundle extension into a single file for faster activation
@@ -91,20 +130,30 @@ You are a VS Code extension development advisor. Base ALL guidance on the refere
91
130
 
92
131
  ## Reference Files
93
132
 
94
- | File | Topics |
95
- | ----------------------------------- | ------------------------------------------------------------------- |
96
- | `references/package-json-schema.md` | contributes, activationEvents, engines, scripts, devDependencies |
97
- | `references/api-patterns.md` | TreeView, Webview, QuickPick, StatusBar, SecretStorage, withProgress |
98
- | `references/architecture.md` | Project structure, layered architecture, testing strategy |
99
- | `references/publishing.md` | vsce, .vscodeignore, CI/CD, Open VSX, versioning |
133
+ | File | Topics |
134
+ | ------------------------------------- | ---------------------------------------------------------------------------------- |
135
+ | `references/api-treeview.md` | TreeDataProvider, TreeView registration |
136
+ | `references/api-webview.md` | Webview Panel, CSP/nonce, postMessage, asWebviewUri |
137
+ | `references/api-quickpick.md` | Simple and async QuickPick with debounced search |
138
+ | `references/api-statusbar.md` | StatusBarItem, codicons, dynamic updates |
139
+ | `references/api-secretstorage.md` | Credential manager pattern, onDidChange |
140
+ | `references/api-progress.md` | withProgress (Notification + Window), cancellation tokens |
141
+ | `references/api-additional.md` | FileSystemWatcher, Disposable cleanup, Diagnostics, OutputChannel, ContextKeys, TextDocumentContentProvider |
142
+ | `references/architecture.md` | Project structure, layered architecture, testing strategy |
143
+ | `references/package-json-schema.md` | contributes, activationEvents, engines, scripts, devDependencies |
144
+ | `references/publishing.md` | vsce, .vscodeignore, CI/CD, Open VSX, versioning |
145
+ | `references/lsp.md` | LSP client setup, server lifecycle, capabilities, diagnostics |
146
+ | `references/notebooks.md` | Notebook serializers, controllers, renderers, output mime types |
147
+ | `references/debugger.md` | DAP: descriptor factory, configuration provider, adapter lifecycle |
148
+ | `references/testing.md` | Multi-suite test config, workspace fixtures, mocking `vscode`, CI, coverage |
100
149
 
101
150
  ## Anti-Patterns to Avoid
102
151
 
103
- - Using `*` activation event in production (activates on every VS Code start)
104
- - Storing secrets in `configuration` instead of `SecretStorage`
105
- - Forgetting to dispose subscriptions (causes memory leaks)
106
- - Missing CSP in Webviews (security vulnerability)
107
- - Bundling `node_modules` instead of using esbuild/webpack
108
- - Using synchronous file I/O in the extension host (blocks the UI)
109
- - Registering commands without corresponding `contributes.commands` entries
110
- - Hardcoding `vscode.workspace.rootPath` (deprecated — use `workspaceFolders`)
152
+ - Using `*` activation event in production (activates on every VS Code start) [source: references/package-json-schema.md]
153
+ - Storing secrets in `configuration` instead of `SecretStorage` [source: references/api-secretstorage.md]
154
+ - Forgetting to dispose subscriptions (causes memory leaks) [source: references/api-additional.md]
155
+ - Missing CSP in Webviews (security vulnerability) [source: references/api-webview.md]
156
+ - Bundling `node_modules` instead of using esbuild/webpack [source: references/package-json-schema.md]
157
+ - Using synchronous file I/O in the extension host (blocks the UI) [source: references/architecture.md]
158
+ - Registering commands without corresponding `contributes.commands` entries [source: references/package-json-schema.md]
159
+ - Hardcoding `vscode.workspace.rootPath` (deprecated — use `workspaceFolders`) [source: references/architecture.md]
@@ -0,0 +1,168 @@
1
+ # Additional API Patterns
2
+
3
+ Lower-frequency patterns that complement the core UI components.
4
+
5
+ ## FileSystemWatcher
6
+
7
+ React to file changes in the workspace.
8
+
9
+ ```typescript
10
+ export function activate(context: vscode.ExtensionContext) {
11
+ const watcher = vscode.workspace.createFileSystemWatcher(
12
+ '**/*.json', // glob pattern
13
+ false, // ignoreCreateEvents
14
+ false, // ignoreChangeEvents
15
+ false, // ignoreDeleteEvents
16
+ );
17
+
18
+ context.subscriptions.push(
19
+ watcher,
20
+ watcher.onDidCreate((uri) => {
21
+ console.log(`Created: ${uri.fsPath}`);
22
+ }),
23
+ watcher.onDidChange((uri) => {
24
+ console.log(`Changed: ${uri.fsPath}`);
25
+ }),
26
+ watcher.onDidDelete((uri) => {
27
+ console.log(`Deleted: ${uri.fsPath}`);
28
+ }),
29
+ );
30
+ }
31
+ ```
32
+
33
+ ## Disposable Cleanup Pattern
34
+
35
+ The standard pattern for managing extension lifecycle.
36
+
37
+ ```typescript
38
+ import * as vscode from 'vscode';
39
+
40
+ let outputChannel: vscode.OutputChannel | undefined;
41
+
42
+ export function activate(context: vscode.ExtensionContext) {
43
+ // Output channel for logging
44
+ outputChannel = vscode.window.createOutputChannel('My Extension');
45
+ context.subscriptions.push(outputChannel);
46
+
47
+ // All registrations go into context.subscriptions
48
+ context.subscriptions.push(
49
+ vscode.commands.registerCommand('myExt.run', run),
50
+ vscode.workspace.onDidSaveTextDocument(onDocSaved),
51
+ vscode.window.onDidChangeActiveTextEditor(onEditorChanged),
52
+ );
53
+
54
+ outputChannel.appendLine('Extension activated');
55
+ }
56
+
57
+ export function deactivate(): void {
58
+ // Only needed for async cleanup like:
59
+ // - Closing network connections
60
+ // - Stopping child processes
61
+ // - Flushing buffers
62
+ // Disposables in context.subscriptions are auto-disposed.
63
+ }
64
+
65
+ function run(): void {
66
+ outputChannel?.appendLine('Command executed');
67
+ }
68
+
69
+ function onDocSaved(doc: vscode.TextDocument): void {
70
+ outputChannel?.appendLine(`Saved: ${doc.fileName}`);
71
+ }
72
+
73
+ function onEditorChanged(editor: vscode.TextEditor | undefined): void {
74
+ outputChannel?.appendLine(`Active editor: ${editor?.document.fileName ?? 'none'}`);
75
+ }
76
+ ```
77
+
78
+ ## Diagnostic Collection
79
+
80
+ Report problems (errors, warnings) in the Problems panel.
81
+
82
+ ```typescript
83
+ const diagnostics = vscode.languages.createDiagnosticCollection('myExt');
84
+ context.subscriptions.push(diagnostics);
85
+
86
+ function validateDocument(doc: vscode.TextDocument): void {
87
+ const issues: vscode.Diagnostic[] = [];
88
+
89
+ for (let i = 0; i < doc.lineCount; i++) {
90
+ const line = doc.lineAt(i);
91
+ if (line.text.includes('TODO')) {
92
+ issues.push(
93
+ new vscode.Diagnostic(
94
+ line.range,
95
+ 'TODO comment found',
96
+ vscode.DiagnosticSeverity.Warning,
97
+ ),
98
+ );
99
+ }
100
+ }
101
+
102
+ diagnostics.set(doc.uri, issues);
103
+ }
104
+ ```
105
+
106
+ ## Output Channel and Logging
107
+
108
+ ```typescript
109
+ // Simple output channel
110
+ const output = vscode.window.createOutputChannel('My Extension');
111
+ output.appendLine('Info message');
112
+ output.show(true); // true = preserve focus
113
+
114
+ // Log output channel (structured, with log levels — VS Code 1.74+)
115
+ const log = vscode.window.createOutputChannel('My Extension', { log: true });
116
+ log.info('Started');
117
+ log.warn('Something looks off');
118
+ log.error('Something failed', new Error('details'));
119
+ log.debug('Debug data', { key: 'value' });
120
+ ```
121
+
122
+ ## Context Keys (When Clauses)
123
+
124
+ Set custom context keys to control menu/command visibility.
125
+
126
+ ```typescript
127
+ // Set a context key
128
+ vscode.commands.executeCommand('setContext', 'myExt.isConnected', true);
129
+
130
+ // Use in package.json when clauses:
131
+ // "when": "myExt.isConnected"
132
+ // "when": "myExt.isConnected && editorLangId == typescript"
133
+
134
+ // Clear it
135
+ vscode.commands.executeCommand('setContext', 'myExt.isConnected', false);
136
+ ```
137
+
138
+ ## TextDocumentContentProvider
139
+
140
+ Provide virtual read-only documents.
141
+
142
+ ```typescript
143
+ class MyContentProvider implements vscode.TextDocumentContentProvider {
144
+ private _onDidChange = new vscode.EventEmitter<vscode.Uri>();
145
+ readonly onDidChange = this._onDidChange.event;
146
+
147
+ provideTextDocumentContent(uri: vscode.Uri): string {
148
+ const query = new URLSearchParams(uri.query);
149
+ const id = query.get('id') ?? 'unknown';
150
+ return `Content for: ${id}\nGenerated at: ${new Date().toISOString()}`;
151
+ }
152
+
153
+ refresh(uri: vscode.Uri): void {
154
+ this._onDidChange.fire(uri);
155
+ }
156
+ }
157
+
158
+ // Register
159
+ const provider = new MyContentProvider();
160
+ context.subscriptions.push(
161
+ vscode.workspace.registerTextDocumentContentProvider('myScheme', provider),
162
+ );
163
+
164
+ // Open a virtual document
165
+ const uri = vscode.Uri.parse('myScheme:item?id=123');
166
+ const doc = await vscode.workspace.openTextDocument(uri);
167
+ await vscode.window.showTextDocument(doc);
168
+ ```
@@ -0,0 +1,55 @@
1
+ # withProgress
2
+
3
+ Show progress for long-running operations.
4
+
5
+ ## Notification Progress
6
+
7
+ ```typescript
8
+ async function longRunningTask(): Promise<void> {
9
+ await vscode.window.withProgress(
10
+ {
11
+ location: vscode.ProgressLocation.Notification,
12
+ title: 'Processing items',
13
+ cancellable: true,
14
+ },
15
+ async (progress, token) => {
16
+ const items = await getItems();
17
+ const total = items.length;
18
+
19
+ for (let i = 0; i < total; i++) {
20
+ // Check for cancellation
21
+ if (token.isCancellationRequested) {
22
+ vscode.window.showWarningMessage('Operation cancelled.');
23
+ return;
24
+ }
25
+
26
+ progress.report({
27
+ increment: 100 / total,
28
+ message: `(${i + 1}/${total}) ${items[i].name}`,
29
+ });
30
+
31
+ await processItem(items[i]);
32
+ }
33
+
34
+ vscode.window.showInformationMessage(`Processed ${total} items.`);
35
+ },
36
+ );
37
+ }
38
+ ```
39
+
40
+ ## Status Bar Progress
41
+
42
+ ```typescript
43
+ await vscode.window.withProgress(
44
+ {
45
+ location: vscode.ProgressLocation.Window,
46
+ title: 'Indexing files...',
47
+ },
48
+ async (progress) => {
49
+ progress.report({ message: 'scanning...' });
50
+ await scanFiles();
51
+ progress.report({ message: 'building index...' });
52
+ await buildIndex();
53
+ },
54
+ );
55
+ ```