vskill 1.0.12 → 1.0.13

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.
@@ -0,0 +1,73 @@
1
+ /**
2
+ * 0770 -- Pure regex parser. Normalizes any github.com origin remote
3
+ * (SSH, HTTPS, ssh://) to its canonical `https://github.com/owner/repo`
4
+ * form (no `.git` suffix, no trailing path). Returns null for non-github
5
+ * hosts, malformed input, empty/whitespace strings.
6
+ */
7
+ export declare function parseGithubRemote(remote: string | null | undefined): string | null;
8
+ /**
9
+ * 0770 -- Walk parent directories from `startDir` looking for a `.git` entry
10
+ * (directory OR file -- git worktrees use a `.git` file). Bails at the
11
+ * filesystem root or after `maxLevels` iterations. Returns the absolute
12
+ * path of the discovered git root, or null.
13
+ */
14
+ export declare function walkUpForGitRoot(startDir: string, maxLevels?: number): string | null;
15
+ /**
16
+ * 0770 -- Test-only helper to clear the module-level memoization cache so
17
+ * tests can isolate detection runs across `beforeEach`.
18
+ */
19
+ export declare function resetAuthoredSourceLinkCache(): void;
20
+ /**
21
+ * 0770 -- Detect source-repo provenance for a locally-authored skill (no
22
+ * lockfile entry). Walks for `.git`, reads `origin` remote, normalizes via
23
+ * `parseGithubRemote`, and computes `skillPath` from `git ls-files` (with a
24
+ * filesystem fallback for untracked SKILL.md files). Memoized per absolute
25
+ * skill dir for the eval-server process lifetime.
26
+ *
27
+ * All git invocations use `execFileSync` with explicit argv (no shell), a
28
+ * 1500ms hard timeout, and silenced stderr. Any error converts to
29
+ * `{null, null}` -- `buildSkillMetadata` never throws because of git.
30
+ */
31
+ export declare function detectAuthoredSourceLink(skillDir: string): {
32
+ repoUrl: string | null;
33
+ skillPath: string | null;
34
+ };
35
+ /**
36
+ * 0809 -- Test-only helper to clear the sidecar memoization cache.
37
+ */
38
+ export declare function resetCopiedSkillSidecarCache(): void;
39
+ /**
40
+ * 0809 -- Read `<skillDir>/.vskill-source.json` and return the snapshotted
41
+ * {repoUrl, skillPath}. Returns {null, null} on missing file, JSON parse
42
+ * error, missing/invalid `repoUrl`, or non-github host. Memoized per
43
+ * absolute skill dir for the eval-server lifetime.
44
+ */
45
+ export declare function readCopiedSkillSidecar(skillDir: string): {
46
+ repoUrl: string | null;
47
+ skillPath: string | null;
48
+ };
49
+ /**
50
+ * 0737 -- Resolve the source-repo provenance (repoUrl + skillPath) for a
51
+ * skill. Three precedences:
52
+ * 1. Lockfile receipt with explicit `sourceRepoUrl` (set by recent
53
+ * `vskill install` after 0737 shipped).
54
+ * 2. Lockfile receipt with legacy `source: github:owner/repo` (every
55
+ * pre-0737 install -- 0743 derives skillPath safely).
56
+ * 3. (0809, NEW) `.vskill-source.json` sidecar -- written by the Studio
57
+ * Copy / scope-transfer flow at copy time.
58
+ * 4. (0770) Authored-skill detector -- walks parent `.git` and reads
59
+ * origin remote.
60
+ *
61
+ * Lockfile entries are keyed by plugin name; for nested-layout plugins the
62
+ * skill dir basename and the lockfile key differ -- fall back to the parent
63
+ * directory's basename when no exact match exists.
64
+ *
65
+ * Sidecar beats authored because the studio's CWD git remote (umbrella's
66
+ * repo) is the wrong source of truth for a skill that was COPIED from
67
+ * elsewhere. Lockfile beats sidecar because an explicit install receipt
68
+ * is more authoritative than a copy-time snapshot.
69
+ */
70
+ export declare function resolveSourceLink(skillDir: string, root: string): {
71
+ repoUrl: string | null;
72
+ skillPath: string | null;
73
+ };
@@ -0,0 +1,275 @@
1
+ // ---------------------------------------------------------------------------
2
+ // source-link.ts -- Source-repo provenance resolver for skill metadata.
3
+ //
4
+ // Extracted from api-routes.ts as part of 0809 to (a) eliminate circular-
5
+ // import risk for studio code that needs the resolver at copy time, and
6
+ // (b) give the resolver chain (lockfile -> sidecar -> authored) a focused
7
+ // home alongside its helper functions.
8
+ //
9
+ // Public surface (re-exported from api-routes.ts for backwards compat):
10
+ // - parseGithubRemote
11
+ // - walkUpForGitRoot
12
+ // - detectAuthoredSourceLink (0770)
13
+ // - readCopiedSkillSidecar (0809 — new)
14
+ // - resolveSourceLink (composes the precedence chain)
15
+ // - resetAuthoredSourceLinkCache (test hook)
16
+ // - resetCopiedSkillSidecarCache (test hook — 0809)
17
+ // ---------------------------------------------------------------------------
18
+ import { existsSync, readFileSync } from "node:fs";
19
+ import { execFileSync } from "node:child_process";
20
+ import { join, resolve, dirname, basename, relative } from "node:path";
21
+ import { readLockfile } from "../lockfile/lockfile.js";
22
+ /**
23
+ * 0770 -- Pure regex parser. Normalizes any github.com origin remote
24
+ * (SSH, HTTPS, ssh://) to its canonical `https://github.com/owner/repo`
25
+ * form (no `.git` suffix, no trailing path). Returns null for non-github
26
+ * hosts, malformed input, empty/whitespace strings.
27
+ */
28
+ export function parseGithubRemote(remote) {
29
+ const trimmed = (remote ?? "").trim();
30
+ if (!trimmed)
31
+ return null;
32
+ // SSH: git@github.com:owner/repo[.git]
33
+ let m = /^git@github\.com:([^/\s]+)\/([^/\s]+?)(?:\.git)?$/.exec(trimmed);
34
+ if (m)
35
+ return `https://github.com/${m[1]}/${m[2]}`;
36
+ // ssh://git@github.com/owner/repo[.git]
37
+ m = /^ssh:\/\/git@github\.com\/([^/\s]+)\/([^/\s]+?)(?:\.git)?$/.exec(trimmed);
38
+ if (m)
39
+ return `https://github.com/${m[1]}/${m[2]}`;
40
+ // http(s)://github.com/owner/repo[.git][/...]
41
+ m = /^https?:\/\/github\.com\/([^/\s]+)\/([^/\s?#]+?)(?:\.git)?(?:[/?#].*)?$/.exec(trimmed);
42
+ if (m)
43
+ return `https://github.com/${m[1]}/${m[2]}`;
44
+ return null;
45
+ }
46
+ /**
47
+ * 0770 -- Walk parent directories from `startDir` looking for a `.git` entry
48
+ * (directory OR file -- git worktrees use a `.git` file). Bails at the
49
+ * filesystem root or after `maxLevels` iterations. Returns the absolute
50
+ * path of the discovered git root, or null.
51
+ */
52
+ export function walkUpForGitRoot(startDir, maxLevels = 12) {
53
+ let current = resolve(startDir);
54
+ for (let i = 0; i < maxLevels; i++) {
55
+ if (existsSync(join(current, ".git")))
56
+ return current;
57
+ const parent = dirname(current);
58
+ if (parent === current)
59
+ return null;
60
+ current = parent;
61
+ }
62
+ return null;
63
+ }
64
+ const authoredSourceLinkCache = new Map();
65
+ /**
66
+ * 0770 -- Test-only helper to clear the module-level memoization cache so
67
+ * tests can isolate detection runs across `beforeEach`.
68
+ */
69
+ export function resetAuthoredSourceLinkCache() {
70
+ authoredSourceLinkCache.clear();
71
+ }
72
+ /**
73
+ * 0770 -- Detect source-repo provenance for a locally-authored skill (no
74
+ * lockfile entry). Walks for `.git`, reads `origin` remote, normalizes via
75
+ * `parseGithubRemote`, and computes `skillPath` from `git ls-files` (with a
76
+ * filesystem fallback for untracked SKILL.md files). Memoized per absolute
77
+ * skill dir for the eval-server process lifetime.
78
+ *
79
+ * All git invocations use `execFileSync` with explicit argv (no shell), a
80
+ * 1500ms hard timeout, and silenced stderr. Any error converts to
81
+ * `{null, null}` -- `buildSkillMetadata` never throws because of git.
82
+ */
83
+ export function detectAuthoredSourceLink(skillDir) {
84
+ const absDir = resolve(skillDir);
85
+ const cached = authoredSourceLinkCache.get(absDir);
86
+ if (cached)
87
+ return cached;
88
+ const compute = () => {
89
+ const gitRoot = walkUpForGitRoot(absDir);
90
+ if (!gitRoot)
91
+ return { repoUrl: null, skillPath: null };
92
+ let remote = "";
93
+ try {
94
+ remote = execFileSync("git", ["config", "--get", "remote.origin.url"], {
95
+ cwd: gitRoot,
96
+ timeout: 1500,
97
+ stdio: ["ignore", "pipe", "ignore"],
98
+ encoding: "utf-8",
99
+ }).trim();
100
+ }
101
+ catch {
102
+ return { repoUrl: null, skillPath: null };
103
+ }
104
+ const repoUrl = parseGithubRemote(remote);
105
+ if (!repoUrl)
106
+ return { repoUrl: null, skillPath: null };
107
+ let skillPath = null;
108
+ try {
109
+ const tracked = execFileSync("git", ["ls-files", "--full-name", "SKILL.md"], {
110
+ cwd: absDir,
111
+ timeout: 1500,
112
+ stdio: ["ignore", "pipe", "ignore"],
113
+ encoding: "utf-8",
114
+ }).trim();
115
+ if (tracked)
116
+ skillPath = tracked;
117
+ }
118
+ catch {
119
+ // fall through to filesystem fallback
120
+ }
121
+ if (!skillPath) {
122
+ // Filesystem fallback for untracked SKILL.md -- same path the file will
123
+ // have on github.com once committed and pushed.
124
+ skillPath = relative(gitRoot, join(absDir, "SKILL.md")).replace(/\\/g, "/");
125
+ }
126
+ return { repoUrl, skillPath };
127
+ };
128
+ const result = compute();
129
+ authoredSourceLinkCache.set(absDir, result);
130
+ return result;
131
+ }
132
+ // ---------------------------------------------------------------------------
133
+ // 0809 -- Copied-skill sidecar reader.
134
+ //
135
+ // When the Studio scope-transfer (Copy) flow lands a skill into Personal or
136
+ // Project scope, it persists the SOURCE skill's resolved {repoUrl, skillPath}
137
+ // into a small sidecar file at `<skillDir>/.vskill-source.json`. This reader
138
+ // surfaces that snapshot back into resolveSourceLink without bloating
139
+ // SKILL.md or touching the lockfile (which is owned by `vskill install`).
140
+ //
141
+ // Validation is strict: any deviation from the expected shape returns
142
+ // {null, null} so the resolver can fall through to the authored detector
143
+ // instead of producing a confidently-wrong header anchor.
144
+ // ---------------------------------------------------------------------------
145
+ const SIDECAR_FILENAME = ".vskill-source.json";
146
+ // Canonical form only: no trailing .git, no /tree/, no /blob/, no extra path
147
+ // segments. Rejecting .git here forces the writer (transfer()) to persist the
148
+ // canonical form so the resolver always returns identical strings whether the
149
+ // source was a lockfile install, a sidecar snapshot, or an authored detect.
150
+ const REPO_URL_RE = /^https:\/\/github\.com\/[A-Za-z0-9][A-Za-z0-9-]{0,38}\/(?!.*\.git$)[A-Za-z0-9._-]+$/;
151
+ const copiedSkillSidecarCache = new Map();
152
+ /**
153
+ * 0809 -- Test-only helper to clear the sidecar memoization cache.
154
+ */
155
+ export function resetCopiedSkillSidecarCache() {
156
+ copiedSkillSidecarCache.clear();
157
+ }
158
+ /**
159
+ * 0809 -- Read `<skillDir>/.vskill-source.json` and return the snapshotted
160
+ * {repoUrl, skillPath}. Returns {null, null} on missing file, JSON parse
161
+ * error, missing/invalid `repoUrl`, or non-github host. Memoized per
162
+ * absolute skill dir for the eval-server lifetime.
163
+ */
164
+ export function readCopiedSkillSidecar(skillDir) {
165
+ const absDir = resolve(skillDir);
166
+ const cached = copiedSkillSidecarCache.get(absDir);
167
+ if (cached)
168
+ return cached;
169
+ const compute = () => {
170
+ const sidecarPath = join(absDir, SIDECAR_FILENAME);
171
+ if (!existsSync(sidecarPath))
172
+ return { repoUrl: null, skillPath: null };
173
+ let raw;
174
+ try {
175
+ raw = readFileSync(sidecarPath, "utf-8");
176
+ }
177
+ catch {
178
+ return { repoUrl: null, skillPath: null };
179
+ }
180
+ let parsed;
181
+ try {
182
+ parsed = JSON.parse(raw);
183
+ }
184
+ catch {
185
+ return { repoUrl: null, skillPath: null };
186
+ }
187
+ if (!parsed || typeof parsed !== "object")
188
+ return { repoUrl: null, skillPath: null };
189
+ const obj = parsed;
190
+ const repoUrl = obj.repoUrl;
191
+ if (typeof repoUrl !== "string" || !REPO_URL_RE.test(repoUrl)) {
192
+ return { repoUrl: null, skillPath: null };
193
+ }
194
+ let skillPath = null;
195
+ if (typeof obj.skillPath === "string" && obj.skillPath.trim() !== "") {
196
+ skillPath = obj.skillPath;
197
+ }
198
+ return { repoUrl, skillPath };
199
+ };
200
+ const result = compute();
201
+ copiedSkillSidecarCache.set(absDir, result);
202
+ return result;
203
+ }
204
+ /**
205
+ * 0737 -- Resolve the source-repo provenance (repoUrl + skillPath) for a
206
+ * skill. Three precedences:
207
+ * 1. Lockfile receipt with explicit `sourceRepoUrl` (set by recent
208
+ * `vskill install` after 0737 shipped).
209
+ * 2. Lockfile receipt with legacy `source: github:owner/repo` (every
210
+ * pre-0737 install -- 0743 derives skillPath safely).
211
+ * 3. (0809, NEW) `.vskill-source.json` sidecar -- written by the Studio
212
+ * Copy / scope-transfer flow at copy time.
213
+ * 4. (0770) Authored-skill detector -- walks parent `.git` and reads
214
+ * origin remote.
215
+ *
216
+ * Lockfile entries are keyed by plugin name; for nested-layout plugins the
217
+ * skill dir basename and the lockfile key differ -- fall back to the parent
218
+ * directory's basename when no exact match exists.
219
+ *
220
+ * Sidecar beats authored because the studio's CWD git remote (umbrella's
221
+ * repo) is the wrong source of truth for a skill that was COPIED from
222
+ * elsewhere. Lockfile beats sidecar because an explicit install receipt
223
+ * is more authoritative than a copy-time snapshot.
224
+ */
225
+ export function resolveSourceLink(skillDir, root) {
226
+ const lock = readLockfile(root);
227
+ if (lock) {
228
+ const skillName = basename(skillDir);
229
+ const parentName = basename(dirname(skillDir));
230
+ const entry = lock.skills[skillName] ?? lock.skills[parentName];
231
+ if (entry) {
232
+ if (entry.sourceRepoUrl) {
233
+ return {
234
+ repoUrl: entry.sourceRepoUrl,
235
+ skillPath: entry.sourceSkillPath ?? "SKILL.md",
236
+ };
237
+ }
238
+ // Legacy derivation from `source: github:owner/repo`.
239
+ // 0743: We DO NOT blindly default `skillPath` to "SKILL.md" here. Multi-skill
240
+ // repos (vskill, marketingskills, etc.) hold the SKILL.md under a nested
241
+ // path, and the legacy `source` string carries no path information.
242
+ // Guessing "SKILL.md" produced confidently-wrong 404 anchors for every
243
+ // install from a multi-skill repo.
244
+ //
245
+ // 0773 hotfix: when the matched lockfile entry KEY equals the source repo
246
+ // basename (i.e. `vskill install anton-abyzov/greet-anton` keys the entry
247
+ // as `greet-anton` AND the repo is `greet-anton`), the repo IS the skill --
248
+ // SKILL.md sits at the repo root. Defaulting skillPath to "SKILL.md" in
249
+ // that exact shape restores the working SourceFileLink anchor for
250
+ // single-skill repos without re-introducing 404s for multi-skill repos.
251
+ const m = /^github:([^/]+)\/([^/#]+)/.exec(entry.source ?? "");
252
+ // 0770: do NOT fall through here -- an installed skill with a non-github
253
+ // `source` (e.g. `marketplace:...`) is still installed, not authored. Local
254
+ // git detection would leak the workspace remote (umbrella, etc.).
255
+ if (!m)
256
+ return { repoUrl: null, skillPath: null };
257
+ const repoBasename = m[2];
258
+ const lockKey = lock.skills[skillName] ? skillName : parentName;
259
+ const isSingleSkillRepo = repoBasename === lockKey;
260
+ return {
261
+ repoUrl: `https://github.com/${m[1]}/${m[2]}`,
262
+ skillPath: entry.sourceSkillPath ?? (isSingleSkillRepo ? "SKILL.md" : null),
263
+ };
264
+ }
265
+ }
266
+ // 0809 -- Copied-skill sidecar precedes authored detection so that copies
267
+ // landed via Studio carry the original GitHub source through any
268
+ // intermediate location (e.g. ~/.claude/skills/<name>) -- never the
269
+ // studio CWD's umbrella remote.
270
+ const sidecar = readCopiedSkillSidecar(skillDir);
271
+ if (sidecar.repoUrl)
272
+ return sidecar;
273
+ return detectAuthoredSourceLink(skillDir);
274
+ }
275
+ //# sourceMappingURL=source-link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-link.js","sourceRoot":"","sources":["../../src/eval-server/source-link.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import{j as e,R as j,u as J,a as Z,r as b,g as D,b as B,w as X,c as ee,t as P,L as R,P as te,E as se,d as re,S as ae}from"./index-DhrY6PTA.js";/* empty css */const le=[{key:"slashCommands",label:"Slash"},{key:"hooks",label:"Hooks"},{key:"mcp",label:"MCP"},{key:"customSystemPrompt",label:"Prompt"}];function ne({supported:r,label:l}){return e.jsx("span",{style:{display:"inline-block",fontSize:10,padding:"1px 5px",borderRadius:3,marginRight:3,background:r?"var(--color-success-bg, #d4edda)":"var(--surface-3, #2a2a2a)",color:r?"var(--color-success, #28a745)":"var(--text-tertiary, #666)",border:`1px solid ${r?"var(--color-success, #28a745)":"var(--border-subtle, #333)"}`},children:l})}function F({agent:r,checked:l,onToggle:g}){return e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:8,padding:"6px 8px",borderRadius:6,cursor:"pointer",border:r.installed?"1px solid var(--color-primary, #6366f1)":"1px solid var(--border-subtle, #333)",background:l?"var(--surface-2, #1e1e1e)":"transparent"},children:[e.jsx("input",{type:"checkbox",checked:l,onChange:g,style:{accentColor:"var(--color-primary, #6366f1)"}}),e.jsxs("div",{style:{flex:1},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[e.jsx("span",{style:{fontWeight:500,fontSize:13,color:"var(--text-primary, #fff)"},children:r.displayName}),r.installed&&e.jsx("span",{style:{fontSize:10,padding:"1px 5px",borderRadius:3,background:"var(--color-primary-bg, #312e81)",color:"var(--color-primary, #6366f1)"},children:"installed"})]}),e.jsx("div",{style:{marginTop:3},children:le.map(x=>e.jsx(ne,{supported:r.featureSupport[x.key],label:x.label},x.key))})]})]})}function oe({agents:r,selectedIds:l,onChange:g}){const x=new Set(l),i=r.filter(n=>n.isUniversal),a=r.filter(n=>!n.isUniversal),c=n=>{const o=x.has(n)?l.filter(h=>h!==n):[...l,n];g(o)};return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[i.length>0&&e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:11,fontWeight:600,textTransform:"uppercase",letterSpacing:"0.05em",color:"var(--text-tertiary, #999)",marginBottom:6},children:"Universal Agents"}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:4},children:i.map(n=>e.jsx(F,{agent:n,checked:x.has(n.id),onToggle:()=>c(n.id)},n.id))})]}),a.length>0&&e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:11,fontWeight:600,textTransform:"uppercase",letterSpacing:"0.05em",color:"var(--text-tertiary, #999)",marginBottom:6},children:"Other Agents"}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:4},children:a.map(n=>e.jsx(F,{agent:n,checked:x.has(n.id),onToggle:()=>c(n.id)},n.id))})]})]})}const ie="Cross-universal — emits the same skill to 8 universal agents (Claude, Codex, Cursor, Cline, Gemini CLI, OpenCode, Kimi, Amp). Constrains output to the common schema across all agents. Recommended for portable skills.",de="Powerful Claude-native engine — Anthropic's built-in skill-creator with a slightly richer schema (more expressive on Claude) but Claude-only. Pick this when you only target Claude Code and want full expressiveness.",ce="Generate raw — no engine assistance, you provide the full SKILL.md body.";function ue(r){return[{engine:"vskill",label:"VSkill skill-builder",caption:r.vskillSkillBuilder?`installed${r.vskillVersion?` v${r.vskillVersion}`:""}`:"not installed",tooltip:ie,detected:r.vskillSkillBuilder,installable:!0},{engine:"anthropic-skill-creator",label:"Anthropic skill-creator",caption:r.anthropicSkillCreator?"installed":"not installed",tooltip:de,detected:r.anthropicSkillCreator,installable:!0},{engine:"none",label:"No engine — generate raw",caption:"always available",tooltip:ce,detected:!0,installable:!1}]}function xe(){if(typeof window>"u"||typeof window.matchMedia!="function")return!1;try{return window.matchMedia("(prefers-reduced-motion: reduce)").matches}catch{return!1}}function pe(r){const{detection:l,selected:g,onSelect:x,onInstallClick:i}=r,a=j.useMemo(()=>xe(),[]),c=j.useMemo(()=>ue(l),[l]),n=a?"":"transition-colors";return e.jsxs("fieldset",{className:"flex flex-col gap-2",children:[e.jsx("legend",{className:"text-xs font-semibold text-gray-700",children:"Authoring engine"}),e.jsx("div",{role:"tablist","aria-label":"Authoring engine",className:"flex flex-col gap-1.5",children:c.map(o=>{const h=g===o.engine,p=!o.detected&&o.installable,y=["flex items-center justify-between gap-3 rounded-md border px-3 py-2 text-sm cursor-pointer",n,h?"border-blue-600 bg-blue-50":"border-gray-300 bg-white hover:border-gray-400"].filter(Boolean).join(" "),f=o.detected?{}:{opacity:.6};return e.jsxs("div",{role:"tab",tabIndex:0,"data-testid":`engine-selector-${o.engine}`,"aria-selected":h?"true":"false",title:o.tooltip,style:f,className:y,onClick:()=>x(o.engine),onKeyDown:u=>{(u.key==="Enter"||u.key===" ")&&(u.preventDefault(),x(o.engine))},children:[e.jsxs("div",{className:"flex flex-col",children:[e.jsx("span",{className:"font-medium text-gray-900",children:o.label}),e.jsx("span",{className:"text-xs text-gray-500",children:o.caption})]}),p&&e.jsx("button",{type:"button","data-testid":`install-${o.engine}`,className:"rounded border border-blue-600 px-2 py-1 text-xs font-medium text-blue-700 hover:bg-blue-100",onClick:u=>{u.stopPropagation(),i(o.engine)},children:"Install"})]},o.engine)})})]})}const A="(?:0|[1-9]\\d*)",H="[0-9A-Za-z-]",$=`(?:${A}|\\d*[A-Za-z-]${H}*)`,z=`${H}+`,me=`(?:-${$}(?:\\.${$})*)`,ge=`(?:\\+${z}(?:\\.${z})*)`,he=new RegExp(`^${A}\\.${A}\\.${A}${me}?${ge}?$`);function V(r){return typeof r!="string"?!1:he.test(r.trim())}const fe="Skill version (semver). Auto-bumps on update unless versioningMode=author.",ve="Must be valid semver (e.g. 1.0.0, 2.1.3-beta.1)";function ye(r){const{value:l,onChange:g,mode:x,onValidityChange:i,versionsHref:a,disabled:c}=r,[n,o]=j.useState(!1),[h,p]=j.useState(()=>V(l)),y=V(l);j.useEffect(()=>{y!==h?(p(y),i==null||i(y)):i&&i(y)},[y]);const f=n&&!y,u=["w-full rounded-md border px-3 py-2 text-sm font-mono",f?"border-red-500 bg-red-50 focus:outline-red-600":"border-gray-300 bg-white focus:outline-blue-600",c?"opacity-60 cursor-not-allowed":""].join(" ");return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{className:"text-xs font-semibold text-gray-700",htmlFor:"version-input",children:"Version"}),e.jsx("input",{id:"version-input","data-testid":"version-input",type:"text",title:fe,value:l,onChange:m=>g(m.currentTarget.value),onBlur:()=>o(!0),"aria-invalid":f?"true":"false","aria-describedby":f?"version-input-helper":void 0,disabled:c,className:u,placeholder:"1.0.0"}),f&&e.jsx("span",{id:"version-input-helper","data-testid":"version-input-helper",className:"text-xs text-red-600",role:"alert",children:ve}),x==="update"&&a&&e.jsx("a",{"data-testid":"version-input-versions-link",href:a,target:"_blank",rel:"noreferrer",className:"text-xs text-blue-600 hover:underline",children:"Versions →"})]})}const E={status:"idle",liveTail:"",progress:[],exitCode:null,stderr:"",error:null};function be(r={}){const l=r.fetchImpl??globalThis.fetch,g=r.eventSourceCtor??globalThis.EventSource,[x,i]=j.useState(E),a=j.useRef(null),c=j.useRef(null);j.useEffect(()=>()=>{var p;(p=c.current)==null||p.close()},[]);const n=j.useCallback(()=>{var p;(p=c.current)==null||p.close(),c.current=null,a.current=null,i(E)},[]),o=j.useCallback(async p=>{if(!g){i({...E,status:"failure",error:"EventSource not available"});return}a.current=p,i({...E,status:"spawning"});let y;try{const u=await l("/api/studio/install-engine",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({engine:p})});if(!u.ok){const w=await u.json().catch(()=>({}));i({...E,status:"failure",error:w.remediation??w.error??`HTTP ${u.status}`});return}y=(await u.json()).jobId}catch(u){i({...E,status:"failure",error:u.message});return}const f=new g(`/api/studio/install-engine/${y}/stream`);c.current=f,i(u=>({...u,status:"streaming"})),f.addEventListener("progress",u=>{try{const m=JSON.parse(u.data);i(w=>({...w,liveTail:m.line.length>60?m.line.slice(0,60)+"…":m.line,progress:[...w.progress,m].slice(-200)}))}catch{}}),f.addEventListener("done",u=>{try{const m=JSON.parse(u.data);f.close(),c.current=null,i(w=>({...w,status:m.success?"success":"failure",exitCode:m.exitCode,stderr:m.stderr,error:m.success?null:m.stderr||`exit ${m.exitCode}`}))}catch{f.close(),c.current=null,i(m=>({...m,status:"failure",error:"malformed done event"}))}}),f.addEventListener("error",()=>{f.close(),c.current=null,i(u=>({...u,status:u.status==="streaming"?"failure":u.status,error:u.error??"stream error"}))})},[g,l]),h=j.useCallback(async()=>{const p=a.current;p&&await o(p)},[o]);return{state:x,install:o,retry:h,reset:n}}const je={vskill:"vskill install anton-abyzov/vskill/skill-builder","anthropic-skill-creator":"claude plugin install skill-creator"},ke={vskill:"VSkill skill-builder","anthropic-skill-creator":"Anthropic skill-creator"},we="This runs the command in your terminal as your user. Inspect before approving.";function Ne(r){const{engine:l,onClose:g,onSuccess:x,hookOpts:i}=r,{state:a,install:c,retry:n}=be(i),o=je[l],h=ke[l],p=j.useRef(!1);return j.useEffect(()=>{a.status==="success"&&!p.current&&(p.current=!0,x())},[a.status,x]),e.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":"install-engine-title","data-testid":"install-engine-modal",className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40",children:e.jsxs("div",{className:"w-full max-w-lg rounded-lg bg-white p-6 shadow-xl",children:[e.jsxs("h2",{id:"install-engine-title",className:"text-lg font-semibold text-gray-900",children:["Install ",h]}),a.status==="idle"&&e.jsx(Se,{command:o,onCancel:g,onRun:()=>c(l)}),(a.status==="spawning"||a.status==="streaming")&&e.jsx(Ce,{command:o,liveTail:a.liveTail}),a.status==="success"&&e.jsx(Le,{label:h,onClose:g}),a.status==="failure"&&e.jsx(Ee,{error:a.error??"Install failed",stderr:a.stderr,progress:a.progress,onRetry:()=>n(),onClose:g})]})})}function G({command:r}){return e.jsxs("pre",{"data-testid":"install-command-preview",className:"my-3 overflow-x-auto rounded bg-gray-900 px-3 py-2 font-mono text-xs text-green-300",children:["$ ",r]})}function Se(r){return e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"mt-2 text-sm text-gray-700",children:"Studio will run this command on your behalf:"}),e.jsx(G,{command:r.command}),e.jsx("p",{className:"text-xs text-amber-700","data-testid":"install-security-note",children:we}),e.jsxs("div",{className:"mt-4 flex justify-end gap-2",children:[e.jsx("button",{type:"button","data-testid":"install-cancel",className:"rounded border border-gray-300 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-50",onClick:r.onCancel,children:"Cancel"}),e.jsx("button",{type:"button","data-testid":"install-run",className:"rounded bg-blue-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-700",onClick:r.onRun,children:"Run install"})]})]})}function Ce(r){return e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"mt-2 text-sm text-gray-700",children:"Installing…"}),e.jsx(G,{command:r.command}),e.jsxs("div",{className:"mt-3 flex items-center gap-2 text-xs text-gray-600",children:[e.jsx("span",{"data-testid":"install-spinner",className:"inline-block h-3 w-3 animate-spin rounded-full border-2 border-gray-300 border-t-blue-600"}),e.jsx("span",{"data-testid":"install-live-tail",className:"font-mono",children:r.liveTail||"starting…"})]})]})}function Le(r){return e.jsxs(e.Fragment,{children:[e.jsxs("p",{"data-testid":"install-success",className:"mt-3 text-sm font-medium text-green-700",children:["✓ ",r.label," installed"]}),e.jsx("div",{className:"mt-4 flex justify-end",children:e.jsx("button",{type:"button","data-testid":"install-close",className:"rounded bg-blue-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-700",onClick:r.onClose,children:"Done"})})]})}function Ee(r){const[l,g]=j.useState(!1),x=r.progress.filter(a=>a.stream==="stderr").map(a=>a.line),i=x.length>0?x.join(`
1
+ import{j as e,R as j,u as J,a as Z,r as b,g as D,b as B,w as X,c as ee,t as P,L as R,P as te,E as se,d as re,S as ae}from"./index-C3S9iHnq.js";/* empty css */const le=[{key:"slashCommands",label:"Slash"},{key:"hooks",label:"Hooks"},{key:"mcp",label:"MCP"},{key:"customSystemPrompt",label:"Prompt"}];function ne({supported:r,label:l}){return e.jsx("span",{style:{display:"inline-block",fontSize:10,padding:"1px 5px",borderRadius:3,marginRight:3,background:r?"var(--color-success-bg, #d4edda)":"var(--surface-3, #2a2a2a)",color:r?"var(--color-success, #28a745)":"var(--text-tertiary, #666)",border:`1px solid ${r?"var(--color-success, #28a745)":"var(--border-subtle, #333)"}`},children:l})}function F({agent:r,checked:l,onToggle:g}){return e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:8,padding:"6px 8px",borderRadius:6,cursor:"pointer",border:r.installed?"1px solid var(--color-primary, #6366f1)":"1px solid var(--border-subtle, #333)",background:l?"var(--surface-2, #1e1e1e)":"transparent"},children:[e.jsx("input",{type:"checkbox",checked:l,onChange:g,style:{accentColor:"var(--color-primary, #6366f1)"}}),e.jsxs("div",{style:{flex:1},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[e.jsx("span",{style:{fontWeight:500,fontSize:13,color:"var(--text-primary, #fff)"},children:r.displayName}),r.installed&&e.jsx("span",{style:{fontSize:10,padding:"1px 5px",borderRadius:3,background:"var(--color-primary-bg, #312e81)",color:"var(--color-primary, #6366f1)"},children:"installed"})]}),e.jsx("div",{style:{marginTop:3},children:le.map(x=>e.jsx(ne,{supported:r.featureSupport[x.key],label:x.label},x.key))})]})]})}function oe({agents:r,selectedIds:l,onChange:g}){const x=new Set(l),i=r.filter(n=>n.isUniversal),a=r.filter(n=>!n.isUniversal),c=n=>{const o=x.has(n)?l.filter(h=>h!==n):[...l,n];g(o)};return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[i.length>0&&e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:11,fontWeight:600,textTransform:"uppercase",letterSpacing:"0.05em",color:"var(--text-tertiary, #999)",marginBottom:6},children:"Universal Agents"}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:4},children:i.map(n=>e.jsx(F,{agent:n,checked:x.has(n.id),onToggle:()=>c(n.id)},n.id))})]}),a.length>0&&e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:11,fontWeight:600,textTransform:"uppercase",letterSpacing:"0.05em",color:"var(--text-tertiary, #999)",marginBottom:6},children:"Other Agents"}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:4},children:a.map(n=>e.jsx(F,{agent:n,checked:x.has(n.id),onToggle:()=>c(n.id)},n.id))})]})]})}const ie="Cross-universal — emits the same skill to 8 universal agents (Claude, Codex, Cursor, Cline, Gemini CLI, OpenCode, Kimi, Amp). Constrains output to the common schema across all agents. Recommended for portable skills.",de="Powerful Claude-native engine — Anthropic's built-in skill-creator with a slightly richer schema (more expressive on Claude) but Claude-only. Pick this when you only target Claude Code and want full expressiveness.",ce="Generate raw — no engine assistance, you provide the full SKILL.md body.";function ue(r){return[{engine:"vskill",label:"VSkill skill-builder",caption:r.vskillSkillBuilder?`installed${r.vskillVersion?` v${r.vskillVersion}`:""}`:"not installed",tooltip:ie,detected:r.vskillSkillBuilder,installable:!0},{engine:"anthropic-skill-creator",label:"Anthropic skill-creator",caption:r.anthropicSkillCreator?"installed":"not installed",tooltip:de,detected:r.anthropicSkillCreator,installable:!0},{engine:"none",label:"No engine — generate raw",caption:"always available",tooltip:ce,detected:!0,installable:!1}]}function xe(){if(typeof window>"u"||typeof window.matchMedia!="function")return!1;try{return window.matchMedia("(prefers-reduced-motion: reduce)").matches}catch{return!1}}function pe(r){const{detection:l,selected:g,onSelect:x,onInstallClick:i}=r,a=j.useMemo(()=>xe(),[]),c=j.useMemo(()=>ue(l),[l]),n=a?"":"transition-colors";return e.jsxs("fieldset",{className:"flex flex-col gap-2",children:[e.jsx("legend",{className:"text-xs font-semibold text-gray-700",children:"Authoring engine"}),e.jsx("div",{role:"tablist","aria-label":"Authoring engine",className:"flex flex-col gap-1.5",children:c.map(o=>{const h=g===o.engine,p=!o.detected&&o.installable,y=["flex items-center justify-between gap-3 rounded-md border px-3 py-2 text-sm cursor-pointer",n,h?"border-blue-600 bg-blue-50":"border-gray-300 bg-white hover:border-gray-400"].filter(Boolean).join(" "),f=o.detected?{}:{opacity:.6};return e.jsxs("div",{role:"tab",tabIndex:0,"data-testid":`engine-selector-${o.engine}`,"aria-selected":h?"true":"false",title:o.tooltip,style:f,className:y,onClick:()=>x(o.engine),onKeyDown:u=>{(u.key==="Enter"||u.key===" ")&&(u.preventDefault(),x(o.engine))},children:[e.jsxs("div",{className:"flex flex-col",children:[e.jsx("span",{className:"font-medium text-gray-900",children:o.label}),e.jsx("span",{className:"text-xs text-gray-500",children:o.caption})]}),p&&e.jsx("button",{type:"button","data-testid":`install-${o.engine}`,className:"rounded border border-blue-600 px-2 py-1 text-xs font-medium text-blue-700 hover:bg-blue-100",onClick:u=>{u.stopPropagation(),i(o.engine)},children:"Install"})]},o.engine)})})]})}const A="(?:0|[1-9]\\d*)",H="[0-9A-Za-z-]",$=`(?:${A}|\\d*[A-Za-z-]${H}*)`,z=`${H}+`,me=`(?:-${$}(?:\\.${$})*)`,ge=`(?:\\+${z}(?:\\.${z})*)`,he=new RegExp(`^${A}\\.${A}\\.${A}${me}?${ge}?$`);function V(r){return typeof r!="string"?!1:he.test(r.trim())}const fe="Skill version (semver). Auto-bumps on update unless versioningMode=author.",ve="Must be valid semver (e.g. 1.0.0, 2.1.3-beta.1)";function ye(r){const{value:l,onChange:g,mode:x,onValidityChange:i,versionsHref:a,disabled:c}=r,[n,o]=j.useState(!1),[h,p]=j.useState(()=>V(l)),y=V(l);j.useEffect(()=>{y!==h?(p(y),i==null||i(y)):i&&i(y)},[y]);const f=n&&!y,u=["w-full rounded-md border px-3 py-2 text-sm font-mono",f?"border-red-500 bg-red-50 focus:outline-red-600":"border-gray-300 bg-white focus:outline-blue-600",c?"opacity-60 cursor-not-allowed":""].join(" ");return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{className:"text-xs font-semibold text-gray-700",htmlFor:"version-input",children:"Version"}),e.jsx("input",{id:"version-input","data-testid":"version-input",type:"text",title:fe,value:l,onChange:m=>g(m.currentTarget.value),onBlur:()=>o(!0),"aria-invalid":f?"true":"false","aria-describedby":f?"version-input-helper":void 0,disabled:c,className:u,placeholder:"1.0.0"}),f&&e.jsx("span",{id:"version-input-helper","data-testid":"version-input-helper",className:"text-xs text-red-600",role:"alert",children:ve}),x==="update"&&a&&e.jsx("a",{"data-testid":"version-input-versions-link",href:a,target:"_blank",rel:"noreferrer",className:"text-xs text-blue-600 hover:underline",children:"Versions →"})]})}const E={status:"idle",liveTail:"",progress:[],exitCode:null,stderr:"",error:null};function be(r={}){const l=r.fetchImpl??globalThis.fetch,g=r.eventSourceCtor??globalThis.EventSource,[x,i]=j.useState(E),a=j.useRef(null),c=j.useRef(null);j.useEffect(()=>()=>{var p;(p=c.current)==null||p.close()},[]);const n=j.useCallback(()=>{var p;(p=c.current)==null||p.close(),c.current=null,a.current=null,i(E)},[]),o=j.useCallback(async p=>{if(!g){i({...E,status:"failure",error:"EventSource not available"});return}a.current=p,i({...E,status:"spawning"});let y;try{const u=await l("/api/studio/install-engine",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({engine:p})});if(!u.ok){const w=await u.json().catch(()=>({}));i({...E,status:"failure",error:w.remediation??w.error??`HTTP ${u.status}`});return}y=(await u.json()).jobId}catch(u){i({...E,status:"failure",error:u.message});return}const f=new g(`/api/studio/install-engine/${y}/stream`);c.current=f,i(u=>({...u,status:"streaming"})),f.addEventListener("progress",u=>{try{const m=JSON.parse(u.data);i(w=>({...w,liveTail:m.line.length>60?m.line.slice(0,60)+"…":m.line,progress:[...w.progress,m].slice(-200)}))}catch{}}),f.addEventListener("done",u=>{try{const m=JSON.parse(u.data);f.close(),c.current=null,i(w=>({...w,status:m.success?"success":"failure",exitCode:m.exitCode,stderr:m.stderr,error:m.success?null:m.stderr||`exit ${m.exitCode}`}))}catch{f.close(),c.current=null,i(m=>({...m,status:"failure",error:"malformed done event"}))}}),f.addEventListener("error",()=>{f.close(),c.current=null,i(u=>({...u,status:u.status==="streaming"?"failure":u.status,error:u.error??"stream error"}))})},[g,l]),h=j.useCallback(async()=>{const p=a.current;p&&await o(p)},[o]);return{state:x,install:o,retry:h,reset:n}}const je={vskill:"vskill install anton-abyzov/vskill/skill-builder","anthropic-skill-creator":"claude plugin install skill-creator"},ke={vskill:"VSkill skill-builder","anthropic-skill-creator":"Anthropic skill-creator"},we="This runs the command in your terminal as your user. Inspect before approving.";function Ne(r){const{engine:l,onClose:g,onSuccess:x,hookOpts:i}=r,{state:a,install:c,retry:n}=be(i),o=je[l],h=ke[l],p=j.useRef(!1);return j.useEffect(()=>{a.status==="success"&&!p.current&&(p.current=!0,x())},[a.status,x]),e.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":"install-engine-title","data-testid":"install-engine-modal",className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40",children:e.jsxs("div",{className:"w-full max-w-lg rounded-lg bg-white p-6 shadow-xl",children:[e.jsxs("h2",{id:"install-engine-title",className:"text-lg font-semibold text-gray-900",children:["Install ",h]}),a.status==="idle"&&e.jsx(Se,{command:o,onCancel:g,onRun:()=>c(l)}),(a.status==="spawning"||a.status==="streaming")&&e.jsx(Ce,{command:o,liveTail:a.liveTail}),a.status==="success"&&e.jsx(Le,{label:h,onClose:g}),a.status==="failure"&&e.jsx(Ee,{error:a.error??"Install failed",stderr:a.stderr,progress:a.progress,onRetry:()=>n(),onClose:g})]})})}function G({command:r}){return e.jsxs("pre",{"data-testid":"install-command-preview",className:"my-3 overflow-x-auto rounded bg-gray-900 px-3 py-2 font-mono text-xs text-green-300",children:["$ ",r]})}function Se(r){return e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"mt-2 text-sm text-gray-700",children:"Studio will run this command on your behalf:"}),e.jsx(G,{command:r.command}),e.jsx("p",{className:"text-xs text-amber-700","data-testid":"install-security-note",children:we}),e.jsxs("div",{className:"mt-4 flex justify-end gap-2",children:[e.jsx("button",{type:"button","data-testid":"install-cancel",className:"rounded border border-gray-300 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-50",onClick:r.onCancel,children:"Cancel"}),e.jsx("button",{type:"button","data-testid":"install-run",className:"rounded bg-blue-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-700",onClick:r.onRun,children:"Run install"})]})]})}function Ce(r){return e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"mt-2 text-sm text-gray-700",children:"Installing…"}),e.jsx(G,{command:r.command}),e.jsxs("div",{className:"mt-3 flex items-center gap-2 text-xs text-gray-600",children:[e.jsx("span",{"data-testid":"install-spinner",className:"inline-block h-3 w-3 animate-spin rounded-full border-2 border-gray-300 border-t-blue-600"}),e.jsx("span",{"data-testid":"install-live-tail",className:"font-mono",children:r.liveTail||"starting…"})]})]})}function Le(r){return e.jsxs(e.Fragment,{children:[e.jsxs("p",{"data-testid":"install-success",className:"mt-3 text-sm font-medium text-green-700",children:["✓ ",r.label," installed"]}),e.jsx("div",{className:"mt-4 flex justify-end",children:e.jsx("button",{type:"button","data-testid":"install-close",className:"rounded bg-blue-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-700",onClick:r.onClose,children:"Done"})})]})}function Ee(r){const[l,g]=j.useState(!1),x=r.progress.filter(a=>a.stream==="stderr").map(a=>a.line),i=x.length>0?x.join(`
2
2
  `):r.stderr;return e.jsxs(e.Fragment,{children:[e.jsx("p",{"data-testid":"install-failure",className:"mt-3 text-sm font-medium text-red-700",children:"✗ Install failed"}),e.jsx("p",{className:"mt-1 text-xs text-gray-700",children:r.error}),i&&e.jsxs("details",{className:"mt-3 text-xs",open:l,onToggle:a=>g(a.currentTarget.open),children:[e.jsx("summary",{className:"cursor-pointer text-gray-600",children:"stderr"}),e.jsx("pre",{"data-testid":"install-stderr",className:"mt-2 overflow-x-auto rounded bg-gray-900 px-3 py-2 font-mono text-xs text-red-300",children:i})]}),e.jsxs("div",{className:"mt-4 flex justify-end gap-2",children:[e.jsx("button",{type:"button","data-testid":"install-close",className:"rounded border border-gray-300 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-50",onClick:r.onClose,children:"Close"}),e.jsx("button",{type:"button","data-testid":"install-retry",className:"rounded bg-blue-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-700",onClick:r.onRetry,children:"Retry"})]})]})}const S={background:"var(--surface-3)",color:"var(--text-primary)",border:"1px solid var(--border-subtle)"};function Pe(r){return r?/API usage limits|usage limit/i.test(r)&&/regain access|reset/i.test(r):!1}function Ie(r){const l=r.match(/regain access on ([^"\\]+?)(?:\s*UTC)?["\\]/i)??r.match(/regain access on ([^"\\]+)/i);return l?`Resets ${l[1].trim()} UTC`:"Quota resets at the start of your next billing period"}function I(r){switch(r){case"claude-cli":return"Uses your logged-in Claude Code session — your existing CLI session handles quota. No API key needed. Overflow runs at standard API rates if extra usage is enabled in your account settings.";case"anthropic":return"Direct Anthropic API — pay-per-token. Full Opus / Sonnet / Haiku catalog. Requires ANTHROPIC_API_KEY.";case"openrouter":return"One API key → 300+ models from Anthropic, OpenAI (GPT-5 / o4-mini), Google (Gemini), Meta (Llama) and more. Same prices as direct.";case"ollama":return"Local models on your machine (Llama, Qwen, Mistral, etc.). Zero cost, zero data leaves your laptop.";case"lm-studio":return"Local models via LM Studio's OpenAI-compatible server. Works offline. Pick any model you've loaded in LM Studio.";default:return""}}function M({size:r=14,color:l="currentColor"}){return e.jsx("svg",{width:r,height:r,viewBox:"0 0 24 24",fill:"none",stroke:l,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:e.jsx("path",{d:"M12 3l1.912 5.813a2 2 0 001.275 1.275L21 12l-5.813 1.912a2 2 0 00-1.275 1.275L12 21l-1.912-5.813a2 2 0 00-1.275-1.275L3 12l5.813-1.912a2 2 0 001.275-1.275L12 3z"})})}function Re(){const{config:r}=J(),{refreshSkills:l,revealSkill:g}=Z(),[x,i]=b.useState(null),a=j.useMemo(()=>{if(typeof window>"u")return{};const s=window.location.hash,d=s.indexOf("?");if(d===-1)return{};const N=new URLSearchParams(s.slice(d+1)),k={};for(const v of["mode","skillName","description","pluginName"]){const L=N.get(v);L&&(k[v]=L)}return k},[]),[c,n]=b.useState("claude-cli"),[o,h]=b.useState("sonnet"),[p,y]=b.useState(!1),[f,u]=b.useState(null),m=b.useRef(!1),[w,W]=b.useState([]),[U,K]=b.useState(()=>D("activeAgent",null));b.useEffect(()=>{function s(){K(D("activeAgent",null))}return window.addEventListener("studio:agent-changed",s),window.addEventListener("storage",s),()=>{window.removeEventListener("studio:agent-changed",s),window.removeEventListener("storage",s)}},[]);const Y=U!=="claude-code";b.useEffect(()=>{fetch("/api/agents/installed").then(s=>s.json()).then(s=>{s.agents&&W(s.agents)}).catch(()=>{})},[]),b.useEffect(()=>{var k;if(!r)return;const s=r.providers.filter(v=>v.available),d=B().skillGenModel;if(s.length===0){m.current=!0;return}if(d&&typeof d=="object"&&typeof d.provider=="string"&&typeof d.model=="string"){const v=s.find(T=>T.id===d.provider),L=v==null?void 0:v.models.some(T=>T.id===d.model);if(v&&L){n(d.provider),h(d.model),y(!0),m.current=!0;return}u({provider:d.provider,model:d.model})}if(s.find(v=>v.id==="claude-cli"))n("claude-cli"),h("sonnet");else{const v=s[0];n(v.id),h(((k=v.models[0])==null?void 0:k.id)??"")}y(!1),m.current=!0},[r]),b.useEffect(()=>{const s=d=>{if(d.key!==null&&!d.key.includes("vskill.studio.prefs"))return;const k=B().skillGenModel;k&&typeof k=="object"&&typeof k.provider=="string"&&typeof k.model=="string"&&(n(k.provider),h(k.model),y(!0))};return window.addEventListener("storage",s),()=>window.removeEventListener("storage",s)},[]);const O=b.useCallback((s,d)=>{X("skillGenModel",{provider:s,model:d}),y(!0)},[]),q=b.useCallback(()=>({provider:c,model:o}),[c,o]),Q=a.mode==="standalone"?3:void 0,t=ee({onCreated:(s,d)=>{l(),setTimeout(()=>g(s,d),500)},resolveAiConfigOverride:q,forceLayout:Q});b.useEffect(()=>{a.skillName&&!t.name&&t.setName(P(a.skillName)),a.description&&!t.description&&t.setDescription(a.description),a.description&&!t.aiPrompt&&t.setAiPrompt(a.description),a.pluginName&&!t.plugin&&t.setPlugin(P(a.pluginName))},[]);const C=r==null?void 0:r.providers.find(s=>s.id===c&&s.available),_=b.useMemo(()=>{const s=["---"];return t.description?s.push(`description: "${t.description.replace(/"/g,'\\"')}"`):s.push('description: ""'),t.allowedTools.trim()&&s.push(`allowed-tools: ${t.allowedTools.trim()}`),t.model&&s.push(`model: ${t.model}`),t.targetAgents.length>0&&s.push(`target-agents: ${t.targetAgents.join(", ")}`),s.push("---"),s.push(""),t.body.trim()?s.push(t.body.trim()):(s.push(`# /${t.name||"skill-name"}`),s.push(""),s.push("You are a helpful assistant.")),s.join(`
3
3
  `)},[t.name,t.description,t.model,t.allowedTools,t.body]);return e.jsxs("div",{className:"px-4 py-6 sm:px-6 sm:py-7 lg:px-10 lg:py-8 max-w-6xl mx-auto w-full overflow-x-hidden",children:[e.jsxs("div",{className:"mb-6",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[12px] mb-3",style:{color:"var(--text-tertiary)"},children:[e.jsx(R,{to:"/",className:"hover:underline",style:{color:"var(--text-tertiary)"},children:"Skills"}),e.jsx("span",{children:"/"}),e.jsx("span",{style:{color:"var(--text-secondary)"},children:"New Skill"})]}),e.jsxs("div",{className:"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("h2",{className:"text-[22px] font-semibold tracking-tight",style:{color:"var(--text-primary)"},children:"Create a New Skill"}),t.standaloneLocked&&e.jsx("span",{className:"inline-flex items-center gap-1 text-[10px] font-medium uppercase tracking-wider px-2 py-0.5 rounded whitespace-nowrap",style:{background:"var(--accent-muted)",color:"var(--accent)",border:"1px solid var(--accent-muted)"},title:"You chose Standalone in the previous step. Plugin selection is disabled.",children:"Standalone"})]}),e.jsx("p",{className:"text-[13px] mt-1",style:{color:"var(--text-tertiary)"},children:"Define your skill's metadata, content, and placement"})]}),e.jsxs("div",{className:"inline-flex rounded-lg p-1 self-start sm:self-auto sm:flex-shrink-0 max-w-full",style:{background:"var(--surface-2)",border:"1px solid var(--border-subtle)"},role:"tablist","aria-label":"Creation mode",children:[e.jsx("button",{onClick:()=>t.setMode("ai"),className:"px-4 py-2 rounded-md text-[13px] font-medium transition-all duration-200",style:{background:t.mode==="ai"?"var(--purple-muted)":"transparent",color:t.mode==="ai"?"var(--purple)":"var(--text-tertiary)",boxShadow:t.mode==="ai"?"0 1px 3px rgba(0,0,0,0.08)":"none"},children:e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(M,{size:14}),"AI-Assisted"]})}),e.jsx("button",{onClick:()=>t.setMode("manual"),className:"px-4 py-2 rounded-md text-[13px] font-medium transition-all duration-200",style:{background:t.mode==="manual"?"var(--surface-4, var(--surface-3))":"transparent",color:t.mode==="manual"?"var(--text-primary)":"var(--text-tertiary)",boxShadow:t.mode==="manual"?"0 1px 3px rgba(0,0,0,0.1)":"none"},children:"Manual"})]})]})]}),t.engineDetection&&e.jsx("div",{className:"mb-4",children:e.jsx(pe,{detection:t.engineDetection,selected:t.engine,onSelect:s=>t.setEngine(s),onInstallClick:s=>i(s)})}),t.layoutLoading&&e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"skeleton h-10 w-full rounded-lg"}),e.jsx("div",{className:"skeleton h-10 w-full rounded-lg"}),e.jsx("div",{className:"skeleton h-10 w-full rounded-lg"})]}),!t.layoutLoading&&t.layout&&t.mode==="ai"&&e.jsxs("div",{className:"flex flex-col lg:flex-row gap-6 animate-fade-in",children:[e.jsxs("div",{className:"flex-1 min-w-0 space-y-5",children:[e.jsxs("div",{className:"glass-card p-5",children:[e.jsxs("h3",{className:"text-[13px] font-semibold mb-3 flex items-center gap-2",style:{color:"var(--text-primary)"},children:[e.jsx("div",{className:"w-6 h-6 rounded-md flex items-center justify-center",style:{background:"var(--purple-muted)"},children:e.jsx(M,{size:13,color:"var(--purple)"})}),"Describe Your Skill"]}),e.jsx("textarea",{ref:t.promptRef,value:t.aiPrompt,onChange:s=>t.setAiPrompt(s.target.value),placeholder:`e.g., A skill that helps format SQL queries, optimize them for performance, and explain query execution plans.
4
4
 
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/SearchPaletteCore-DE6FhFNX.js","assets/index-DhrY6PTA.js","assets/index-BKAvJDDF.css","assets/fonts-i7Lkz2zN.css","assets/skill-url-C4ekwoGs.js"])))=>i.map(i=>d[i]);
2
- import{r as t,j as d,_ as l}from"./index-DhrY6PTA.js";/* empty css */const f=t.lazy(()=>l(()=>import("./SearchPaletteCore-DE6FhFNX.js"),__vite__mapDeps([0,1,2,3,4])));function w(){if(typeof window>"u"||typeof window.matchMedia!="function")return!1;try{return window.matchMedia("(prefers-reduced-motion: reduce)").matches}catch{return!1}}function y({onSelect:i,onNavigate:u}={}){const[n,o]=t.useState(!1),s=t.useRef(null),a=w();t.useEffect(()=>{function e(){s.current=document.activeElement??null,o(!0)}return window.addEventListener("openFindSkills",e),()=>window.removeEventListener("openFindSkills",e)},[]),t.useEffect(()=>{if(!n)return;function e(r){r.key==="Escape"&&o(!1)}return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[n]),t.useEffect(()=>{if(n)return;const e=s.current;if(e&&typeof e.focus=="function")try{e.focus()}catch{}s.current=null},[n]);const c=t.useCallback((e,r)=>{try{typeof window<"u"&&window.sessionStorage&&window.sessionStorage.setItem("find-skills:last-query",r??"")}catch{}if(o(!1),i)try{i(e,r)}catch{}},[i]);return n?d.jsx("div",{"data-testid":"find-skills-palette-shell","data-reduced-motion":a?"true":"false",children:d.jsx(t.Suspense,{fallback:null,children:d.jsx(f,{initialOpen:!0,onSelect:c,onNavigate:u})})}):null}export{y as FindSkillsPalette,y as default};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/SearchPaletteCore-EhBtr4Xx.js","assets/index-C3S9iHnq.js","assets/index-BKAvJDDF.css","assets/fonts-i7Lkz2zN.css","assets/skill-url-C4ekwoGs.js"])))=>i.map(i=>d[i]);
2
+ import{r as t,j as d,_ as l}from"./index-C3S9iHnq.js";/* empty css */const f=t.lazy(()=>l(()=>import("./SearchPaletteCore-EhBtr4Xx.js"),__vite__mapDeps([0,1,2,3,4])));function w(){if(typeof window>"u"||typeof window.matchMedia!="function")return!1;try{return window.matchMedia("(prefers-reduced-motion: reduce)").matches}catch{return!1}}function y({onSelect:i,onNavigate:u}={}){const[n,o]=t.useState(!1),s=t.useRef(null),a=w();t.useEffect(()=>{function e(){s.current=document.activeElement??null,o(!0)}return window.addEventListener("openFindSkills",e),()=>window.removeEventListener("openFindSkills",e)},[]),t.useEffect(()=>{if(!n)return;function e(r){r.key==="Escape"&&o(!1)}return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[n]),t.useEffect(()=>{if(n)return;const e=s.current;if(e&&typeof e.focus=="function")try{e.focus()}catch{}s.current=null},[n]);const c=t.useCallback((e,r)=>{try{typeof window<"u"&&window.sessionStorage&&window.sessionStorage.setItem("find-skills:last-query",r??"")}catch{}if(o(!1),i)try{i(e,r)}catch{}},[i]);return n?d.jsx("div",{"data-testid":"find-skills-palette-shell","data-reduced-motion":a?"true":"false",children:d.jsx(t.Suspense,{fallback:null,children:d.jsx(f,{initialOpen:!0,onSelect:c,onNavigate:u})})}):null}export{y as FindSkillsPalette,y as default};
@@ -1,4 +1,4 @@
1
- import{r as a,j as t,h as xe}from"./index-DhrY6PTA.js";import{a as ye}from"./skill-url-C4ekwoGs.js";/* empty css */function me(i){return i?i.replace(/<(?!\/?b>)[^>]+>/gi,""):""}function be(i){return i.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Ie(i,p){if(!i)return"";const d=be(i);if(!p)return d;const u=p.trim().split(/\s+/).filter(Boolean);if(u.length===0)return d;const T=u.map(W=>W.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|"),b=new RegExp(`(${T})`,"gi");return d.replace(b,"<b>$1</b>")}function ve(i){return i?i<1e3?String(i):`${(i/1e3).toFixed(1)}k`:""}const ke=[{label:"Security",href:"/skills?category=security"},{label:"Coding",href:"/skills?category=development"},{label:"DevOps",href:"/skills?category=devops"},{label:"Testing",href:"/skills?category=testing"},{label:"Data",href:"/skills?category=data"},{label:"Design",href:"/skills?category=design"}],Se=[{label:"Submit a skill",href:"/submit"},{label:"Browse all skills",href:"/skills"}],J="var(--font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif)",c="var(--font-mono, 'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace)";function Ee({tier:i,isTainted:p,isBlocked:d}){const u={display:"inline-flex",alignItems:"center",padding:"1px 6px",height:16,borderRadius:3,fontFamily:c,fontSize:9.5,fontWeight:600,letterSpacing:"0.04em",whiteSpace:"nowrap",lineHeight:1,textTransform:"uppercase"};if(d)return t.jsx("span",{"data-testid":"mini-tier-badge","data-tier":"BLOCKED",style:{...u,color:"#7A1F1F",background:"#FBE8E5",border:"1px solid #E8B7B0"},children:"BLOCKED"});if(p)return t.jsx("span",{"data-testid":"mini-tier-badge","data-tier":"TAINTED",style:{...u,color:"#7A4A00",background:"#FBEFD3",border:"1px solid #E8C885"},children:"Tainted"});const b={CERTIFIED:{color:"var(--color-installed, #2F6A4A)",bg:"rgba(47,106,74,0.08)",border:"rgba(47,106,74,0.25)"},VERIFIED:{color:"var(--color-focus, #3B6EA8)",bg:"rgba(59,110,168,0.08)",border:"rgba(59,110,168,0.25)"},REJECTED:{color:"#7A1F1F",bg:"#FBE8E5",border:"#E8B7B0"},BLOCKED:{color:"#7A1F1F",bg:"#FBE8E5",border:"#E8B7B0"}}[i];return b?t.jsx("span",{"data-testid":"mini-tier-badge","data-tier":i,style:{...u,color:b.color,background:b.bg,border:`1px solid ${b.border}`},children:xe(i)}):null}function O(){return t.jsxs("div",{"data-testid":"skeleton-row",style:{padding:"10px 18px",display:"flex",alignItems:"center",gap:10},children:[t.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column",gap:6},children:[t.jsx("div",{style:{height:12,width:"32%",borderRadius:3,background:"var(--color-rule, #E8E1D6)",animation:"fsp-pulse 1.4s ease-in-out infinite"}}),t.jsx("div",{style:{height:9,width:"55%",borderRadius:3,background:"var(--color-rule, #E8E1D6)",animation:"fsp-pulse 1.4s ease-in-out infinite",animationDelay:"0.18s"}})]}),t.jsx("div",{style:{height:14,width:52,borderRadius:3,background:"var(--color-rule, #E8E1D6)",animation:"fsp-pulse 1.4s ease-in-out infinite",animationDelay:"0.36s"}})]})}function Fe(i){var d,u;const p=(d=i.target)==null?void 0:d.tagName;return!!(p==="INPUT"||p==="TEXTAREA"||p==="SELECT"||(u=i.target)!=null&&u.isContentEditable)}const je="/api/v1/studio/search",we="/api/v1/stats",Ae="/api/v1/studio/telemetry/search-select",Re=10,Q=20,Ce=150;function Be({onSelect:i,onNavigate:p,searchUrl:d=je,trendingUrl:u=we,telemetrySelectUrl:T=Ae,maxPages:b=Re,initialOpen:W=!1}={}){const[L,E]=a.useState(W),[o,F]=a.useState(""),[I,h]=a.useState([]),[U,v]=a.useState(0),[j,B]=a.useState(!1),[_,w]=a.useState(1),[H,x]=a.useState(!1),[M,V]=a.useState(!1),[$,k]=a.useState(null),[A,R]=a.useState(!1),Z=a.useRef(null),N=a.useRef(null),z=a.useRef(!1),ee=a.useRef(null),te=a.useRef(null),q=a.useRef(new Map),S=a.useRef(null),[,ue]=a.useState(!1),re=a.useMemo(()=>typeof navigator<"u"&&/Mac|iPod|iPhone|iPad/.test(navigator.platform||""),[]),K=a.useRef(o);a.useEffect(()=>{K.current=o},[o]),a.useEffect(()=>{S.current||fetch(u).then(e=>e.json()).then(e=>{S.current=e.trendingSkills??[],ue(!0)}).catch(()=>{})},[u]),a.useEffect(()=>{const e=r=>{if(r.key==="Escape"){E(!1);return}if(L&&(r.metaKey||r.ctrlKey)&&/^[1-9]$/.test(r.key)){r.preventDefault();const s=Number(r.key)-1;v(s),window.dispatchEvent(new CustomEvent("findSkillsActivateAt",{detail:{index:s}}));return}!r.metaKey&&!r.ctrlKey&&!r.altKey&&r.key.length===1&&!Fe(r)&&(z.current=!0,F(r.key),E(!0))},n=r=>{var y;const l=(y=r.detail)==null?void 0:y.query;l&&(z.current=!0,F(l)),E(!0)};return window.addEventListener("keydown",e),window.addEventListener("openFindSkills",n),()=>{window.removeEventListener("keydown",e),window.removeEventListener("openFindSkills",n)}},[L]),a.useLayoutEffect(()=>{var n;if(!L){(n=N.current)==null||n.abort();return}if(z.current)z.current=!1,h([]),v(0),w(1),x(!1),B(!1),k(null),R(!1);else{const r=(()=>{var s;try{return((s=window.sessionStorage)==null?void 0:s.getItem("find-skills:last-query"))??""}catch{return""}})();F(r),h([]),v(0),w(1),x(!1),B(!1),k(null),R(!1)}const e=Z.current;if(e){e.focus({preventScroll:!0});const r=e.value.length;e.setSelectionRange(r,r)}},[L]),a.useEffect(()=>{if(!o.trim()||o.trim().length<2){h([]),x(!1),w(1),k(null);return}const e=6e4,n=o.trim().toLowerCase(),r=q.current.get(n);if(r&&Date.now()-r.timestamp<e){h(r.results),x(r.hasMore),w(1),B(!1),k(null),fetch(`${d}?q=${encodeURIComponent(o)}&limit=${Q}&page=1`).then(m=>m.ok?m.json():null).then(m=>{var g;m&&q.current.set(n,{results:m.results||[],hasMore:((g=m.pagination)==null?void 0:g.hasMore)??!1,timestamp:Date.now()})}).catch(()=>{});return}B(!0),k(null);const l=new AbortController,y=setTimeout(async()=>{var m;try{const g=await fetch(`${d}?q=${encodeURIComponent(o)}&limit=${Q}&page=1`,{signal:l.signal});if(g.status>=500){R(!0),h([]),x(!1),k(null);return}if(!g.ok){h([]),x(!1),k(`search failed (${g.status})`);return}const ce=await g.json(),de=ce.results||[],pe=((m=ce.pagination)==null?void 0:m.hasMore)??!1;h(de),x(pe),w(1),R(!1),q.current.set(n,{results:de,hasMore:pe,timestamp:Date.now()})}catch(g){if(g instanceof DOMException&&g.name==="AbortError")return;R(!0),h([]),x(!1),k(null)}finally{l.signal.aborted||B(!1)}},Ce);return()=>{clearTimeout(y),l.abort()}},[o,d]);const C=_>=b,ne=a.useCallback(async()=>{var n,r;if(M||C)return;const e=_+1;V(!0),N.current=new AbortController;try{const s=await fetch(`${d}?q=${encodeURIComponent(o)}&limit=${Q}&page=${e}`,{signal:N.current.signal});if(!s.ok)return;const l=await s.json();h(y=>[...y,...l.results||[]]),x(((n=l.pagination)==null?void 0:n.hasMore)??!1),w(e)}catch(s){if(s instanceof DOMException&&s.name==="AbortError")return}finally{(r=N.current)!=null&&r.signal.aborted||V(!1)}},[_,o,M,C,d]);a.useEffect(()=>{const e=ee.current,n=te.current;if(!e||!n||typeof IntersectionObserver>"u")return;const r=new IntersectionObserver(s=>{s[0].isIntersecting&&H&&!j&&!M&&!C&&ne()},{root:n,rootMargin:"100px"});return r.observe(e),()=>r.disconnect()},[H,j,M,C,ne]);const P=e=>({name:e.name,displayName:e.displayName,author:e.author,repoUrl:e.repoUrl,certTier:e.certTier,githubStars:0,highlight:"",category:"",ownerSlug:e.ownerSlug,repoSlug:e.repoSlug,skillSlug:e.skillSlug}),G=(()=>{const e=o.trim();if(A&&e.length>=1&&S.current){const n=e.toLowerCase();return S.current.filter(r=>r.name.toLowerCase().includes(n)||(r.displayName??"").toLowerCase().includes(n)).slice(0,30).map(P)}if(e.length>=2)return I;if(e.length===1&&S.current){const n=e.toLowerCase();return S.current.filter(r=>r.name.toLowerCase().startsWith(n)||r.displayName.toLowerCase().startsWith(n)).slice(0,10).map(P)}return e.length===0&&S.current?S.current.slice(0,10).map(P):[]})(),f=[...G.map(e=>{const n=e.skillSlug||e.name.split("/").pop()||e.name,r=e.ownerSlug&&e.repoSlug?`${e.ownerSlug}/${e.repoSlug}`:e.author;return{type:"skill",label:n,publisher:r,name:e.name,command:e.command?e.pluginName?`${e.pluginName}:${e.command}`:e.command:void 0,pluginName:e.pluginName||void 0,meta:e.category||"",certTier:e.certTier,isTainted:e.isTainted,isBlocked:e.isBlocked,repoUrl:e.repoUrl,highlight:e.highlight,githubStars:e.githubStars,category:e.category,href:ye(e.name),sourceResult:e}}),...!o&&G.length===0?ke.map(e=>({type:"category",label:e.label,publisher:"",name:"",meta:"",certTier:"",repoUrl:"",href:e.href})):[],...!o&&G.length===0?Se.map(e=>({type:"action",label:e.label,publisher:"",name:"",meta:"",certTier:"",repoUrl:"",href:e.href})):[]],ae=a.useCallback(e=>{try{fetch(T,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({skillName:e,q:K.current.trim(),ts:Date.now()}),keepalive:!0}).catch(()=>{})}catch{}},[T]),D=a.useCallback((e,n)=>{if(n&&(ae(n.name),i))try{i(n,K.current.trim())}catch{}if(E(!1),p)try{p(e)}catch{}},[i,p,ae]);a.useEffect(()=>{function e(n){var l;const r=((l=n.detail)==null?void 0:l.index)??-1,s=f[r];s&&D(s.href,s.type==="skill"?s.sourceResult:void 0)}return window.addEventListener("findSkillsActivateAt",e),()=>window.removeEventListener("findSkillsActivateAt",e)},[f,D]);const fe=e=>{if(e.key==="ArrowDown")e.preventDefault(),v(n=>Math.min(n+1,f.length-1));else if(e.key==="ArrowUp")e.preventDefault(),v(n=>Math.max(n-1,0));else if(e.key==="Enter"&&f[U]){const n=f[U];D(n.href,n.type==="skill"?n.sourceResult:void 0)}};if(!L)return null;let ie="";const se=!j&&!$&&!A&&o.trim().length>=2&&I.length===0,Y=j&&I.length===0&&o.trim().length>=2&&!A,oe=o.trim(),le=()=>{R(!1);const e=o;F(""),setTimeout(()=>F(e),0)},ge={position:"fixed",inset:0,background:"color-mix(in srgb, var(--color-ink, #191919) 35%, transparent)",backdropFilter:"blur(6px) saturate(1.1)",WebkitBackdropFilter:"blur(6px) saturate(1.1)"},he={position:"relative",width:"100%",maxWidth:640,margin:"0 16px",background:"var(--bg-surface, #FFFFFF)",color:"var(--text-primary, #191919)",borderRadius:12,border:"1px solid var(--color-rule, #E8E1D6)",boxShadow:"0 1px 0 rgba(255,255,255,0.6) inset,0 24px 60px -12px rgba(25,20,15,0.28),0 12px 24px -8px rgba(25,20,15,0.18)",overflow:"hidden",fontFamily:J};return t.jsxs("div",{"data-testid":"find-skills-palette",role:"dialog","aria-modal":"true","aria-label":"Find verified skills",style:{position:"fixed",inset:0,zIndex:9999,display:"flex",alignItems:"flex-start",justifyContent:"center",paddingTop:"min(18vh, 144px)"},onClick:()=>E(!1),children:[t.jsx("div",{style:ge}),t.jsx("style",{children:`
1
+ import{r as a,j as t,h as xe}from"./index-C3S9iHnq.js";import{a as ye}from"./skill-url-C4ekwoGs.js";/* empty css */function me(i){return i?i.replace(/<(?!\/?b>)[^>]+>/gi,""):""}function be(i){return i.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Ie(i,p){if(!i)return"";const d=be(i);if(!p)return d;const u=p.trim().split(/\s+/).filter(Boolean);if(u.length===0)return d;const T=u.map(W=>W.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|"),b=new RegExp(`(${T})`,"gi");return d.replace(b,"<b>$1</b>")}function ve(i){return i?i<1e3?String(i):`${(i/1e3).toFixed(1)}k`:""}const ke=[{label:"Security",href:"/skills?category=security"},{label:"Coding",href:"/skills?category=development"},{label:"DevOps",href:"/skills?category=devops"},{label:"Testing",href:"/skills?category=testing"},{label:"Data",href:"/skills?category=data"},{label:"Design",href:"/skills?category=design"}],Se=[{label:"Submit a skill",href:"/submit"},{label:"Browse all skills",href:"/skills"}],J="var(--font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif)",c="var(--font-mono, 'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace)";function Ee({tier:i,isTainted:p,isBlocked:d}){const u={display:"inline-flex",alignItems:"center",padding:"1px 6px",height:16,borderRadius:3,fontFamily:c,fontSize:9.5,fontWeight:600,letterSpacing:"0.04em",whiteSpace:"nowrap",lineHeight:1,textTransform:"uppercase"};if(d)return t.jsx("span",{"data-testid":"mini-tier-badge","data-tier":"BLOCKED",style:{...u,color:"#7A1F1F",background:"#FBE8E5",border:"1px solid #E8B7B0"},children:"BLOCKED"});if(p)return t.jsx("span",{"data-testid":"mini-tier-badge","data-tier":"TAINTED",style:{...u,color:"#7A4A00",background:"#FBEFD3",border:"1px solid #E8C885"},children:"Tainted"});const b={CERTIFIED:{color:"var(--color-installed, #2F6A4A)",bg:"rgba(47,106,74,0.08)",border:"rgba(47,106,74,0.25)"},VERIFIED:{color:"var(--color-focus, #3B6EA8)",bg:"rgba(59,110,168,0.08)",border:"rgba(59,110,168,0.25)"},REJECTED:{color:"#7A1F1F",bg:"#FBE8E5",border:"#E8B7B0"},BLOCKED:{color:"#7A1F1F",bg:"#FBE8E5",border:"#E8B7B0"}}[i];return b?t.jsx("span",{"data-testid":"mini-tier-badge","data-tier":i,style:{...u,color:b.color,background:b.bg,border:`1px solid ${b.border}`},children:xe(i)}):null}function O(){return t.jsxs("div",{"data-testid":"skeleton-row",style:{padding:"10px 18px",display:"flex",alignItems:"center",gap:10},children:[t.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column",gap:6},children:[t.jsx("div",{style:{height:12,width:"32%",borderRadius:3,background:"var(--color-rule, #E8E1D6)",animation:"fsp-pulse 1.4s ease-in-out infinite"}}),t.jsx("div",{style:{height:9,width:"55%",borderRadius:3,background:"var(--color-rule, #E8E1D6)",animation:"fsp-pulse 1.4s ease-in-out infinite",animationDelay:"0.18s"}})]}),t.jsx("div",{style:{height:14,width:52,borderRadius:3,background:"var(--color-rule, #E8E1D6)",animation:"fsp-pulse 1.4s ease-in-out infinite",animationDelay:"0.36s"}})]})}function Fe(i){var d,u;const p=(d=i.target)==null?void 0:d.tagName;return!!(p==="INPUT"||p==="TEXTAREA"||p==="SELECT"||(u=i.target)!=null&&u.isContentEditable)}const je="/api/v1/studio/search",we="/api/v1/stats",Ae="/api/v1/studio/telemetry/search-select",Re=10,Q=20,Ce=150;function Be({onSelect:i,onNavigate:p,searchUrl:d=je,trendingUrl:u=we,telemetrySelectUrl:T=Ae,maxPages:b=Re,initialOpen:W=!1}={}){const[L,E]=a.useState(W),[o,F]=a.useState(""),[I,h]=a.useState([]),[U,v]=a.useState(0),[j,B]=a.useState(!1),[_,w]=a.useState(1),[H,x]=a.useState(!1),[M,V]=a.useState(!1),[$,k]=a.useState(null),[A,R]=a.useState(!1),Z=a.useRef(null),N=a.useRef(null),z=a.useRef(!1),ee=a.useRef(null),te=a.useRef(null),q=a.useRef(new Map),S=a.useRef(null),[,ue]=a.useState(!1),re=a.useMemo(()=>typeof navigator<"u"&&/Mac|iPod|iPhone|iPad/.test(navigator.platform||""),[]),K=a.useRef(o);a.useEffect(()=>{K.current=o},[o]),a.useEffect(()=>{S.current||fetch(u).then(e=>e.json()).then(e=>{S.current=e.trendingSkills??[],ue(!0)}).catch(()=>{})},[u]),a.useEffect(()=>{const e=r=>{if(r.key==="Escape"){E(!1);return}if(L&&(r.metaKey||r.ctrlKey)&&/^[1-9]$/.test(r.key)){r.preventDefault();const s=Number(r.key)-1;v(s),window.dispatchEvent(new CustomEvent("findSkillsActivateAt",{detail:{index:s}}));return}!r.metaKey&&!r.ctrlKey&&!r.altKey&&r.key.length===1&&!Fe(r)&&(z.current=!0,F(r.key),E(!0))},n=r=>{var y;const l=(y=r.detail)==null?void 0:y.query;l&&(z.current=!0,F(l)),E(!0)};return window.addEventListener("keydown",e),window.addEventListener("openFindSkills",n),()=>{window.removeEventListener("keydown",e),window.removeEventListener("openFindSkills",n)}},[L]),a.useLayoutEffect(()=>{var n;if(!L){(n=N.current)==null||n.abort();return}if(z.current)z.current=!1,h([]),v(0),w(1),x(!1),B(!1),k(null),R(!1);else{const r=(()=>{var s;try{return((s=window.sessionStorage)==null?void 0:s.getItem("find-skills:last-query"))??""}catch{return""}})();F(r),h([]),v(0),w(1),x(!1),B(!1),k(null),R(!1)}const e=Z.current;if(e){e.focus({preventScroll:!0});const r=e.value.length;e.setSelectionRange(r,r)}},[L]),a.useEffect(()=>{if(!o.trim()||o.trim().length<2){h([]),x(!1),w(1),k(null);return}const e=6e4,n=o.trim().toLowerCase(),r=q.current.get(n);if(r&&Date.now()-r.timestamp<e){h(r.results),x(r.hasMore),w(1),B(!1),k(null),fetch(`${d}?q=${encodeURIComponent(o)}&limit=${Q}&page=1`).then(m=>m.ok?m.json():null).then(m=>{var g;m&&q.current.set(n,{results:m.results||[],hasMore:((g=m.pagination)==null?void 0:g.hasMore)??!1,timestamp:Date.now()})}).catch(()=>{});return}B(!0),k(null);const l=new AbortController,y=setTimeout(async()=>{var m;try{const g=await fetch(`${d}?q=${encodeURIComponent(o)}&limit=${Q}&page=1`,{signal:l.signal});if(g.status>=500){R(!0),h([]),x(!1),k(null);return}if(!g.ok){h([]),x(!1),k(`search failed (${g.status})`);return}const ce=await g.json(),de=ce.results||[],pe=((m=ce.pagination)==null?void 0:m.hasMore)??!1;h(de),x(pe),w(1),R(!1),q.current.set(n,{results:de,hasMore:pe,timestamp:Date.now()})}catch(g){if(g instanceof DOMException&&g.name==="AbortError")return;R(!0),h([]),x(!1),k(null)}finally{l.signal.aborted||B(!1)}},Ce);return()=>{clearTimeout(y),l.abort()}},[o,d]);const C=_>=b,ne=a.useCallback(async()=>{var n,r;if(M||C)return;const e=_+1;V(!0),N.current=new AbortController;try{const s=await fetch(`${d}?q=${encodeURIComponent(o)}&limit=${Q}&page=${e}`,{signal:N.current.signal});if(!s.ok)return;const l=await s.json();h(y=>[...y,...l.results||[]]),x(((n=l.pagination)==null?void 0:n.hasMore)??!1),w(e)}catch(s){if(s instanceof DOMException&&s.name==="AbortError")return}finally{(r=N.current)!=null&&r.signal.aborted||V(!1)}},[_,o,M,C,d]);a.useEffect(()=>{const e=ee.current,n=te.current;if(!e||!n||typeof IntersectionObserver>"u")return;const r=new IntersectionObserver(s=>{s[0].isIntersecting&&H&&!j&&!M&&!C&&ne()},{root:n,rootMargin:"100px"});return r.observe(e),()=>r.disconnect()},[H,j,M,C,ne]);const P=e=>({name:e.name,displayName:e.displayName,author:e.author,repoUrl:e.repoUrl,certTier:e.certTier,githubStars:0,highlight:"",category:"",ownerSlug:e.ownerSlug,repoSlug:e.repoSlug,skillSlug:e.skillSlug}),G=(()=>{const e=o.trim();if(A&&e.length>=1&&S.current){const n=e.toLowerCase();return S.current.filter(r=>r.name.toLowerCase().includes(n)||(r.displayName??"").toLowerCase().includes(n)).slice(0,30).map(P)}if(e.length>=2)return I;if(e.length===1&&S.current){const n=e.toLowerCase();return S.current.filter(r=>r.name.toLowerCase().startsWith(n)||r.displayName.toLowerCase().startsWith(n)).slice(0,10).map(P)}return e.length===0&&S.current?S.current.slice(0,10).map(P):[]})(),f=[...G.map(e=>{const n=e.skillSlug||e.name.split("/").pop()||e.name,r=e.ownerSlug&&e.repoSlug?`${e.ownerSlug}/${e.repoSlug}`:e.author;return{type:"skill",label:n,publisher:r,name:e.name,command:e.command?e.pluginName?`${e.pluginName}:${e.command}`:e.command:void 0,pluginName:e.pluginName||void 0,meta:e.category||"",certTier:e.certTier,isTainted:e.isTainted,isBlocked:e.isBlocked,repoUrl:e.repoUrl,highlight:e.highlight,githubStars:e.githubStars,category:e.category,href:ye(e.name),sourceResult:e}}),...!o&&G.length===0?ke.map(e=>({type:"category",label:e.label,publisher:"",name:"",meta:"",certTier:"",repoUrl:"",href:e.href})):[],...!o&&G.length===0?Se.map(e=>({type:"action",label:e.label,publisher:"",name:"",meta:"",certTier:"",repoUrl:"",href:e.href})):[]],ae=a.useCallback(e=>{try{fetch(T,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({skillName:e,q:K.current.trim(),ts:Date.now()}),keepalive:!0}).catch(()=>{})}catch{}},[T]),D=a.useCallback((e,n)=>{if(n&&(ae(n.name),i))try{i(n,K.current.trim())}catch{}if(E(!1),p)try{p(e)}catch{}},[i,p,ae]);a.useEffect(()=>{function e(n){var l;const r=((l=n.detail)==null?void 0:l.index)??-1,s=f[r];s&&D(s.href,s.type==="skill"?s.sourceResult:void 0)}return window.addEventListener("findSkillsActivateAt",e),()=>window.removeEventListener("findSkillsActivateAt",e)},[f,D]);const fe=e=>{if(e.key==="ArrowDown")e.preventDefault(),v(n=>Math.min(n+1,f.length-1));else if(e.key==="ArrowUp")e.preventDefault(),v(n=>Math.max(n-1,0));else if(e.key==="Enter"&&f[U]){const n=f[U];D(n.href,n.type==="skill"?n.sourceResult:void 0)}};if(!L)return null;let ie="";const se=!j&&!$&&!A&&o.trim().length>=2&&I.length===0,Y=j&&I.length===0&&o.trim().length>=2&&!A,oe=o.trim(),le=()=>{R(!1);const e=o;F(""),setTimeout(()=>F(e),0)},ge={position:"fixed",inset:0,background:"color-mix(in srgb, var(--color-ink, #191919) 35%, transparent)",backdropFilter:"blur(6px) saturate(1.1)",WebkitBackdropFilter:"blur(6px) saturate(1.1)"},he={position:"relative",width:"100%",maxWidth:640,margin:"0 16px",background:"var(--bg-surface, #FFFFFF)",color:"var(--text-primary, #191919)",borderRadius:12,border:"1px solid var(--color-rule, #E8E1D6)",boxShadow:"0 1px 0 rgba(255,255,255,0.6) inset,0 24px 60px -12px rgba(25,20,15,0.28),0 12px 24px -8px rgba(25,20,15,0.18)",overflow:"hidden",fontFamily:J};return t.jsxs("div",{"data-testid":"find-skills-palette",role:"dialog","aria-modal":"true","aria-label":"Find verified skills",style:{position:"fixed",inset:0,zIndex:9999,display:"flex",alignItems:"flex-start",justifyContent:"center",paddingTop:"min(18vh, 144px)"},onClick:()=>E(!1),children:[t.jsx("div",{style:ge}),t.jsx("style",{children:`
2
2
  @keyframes fsp-pulse {
3
3
  0%, 100% { opacity: 1; }
4
4
  50% { opacity: 0.45; }