@maccesar/aiskills 1.11.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.
- package/README.md +43 -8
- package/lib/cleanup.js +42 -0
- package/lib/commands/skills.js +110 -8
- package/lib/config.js +17 -12
- package/lib/installer.js +5 -3
- package/lib/platform.js +1 -1
- package/lib/symlink.js +45 -3
- package/lib/utils.js +41 -0
- package/package.json +1 -1
- package/skills/audit-codebase/SKILL.md +70 -0
- package/skills/audit-codebase/agents/openai.yaml +4 -0
- package/skills/audit-codebase/references/comprehensive-audit.md +220 -0
- package/skills/audit-codebase/references/report-format.md +119 -0
- package/skills/humaniza/SKILL.md +55 -4
- package/skills/humaniza/references/ai-patterns-es.md +40 -0
- package/skills/humaniza/references/checklist.md +9 -0
- package/skills/humaniza/references/examples.md +16 -0
- package/skills/humaniza/references/lexicon-es-mx.md +18 -0
- package/skills/humaniza/references/structures-es.md +132 -0
- package/skills/humaniza/scripts/check_ai_patterns.py +216 -0
- package/skills/refactoring-ui/SKILL.md +65 -29
- package/skills/refactoring-ui/references/05-motion.md +124 -0
- package/skills/refactoring-ui/references/06-dark-mode.md +117 -0
- package/skills/refactoring-ui/references/07-component-patterns.md +181 -0
- package/skills/stitch-showcase/SKILL.md +24 -232
- package/skills/stitch-showcase/references/07-theme-system.md +12 -0
- package/skills/stitch-showcase/references/08-type-detection.md +9 -1
- package/skills/stitch-showcase/references/10-component-standardization.md +25 -0
- package/skills/stitch-showcase/references/12-video-embedding.md +113 -0
- package/skills/stitch-showcase/references/13-language-detection.md +82 -0
- package/skills/stitch-showcase/references/14-troubleshooting-known-issues.md +122 -0
- package/skills/stitch-showcase/references/15-build-flags.md +71 -0
- package/skills/stitch-showcase/references/16-design-md-format.md +107 -0
- package/skills/stitch-showcase/references/index.html +25 -19
- package/skills/stitch-showcase/references/viewer.html +24 -12
- package/skills/stitch-showcase/scripts/__pycache__/build_showcase.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/component_utils.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/detect_components.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/extract_catalog.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/extract_text.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/extract_zips.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/parse_design_md.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/slug_demangle.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/build_showcase.py +150 -10
- package/skills/stitch-showcase/scripts/parse_design_md.py +145 -12
- package/skills/stitch-showcase/scripts/slug_demangle.py +209 -0
- package/skills/vscode-extension-dev/SKILL.md +90 -41
- package/skills/vscode-extension-dev/references/api-additional.md +168 -0
- package/skills/vscode-extension-dev/references/api-progress.md +55 -0
- package/skills/vscode-extension-dev/references/api-quickpick.md +75 -0
- package/skills/vscode-extension-dev/references/api-secretstorage.md +57 -0
- package/skills/vscode-extension-dev/references/api-statusbar.md +38 -0
- package/skills/vscode-extension-dev/references/api-treeview.md +78 -0
- package/skills/vscode-extension-dev/references/api-webview.md +149 -0
- package/skills/vscode-extension-dev/references/architecture.md +67 -0
- package/skills/vscode-extension-dev/references/debugger.md +179 -0
- package/skills/vscode-extension-dev/references/lsp.md +175 -0
- package/skills/vscode-extension-dev/references/notebooks.md +208 -0
- package/skills/vscode-extension-dev/references/testing.md +208 -0
- 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:
|
|
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
|
-
##
|
|
10
|
+
## Required workflow (read before responding)
|
|
27
11
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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** —
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
95
|
-
|
|
|
96
|
-
| `references/
|
|
97
|
-
| `references/api-
|
|
98
|
-
| `references/
|
|
99
|
-
| `references/
|
|
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
|
+
```
|