opendevbrowser 0.0.21 → 0.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +12 -2
  2. package/dist/chunk-3ILXPKSJ.js +86 -0
  3. package/dist/chunk-3ILXPKSJ.js.map +1 -0
  4. package/dist/{chunk-4KVXCXV3.js → chunk-OGE5KJ4X.js} +10 -6
  5. package/dist/{chunk-4KVXCXV3.js.map → chunk-OGE5KJ4X.js.map} +1 -1
  6. package/dist/chunk-QVWOPIZJ.js +612 -0
  7. package/dist/chunk-QVWOPIZJ.js.map +1 -0
  8. package/dist/{chunk-3VA6XR25.js → chunk-STGGGVYT.js} +23 -100
  9. package/dist/chunk-STGGGVYT.js.map +1 -0
  10. package/dist/cli/commands/uninstall.d.ts +1 -0
  11. package/dist/cli/commands/uninstall.d.ts.map +1 -1
  12. package/dist/cli/index.js +249 -614
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/cli/installers/postinstall-skill-sync.d.ts +15 -0
  15. package/dist/cli/installers/postinstall-skill-sync.d.ts.map +1 -0
  16. package/dist/cli/installers/postinstall-skill-sync.js +48 -0
  17. package/dist/cli/installers/postinstall-skill-sync.js.map +1 -0
  18. package/dist/cli/installers/skills.d.ts +9 -14
  19. package/dist/cli/installers/skills.d.ts.map +1 -1
  20. package/dist/cli/skill-lifecycle.d.ts +26 -0
  21. package/dist/cli/skill-lifecycle.d.ts.map +1 -0
  22. package/dist/cli/update-skill-modes.d.ts +3 -0
  23. package/dist/cli/update-skill-modes.d.ts.map +1 -0
  24. package/dist/index.js +3 -2
  25. package/dist/index.js.map +1 -1
  26. package/dist/opendevbrowser.js +3 -2
  27. package/dist/opendevbrowser.js.map +1 -1
  28. package/dist/public-surface/generated-manifest.d.ts +3 -3
  29. package/dist/public-surface/generated-manifest.d.ts.map +1 -1
  30. package/dist/public-surface/source.d.ts +4 -4
  31. package/dist/skills/skill-loader.js +2 -1
  32. package/extension/manifest.json +1 -1
  33. package/package.json +6 -4
  34. package/scripts/postinstall-sync-skills.mjs +33 -0
  35. package/dist/chunk-3VA6XR25.js.map +0 -1
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { CommandHelpDetail, PublicSurfaceCliCommandGroupDefinition, PublicSurfaceCliCommandName, PublicSurfaceFlagName, ToolSurfaceEntry } from "./source";
6
6
  export declare const PUBLIC_SURFACE_MANIFEST_SCHEMA_VERSION: "2026-04-04";
7
- export declare const PUBLIC_SURFACE_MANIFEST_GENERATED_AT: "2026-04-17T01:10:55.127Z";
7
+ export declare const PUBLIC_SURFACE_MANIFEST_GENERATED_AT: "2026-04-20T04:16:59.279Z";
8
8
  export declare const PUBLIC_SURFACE_MANIFEST: {
9
9
  schemaVersion: string;
10
10
  generatedAt: string;
@@ -87,7 +87,7 @@ export declare const PUBLIC_SURFACE_MANIFEST: {
87
87
  name: "update";
88
88
  description: string;
89
89
  usage: string;
90
- flags: ("--global" | "--local")[];
90
+ flags: ("--global" | "--local" | "--skills-global" | "--skills-local" | "--no-skills")[];
91
91
  groupId: string;
92
92
  groupTitle: string;
93
93
  groupSummary: string;
@@ -95,7 +95,7 @@ export declare const PUBLIC_SURFACE_MANIFEST: {
95
95
  name: "uninstall";
96
96
  description: string;
97
97
  usage: string;
98
- flags: ("--global" | "--local" | "--no-prompt" | "--quiet")[];
98
+ flags: ("--global" | "--local" | "--no-prompt" | "--quiet" | "--no-skills")[];
99
99
  groupId: string;
100
100
  groupTitle: string;
101
101
  groupSummary: string;
@@ -1 +1 @@
1
- {"version":3,"file":"generated-manifest.d.ts","sourceRoot":"","sources":["../../src/public-surface/generated-manifest.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,sCAAsC,EACtC,2BAA2B,EAC3B,qBAAqB,EAErB,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAElB,eAAO,MAAM,sCAAsC,EAAG,YAAqB,CAAC;AAC5E,eAAO,MAAM,oCAAoC,EAAG,0BAAmC,CAAC;AAExF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA07EH,CAAC;AAElC,eAAO,MAAM,WAAW,EAAiE,qBAAqB,EAAE,CAAC;AACjH,eAAO,MAAM,kBAAkB,EAAmD,qBAAqB,EAAE,CAAC;AAC1G,eAAO,MAAM,YAAY,EAA0E,2BAA2B,EAAE,CAAC;AAEjI,eAAO,MAAM,wBAAwB,EASrB,MAAM,CAAC,2BAA2B,EAAE,iBAAiB,CAAC,CAAC;AAgBvE,eAAO,MAAM,yBAAyB,EAK/B,SAAS,sCAAsC,EAAE,CAAC;AAEzD,eAAO,MAAM,oBAAoB,EAI1B,SAAS,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"generated-manifest.d.ts","sourceRoot":"","sources":["../../src/public-surface/generated-manifest.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,sCAAsC,EACtC,2BAA2B,EAC3B,qBAAqB,EAErB,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAElB,eAAO,MAAM,sCAAsC,EAAG,YAAqB,CAAC;AAC5E,eAAO,MAAM,oCAAoC,EAAG,0BAAmC,CAAC;AAExF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA87EH,CAAC;AAElC,eAAO,MAAM,WAAW,EAAiE,qBAAqB,EAAE,CAAC;AACjH,eAAO,MAAM,kBAAkB,EAAmD,qBAAqB,EAAE,CAAC;AAC1G,eAAO,MAAM,YAAY,EAA0E,2BAA2B,EAAE,CAAC;AAEjI,eAAO,MAAM,wBAAwB,EASrB,MAAM,CAAC,2BAA2B,EAAE,iBAAiB,CAAC,CAAC;AAgBvE,eAAO,MAAM,yBAAyB,EAK/B,SAAS,sCAAsC,EAAE,CAAC;AAEzD,eAAO,MAAM,oBAAoB,EAI1B,SAAS,gBAAgB,EAAE,CAAC"}
@@ -31,13 +31,13 @@ export declare const PUBLIC_CLI_COMMAND_GROUPS: readonly [{
31
31
  }, {
32
32
  readonly name: "update";
33
33
  readonly description: "Clear cached plugin and refresh managed skill packs";
34
- readonly usage: "npx opendevbrowser update [--global|--local]";
35
- readonly flags: readonly ["--global", "--local"];
34
+ readonly usage: "npx opendevbrowser update [--global|--local] [--skills-global|--skills-local|--no-skills]";
35
+ readonly flags: readonly ["--global", "--local", "--skills-global", "--skills-local", "--no-skills"];
36
36
  }, {
37
37
  readonly name: "uninstall";
38
38
  readonly description: "Remove plugin from config and clean managed skill packs";
39
- readonly usage: "npx opendevbrowser uninstall [--global|--local] [--no-prompt] [--quiet]";
40
- readonly flags: readonly ["--global", "--local", "--no-prompt", "--quiet"];
39
+ readonly usage: "npx opendevbrowser uninstall [--global|--local] [--no-skills] [--no-prompt] [--quiet]";
40
+ readonly flags: readonly ["--global", "--local", "--no-skills", "--no-prompt", "--quiet"];
41
41
  }, {
42
42
  readonly name: "help";
43
43
  readonly description: "Show help";
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  SkillLoader
3
- } from "../chunk-3VA6XR25.js";
3
+ } from "../chunk-STGGGVYT.js";
4
+ import "../chunk-3ILXPKSJ.js";
4
5
  export {
5
6
  SkillLoader
6
7
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "OpenDevBrowser Relay",
4
- "version": "0.0.21",
4
+ "version": "0.0.22",
5
5
  "description": "Optional bridge to reuse existing Chrome tabs with OpenDevBrowser.",
6
6
  "permissions": [
7
7
  "debugger",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opendevbrowser",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "description": "Browser automation runtime with snapshot-refs-actions, browser replay screencasts, public read-only desktop observation, and browser-scoped computer-use orchestration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,6 +11,7 @@
11
11
  "files": [
12
12
  "dist",
13
13
  "skills",
14
+ "scripts/postinstall-sync-skills.mjs",
14
15
  "scripts/native",
15
16
  "extension/canvas.html",
16
17
  "extension/manifest.json",
@@ -45,8 +46,8 @@
45
46
  "node": ">=18"
46
47
  },
47
48
  "scripts": {
48
- "build": "node scripts/run-package-tool.mjs tsup src/index.ts src/cli/index.ts src/skills/skill-loader.ts --format esm --clean --sourcemap && node scripts/run-package-tool.mjs tsc --emitDeclarationOnly --declaration --declarationMap -p tsconfig.json && node scripts/postbuild-dist.mjs",
49
- "dev": "tsup src/index.ts src/cli/index.ts src/skills/skill-loader.ts --format esm --dts --watch",
49
+ "build": "node scripts/run-package-tool.mjs tsup src/index.ts src/cli/index.ts src/cli/installers/postinstall-skill-sync.ts src/skills/skill-loader.ts --format esm --clean --sourcemap && node scripts/run-package-tool.mjs tsc --emitDeclarationOnly --declaration --declarationMap -p tsconfig.json && node scripts/postbuild-dist.mjs",
50
+ "dev": "tsup src/index.ts src/cli/index.ts src/cli/installers/postinstall-skill-sync.ts src/skills/skill-loader.ts --format esm --dts --watch",
50
51
  "lint": "node scripts/run-package-tool.mjs eslint \"src/**/*.ts\" \"tests/**/*.ts\"",
51
52
  "typecheck": "node scripts/run-package-tool.mjs tsc --noEmit -p tsconfig.json",
52
53
  "test": "node scripts/run-vitest-coverage.mjs",
@@ -61,7 +62,8 @@
61
62
  "extension:pack": "cd extension && zip -r ../opendevbrowser-extension.zip manifest.json popup.html canvas.html dist/ icons/",
62
63
  "extension:store": "node scripts/chrome-store-publish.mjs",
63
64
  "version:check": "node scripts/verify-versions.mjs",
64
- "prepack": "npm run version:check && npm run build && npm run extension:build"
65
+ "prepack": "npm run version:check && npm run build && npm run extension:build",
66
+ "postinstall": "node scripts/postinstall-sync-skills.mjs"
65
67
  },
66
68
  "dependencies": {
67
69
  "@opencode-ai/plugin": "^1.2.25",
@@ -0,0 +1,33 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import { fileURLToPath, pathToFileURL } from "url";
4
+
5
+ const scriptDir = path.dirname(fileURLToPath(import.meta.url));
6
+ const packageRoot = path.resolve(scriptDir, "..");
7
+
8
+ if (process.env.OPDEVBROWSER_SKIP_POSTINSTALL_SKILL_SYNC === "1") {
9
+ process.exit(0);
10
+ }
11
+
12
+ if (fs.existsSync(path.join(packageRoot, ".git"))) {
13
+ process.exit(0);
14
+ }
15
+
16
+ const entryPath = path.join(packageRoot, "dist", "cli", "installers", "postinstall-skill-sync.js");
17
+
18
+ if (!fs.existsSync(entryPath)) {
19
+ console.warn("[opendevbrowser] postinstall skill sync skipped: built installer entry missing.");
20
+ process.exit(0);
21
+ }
22
+
23
+ try {
24
+ const { runPostinstallSkillSync } = await import(pathToFileURL(entryPath).href);
25
+ const result = runPostinstallSkillSync();
26
+
27
+ if (!result.success || result.skipped) {
28
+ console.warn(`[opendevbrowser] ${result.message}`);
29
+ }
30
+ } catch (error) {
31
+ const message = error instanceof Error ? error.message : String(error);
32
+ console.warn(`[opendevbrowser] postinstall skill sync failed: ${message}`);
33
+ }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/skills/skill-loader.ts","../src/utils/package-assets.ts","../src/skills/bundled-skill-directories.ts"],"sourcesContent":["import { readFile, readdir } from \"fs/promises\";\nimport { join } from \"path\";\nimport * as os from \"os\";\nimport type {\n SkillAlternative,\n SkillDiscoveryIssue,\n SkillDiscoveryReport,\n SkillInfo,\n SkillMetadata,\n SkillSearchPath\n} from \"./types\";\nimport { findBundledSkillsDir } from \"../utils/package-assets\";\nimport { isBundledSkillName } from \"./bundled-skill-directories\";\n\nexport class SkillLoader {\n private rootDir: string;\n private additionalPaths: string[];\n private bundledSkillsDir: string | null;\n private discoveryReportCache: SkillDiscoveryReport | null = null;\n private skillCache: SkillInfo[] | null = null;\n\n constructor(rootDir: string, additionalPaths: string[] = []) {\n this.rootDir = rootDir;\n this.additionalPaths = additionalPaths.map((p) => this.expandPath(p));\n this.bundledSkillsDir = findBundledSkillsDir();\n }\n\n private expandPath(p: string): string {\n if (p.startsWith(\"~\")) {\n return join(os.homedir(), p.slice(1));\n }\n return p;\n }\n\n private getCodexHome(): string {\n return process.env.CODEX_HOME || join(os.homedir(), \".codex\");\n }\n\n private getClaudeCodeHome(): string {\n return process.env.CLAUDECODE_HOME || join(os.homedir(), \".claude\");\n }\n\n private getAmpHome(): string {\n return process.env.AMP_CLI_HOME || join(os.homedir(), \".amp\");\n }\n\n async loadBestPractices(topic?: string): Promise<string> {\n return this.loadSkill(\"opendevbrowser-best-practices\", topic);\n }\n\n async loadSkill(name: string, topic?: string): Promise<string> {\n const skills = await this.listSkills();\n const skill = skills.find((s) => s.name === name);\n\n if (!skill) {\n const available = skills.map((s) => s.name).join(\", \") || \"none\";\n throw new Error(`Skill \"${name}\" not found. Available: ${available}`);\n }\n\n const content = await readFile(skill.path, \"utf8\");\n const trimmed = content.trim();\n\n if (!topic || !topic.trim()) {\n return trimmed;\n }\n\n const filtered = filterSections(trimmed, topic);\n return filtered || trimmed;\n }\n\n async listSkills(): Promise<SkillInfo[]> {\n if (this.skillCache) {\n return this.skillCache;\n }\n\n const report = await this.getDiscoveryReport();\n this.skillCache = report.skills;\n return report.skills;\n }\n\n async getDiscoveryReport(): Promise<SkillDiscoveryReport> {\n if (this.discoveryReportCache) {\n return this.discoveryReportCache;\n }\n\n const skills: SkillInfo[] = [];\n const issues: SkillDiscoveryIssue[] = [];\n const byName = new Map<string, SkillInfo>();\n const searchPaths = this.getSearchPaths();\n\n for (const searchPath of searchPaths) {\n const discovered = await this.discoverSkillsInPath(searchPath);\n issues.push(...discovered.issues);\n for (const skill of discovered.skills) {\n const alternative = this.toAlternative(skill);\n const existing = byName.get(skill.name);\n if (!existing) {\n const winner: SkillInfo = {\n ...skill,\n shadowedAlternatives: []\n };\n byName.set(skill.name, winner);\n skills.push(winner);\n continue;\n }\n existing.shadowedAlternatives?.push(alternative);\n }\n }\n\n this.discoveryReportCache = {\n skills,\n issues,\n searchOrder: searchPaths\n };\n this.skillCache = skills;\n return this.discoveryReportCache;\n }\n\n private getSearchPaths(): SkillSearchPath[] {\n const configDir = process.env.OPENCODE_CONFIG_DIR\n || join(os.homedir(), \".config\", \"opencode\");\n\n const searchPaths: SkillSearchPath[] = [\n {\n path: join(this.rootDir, \".opencode\", \"skill\"),\n sourceFamily: \"project-opencode\",\n isBundled: false\n },\n {\n path: join(configDir, \"skill\"),\n sourceFamily: \"global-opencode\",\n isBundled: false\n },\n {\n path: join(this.rootDir, \".codex\", \"skills\"),\n sourceFamily: \"project-codex\",\n isBundled: false\n },\n {\n path: join(this.getCodexHome(), \"skills\"),\n sourceFamily: \"global-codex\",\n isBundled: false\n },\n {\n path: join(this.rootDir, \".claude\", \"skills\"),\n sourceFamily: \"project-claudecode\",\n isBundled: false\n },\n {\n path: join(this.getClaudeCodeHome(), \"skills\"),\n sourceFamily: \"global-claudecode\",\n isBundled: false\n },\n {\n path: join(this.rootDir, \".amp\", \"skills\"),\n sourceFamily: \"project-ampcli\",\n isBundled: false\n },\n {\n path: join(this.getAmpHome(), \"skills\"),\n sourceFamily: \"global-ampcli\",\n isBundled: false\n },\n ...this.additionalPaths.map((path) => ({\n path,\n sourceFamily: \"custom\" as const,\n isBundled: false\n })),\n ...(this.bundledSkillsDir\n ? [{\n path: this.bundledSkillsDir,\n sourceFamily: \"bundled\" as const,\n isBundled: true\n }]\n : [])\n ];\n\n const uniquePaths = new Set<string>();\n return searchPaths.filter((entry) => {\n if (uniquePaths.has(entry.path)) {\n return false;\n }\n uniquePaths.add(entry.path);\n return true;\n });\n }\n\n private async discoverSkillsInPath(searchPath: SkillSearchPath): Promise<{\n skills: SkillInfo[];\n issues: SkillDiscoveryIssue[];\n }> {\n const skills: SkillInfo[] = [];\n const issues: SkillDiscoveryIssue[] = [];\n\n try {\n const entries = await readdir(searchPath.path, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (searchPath.isBundled) {\n if (!isBundledSkillName(entry.name)) {\n continue;\n }\n }\n\n const skillPath = join(searchPath.path, entry.name, \"SKILL.md\");\n try {\n const content = await readFile(skillPath, \"utf8\");\n const metadata = this.parseSkillMetadata(content, entry.name);\n if (metadata.name !== entry.name) {\n issues.push({\n kind: \"skill_entry\",\n code: \"metadata_name_mismatch\",\n detail: `Frontmatter name \"${metadata.name}\" does not match directory \"${entry.name}\".`,\n searchPath: searchPath.path,\n sourceFamily: searchPath.sourceFamily,\n dirName: entry.name,\n skillPath\n });\n }\n\n skills.push({\n name: metadata.name,\n description: metadata.description,\n version: metadata.version ?? \"1.0.0\",\n path: skillPath,\n searchPath: searchPath.path,\n sourceFamily: searchPath.sourceFamily,\n isBundled: searchPath.isBundled,\n shadowedAlternatives: []\n });\n } catch (error) {\n issues.push(this.createDiscoveryIssue(searchPath, entry.name, skillPath, error));\n }\n }\n } catch (error) {\n if (this.readErrorCode(error) !== \"ENOENT\") {\n issues.push(this.createSearchPathIssue(searchPath, error));\n }\n }\n\n return { skills, issues };\n }\n\n parseSkillMetadata(content: string, dirName: string): SkillMetadata {\n const frontmatterMatch = content.match(/^---\\s*\\n([\\s\\S]*?)\\n---/);\n\n if (!frontmatterMatch) {\n return {\n name: dirName,\n description: this.extractFirstParagraph(content) || `Skill: ${dirName}`\n };\n }\n\n const frontmatter = frontmatterMatch[1] || \"\";\n const metadata: SkillMetadata = {\n name: dirName,\n description: \"\"\n };\n\n const nameMatch = frontmatter.match(/^name:\\s*[\"']?([^\"'\\n]+)[\"']?\\s*$/m);\n if (nameMatch?.[1]) {\n metadata.name = nameMatch[1].trim();\n }\n\n const descMatch = frontmatter.match(/^description:\\s*[\"']?([^\"'\\n]+)[\"']?\\s*$/m);\n if (descMatch?.[1]) {\n metadata.description = descMatch[1].trim();\n }\n\n const versionMatch = frontmatter.match(/^version:\\s*[\"']?([^\"'\\n]+)[\"']?\\s*$/m);\n if (versionMatch?.[1]) {\n metadata.version = versionMatch[1].trim();\n }\n\n if (!metadata.description) {\n const afterFrontmatter = content.slice(frontmatterMatch[0].length);\n metadata.description = this.extractFirstParagraph(afterFrontmatter) || `Skill: ${metadata.name}`;\n }\n\n return metadata;\n }\n\n private extractFirstParagraph(content: string): string | null {\n const lines = content.trim().split(/\\n/);\n const paragraphLines: string[] = [];\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n if (trimmedLine.startsWith(\"#\")) continue;\n if (trimmedLine === \"\" && paragraphLines.length > 0) break;\n if (trimmedLine !== \"\") {\n paragraphLines.push(trimmedLine);\n }\n }\n\n const paragraph = paragraphLines.join(\" \").trim();\n return paragraph.length > 0 ? paragraph.slice(0, 200) : null;\n }\n\n clearCache(): void {\n this.discoveryReportCache = null;\n this.skillCache = null;\n }\n\n private createSearchPathIssue(searchPath: SkillSearchPath, error: unknown): SkillDiscoveryIssue {\n return {\n kind: \"search_path\",\n code: this.readErrorCode(error),\n detail: this.readErrorDetail(error),\n searchPath: searchPath.path,\n sourceFamily: searchPath.sourceFamily\n };\n }\n\n private createDiscoveryIssue(\n searchPath: SkillSearchPath,\n dirName: string,\n skillPath: string,\n error: unknown\n ): SkillDiscoveryIssue {\n return {\n kind: \"skill_entry\",\n code: this.readErrorCode(error),\n detail: this.readErrorDetail(error),\n searchPath: searchPath.path,\n sourceFamily: searchPath.sourceFamily,\n dirName,\n skillPath\n };\n }\n\n private readErrorCode(error: unknown): string {\n if (error && typeof error === \"object\" && \"code\" in error && typeof error.code === \"string\") {\n return error.code;\n }\n return \"unknown\";\n }\n\n private readErrorDetail(error: unknown): string {\n if (error instanceof Error && error.message.trim().length > 0) {\n return error.message;\n }\n return String(error);\n }\n\n private toAlternative(skill: SkillInfo): SkillAlternative {\n return {\n name: skill.name,\n path: skill.path,\n searchPath: skill.searchPath ?? \"\",\n sourceFamily: skill.sourceFamily ?? \"custom\",\n isBundled: skill.isBundled ?? false\n };\n }\n}\n\nfunction filterSections(content: string, topic: string): string | null {\n const normalized = topic.trim().toLowerCase();\n const lines = content.split(/\\r?\\n/);\n const sections: Array<{ heading: string; body: string[] }> = [];\n let currentHeading = \"\";\n let currentBody: string[] = [];\n\n const flush = () => {\n if (currentHeading || currentBody.length > 0) {\n sections.push({ heading: currentHeading, body: [...currentBody] });\n }\n currentHeading = \"\";\n currentBody = [];\n };\n\n for (const line of lines) {\n const headingMatch = line.match(/^(#{1,3})\\s+(.*)$/);\n if (headingMatch) {\n flush();\n currentHeading = (headingMatch[2] || \"\").trim();\n currentBody.push(line);\n continue;\n }\n currentBody.push(line);\n }\n flush();\n\n const matches = sections.filter((section) => section.heading.toLowerCase().includes(normalized));\n if (matches.length === 0) {\n return null;\n }\n return matches.map((section) => section.body.join(\"\\n\")).join(\"\\n\\n\");\n}\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { fileURLToPath } from \"url\";\n\nconst PACKAGE_NAME = \"opendevbrowser\";\nconst SKILLS_DIR_NAME = \"skills\";\n\nlet cachedPackageRoot: string | null = null;\n\nfunction findPackageRoot(startDir: string): string | null {\n let current = startDir;\n\n while (true) {\n const pkgPath = path.join(current, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n try {\n const parsed = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\")) as { name?: string };\n if (parsed.name === PACKAGE_NAME) {\n return current;\n }\n } catch {\n void 0;\n }\n }\n\n const parent = path.dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n\n return null;\n}\n\nexport function getPackageRoot(): string {\n if (cachedPackageRoot) {\n return cachedPackageRoot;\n }\n const moduleDir = path.dirname(fileURLToPath(import.meta.url));\n const packageRoot = findPackageRoot(moduleDir);\n if (!packageRoot) {\n throw new Error(`Unable to locate ${PACKAGE_NAME} package root.`);\n }\n cachedPackageRoot = packageRoot;\n return cachedPackageRoot;\n}\n\nexport function findBundledSkillsDir(): string | null {\n try {\n const skillsDir = path.join(getPackageRoot(), SKILLS_DIR_NAME);\n return fs.existsSync(skillsDir) ? skillsDir : null;\n } catch {\n return null;\n }\n}\n\nexport function getBundledSkillsDir(): string {\n const skillsDir = findBundledSkillsDir();\n if (!skillsDir) {\n throw new Error(`Bundled skills directory not found in ${PACKAGE_NAME} package.`);\n }\n return skillsDir;\n}\n","export interface BundledSkillDirectory {\n name: string;\n}\n\nexport const bundledSkillDirectories: BundledSkillDirectory[] = [\n { name: \"opendevbrowser-best-practices\" },\n { name: \"opendevbrowser-continuity-ledger\" },\n { name: \"opendevbrowser-data-extraction\" },\n { name: \"opendevbrowser-design-agent\" },\n { name: \"opendevbrowser-form-testing\" },\n { name: \"opendevbrowser-login-automation\" },\n { name: \"opendevbrowser-product-presentation-asset\" },\n { name: \"opendevbrowser-research\" },\n { name: \"opendevbrowser-shopping\" }\n];\n\nconst bundledSkillDirectoryByName = new Map(\n bundledSkillDirectories.map((entry) => [entry.name, entry] as const)\n);\n\nexport function listBundledSkillDirectories(): BundledSkillDirectory[] {\n return [...bundledSkillDirectories];\n}\n\nexport function getBundledSkillDirectory(name: string): BundledSkillDirectory | null {\n return bundledSkillDirectoryByName.get(name) ?? null;\n}\n\nexport function isBundledSkillName(name: string): boolean {\n return bundledSkillDirectoryByName.has(name);\n}\n"],"mappings":"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","names":["join","join","path"]}