skill-creator 1.5.2 → 2.0.1

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 (140) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/LICENSE +21 -0
  3. package/README.md +248 -345
  4. package/dist/cli.js +51209 -0
  5. package/dist/cli.js.map +7 -0
  6. package/dist/daemon.js +52243 -0
  7. package/dist/daemon.js.map +7 -0
  8. package/dist/package.json +5 -0
  9. package/dist/webui/_app/immutable/assets/0.0XN00VKF.css +2 -0
  10. package/dist/webui/_app/immutable/assets/ProviderView.DEH95hqa.css +1 -0
  11. package/dist/webui/_app/immutable/assets/inter-cyrillic-ext-wght-normal.BOeWTOD4.woff2 +0 -0
  12. package/dist/webui/_app/immutable/assets/inter-cyrillic-wght-normal.DqGufNeO.woff2 +0 -0
  13. package/dist/webui/_app/immutable/assets/inter-greek-ext-wght-normal.DlzME5K_.woff2 +0 -0
  14. package/dist/webui/_app/immutable/assets/inter-greek-wght-normal.CkhJZR-_.woff2 +0 -0
  15. package/dist/webui/_app/immutable/assets/inter-latin-ext-wght-normal.DO1Apj_S.woff2 +0 -0
  16. package/dist/webui/_app/immutable/assets/inter-latin-wght-normal.Dx4kXJAl.woff2 +0 -0
  17. package/dist/webui/_app/immutable/assets/inter-vietnamese-wght-normal.CBcvBZtf.woff2 +0 -0
  18. package/dist/webui/_app/immutable/assets/shell.U4CQV8re.css +1 -0
  19. package/dist/webui/_app/immutable/chunks/0umLG1IN.js +1 -0
  20. package/dist/webui/_app/immutable/chunks/B0pe_B_o.js +1 -0
  21. package/dist/webui/_app/immutable/chunks/BEPs9Z9s.js +1 -0
  22. package/dist/webui/_app/immutable/chunks/BEsyQXpe.js +1 -0
  23. package/dist/webui/_app/immutable/chunks/BIfnT_mK.js +1 -0
  24. package/dist/webui/_app/immutable/chunks/BQ8kO0xi.js +2 -0
  25. package/dist/webui/_app/immutable/chunks/BYNWtKcf.js +259 -0
  26. package/dist/webui/_app/immutable/chunks/BZ2Jwl6O.js +1 -0
  27. package/dist/webui/_app/immutable/chunks/Bg2k7op5.js +1 -0
  28. package/dist/webui/_app/immutable/chunks/Bjy-W4x2.js +81 -0
  29. package/dist/webui/_app/immutable/chunks/BkEnd9_Z.js +1 -0
  30. package/dist/webui/_app/immutable/chunks/BoMQFGOq.js +52 -0
  31. package/dist/webui/_app/immutable/chunks/Bs27XW8_.js +1 -0
  32. package/dist/webui/_app/immutable/chunks/C3mlWJXx.js +1 -0
  33. package/dist/webui/_app/immutable/chunks/CGrKeCdk.js +8 -0
  34. package/dist/webui/_app/immutable/chunks/CIFG41pU.js +1 -0
  35. package/dist/webui/_app/immutable/chunks/CNPsST_i.js +1 -0
  36. package/dist/webui/_app/immutable/chunks/COoMyR0G.js +1 -0
  37. package/dist/webui/_app/immutable/chunks/CQD9uzpA.js +1 -0
  38. package/dist/webui/_app/immutable/chunks/CeR4do8T.js +1 -0
  39. package/dist/webui/_app/immutable/chunks/Ckw1quWt.js +1 -0
  40. package/dist/webui/_app/immutable/chunks/CmCJ0SKP.js +3 -0
  41. package/dist/webui/_app/immutable/chunks/CqzSRtkf.js +1 -0
  42. package/dist/webui/_app/immutable/chunks/CsaIfA9E.js +1 -0
  43. package/dist/webui/_app/immutable/chunks/D-Jy42mM.js +1 -0
  44. package/dist/webui/_app/immutable/chunks/D-V0xBeS.js +1 -0
  45. package/dist/webui/_app/immutable/chunks/D8Der6oM.js +1 -0
  46. package/dist/webui/_app/immutable/chunks/DPrjly2t.js +1 -0
  47. package/dist/webui/_app/immutable/chunks/DZ_Kltd5.js +1 -0
  48. package/dist/webui/_app/immutable/chunks/DecrR9TK.js +1 -0
  49. package/dist/webui/_app/immutable/chunks/Dl8eQ129.js +5 -0
  50. package/dist/webui/_app/immutable/chunks/Dnkino9G.js +1 -0
  51. package/dist/webui/_app/immutable/chunks/FuwccWbx.js +1 -0
  52. package/dist/webui/_app/immutable/chunks/HclGiUj8.js +1 -0
  53. package/dist/webui/_app/immutable/chunks/J36u8XLO.js +1 -0
  54. package/dist/webui/_app/immutable/chunks/JcDjicYT.js +1 -0
  55. package/dist/webui/_app/immutable/chunks/O2CEZ91h.js +1 -0
  56. package/dist/webui/_app/immutable/chunks/UeEccMjN.js +1 -0
  57. package/dist/webui/_app/immutable/chunks/Y--VMh3y.js +1 -0
  58. package/dist/webui/_app/immutable/chunks/gkPAnPzC.js +3 -0
  59. package/dist/webui/_app/immutable/chunks/r1y9r7sj.js +2 -0
  60. package/dist/webui/_app/immutable/chunks/s48N5eaK.js +67 -0
  61. package/dist/webui/_app/immutable/chunks/xihTtKlq.js +1 -0
  62. package/dist/webui/_app/immutable/entry/app.BisiObvX.js +2 -0
  63. package/dist/webui/_app/immutable/entry/start.uEYh5tXy.js +1 -0
  64. package/dist/webui/_app/immutable/nodes/0.C8yGM2gr.js +231 -0
  65. package/dist/webui/_app/immutable/nodes/1.BUJKZ337.js +1 -0
  66. package/dist/webui/_app/immutable/nodes/2.Db-aM2Oa.js +1 -0
  67. package/dist/webui/_app/immutable/nodes/3.DCVfhckZ.js +1 -0
  68. package/dist/webui/_app/version.json +1 -0
  69. package/dist/webui/icons/app-icon/darwin-dark.icns +0 -0
  70. package/dist/webui/icons/app-icon/darwin-light.icns +0 -0
  71. package/dist/webui/icons/app-icon/win32-dark.ico +0 -0
  72. package/dist/webui/icons/app-icon/win32-light.ico +0 -0
  73. package/dist/webui/icons/app-icon.icns +0 -0
  74. package/dist/webui/icons/app-icon.ico +0 -0
  75. package/dist/webui/icons/app-icon.json +84 -0
  76. package/dist/webui/icons/app-icon.png +0 -0
  77. package/dist/webui/icons/flat-symbol.png +0 -0
  78. package/dist/webui/icons/linux/128x128/app-icon.png +0 -0
  79. package/dist/webui/icons/linux/16x16/app-icon.png +0 -0
  80. package/dist/webui/icons/linux/256x256/app-icon.png +0 -0
  81. package/dist/webui/icons/linux/32x32/app-icon.png +0 -0
  82. package/dist/webui/icons/linux/48x48/app-icon.png +0 -0
  83. package/dist/webui/icons/linux/512x512/app-icon.png +0 -0
  84. package/dist/webui/icons/linux/64x64/app-icon.png +0 -0
  85. package/dist/webui/icons/monochrome-mini.png +0 -0
  86. package/dist/webui/index.html +62 -0
  87. package/dist/webui/robots.txt +3 -0
  88. package/package.json +99 -73
  89. package/dist/buildIndex-B_9ABRtx.mjs +0 -2
  90. package/dist/buildIndex-B_9ABRtx.mjs.map +0 -1
  91. package/dist/buildIndex-Cea97e0l.mjs +0 -1
  92. package/dist/cli.d.mts +0 -1016
  93. package/dist/cli.d.mts.map +0 -1
  94. package/dist/cli.mjs +0 -20
  95. package/dist/cli.mjs.map +0 -1
  96. package/dist/contentManager-CoVTiSDT.mjs +0 -13
  97. package/dist/contentManager-CoVTiSDT.mjs.map +0 -1
  98. package/dist/contentManager-CwquwC1s.mjs +0 -1
  99. package/dist/context7-BejCCqkm.mjs +0 -1
  100. package/dist/context7-BxMpyQiW.mjs +0 -2
  101. package/dist/context7-BxMpyQiW.mjs.map +0 -1
  102. package/dist/index.d.mts +0 -2158
  103. package/dist/index.d.mts.map +0 -1
  104. package/dist/index.mjs +0 -2
  105. package/dist/index.mjs.map +0 -1
  106. package/dist/listContext7-DHj9AL-z.mjs +0 -2
  107. package/dist/listContext7-DHj9AL-z.mjs.map +0 -1
  108. package/dist/package-CFJazwTO.mjs +0 -2
  109. package/dist/package-CFJazwTO.mjs.map +0 -1
  110. package/dist/referenceSearchUtils-DZgupMZp.mjs +0 -2
  111. package/dist/referenceSearchUtils-DZgupMZp.mjs.map +0 -1
  112. package/dist/removeContext7-BZtL4_CJ.mjs +0 -3
  113. package/dist/removeContext7-BZtL4_CJ.mjs.map +0 -1
  114. package/dist/removeSkill-Bat_plVG.mjs +0 -5
  115. package/dist/removeSkill-Bat_plVG.mjs.map +0 -1
  116. package/dist/removeSkill-DjDZjhJU.mjs +0 -1
  117. package/dist/runScript-CSKqb831.mjs +0 -13
  118. package/dist/runScript-CSKqb831.mjs.map +0 -1
  119. package/dist/scopeSelection-BWteJQSv.mjs +0 -2
  120. package/dist/scopeSelection-BWteJQSv.mjs.map +0 -1
  121. package/dist/searchQuality-DVdHmamh.mjs +0 -2
  122. package/dist/searchQuality-DVdHmamh.mjs.map +0 -1
  123. package/dist/search_format-RyjXACJa.mjs +0 -5
  124. package/dist/search_format-RyjXACJa.mjs.map +0 -1
  125. package/dist/shared-DsVh4gOV.mjs +0 -2
  126. package/dist/shared-DsVh4gOV.mjs.map +0 -1
  127. package/dist/skillCreator-BomXoqdw.mjs +0 -2
  128. package/dist/skillCreator-BomXoqdw.mjs.map +0 -1
  129. package/dist/skillMdManager-DGBZ6M5J.mjs +0 -7
  130. package/dist/skillMdManager-DGBZ6M5J.mjs.map +0 -1
  131. package/dist/sqliteVectorSearchAdapter-56kZjbUT.mjs +0 -28
  132. package/dist/sqliteVectorSearchAdapter-56kZjbUT.mjs.map +0 -1
  133. package/dist/sqliteVectorSearchAdapter-DNkyKuZs.mjs +0 -1
  134. package/dist/unifiedSearch-CLdazMYU.mjs +0 -4
  135. package/dist/unifiedSearch-CLdazMYU.mjs.map +0 -1
  136. package/dist/unifiedSearch-DCFPrtzZ.mjs +0 -1
  137. package/templates/SKILL.md +0 -56
  138. package/templates/SKILL.zh-CN.md +0 -339
  139. package/templates/skill-creator.md +0 -130
  140. package/templates/skill-creator.zh-CN.md +0 -133
package/dist/index.mjs DELETED
@@ -1,2 +0,0 @@
1
- import{n as e,r as t,t as n}from"./unifiedSearch-CLdazMYU.mjs";import{t as r}from"./package-CFJazwTO.mjs";import{t as i}from"./skillCreator-BomXoqdw.mjs";import"./referenceSearchUtils-DZgupMZp.mjs";import{t as a}from"./sqliteVectorSearchAdapter-56kZjbUT.mjs";import"./searchQuality-DVdHmamh.mjs";import"./search_format-RyjXACJa.mjs";import{t as o}from"./contentManager-CoVTiSDT.mjs";import{t as s}from"./context7-BxMpyQiW.mjs";import{readFileSync as c,writeFileSync as l}from"node:fs";import{z as u}from"zod";const d=u.object({downloadedAt:u.string(),filesCount:u.number()}),f=u.object({context7ProjectId:u.string().optional(),context7Projects:u.record(u.string(),d).optional()});var p=class{static load(e){try{let t=c(e,`utf-8`);return f.parse(JSON.parse(t))}catch(t){throw Error(`Failed to load config from ${e}: ${t}`)}}static save(e,t){l(t,JSON.stringify(e,null,2))}static loadWithDefaults(e){try{return this.load(e)}catch{return console.warn(`⚠️ Warning: Could not load config from ${e}. Using default values.`),{}}}};export{p as Config,o as ContentManager,s as Context7Utils,t as FuzzySearchAdapter,e as MiniSearchAdapter,r as PackageUtils,i as SkillCreator,a as SqliteVectorSearchAdapter,n as UnifiedSearchEngine};
2
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/utils/config.ts"],"sourcesContent":["/**\n * Configuration utilities\n */\n\nimport { z } from 'zod'\nimport { readFileSync, writeFileSync } from 'node:fs'\n\nexport const Context7ProjectInfoSchema = z.object({\n downloadedAt: z.string(),\n filesCount: z.number(),\n})\n\nexport const SkillConfigSchema = z.object({\n // Legacy field for backward compatibility\n context7ProjectId: z.string().optional(),\n // New field to support multiple context7 projects\n context7Projects: z.record(z.string(), Context7ProjectInfoSchema).optional(),\n})\n\nexport type SkillConfig = z.input<typeof SkillConfigSchema>\nexport type Context7ProjectInfo = z.input<typeof Context7ProjectInfoSchema>\n\nexport class Config {\n static load(filePath: string): SkillConfig {\n try {\n const content = readFileSync(filePath, 'utf-8')\n const config = SkillConfigSchema.parse(JSON.parse(content))\n return config\n } catch (error) {\n throw new Error(`Failed to load config from ${filePath}: ${error}`)\n }\n }\n\n static save(config: SkillConfig, filePath: string): void {\n writeFileSync(filePath, JSON.stringify(config, null, 2))\n }\n\n static loadWithDefaults(filePath: string): SkillConfig {\n try {\n return this.load(filePath)\n } catch (error) {\n // If config file doesn't exist or is invalid, return a minimal default config\n console.warn(`⚠️ Warning: Could not load config from ${filePath}. Using default values.`)\n return {}\n }\n }\n}\n"],"mappings":"6fAOA,MAAa,EAA4B,EAAE,OAAO,CAChD,aAAc,EAAE,QAAQ,CACxB,WAAY,EAAE,QAAQ,CACvB,CAAC,CAEW,EAAoB,EAAE,OAAO,CAExC,kBAAmB,EAAE,QAAQ,CAAC,UAAU,CAExC,iBAAkB,EAAE,OAAO,EAAE,QAAQ,CAAE,EAA0B,CAAC,UAAU,CAC7E,CAAC,CAKF,IAAa,EAAb,KAAoB,CAClB,OAAO,KAAK,EAA+B,CACzC,GAAI,CACF,IAAM,EAAU,EAAa,EAAU,QAAQ,CAE/C,OADe,EAAkB,MAAM,KAAK,MAAM,EAAQ,CAAC,OAEpD,EAAO,CACd,MAAU,MAAM,8BAA8B,EAAS,IAAI,IAAQ,EAIvE,OAAO,KAAK,EAAqB,EAAwB,CACvD,EAAc,EAAU,KAAK,UAAU,EAAQ,KAAM,EAAE,CAAC,CAG1D,OAAO,iBAAiB,EAA+B,CACrD,GAAI,CACF,OAAO,KAAK,KAAK,EAAS,MACZ,CAGd,OADA,QAAQ,KAAK,2CAA2C,EAAS,yBAAyB,CACnF,EAAE"}
@@ -1,2 +0,0 @@
1
- import{t as e}from"./shared-DsVh4gOV.mjs";import{join as t}from"node:path";async function n(){let n=await e({}),{ContentManager:r}=await import(`./contentManager-CwquwC1s.mjs`),i=new r({searchEngine:n,referencesDir:t(process.cwd(),`assets`,`references`)}).listContext7Projects();if(i.length===0){console.log(`📭 No Context7 projects found`);return}console.log(`\n📦 Context7 Projects (${i.length}):\n`);for(let e of i)console.log(` 🔹 ${e.projectId}`),console.log(` Files: ${e.filesCount}`),console.log(` Directory: ${e.directory}`),console.log()}export{n as listContext7};
2
- //# sourceMappingURL=listContext7-DHj9AL-z.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"listContext7-DHj9AL-z.mjs","names":[],"sources":["../src/commands/listContext7.ts"],"sourcesContent":["/**\n * List Context7 projects command\n */\n\nimport { join } from 'node:path'\nimport { createSearchEngine } from './shared.js'\n\nexport async function listContext7(): Promise<void> {\n const searchEngine = await createSearchEngine({})\n\n const { ContentManager } = await import('../core/contentManager.js')\n\n const contentManager = new ContentManager({\n searchEngine,\n referencesDir: join(process.cwd(), 'assets', 'references'),\n })\n\n const projects = contentManager.listContext7Projects()\n\n if (projects.length === 0) {\n console.log('📭 No Context7 projects found')\n return\n }\n\n console.log(`\\n📦 Context7 Projects (${projects.length}):\\n`)\n\n for (const project of projects) {\n console.log(` 🔹 ${project.projectId}`)\n console.log(` Files: ${project.filesCount}`)\n console.log(` Directory: ${project.directory}`)\n console.log()\n }\n}\n"],"mappings":"2EAOA,eAAsB,GAA8B,CAClD,IAAM,EAAe,MAAM,EAAmB,EAAE,CAAC,CAE3C,CAAE,kBAAmB,MAAM,OAAO,iCAOlC,EALiB,IAAI,EAAe,CACxC,eACA,cAAe,EAAK,QAAQ,KAAK,CAAE,SAAU,aAAa,CAC3D,CAAC,CAE8B,sBAAsB,CAEtD,GAAI,EAAS,SAAW,EAAG,CACzB,QAAQ,IAAI,gCAAgC,CAC5C,OAGF,QAAQ,IAAI,2BAA2B,EAAS,OAAO,MAAM,CAE7D,IAAK,IAAM,KAAW,EACpB,QAAQ,IAAI,QAAQ,EAAQ,YAAY,CACxC,QAAQ,IAAI,eAAe,EAAQ,aAAa,CAChD,QAAQ,IAAI,mBAAmB,EAAQ,YAAY,CACnD,QAAQ,KAAK"}
@@ -1,2 +0,0 @@
1
- import{readFileSync as e}from"node:fs";import{createResolverByRootFile as t}from"@gaubee/nodekit";const n=t(import.meta.url,`package.json`);async function r(e){try{await e.body?.cancel()}catch{}}var i=class t{static getRegistryBaseUrl(){return(process.env.SKILL_CREATOR_NPM_REGISTRY_BASE_URL??`https://registry.npmjs.org`).replace(/\/+$/,``)}static getSearchBaseUrl(){return(process.env.SKILL_CREATOR_NPM_SEARCH_BASE_URL??`${this.getRegistryBaseUrl()}/-/v1/search`).replace(/\/+$/,``)}static async getPackageVersion(e){try{let t=await fetch(`${this.getRegistryBaseUrl()}/${e}/latest`);return t.ok?(await t.json()).version:(await r(t),null)}catch{return null}}static async getPackageInfo(e){try{let t=await fetch(`${this.getRegistryBaseUrl()}/${e}`);if(!t.ok)return await r(t),null;let n=await t.json(),i=n[`dist-tags`]?.latest;return i&&n.versions?.[i]||null}catch{return null}}static getCurrentPackageInfo(){try{return JSON.parse(e(n(`package.json`),`utf-8`))}catch{return null}}static formatVersion(e){if(!e)return``;e.startsWith(`v`)&&(e=e.slice(1));let t=e.split(`.`);if(t.length>=2){let e=parseInt(t[0],10);return e>=1?String(e):`${e}.${t[1]}`}return e}static createSkillFolderName(e,t){let n=e.replace(/\//g,`__`),r=this.formatVersion(t);return r?`${n}@${r}`:n}static normalizePackageName(e){return e.replace(/^@/,``).replace(/\//g,`__`).replace(/[^a-z0-9@._-]/gi,``).toLowerCase()}static validatePackageName(e){return!e||e.length===0?!1:/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(e)}static async searchPackages(e,t={}){let{limit:n=10,minScore:i=.3}=t;try{let t=e.join(` `),a=new URL(this.getSearchBaseUrl());a.searchParams.set(`text`,t),a.searchParams.set(`size`,String(n*2));let o=await fetch(a);if(!o.ok)return await r(o),[];let s=await o.json(),c=[];for(let e of s.objects||[]){let t=e.score?.detail?.popularity||0;if(t>=i){let n=await this.getPackageInfo(e.package.name);c.push({name:e.package.name,description:e.package.description||``,version:e.package.version,date:e.package.date,publisher:e.package.publisher?.username||`unknown`,score:t,homepage:n?.homepage,repository:n?.repository?.url,skill_dir_name:n?this.createSkillFolderName(n.name,n.version):void 0})}}return c.slice(0,n)}catch{return[]}}static async findExactPackage(e){try{let t=await this.getPackageInfo(e);return t?{name:t.name,description:t.description||``,version:t.version,date:t.time?.modified||new Date().toISOString(),publisher:t.publisher?.username||`unknown`,score:1,homepage:t.homepage,repository:t.repository?.url,skill_dir_name:this.createSkillFolderName(t.name,t.version)}:null}catch{return null}}static async suggestPackages(e,n={}){let r=[];if(t.validatePackageName(e)){let n=await t.findExactPackage(e);n&&r.push(n)}let i=e.split(/[\s-]+/).filter(e=>e.length>2).slice(0,3);i.length===0&&i.push(e);let a=await t.searchPackages(i,n),o=new Set(r.map(e=>e.name)),s=a.filter(e=>!o.has(e.name));return[...r,...s].slice(0,n.limit||10)}static async selectPackage(e){let n=await t.suggestPackages(e,{limit:5});if(n.length===0)return null;if(n.length===1){let e=n[0],r=await t.getPackageVersion(e.name);return{name:e.name,version:r||e.version}}let r=n.reduce((e,t)=>t.score>e.score?t:e),i=await t.getPackageVersion(r.name);return{name:r.name,version:i||r.version}}};export{n,i as t};
2
- //# sourceMappingURL=package-CFJazwTO.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"package-CFJazwTO.mjs","names":["results: SearchResult[]","version"],"sources":["../src/utils/path.ts","../src/utils/package.ts"],"sourcesContent":["import { createResolverByRootFile } from '@gaubee/nodekit'\n\n/**\n * rootResolver.dirname\n * rootResolver('templates/SKILL.md')\n */\nexport const rootResolver = createResolverByRootFile(import.meta.url, 'package.json')\n","/**\n * Package utilities\n */\n\nimport { readFileSync } from 'node:fs'\nimport type { PackageVersion } from '../types/index.js'\nimport { resolve } from 'node:path'\nimport { rootResolver } from './path.js'\n\nexport interface SearchResult {\n name: string\n description: string\n version: string\n date: string\n publisher: string\n score: number\n homepage?: string\n repository?: string\n skill_dir_name?: string\n}\n\nexport interface SearchOptions {\n limit?: number\n minScore?: number\n}\n\nasync function discardResponseBody(response: Response): Promise<void> {\n try {\n await response.body?.cancel()\n } catch {\n // Ignore cleanup failures on best-effort response disposal.\n }\n}\n\nexport class PackageUtils {\n private static getRegistryBaseUrl(): string {\n return (process.env.SKILL_CREATOR_NPM_REGISTRY_BASE_URL ?? 'https://registry.npmjs.org').replace(\n /\\/+$/,\n ''\n )\n }\n\n private static getSearchBaseUrl(): string {\n return (\n process.env.SKILL_CREATOR_NPM_SEARCH_BASE_URL ?? `${this.getRegistryBaseUrl()}/-/v1/search`\n ).replace(/\\/+$/, '')\n }\n\n /**\n * Get package version from npm registry\n */\n static async getPackageVersion(packageName: string): Promise<string | null> {\n try {\n const response = await fetch(`${this.getRegistryBaseUrl()}/${packageName}/latest`)\n if (!response.ok) {\n await discardResponseBody(response)\n return null\n }\n\n const data = await response.json()\n return data.version as string\n } catch {\n return null\n }\n }\n\n /**\n * Get full package info from npm registry for the latest version\n */\n static async getPackageInfo(packageName: string): Promise<{\n name: string\n version: string\n description: string\n homepage?: string\n repository?: { type: string; url: string }\n [key: string]: any\n } | null> {\n try {\n const response = await fetch(`${this.getRegistryBaseUrl()}/${packageName}`)\n if (!response.ok) {\n await discardResponseBody(response)\n return null\n }\n\n const data = await response.json()\n const latestVersionTag = data['dist-tags']?.latest\n if (!latestVersionTag) return null\n\n const latestVersionInfo = data.versions?.[latestVersionTag]\n if (!latestVersionInfo) return null\n\n return latestVersionInfo\n } catch {\n return null\n }\n }\n\n /**\n * Get full package info from npm registry for the latest version\n */\n static getCurrentPackageInfo(): {\n name: string\n version: string\n description: string\n homepage?: string\n repository?: { type: string; url: string }\n [key: string]: any\n } | null {\n try {\n const packageInfo = JSON.parse(readFileSync(rootResolver('package.json'), 'utf-8'))\n return packageInfo\n } catch {\n return null\n }\n }\n\n /**\n * Format version according to the skill directory naming rules.\n */\n static formatVersion(version: string): string {\n if (!version) return ''\n\n // Remove 'v' prefix if present\n if (version.startsWith('v')) {\n version = version.slice(1)\n }\n\n const parts = version.split('.')\n if (parts.length >= 2) {\n const major = parseInt(parts[0], 10)\n if (major >= 1) {\n return String(major)\n } else {\n return `${major}.${parts[1]}`\n }\n }\n\n return version\n }\n\n /**\n * Create skill folder name according to spec\n */\n static createSkillFolderName(packageName: string, version: string): string {\n // Replace / with __ so scoped packages map cleanly to a single skill directory name.\n const safePackage = packageName.replace(/\\//g, '__')\n const formattedVersion = this.formatVersion(version)\n\n if (formattedVersion) {\n return `${safePackage}@${formattedVersion}`\n } else {\n return safePackage\n }\n }\n\n /**\n * Normalize package name (remove @ prefix)\n */\n static normalizePackageName(packageName: string): string {\n return packageName\n .replace(/^@/, '')\n .replace(/\\//g, '__')\n .replace(/[^a-z0-9@._-]/gi, '')\n .toLowerCase()\n }\n\n /**\n * Validate package name format\n */\n static validatePackageName(packageName: string): boolean {\n if (!packageName || packageName.length === 0) {\n return false\n }\n\n // Basic validation for npm package names\n const validNamePattern = /^(@[a-z0-9-~][a-z0-9-._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/\n return validNamePattern.test(packageName)\n }\n\n /**\n * Search for packages on npm registry\n */\n static async searchPackages(\n keywords: string[],\n options: SearchOptions = {}\n ): Promise<SearchResult[]> {\n const { limit = 10, minScore = 0.3 } = options\n\n try {\n const query = keywords.join(' ')\n const searchUrl = new URL(this.getSearchBaseUrl())\n searchUrl.searchParams.set('text', query)\n searchUrl.searchParams.set('size', String(limit * 2))\n const response = await fetch(searchUrl)\n\n if (!response.ok) {\n await discardResponseBody(response)\n return []\n }\n\n const data = await response.json()\n const results: SearchResult[] = []\n\n for (const pkg of data.objects || []) {\n const score = pkg.score?.detail?.popularity || 0\n if (score >= minScore) {\n // Get detailed package information including homepage\n const packageInfo = await this.getPackageInfo(pkg.package.name)\n\n results.push({\n name: pkg.package.name,\n description: pkg.package.description || '',\n version: pkg.package.version,\n date: pkg.package.date,\n publisher: pkg.package.publisher?.username || 'unknown',\n score,\n homepage: packageInfo?.homepage,\n repository: packageInfo?.repository?.url,\n skill_dir_name: packageInfo\n ? this.createSkillFolderName(packageInfo.name, packageInfo.version)\n : undefined,\n })\n }\n }\n\n return results.slice(0, limit)\n } catch {\n return []\n }\n }\n\n /**\n * Find exact package match\n */\n static async findExactPackage(packageName: string): Promise<SearchResult | null> {\n try {\n const packageInfo = await this.getPackageInfo(packageName)\n if (!packageInfo) return null\n\n return {\n name: packageInfo.name,\n description: packageInfo.description || '',\n version: packageInfo.version,\n date: packageInfo.time?.modified || new Date().toISOString(),\n publisher: packageInfo.publisher?.username || 'unknown',\n score: 1.0,\n homepage: packageInfo.homepage,\n repository: packageInfo.repository?.url,\n skill_dir_name: this.createSkillFolderName(packageInfo.name, packageInfo.version),\n }\n } catch {\n return null\n }\n }\n\n /**\n * Suggest packages based on keywords\n */\n static async suggestPackages(\n input: string,\n options: SearchOptions = {}\n ): Promise<SearchResult[]> {\n const results: SearchResult[] = []\n\n // Check if input looks like an exact package name and include it as first result\n if (PackageUtils.validatePackageName(input)) {\n const exact = await PackageUtils.findExactPackage(input)\n if (exact) {\n results.push(exact)\n }\n }\n\n // Always perform broader search to find related packages\n // Extract keywords from input\n const keywords = input\n .split(/[\\s-]+/)\n .filter((word) => word.length > 2)\n .slice(0, 3)\n\n if (keywords.length === 0) {\n // Fallback: search with the whole input\n keywords.push(input)\n }\n\n const searchResults = await PackageUtils.searchPackages(keywords, options)\n\n // Merge exact match with search results, avoiding duplicates\n const exactMatchNames = new Set(results.map((r) => r.name))\n const additionalResults = searchResults.filter((r) => !exactMatchNames.has(r.name))\n\n return [...results, ...additionalResults].slice(0, options.limit || 10)\n }\n\n /**\n * Select package from multiple options\n */\n static async selectPackage(input: string): Promise<{ name: string; version: string } | null> {\n const suggestions = await PackageUtils.suggestPackages(input, { limit: 5 })\n\n if (suggestions.length === 0) {\n return null\n }\n\n if (suggestions.length === 1) {\n const pkg = suggestions[0]\n const version = await PackageUtils.getPackageVersion(pkg.name)\n return { name: pkg.name, version: version || pkg.version }\n }\n\n // Multiple options found - would need interactive selection in CLI\n // For now, return the highest scored package\n const best = suggestions.reduce((prev, curr) => (curr.score > prev.score ? curr : prev))\n\n const version = await PackageUtils.getPackageVersion(best.name)\n return { name: best.name, version: version || best.version }\n }\n}\n"],"mappings":"kGAMA,MAAa,EAAe,EAAyB,OAAO,KAAK,IAAK,eAAe,CCoBrF,eAAe,EAAoB,EAAmC,CACpE,GAAI,CACF,MAAM,EAAS,MAAM,QAAQ,MACvB,GAKV,IAAa,EAAb,MAAa,CAAa,CACxB,OAAe,oBAA6B,CAC1C,OAAQ,QAAQ,IAAI,qCAAuC,8BAA8B,QACvF,OACA,GACD,CAGH,OAAe,kBAA2B,CACxC,OACE,QAAQ,IAAI,mCAAqC,GAAG,KAAK,oBAAoB,CAAC,eAC9E,QAAQ,OAAQ,GAAG,CAMvB,aAAa,kBAAkB,EAA6C,CAC1E,GAAI,CACF,IAAM,EAAW,MAAM,MAAM,GAAG,KAAK,oBAAoB,CAAC,GAAG,EAAY,SAAS,CAOlF,OANK,EAAS,IAKD,MAAM,EAAS,MAAM,EACtB,SALV,MAAM,EAAoB,EAAS,CAC5B,WAKH,CACN,OAAO,MAOX,aAAa,eAAe,EAOlB,CACR,GAAI,CACF,IAAM,EAAW,MAAM,MAAM,GAAG,KAAK,oBAAoB,CAAC,GAAG,IAAc,CAC3E,GAAI,CAAC,EAAS,GAEZ,OADA,MAAM,EAAoB,EAAS,CAC5B,KAGT,IAAM,EAAO,MAAM,EAAS,MAAM,CAC5B,EAAmB,EAAK,cAAc,OAM5C,OALK,GAEqB,EAAK,WAAW,IAFZ,UAMxB,CACN,OAAO,MAOX,OAAO,uBAOE,CACP,GAAI,CAEF,OADoB,KAAK,MAAM,EAAa,EAAa,eAAe,CAAE,QAAQ,CAAC,MAE7E,CACN,OAAO,MAOX,OAAO,cAAc,EAAyB,CAC5C,GAAI,CAAC,EAAS,MAAO,GAGjB,EAAQ,WAAW,IAAI,GACzB,EAAU,EAAQ,MAAM,EAAE,EAG5B,IAAM,EAAQ,EAAQ,MAAM,IAAI,CAChC,GAAI,EAAM,QAAU,EAAG,CACrB,IAAM,EAAQ,SAAS,EAAM,GAAI,GAAG,CAIlC,OAHE,GAAS,EACJ,OAAO,EAAM,CAEb,GAAG,EAAM,GAAG,EAAM,KAI7B,OAAO,EAMT,OAAO,sBAAsB,EAAqB,EAAyB,CAEzE,IAAM,EAAc,EAAY,QAAQ,MAAO,KAAK,CAC9C,EAAmB,KAAK,cAAc,EAAQ,CAKlD,OAHE,EACK,GAAG,EAAY,GAAG,IAElB,EAOX,OAAO,qBAAqB,EAA6B,CACvD,OAAO,EACJ,QAAQ,KAAM,GAAG,CACjB,QAAQ,MAAO,KAAK,CACpB,QAAQ,kBAAmB,GAAG,CAC9B,aAAa,CAMlB,OAAO,oBAAoB,EAA8B,CAOvD,MANI,CAAC,GAAe,EAAY,SAAW,EAClC,GAIgB,yDACD,KAAK,EAAY,CAM3C,aAAa,eACX,EACA,EAAyB,EAAE,CACF,CACzB,GAAM,CAAE,QAAQ,GAAI,WAAW,IAAQ,EAEvC,GAAI,CACF,IAAM,EAAQ,EAAS,KAAK,IAAI,CAC1B,EAAY,IAAI,IAAI,KAAK,kBAAkB,CAAC,CAClD,EAAU,aAAa,IAAI,OAAQ,EAAM,CACzC,EAAU,aAAa,IAAI,OAAQ,OAAO,EAAQ,EAAE,CAAC,CACrD,IAAM,EAAW,MAAM,MAAM,EAAU,CAEvC,GAAI,CAAC,EAAS,GAEZ,OADA,MAAM,EAAoB,EAAS,CAC5B,EAAE,CAGX,IAAM,EAAO,MAAM,EAAS,MAAM,CAC5BA,EAA0B,EAAE,CAElC,IAAK,IAAM,KAAO,EAAK,SAAW,EAAE,CAAE,CACpC,IAAM,EAAQ,EAAI,OAAO,QAAQ,YAAc,EAC/C,GAAI,GAAS,EAAU,CAErB,IAAM,EAAc,MAAM,KAAK,eAAe,EAAI,QAAQ,KAAK,CAE/D,EAAQ,KAAK,CACX,KAAM,EAAI,QAAQ,KAClB,YAAa,EAAI,QAAQ,aAAe,GACxC,QAAS,EAAI,QAAQ,QACrB,KAAM,EAAI,QAAQ,KAClB,UAAW,EAAI,QAAQ,WAAW,UAAY,UAC9C,QACA,SAAU,GAAa,SACvB,WAAY,GAAa,YAAY,IACrC,eAAgB,EACZ,KAAK,sBAAsB,EAAY,KAAM,EAAY,QAAQ,CACjE,IAAA,GACL,CAAC,EAIN,OAAO,EAAQ,MAAM,EAAG,EAAM,MACxB,CACN,MAAO,EAAE,EAOb,aAAa,iBAAiB,EAAmD,CAC/E,GAAI,CACF,IAAM,EAAc,MAAM,KAAK,eAAe,EAAY,CAG1D,OAFK,EAEE,CACL,KAAM,EAAY,KAClB,YAAa,EAAY,aAAe,GACxC,QAAS,EAAY,QACrB,KAAM,EAAY,MAAM,UAAY,IAAI,MAAM,CAAC,aAAa,CAC5D,UAAW,EAAY,WAAW,UAAY,UAC9C,MAAO,EACP,SAAU,EAAY,SACtB,WAAY,EAAY,YAAY,IACpC,eAAgB,KAAK,sBAAsB,EAAY,KAAM,EAAY,QAAQ,CAClF,CAZwB,UAanB,CACN,OAAO,MAOX,aAAa,gBACX,EACA,EAAyB,EAAE,CACF,CACzB,IAAMA,EAA0B,EAAE,CAGlC,GAAI,EAAa,oBAAoB,EAAM,CAAE,CAC3C,IAAM,EAAQ,MAAM,EAAa,iBAAiB,EAAM,CACpD,GACF,EAAQ,KAAK,EAAM,CAMvB,IAAM,EAAW,EACd,MAAM,SAAS,CACf,OAAQ,GAAS,EAAK,OAAS,EAAE,CACjC,MAAM,EAAG,EAAE,CAEV,EAAS,SAAW,GAEtB,EAAS,KAAK,EAAM,CAGtB,IAAM,EAAgB,MAAM,EAAa,eAAe,EAAU,EAAQ,CAGpE,EAAkB,IAAI,IAAI,EAAQ,IAAK,GAAM,EAAE,KAAK,CAAC,CACrD,EAAoB,EAAc,OAAQ,GAAM,CAAC,EAAgB,IAAI,EAAE,KAAK,CAAC,CAEnF,MAAO,CAAC,GAAG,EAAS,GAAG,EAAkB,CAAC,MAAM,EAAG,EAAQ,OAAS,GAAG,CAMzE,aAAa,cAAc,EAAkE,CAC3F,IAAM,EAAc,MAAM,EAAa,gBAAgB,EAAO,CAAE,MAAO,EAAG,CAAC,CAE3E,GAAI,EAAY,SAAW,EACzB,OAAO,KAGT,GAAI,EAAY,SAAW,EAAG,CAC5B,IAAM,EAAM,EAAY,GAClBC,EAAU,MAAM,EAAa,kBAAkB,EAAI,KAAK,CAC9D,MAAO,CAAE,KAAM,EAAI,KAAM,QAASA,GAAW,EAAI,QAAS,CAK5D,IAAM,EAAO,EAAY,QAAQ,EAAM,IAAU,EAAK,MAAQ,EAAK,MAAQ,EAAO,EAAM,CAElF,EAAU,MAAM,EAAa,kBAAkB,EAAK,KAAK,CAC/D,MAAO,CAAE,KAAM,EAAK,KAAM,QAAS,GAAW,EAAK,QAAS"}
@@ -1,2 +0,0 @@
1
- import{createHash as e}from"node:crypto";const t={minisearch:`2026-05-21-v1`,sqliteVec:`2026-05-21-v2`};function n(e){let t=e.replace(/\\/g,`/`);return t.startsWith(`context7/`)||t.startsWith(`official/`)?`context7`:`user`}function r(e){return e.replace(/\[([^\]]+)\]\(([^)]+)\)/g,`$1`).replace(/`([^`]+)`/g,`$1`)}function i(e){return r(e).replace(/([A-Z]+)([A-Z][a-z])/g,`$1 $2`).replace(/([a-z\d])([A-Z])/g,`$1 $2`)}function a(t){let n=e(`sha256`);for(let e of t)n.update(e);return n.digest(`hex`)}export{i as a,r as i,a as n,n as r,t};
2
- //# sourceMappingURL=referenceSearchUtils-DZgupMZp.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"referenceSearchUtils-DZgupMZp.mjs","names":[],"sources":["../src/core/referenceSearchUtils.ts"],"sourcesContent":["import { createHash } from 'node:crypto'\n\nexport const SEARCH_RULESET_VERSIONS = {\n minisearch: '2026-05-21-v1',\n sqliteVec: '2026-05-21-v2',\n} as const\n\nexport function detectReferenceSource(relativePath: string): 'user' | 'context7' {\n const normalizedPath = relativePath.replace(/\\\\/g, '/')\n if (normalizedPath.startsWith('context7/') || normalizedPath.startsWith('official/')) {\n return 'context7'\n }\n return 'user'\n}\n\nexport function normalizeReferenceContent(content: string): string {\n return content\n .replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '$1')\n .replace(/`([^`]+)`/g, '$1')\n}\n\nexport function normalizeSearchableText(content: string): string {\n return normalizeReferenceContent(content)\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n}\n\nexport function createSearchRulesetHash(parts: Array<string>): string {\n const hash = createHash('sha256')\n for (const part of parts) {\n hash.update(part)\n }\n return hash.digest('hex')\n}\n"],"mappings":"yCAEA,MAAa,EAA0B,CACrC,WAAY,gBACZ,UAAW,gBACZ,CAED,SAAgB,EAAsB,EAA2C,CAC/E,IAAM,EAAiB,EAAa,QAAQ,MAAO,IAAI,CAIvD,OAHI,EAAe,WAAW,YAAY,EAAI,EAAe,WAAW,YAAY,CAC3E,WAEF,OAGT,SAAgB,EAA0B,EAAyB,CACjE,OAAO,EACJ,QAAQ,2BAA4B,KAAK,CACzC,QAAQ,aAAc,KAAK,CAGhC,SAAgB,EAAwB,EAAyB,CAC/D,OAAO,EAA0B,EAAQ,CACtC,QAAQ,wBAAyB,QAAQ,CACzC,QAAQ,oBAAqB,QAAQ,CAG1C,SAAgB,EAAwB,EAA8B,CACpE,IAAM,EAAO,EAAW,SAAS,CACjC,IAAK,IAAM,KAAQ,EACjB,EAAK,OAAO,EAAK,CAEnB,OAAO,EAAK,OAAO,MAAM"}
@@ -1,3 +0,0 @@
1
- import{r as e,t}from"./shared-DsVh4gOV.mjs";import{t as n}from"./skillMdManager-DGBZ6M5J.mjs";import{join as r}from"node:path";import{existsSync as i}from"node:fs";async function a(a){let o=await t({}),{ContentManager:s}=await import(`./contentManager-CwquwC1s.mjs`),c=new s({searchEngine:o,referencesDir:r(process.cwd(),`assets`,`references`)}),l=e(a,[{name:`project-id`,type:`string`}])[`project-id`];l||(console.error(`❌ No Context7 project ID provided`),console.error(` Use --project-id <id>`),process.exit(1)),console.log(`🗑️ Removing Context7 project: ${l}`);try{let e=c.removeContext7Project(l);e.success||(console.error(`❌ ${e.message}`),process.exit(1)),console.log(`✅ ${e.message}`);let t=r(process.cwd(),`SKILL.md`);i(t)&&(n(t,l),console.log(`📝 Updated SKILL.md`)),console.log(`
2
- 🔧 Rebuilding search index...`);try{await o.initialize(),await o.buildIndex(r(process.cwd(),`assets`,`references`)),console.log(`✅ Index rebuilt successfully`)}catch(e){console.log(`⚠️ Index rebuild failed: ${e instanceof Error?e.message:String(e)}`)}}catch(e){console.error(`❌ Error removing Context7 project:`,e),process.exit(1)}}export{a as removeContext7};
3
- //# sourceMappingURL=removeContext7-BZtL4_CJ.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"removeContext7-BZtL4_CJ.mjs","names":[],"sources":["../src/commands/removeContext7.ts"],"sourcesContent":["/**\n * Remove Context7 project command\n */\n\nimport { join } from 'node:path'\nimport { existsSync } from 'node:fs'\nimport { parseArgs, createSearchEngine } from './shared.js'\nimport { removeContext7TagFromFile } from '../utils/skillMdManager.js'\n\nexport async function removeContext7(args: string[]): Promise<void> {\n const searchEngine = await createSearchEngine({})\n\n const { ContentManager } = await import('../core/contentManager.js')\n\n const contentManager = new ContentManager({\n searchEngine,\n referencesDir: join(process.cwd(), 'assets', 'references'),\n })\n\n // Parse arguments\n const options = parseArgs(args, [{ name: 'project-id', type: 'string' }])\n\n const projectId = options['project-id']\n if (!projectId) {\n console.error('❌ No Context7 project ID provided')\n console.error(' Use --project-id <id>')\n process.exit(1)\n }\n\n console.log(`🗑️ Removing Context7 project: ${projectId}`)\n\n try {\n // Remove project from filesystem\n const result = contentManager.removeContext7Project(projectId)\n\n if (!result.success) {\n console.error(`❌ ${result.message}`)\n process.exit(1)\n }\n\n console.log(`✅ ${result.message}`)\n\n // Remove from SKILL.md\n const skillMdPath = join(process.cwd(), 'SKILL.md')\n if (existsSync(skillMdPath)) {\n removeContext7TagFromFile(skillMdPath, projectId)\n console.log(`📝 Updated SKILL.md`)\n }\n\n // Rebuild index\n console.log(`\\n🔧 Rebuilding search index...`)\n try {\n await searchEngine.initialize()\n await searchEngine.buildIndex(join(process.cwd(), 'assets', 'references'))\n console.log(`✅ Index rebuilt successfully`)\n } catch (error) {\n console.log(\n `⚠️ Index rebuild failed: ${error instanceof Error ? error.message : String(error)}`\n )\n }\n } catch (error) {\n console.error(`❌ Error removing Context7 project:`, error)\n process.exit(1)\n }\n}\n"],"mappings":"oKASA,eAAsB,EAAe,EAA+B,CAClE,IAAM,EAAe,MAAM,EAAmB,EAAE,CAAC,CAE3C,CAAE,kBAAmB,MAAM,OAAO,iCAElC,EAAiB,IAAI,EAAe,CACxC,eACA,cAAe,EAAK,QAAQ,KAAK,CAAE,SAAU,aAAa,CAC3D,CAAC,CAKI,EAFU,EAAU,EAAM,CAAC,CAAE,KAAM,aAAc,KAAM,SAAU,CAAC,CAAC,CAE/C,cACrB,IACH,QAAQ,MAAM,oCAAoC,CAClD,QAAQ,MAAM,2BAA2B,CACzC,QAAQ,KAAK,EAAE,EAGjB,QAAQ,IAAI,mCAAmC,IAAY,CAE3D,GAAI,CAEF,IAAM,EAAS,EAAe,sBAAsB,EAAU,CAEzD,EAAO,UACV,QAAQ,MAAM,KAAK,EAAO,UAAU,CACpC,QAAQ,KAAK,EAAE,EAGjB,QAAQ,IAAI,KAAK,EAAO,UAAU,CAGlC,IAAM,EAAc,EAAK,QAAQ,KAAK,CAAE,WAAW,CAC/C,EAAW,EAAY,GACzB,EAA0B,EAAa,EAAU,CACjD,QAAQ,IAAI,sBAAsB,EAIpC,QAAQ,IAAI;+BAAkC,CAC9C,GAAI,CACF,MAAM,EAAa,YAAY,CAC/B,MAAM,EAAa,WAAW,EAAK,QAAQ,KAAK,CAAE,SAAU,aAAa,CAAC,CAC1E,QAAQ,IAAI,+BAA+B,OACpC,EAAO,CACd,QAAQ,IACN,6BAA6B,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,GACpF,QAEI,EAAO,CACd,QAAQ,MAAM,qCAAsC,EAAM,CAC1D,QAAQ,KAAK,EAAE"}
@@ -1,5 +0,0 @@
1
- import{r as e}from"./shared-DsVh4gOV.mjs";import{n as t}from"./skillMdManager-DGBZ6M5J.mjs";import{join as n}from"node:path";import{existsSync as r,readdirSync as i,unlinkSync as a}from"node:fs";async function o(o){let s=e(o,[{name:`type`,type:`string`,required:!0},{name:`file`,type:`string`,required:!0}]),c=s.type,l=s.file,u=`user`,d;c.startsWith(`context7:`)?(u=`context7`,d=c.slice(9),d||(console.error(`❌ Invalid type format. Use: user or context7:<project_id>`),process.exit(1))):c===`user`?u=`user`:(console.error(`❌ Invalid type. Use: user or context7:<project_id>`),process.exit(1));let f=n(process.cwd(),`assets`,`references`),p;u===`user`?p=n(f,`user`,l):u===`context7`&&d?p=n(f,`context7`,encodeURIComponent(d),l):(console.error(`❌ Invalid configuration`),process.exit(1)),r(p)||(console.error(`❌ File not found: ${p}`),process.exit(1));try{a(p),console.log(`✅ Removed file: ${l}`);let e=n(process.cwd(),`SKILL.md`);r(e)&&(u===`user`?(t(e,`user-skills`,i(n(f,`user`)).filter(e=>e.endsWith(`.md`)).map(e=>`- ${e}`).join(`
2
- `)),console.log(`📝 Updated SKILL.md`)):u===`context7`&&d&&(t(e,`context7-skills`,i(n(f,`context7`,encodeURIComponent(d))).filter(e=>e.endsWith(`.md`)).map(e=>`- ${e}`).join(`
3
- `),d,`assets/references/context7/${encodeURIComponent(d)}`),console.log(`📝 Updated SKILL.md`))),console.log(`
4
- ✅ Skill file removed successfully`)}catch(e){console.error(`❌ Error removing skill file:`,e),process.exit(1)}}export{o as t};
5
- //# sourceMappingURL=removeSkill-Bat_plVG.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"removeSkill-Bat_plVG.mjs","names":["source: 'user' | 'context7'","projectId: string | undefined","filePath: string"],"sources":["../src/commands/removeSkill.ts"],"sourcesContent":["/**\n * Remove skill file command\n */\n\nimport { join } from 'node:path'\nimport { existsSync, unlinkSync, readdirSync } from 'node:fs'\nimport { parseArgs } from './shared.js'\nimport { updateSkillMdFile } from '../utils/skillMdManager.js'\n\nexport async function removeSkill(args: string[]): Promise<void> {\n // Parse arguments\n const options = parseArgs(args, [\n { name: 'type', type: 'string', required: true },\n { name: 'file', type: 'string', required: true },\n ])\n\n const type = options.type\n const fileName = options.file\n\n // Parse type: user or context7:<project_id>\n let source: 'user' | 'context7' = 'user'\n let projectId: string | undefined\n\n if (type.startsWith('context7:')) {\n source = 'context7'\n projectId = type.slice('context7:'.length)\n if (!projectId) {\n console.error('❌ Invalid type format. Use: user or context7:<project_id>')\n process.exit(1)\n }\n } else if (type === 'user') {\n source = 'user'\n } else {\n console.error('❌ Invalid type. Use: user or context7:<project_id>')\n process.exit(1)\n }\n\n // Construct file path\n const referencesDir = join(process.cwd(), 'assets', 'references')\n let filePath: string\n\n if (source === 'user') {\n filePath = join(referencesDir, 'user', fileName)\n } else if (source === 'context7' && projectId) {\n filePath = join(referencesDir, 'context7', encodeURIComponent(projectId), fileName)\n } else {\n console.error('❌ Invalid configuration')\n process.exit(1)\n }\n\n // Check if file exists\n if (!existsSync(filePath)) {\n console.error(`❌ File not found: ${filePath}`)\n process.exit(1)\n }\n\n try {\n // Remove file\n unlinkSync(filePath)\n console.log(`✅ Removed file: ${fileName}`)\n\n // Update SKILL.md\n const skillMdPath = join(process.cwd(), 'SKILL.md')\n if (existsSync(skillMdPath)) {\n if (source === 'user') {\n // Update user-skills tag\n const userDir = join(referencesDir, 'user')\n const files = readdirSync(userDir).filter((f) => f.endsWith('.md'))\n const fileList = files.map((f) => `- ${f}`).join('\\n')\n\n updateSkillMdFile(skillMdPath, 'user-skills', fileList)\n console.log(`📝 Updated SKILL.md`)\n } else if (source === 'context7' && projectId) {\n // Update context7-skills tag\n const projectDir = join(referencesDir, 'context7', encodeURIComponent(projectId))\n const files = readdirSync(projectDir).filter((f) => f.endsWith('.md'))\n const fileList = files.map((f) => `- ${f}`).join('\\n')\n\n updateSkillMdFile(\n skillMdPath,\n 'context7-skills',\n fileList,\n projectId,\n `assets/references/context7/${encodeURIComponent(projectId)}`\n )\n console.log(`📝 Updated SKILL.md`)\n }\n }\n\n console.log(`\\n✅ Skill file removed successfully`)\n } catch (error) {\n console.error(`❌ Error removing skill file:`, error)\n process.exit(1)\n }\n}\n"],"mappings":"mMASA,eAAsB,EAAY,EAA+B,CAE/D,IAAM,EAAU,EAAU,EAAM,CAC9B,CAAE,KAAM,OAAQ,KAAM,SAAU,SAAU,GAAM,CAChD,CAAE,KAAM,OAAQ,KAAM,SAAU,SAAU,GAAM,CACjD,CAAC,CAEI,EAAO,EAAQ,KACf,EAAW,EAAQ,KAGrBA,EAA8B,OAC9BC,EAEA,EAAK,WAAW,YAAY,EAC9B,EAAS,WACT,EAAY,EAAK,MAAM,EAAmB,CACrC,IACH,QAAQ,MAAM,4DAA4D,CAC1E,QAAQ,KAAK,EAAE,GAER,IAAS,OAClB,EAAS,QAET,QAAQ,MAAM,qDAAqD,CACnE,QAAQ,KAAK,EAAE,EAIjB,IAAM,EAAgB,EAAK,QAAQ,KAAK,CAAE,SAAU,aAAa,CAC7DC,EAEA,IAAW,OACb,EAAW,EAAK,EAAe,OAAQ,EAAS,CACvC,IAAW,YAAc,EAClC,EAAW,EAAK,EAAe,WAAY,mBAAmB,EAAU,CAAE,EAAS,EAEnF,QAAQ,MAAM,0BAA0B,CACxC,QAAQ,KAAK,EAAE,EAIZ,EAAW,EAAS,GACvB,QAAQ,MAAM,qBAAqB,IAAW,CAC9C,QAAQ,KAAK,EAAE,EAGjB,GAAI,CAEF,EAAW,EAAS,CACpB,QAAQ,IAAI,mBAAmB,IAAW,CAG1C,IAAM,EAAc,EAAK,QAAQ,KAAK,CAAE,WAAW,CAC/C,EAAW,EAAY,GACrB,IAAW,QAMb,EAAkB,EAAa,cAHjB,EADE,EAAK,EAAe,OAAO,CACT,CAAC,OAAQ,GAAM,EAAE,SAAS,MAAM,CAAC,CAC5C,IAAK,GAAM,KAAK,IAAI,CAAC,KAAK;EAAK,CAEC,CACvD,QAAQ,IAAI,sBAAsB,EACzB,IAAW,YAAc,IAMlC,EACE,EACA,kBALY,EADK,EAAK,EAAe,WAAY,mBAAmB,EAAU,CAAC,CAC5C,CAAC,OAAQ,GAAM,EAAE,SAAS,MAAM,CAAC,CAC/C,IAAK,GAAM,KAAK,IAAI,CAAC,KAAK;EAAK,CAMpD,EACA,8BAA8B,mBAAmB,EAAU,GAC5D,CACD,QAAQ,IAAI,sBAAsB,GAItC,QAAQ,IAAI;mCAAsC,OAC3C,EAAO,CACd,QAAQ,MAAM,+BAAgC,EAAM,CACpD,QAAQ,KAAK,EAAE"}
@@ -1 +0,0 @@
1
- import"./shared-DsVh4gOV.mjs";import"./skillMdManager-DGBZ6M5J.mjs";import{t as e}from"./removeSkill-Bat_plVG.mjs";export{e as removeSkill};
@@ -1,13 +0,0 @@
1
- import{n as e}from"./package-CFJazwTO.mjs";import"./searchQuality-DVdHmamh.mjs";import{t}from"./search_format-RyjXACJa.mjs";import{i as n,n as r,t as i}from"./scopeSelection-BWteJQSv.mjs";import{n as a,r as o,t as s}from"./shared-DsVh4gOV.mjs";import{t as c}from"./buildIndex-B_9ABRtx.mjs";import{n as l,r as u}from"./skillMdManager-DGBZ6M5J.mjs";import{t as d}from"./removeSkill-Bat_plVG.mjs";import{join as f}from"node:path";import{existsSync as p,mkdirSync as m,readFileSync as h,readdirSync as g,writeFileSync as _}from"node:fs";async function v(e){let n=o(e,[{name:`query`,alias:`q`,type:`string`,required:!0},{name:`top-k`,type:`number`,default:5},{name:`source`,type:`string`,default:`all`},{name:`mode`,type:`string`,default:`auto`},{name:`vector-embedder`,type:`string`},{name:`list`,type:`boolean`,default:!1}]),r=a(n.mode);if(r===`vector`){let{SqliteVectorSearchAdapter:e}=await import(`./sqliteVectorSearchAdapter-DNkyKuZs.mjs`);await e.isRuntimeSupported()||(console.error(`❌ Vector mode is unavailable in this runtime. It requires node:sqlite support and sqlite-vec.`),process.exit(1))}let i=await s({searchMode:r,useFormatting:!1,vectorEmbedder:n[`vector-embedder`]});await i.initialize();let c=f(process.cwd(),`assets`,`references`);await i.buildIndex(c);let l=n[`top-k`],u=n.source===`all`?void 0:{source:n.source},d=await i.search(n.query,l||5,u),p=await i.getBackendInfo();console.log(`\nSearch Results for: '${n.query}'`),console.log(`Requested mode: ${r}`),p&&console.log(`Active backend: ${p.backendId} (${p.mode})`),n[`vector-embedder`]&&console.log(`Vector embedder: ${n[`vector-embedder`]}`);let m=typeof d[0]?.metadata?.autoDecisionReason==`string`?d[0].metadata.autoDecisionReason:void 0;if(m&&console.log(`Auto decision: ${m}`),console.log(`=`.repeat(50)),d.length===0){console.log(`No results found.`);return}let h=t(n.list?`list`:`enhanced`),g={skillPath:process.cwd(),query:n.query,showFullContentThreshold:.8,minScoreForPreview:.3,maxPreviewLength:200,showLineNumbers:!0},_=h.format(d,g);for(let e=0;e<_.length;e++){let t=_[e],r=t.result,i=r.metadata.sourceRank,a=typeof i==`string`?i:`match`,o=r.metadata.displayScore,s=typeof o==`number`&&Number.isFinite(o)?o.toFixed(2):r.score.toFixed(2);switch(console.log(`\n${e+1}. [Score: ${s}] ${r.title}`),console.log(` Source: ${r.source} (${a})`),typeof r.metadata.backendId==`string`&&console.log(` Backend: ${r.metadata.backendId}`),typeof r.metadata.autoBackendId==`string`&&console.log(` Auto backend: ${r.metadata.autoBackendId}`),console.log(` File: ${r.relativePath||r.file_path}`),t.contentType){case`full-content`:console.log(` FileContent:`),console.log(` ${t.content}`);break;case`preview`:if(n.list)console.log(` Preview: ${t.content}`);else{console.log(` Preview:`);let e=t.content.match(/^<limit-content lines-indexs="([^"]+)">\n(.*)\n<\/limit-content>$/s);if(e){let[,t,n]=e;console.log(` Lines: ${t}`),console.log(` ${n}`)}else console.log(` ${t.content}`)}break;case`metadata-only`:console.log(` Content: (No preview - metadata only)`);break;default:console.log(` Preview: ${t.content}`)}}}async function y(e){let t=await s({}),{ContentManager:n}=await import(`./contentManager-CwquwC1s.mjs`),r=new n({searchEngine:t,referencesDir:f(process.cwd(),`assets`,`references`)}),i=o(e,[{name:`title`,alias:`t`,type:`string`,required:!1},{name:`content`,alias:`c`,type:`string`,required:!1},{name:`file`,alias:`f`,type:`string`,required:!1},{name:`force`,type:`boolean`},{name:`force-append`,type:`boolean`},{name:`no-update`,type:`boolean`},{name:`json`,type:`boolean`}]),a=!!i.json;!i.title&&!i.file&&(console.error(`❌ Please provide either --title or --file`),process.exit(1));let c=i.content||``,u=i.title||``;if(i.file){let{readFileSync:e}=await import(`node:fs`);try{if(c=e(i.file,`utf-8`),!u){let e=i.file.split(`/`).pop()?.replace(/\.[^/.]+$/,``)||``;u=c.split(`
2
- `)[0]?.replace(/^#+\s*/,``)||e||e}}catch{console.error(`❌ Failed to read file: ${i.file}`),process.exit(1)}}let d=await r.addUserContent({title:u,content:c,force:i.force,forceAppend:i[`force-append`],autoUpdate:!i[`no-update`]});if(a||console.log(d.message),d.existingFile)return a||(console.log(`
3
- 📄 Existing file content:`),console.log(`─`.repeat(50)),console.log(d.existingFile.content),console.log(`─`.repeat(50)),process.exit(1)),{...d,skillMdUpdated:!1,userFiles:[]};!a&&d.similarContent&&d.similarContent.length>0&&(console.log(`
4
- Similar content found:`),d.similarContent.forEach((e,t)=>{let n=e.sourceRank??`match`;console.log(`\n${t+1}. [${e.score.toFixed(2)}] ${e.title}`),console.log(` Source: ${e.source} (${n})`),console.log(` Preview: ${e.preview}`)}));let m=!1,h=[];if(d.added||d.updated){let e=f(process.cwd(),`SKILL.md`);if(p(e)){let t=f(process.cwd(),`assets`,`references`,`user`);p(t)&&(h=g(t).filter(e=>e.endsWith(`.md`)),l(e,`user-skills`,h.map(e=>`- ${e}`).join(`
5
- `)),m=!0,a||console.log(`📝 Updated SKILL.md with user skills`))}}return{...d,skillMdUpdated:m,userFiles:h}}async function b(e){let t=await s({}),{ContentManager:r}=await import(`./contentManager-CwquwC1s.mjs`),i=new r({searchEngine:t,referencesDir:f(process.cwd(),`assets`,`references`)}),a=o(e,[{name:`force`,type:`boolean`},{name:`project-id`,type:`string`},{name:`package-name`,type:`string`},{name:`package-version`,type:`string`},{name:`skip-indexing`,type:`boolean`},{name:`json`,type:`boolean`}]),c=!!a.json,d=a[`project-id`];d||(console.error(`❌ No Context7 project ID provided`),console.error(` Use --project-id <id>`),process.exit(1));let m=a[`package-name`],h=a[`package-version`];try{c||(console.log(`📥 Downloading Context7 documentation...`),console.log(`Project ID: ${d}`));let e=await i.updateFromContext7(d,a.force);c||console.log(`✅ ${e.message}`);let r=!1,o=[],s=f(process.cwd(),`SKILL.md`);if(p(s)){let e=n(process.cwd()),t=m||e.packageName;t&&(u(s,{name:t,version:h||e.versionHint}),r=!0),o=i.getContext7ProjectFiles(d),l(s,`context7-skills`,o.map(e=>`- ${e}`).join(`
6
- `),d,`assets/references/context7/${encodeURIComponent(d)}`),r=!0,c||console.log(`📝 Updated SKILL.md with ${o.length} files`)}let g={attempted:!a[`skip-indexing`],skipped:!!a[`skip-indexing`],succeeded:!1,totalDocuments:0};if(a[`skip-indexing`])c||(console.log(`
7
- ⏭️ Skipping search indexing (as requested)`),console.log(`💡 To build index later, run: skill-creator build-index --pwd "${process.cwd()}"`));else{c||console.log(`
8
- 🔧 Building search index...`);try{await t.initialize(),await t.buildIndex(f(process.cwd(),`assets`,`references`));let e=await t.getStats();g.succeeded=!0,g.totalDocuments=e.totalDocuments||0;let n=await t.getBackendInfo();g.backendInfo=n,c||(console.log(`✅ Search index built successfully!`),console.log(`📊 Indexed ${g.totalDocuments} documents`),n&&console.log(`🎯 Active backend: ${n.backendId} (${n.mode})`))}catch(e){g.error=e instanceof Error?e.message:String(e),c||(console.log(`⚠️ Search indexing failed: ${g.error}`),console.log(`💡 You can still use search-skill with another mode, or rebuild later with: skill-creator build-index --pwd "${process.cwd()}"`))}}return{projectId:d,update:e,skillMdUpdated:r,context7Files:o,indexing:g}}catch(e){console.error(`❌ Error downloading Context7 documentation:`,e),process.exit(1)}}async function x(t,n={}){let{targetDir:r,targetFile:i,resolvedScope:a}=t,{quiet:o=!1}=n;if(m(r,{recursive:!0}),_(i,h(e(`templates/skill-creator.md`),`utf-8`)),o)return;let{default:s}=await import(`gradient-string`);console.log(s(`green`,`cyan`)(`
9
- ✅ Skill-creator subagent installed successfully!`)),console.log(`📍 Location: ${i}`),console.log(`📁 Installed scope: ${a}`),a===`user`?console.log(`💡 This makes skill-creator available in all Claude Code sessions`):console.log(`💡 This makes skill-creator available in this project only`)}async function S(e){let{default:t}=await import(`gradient-string`),n=process.cwd(),a=o(e,[{name:`scope`,type:`string`},{name:`json`,type:`boolean`}]),s,c=i(n);if(a.scope)try{s=r(a.scope,n)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exit(1)}else{console.log(t(`blue`,`cyan`)(`
10
- 🚀 Installing skill-creator as subagent...
11
- `));let{default:e}=await import(`inquirer`);s=r((await e.prompt([{type:`list`,name:`location`,message:`Where would you like to install skill-creator?`,choices:[{name:`User directory (recommended) - Available in all Claude Code sessions`,value:`user`},{name:`Current directory only - Available in this project only`,value:`current`}],default:c}])).location,n)}let l={requestedScope:s.requestedScope,resolvedScope:s.resolvedScope,defaultScope:c,targetDir:s.targetDir,targetFile:s.targetFile};a.json||console.log(`\n📦 Installing in ${s.resolvedScope===`user`?`user directory`:`current directory`}...\n`);try{await x(s,{quiet:a.json===!0}),a.json&&console.log(JSON.stringify(l,null,2))}catch(e){console.error(`❌ Installation failed:`,e instanceof Error?e.message:String(e)),process.exit(1)}}async function C(e){let t=await s({}),{ContentManager:n}=await import(`./contentManager-CwquwC1s.mjs`),r=new n({searchEngine:t,referencesDir:f(process.cwd(),`assets`,`references`)}),i=o(e,[{name:`source`,type:`string`,default:`all`}]),a=r.getContentStats();console.log(`
12
- Content Statistics:`),console.log(` User files: ${a.userFiles}`),console.log(` Context7 files: ${a.context7Files}`),console.log(` Total: ${a.totalFiles}\n`);let c=i.source===`all`?void 0:i.source,l=r.listContent(c);if(l.length===0){console.log(`No content found.`);return}console.log(`${`Title`.padEnd(40)} ${`Source`.padEnd(10)} ${`Size`.padEnd(10)} ${`Modified`.padEnd(20)}`),console.log(`-`.repeat(80)),l.forEach(e=>{console.log(`${e.title.padEnd(40)} ${e.source.padEnd(10)} ${String(e.size).padEnd(10)} ${e.modified.toLocaleString().padEnd(20)}`)})}const w={"search-skill":v,add:y,"add-skill":y,"download-context7":b,init:S,"build-index":c,"list-skills":C,"list-content":C,"remove-skill":d};async function T(e,t){let n=w[e.toLowerCase()]||w[e];n||(console.error(`❌ Unknown script: ${e}`),console.error(`Available scripts: ${Object.keys(w).join(`, `)}`),process.exit(1));try{return await n(t)}catch(t){console.error(`❌ Error executing ${e}:`,t),process.exit(1)}}export{T as runScript};
13
- //# sourceMappingURL=runScript-CSKqb831.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runScript-CSKqb831.mjs","names":["formattingOptions: FormattingOptions","readFileSync","userFiles: string[]","context7Files: string[]","indexing: CommandIndexingResult","scopeSelection: ReturnType<typeof resolveAgentInstallScopeSelection>","result: InitCommandResult","commands: Record<string, CommandFunction>"],"sources":["../src/commands/searchContent.ts","../src/commands/addContent.ts","../src/commands/downloadContext7.ts","../src/commands/init.ts","../src/commands/listSkills.ts","../src/core/runScript.ts"],"sourcesContent":["/**\n * Search skill content command\n */\n\nimport { join } from 'node:path'\nimport { parseArgs, createSearchEngine, normalizeSearchMode } from './shared.js'\nimport { createFormatter } from '../search_format/index.js'\nimport type { FormattingOptions } from '../search_format/types.js'\n\nexport async function searchContent(args: string[]): Promise<void> {\n // Parse arguments\n const options = parseArgs(args, [\n { name: 'query', alias: 'q', type: 'string', required: true },\n { name: 'top-k', type: 'number', default: 5 },\n { name: 'source', type: 'string', default: 'all' },\n { name: 'mode', type: 'string', default: 'auto' },\n { name: 'vector-embedder', type: 'string' },\n { name: 'list', type: 'boolean', default: false },\n ])\n\n const normalizedMode = normalizeSearchMode(options.mode)\n\n if (normalizedMode === 'vector') {\n const { SqliteVectorSearchAdapter } = await import('../core/sqliteVectorSearchAdapter.js')\n const runtimeSupported = await SqliteVectorSearchAdapter.isRuntimeSupported()\n if (!runtimeSupported) {\n console.error(\n '❌ Vector mode is unavailable in this runtime. It requires node:sqlite support and sqlite-vec.'\n )\n process.exit(1)\n }\n }\n\n // Create search engine\n const searchEngine = await createSearchEngine({\n searchMode: normalizedMode,\n useFormatting: false, // We'll handle formatting manually for now\n vectorEmbedder: options['vector-embedder'],\n })\n\n // Initialize search engine\n await searchEngine.initialize()\n\n // Build index if needed\n const referencesDir = join(process.cwd(), 'assets', 'references')\n await searchEngine.buildIndex(referencesDir)\n\n // Prepare search options\n const topK = options['top-k']\n const whereFilter = options.source !== 'all' ? { source: options.source } : undefined\n\n // Perform search\n const results = await searchEngine.search(options.query, topK || 5, whereFilter)\n const backendInfo = await searchEngine.getBackendInfo()\n\n console.log(`\\nSearch Results for: '${options.query}'`)\n console.log(`Requested mode: ${normalizedMode}`)\n if (backendInfo) {\n console.log(`Active backend: ${backendInfo.backendId} (${backendInfo.mode})`)\n }\n if (options['vector-embedder']) {\n console.log(`Vector embedder: ${options['vector-embedder']}`)\n }\n const autoDecisionReason =\n typeof results[0]?.metadata?.['autoDecisionReason'] === 'string' ?\n results[0].metadata['autoDecisionReason']\n : undefined\n if (autoDecisionReason) {\n console.log(`Auto decision: ${autoDecisionReason}`)\n }\n console.log('='.repeat(50))\n\n if (results.length === 0) {\n console.log('No results found.')\n return\n }\n\n // Create formatter based on options\n const formatterType = options.list ? 'list' : 'enhanced'\n const formatter = createFormatter(formatterType)\n\n // Prepare formatting options\n const formattingOptions: FormattingOptions = {\n skillPath: process.cwd(),\n query: options.query,\n showFullContentThreshold: 0.8,\n minScoreForPreview: 0.3,\n maxPreviewLength: 200,\n showLineNumbers: true,\n }\n\n // Format and display results\n const formattedResults = formatter.format(results, formattingOptions)\n\n for (let i = 0; i < formattedResults.length; i++) {\n const formattedResult = formattedResults[i]\n const result = formattedResult.result\n const sourceRank = result.metadata.sourceRank\n const sourceLabel = typeof sourceRank === 'string' ? sourceRank : 'match'\n const displayScore = result.metadata.displayScore\n const scoreLabel =\n typeof displayScore === 'number' && Number.isFinite(displayScore) ?\n displayScore.toFixed(2)\n : result.score.toFixed(2)\n\n console.log(`\\n${i + 1}. [Score: ${scoreLabel}] ${result.title}`)\n console.log(` Source: ${result.source} (${sourceLabel})`)\n if (typeof result.metadata.backendId === 'string') {\n console.log(` Backend: ${result.metadata.backendId}`)\n }\n if (typeof result.metadata.autoBackendId === 'string') {\n console.log(` Auto backend: ${result.metadata.autoBackendId}`)\n }\n console.log(` File: ${result.relativePath || result.file_path}`)\n\n // Display formatted content based on content type\n switch (formattedResult.contentType) {\n case 'full-content':\n console.log(` FileContent:`)\n console.log(` ${formattedResult.content}`)\n break\n\n case 'preview':\n if (options.list) {\n // --list mode: simple preview\n console.log(` Preview: ${formattedResult.content}`)\n } else {\n // --enhanced mode (default): enhanced preview with line numbers\n console.log(` Preview:`)\n // Extract content from <limit-content lines-indexs=\"1,3,45\">...</limit-content> format\n const limitContentMatch = formattedResult.content.match(\n /^<limit-content lines-indexs=\"([^\"]+)\">\\n(.*)\\n<\\/limit-content>$/s\n )\n if (limitContentMatch) {\n const [, lineIndexes, content] = limitContentMatch\n console.log(` Lines: ${lineIndexes}`)\n console.log(` ${content}`)\n } else {\n console.log(` ${formattedResult.content}`)\n }\n }\n break\n\n case 'metadata-only':\n console.log(` Content: (No preview - metadata only)`)\n break\n\n default:\n // Fallback to simple preview\n console.log(` Preview: ${formattedResult.content}`)\n }\n }\n}\n","/**\n * Add content command\n */\n\nimport { join } from 'node:path'\nimport { existsSync, readdirSync } from 'node:fs'\nimport { parseArgs, createSearchEngine } from './shared.js'\nimport { updateSkillMdFile } from '../utils/skillMdManager.js'\nimport type { AddContentCommandResult } from '../types/index.js'\n\nexport async function addContent(args: string[]): Promise<AddContentCommandResult> {\n const searchEngine = await createSearchEngine({})\n\n const { ContentManager } = await import('../core/contentManager.js')\n\n const contentManager = new ContentManager({\n searchEngine,\n referencesDir: join(process.cwd(), 'assets', 'references'),\n })\n\n // Parse arguments\n const options = parseArgs(args, [\n { name: 'title', alias: 't', type: 'string', required: false },\n { name: 'content', alias: 'c', type: 'string', required: false },\n { name: 'file', alias: 'f', type: 'string', required: false },\n { name: 'force', type: 'boolean' },\n { name: 'force-append', type: 'boolean' },\n { name: 'no-update', type: 'boolean' },\n { name: 'json', type: 'boolean' },\n ])\n const jsonMode = Boolean(options.json)\n\n if (!options.title && !options.file) {\n console.error('❌ Please provide either --title or --file')\n process.exit(1)\n }\n\n let content = options.content || ''\n let title = options.title || ''\n\n // Read content from file if provided\n if (options.file) {\n const { readFileSync } = await import('node:fs')\n try {\n content = readFileSync(options.file, 'utf-8')\n if (!title) {\n // Extract title from filename or first line\n const fileName =\n options.file\n .split('/')\n .pop()\n ?.replace(/\\.[^/.]+$/, '') || ''\n const firstLine = content.split('\\n')[0]?.replace(/^#+\\s*/, '') || fileName\n title = firstLine || fileName\n }\n } catch (error) {\n console.error(`❌ Failed to read file: ${options.file}`)\n process.exit(1)\n }\n }\n\n const result = await contentManager.addUserContent({\n title,\n content,\n force: options.force,\n forceAppend: options['force-append'],\n autoUpdate: !options['no-update'],\n })\n if (!jsonMode) {\n console.log(result.message)\n }\n\n // Handle existing file case\n if (result.existingFile) {\n if (!jsonMode) {\n console.log('\\n📄 Existing file content:')\n console.log('─'.repeat(50))\n console.log(result.existingFile.content)\n console.log('─'.repeat(50))\n process.exit(1)\n }\n return {\n ...result,\n skillMdUpdated: false,\n userFiles: [],\n }\n }\n\n if (!jsonMode && result.similarContent && result.similarContent.length > 0) {\n console.log('\\nSimilar content found:')\n result.similarContent.forEach((similar, i) => {\n const sourceLabel = similar.sourceRank ?? 'match'\n console.log(`\\n${i + 1}. [${similar.score.toFixed(2)}] ${similar.title}`)\n console.log(` Source: ${similar.source} (${sourceLabel})`)\n console.log(` Preview: ${similar.preview}`)\n })\n }\n\n // Update SKILL.md with user files list\n let skillMdUpdated = false\n let userFiles: string[] = []\n if (result.added || result.updated) {\n const skillMdPath = join(process.cwd(), 'SKILL.md')\n if (existsSync(skillMdPath)) {\n const userDir = join(process.cwd(), 'assets', 'references', 'user')\n if (existsSync(userDir)) {\n userFiles = readdirSync(userDir).filter((f) => f.endsWith('.md'))\n const fileList = userFiles.map((f) => `- ${f}`).join('\\n')\n\n updateSkillMdFile(skillMdPath, 'user-skills', fileList)\n skillMdUpdated = true\n if (!jsonMode) {\n console.log(`📝 Updated SKILL.md with user skills`)\n }\n }\n }\n }\n\n return {\n ...result,\n skillMdUpdated,\n userFiles,\n }\n}\n","/**\n * Download Context7 documentation command with automatic local index refresh\n */\n\nimport { join } from 'node:path'\nimport { existsSync } from 'node:fs'\nimport { parseArgs, createSearchEngine } from './shared.js'\nimport {\n updateSkillMdFile,\n updateSkillPackageMetadataFile,\n} from '../utils/skillMdManager.js'\nimport type {\n CommandIndexingResult,\n DownloadContext7CommandResult,\n} from '../types/index.js'\nimport { inferPackageMetadataFromSkill } from '../utils/skillIdentity.js'\n\nexport async function downloadContext7(\n args: string[]\n): Promise<DownloadContext7CommandResult> {\n const searchEngine = await createSearchEngine({})\n\n const { ContentManager } = await import('../core/contentManager.js')\n\n const contentManager = new ContentManager({\n searchEngine,\n referencesDir: join(process.cwd(), 'assets', 'references'),\n })\n\n // Parse arguments\n const options = parseArgs(args, [\n { name: 'force', type: 'boolean' },\n { name: 'project-id', type: 'string' },\n { name: 'package-name', type: 'string' },\n { name: 'package-version', type: 'string' },\n { name: 'skip-indexing', type: 'boolean' },\n { name: 'json', type: 'boolean' },\n ])\n const jsonMode = Boolean(options.json)\n\n const projectId = options['project-id']\n if (!projectId) {\n console.error('❌ No Context7 project ID provided')\n console.error(' Use --project-id <id>')\n process.exit(1)\n }\n\n const packageName = options['package-name']\n const packageVersion = options['package-version']\n\n try {\n if (!jsonMode) {\n console.log(`📥 Downloading Context7 documentation...`)\n console.log(`Project ID: ${projectId}`)\n }\n\n // Download documentation\n const result = await contentManager.updateFromContext7(projectId, options.force)\n if (!jsonMode) {\n console.log(`✅ ${result.message}`)\n }\n\n // Update SKILL.md with the file list\n let skillMdUpdated = false\n let context7Files: string[] = []\n const skillMdPath = join(process.cwd(), 'SKILL.md')\n if (existsSync(skillMdPath)) {\n const currentMetadata = inferPackageMetadataFromSkill(process.cwd())\n const effectivePackageName = packageName || currentMetadata.packageName\n if (effectivePackageName) {\n updateSkillPackageMetadataFile(skillMdPath, {\n name: effectivePackageName,\n version: packageVersion || currentMetadata.versionHint,\n })\n skillMdUpdated = true\n }\n\n context7Files = contentManager.getContext7ProjectFiles(projectId)\n const fileList = context7Files.map((f) => `- ${f}`).join('\\n')\n\n updateSkillMdFile(\n skillMdPath,\n 'context7-skills',\n fileList,\n projectId,\n `assets/references/context7/${encodeURIComponent(projectId)}`\n )\n skillMdUpdated = true\n if (!jsonMode) {\n console.log(`📝 Updated SKILL.md with ${context7Files.length} files`)\n }\n }\n\n // Auto-build the active local index unless skipped\n const indexing: CommandIndexingResult = {\n attempted: !options['skip-indexing'],\n skipped: Boolean(options['skip-indexing']),\n succeeded: false,\n totalDocuments: 0,\n }\n\n if (!options['skip-indexing']) {\n if (!jsonMode) {\n console.log(`\\n🔧 Building search index...`)\n }\n try {\n await searchEngine.initialize()\n await searchEngine.buildIndex(join(process.cwd(), 'assets', 'references'))\n\n const stats = await searchEngine.getStats()\n indexing.succeeded = true\n indexing.totalDocuments = stats.totalDocuments || 0\n const backendInfo = await searchEngine.getBackendInfo()\n indexing.backendInfo = backendInfo\n if (!jsonMode) {\n console.log(`✅ Search index built successfully!`)\n console.log(`📊 Indexed ${indexing.totalDocuments} documents`)\n if (backendInfo) {\n console.log(`🎯 Active backend: ${backendInfo.backendId} (${backendInfo.mode})`)\n }\n }\n } catch (error) {\n indexing.error = error instanceof Error ? error.message : String(error)\n if (!jsonMode) {\n console.log(`⚠️ Search indexing failed: ${indexing.error}`)\n console.log(\n `💡 You can still use search-skill with another mode, or rebuild later with: skill-creator build-index --pwd \"${process.cwd()}\"`\n )\n }\n }\n } else if (!jsonMode) {\n console.log(`\\n⏭️ Skipping search indexing (as requested)`)\n console.log(`💡 To build index later, run: skill-creator build-index --pwd \"${process.cwd()}\"`)\n }\n\n return {\n projectId,\n update: result,\n skillMdUpdated,\n context7Files,\n indexing,\n }\n } catch (error) {\n console.error(`❌ Error downloading Context7 documentation:`, error)\n process.exit(1)\n }\n}\n","/**\n * Interactive init command to install skill-creator as subagent\n */\n\nimport { mkdirSync, writeFileSync, readFileSync } from 'node:fs'\nimport { parseArgs } from './shared.js'\nimport { rootResolver } from '../utils/path.js'\nimport {\n type DefaultScopedLocation,\n getDefaultScopedLocation,\n resolveAgentInstallScopeSelection,\n} from '../utils/scopeSelection.js'\n\ninterface InitCliOptions {\n scope?: string\n json?: boolean\n}\n\ninterface InitCommandResult {\n requestedScope: string\n resolvedScope: DefaultScopedLocation\n defaultScope: DefaultScopedLocation\n targetDir: string\n targetFile: string\n}\n\n/**\n * Install skill-creator as subagent in specified directory\n */\nasync function installSubagent(\n selection: ReturnType<typeof resolveAgentInstallScopeSelection>,\n options: {\n quiet?: boolean\n } = {}\n): Promise<void> {\n const { targetDir, targetFile, resolvedScope } = selection\n const { quiet = false } = options\n\n // Create directories\n mkdirSync(targetDir, { recursive: true })\n\n // Read the skill-creator template\n const templatePath = rootResolver('templates/skill-creator.md')\n const templateContent = readFileSync(templatePath, 'utf-8')\n\n // Write skill-creator.md file\n writeFileSync(targetFile, templateContent)\n\n if (quiet) {\n return\n }\n\n const { default: gradient } = await import('gradient-string')\n console.log(gradient('green', 'cyan')('\\n✅ Skill-creator subagent installed successfully!'))\n console.log(`📍 Location: ${targetFile}`)\n console.log(`📁 Installed scope: ${resolvedScope}`)\n\n if (resolvedScope === 'user') {\n console.log('💡 This makes skill-creator available in all Claude Code sessions')\n } else {\n console.log('💡 This makes skill-creator available in this project only')\n }\n}\n\nexport async function init(args: string[]): Promise<void> {\n const { default: gradient } = await import('gradient-string')\n const cwd = process.cwd()\n\n // Parse arguments\n const options = parseArgs(args, [\n { name: 'scope', type: 'string' },\n { name: 'json', type: 'boolean' },\n ]) as InitCliOptions\n\n let scopeSelection: ReturnType<typeof resolveAgentInstallScopeSelection>\n const defaultScope = getDefaultScopedLocation(cwd)\n\n // Non-interactive mode if scope is provided\n if (options.scope) {\n try {\n scopeSelection = resolveAgentInstallScopeSelection(options.scope, cwd)\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error))\n process.exit(1)\n }\n } else {\n // Interactive mode\n console.log(gradient('blue', 'cyan')('\\n🚀 Installing skill-creator as subagent...\\n'))\n\n const { default: inquirer } = await import('inquirer')\n\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'location',\n message: 'Where would you like to install skill-creator?',\n choices: [\n {\n name: 'User directory (recommended) - Available in all Claude Code sessions',\n value: 'user',\n },\n {\n name: 'Current directory only - Available in this project only',\n value: 'current',\n },\n ],\n default: defaultScope,\n },\n ])\n\n scopeSelection = resolveAgentInstallScopeSelection(answers.location, cwd)\n }\n\n const result: InitCommandResult = {\n requestedScope: scopeSelection.requestedScope,\n resolvedScope: scopeSelection.resolvedScope,\n defaultScope,\n targetDir: scopeSelection.targetDir,\n targetFile: scopeSelection.targetFile,\n }\n\n if (!options.json) {\n console.log(\n `\\n📦 Installing in ${\n scopeSelection.resolvedScope === 'user' ? 'user directory' : 'current directory'\n }...\\n`\n )\n }\n\n try {\n await installSubagent(scopeSelection, { quiet: options.json === true })\n if (options.json) {\n console.log(JSON.stringify(result, null, 2))\n }\n } catch (error) {\n console.error('❌ Installation failed:', error instanceof Error ? error.message : String(error))\n process.exit(1)\n }\n}\n","/**\n * List skills command\n */\n\nimport { join } from 'node:path'\nimport { parseArgs, createSearchEngine } from './shared.js'\n\nexport async function listSkills(args: string[]): Promise<void> {\n const searchEngine = await createSearchEngine({})\n\n const { ContentManager } = await import('../core/contentManager.js')\n\n const contentManager = new ContentManager({\n searchEngine,\n referencesDir: join(process.cwd(), 'assets', 'references'),\n })\n\n // Parse arguments\n const options = parseArgs(args, [{ name: 'source', type: 'string', default: 'all' }])\n\n // Get stats\n const stats = contentManager.getContentStats()\n console.log(`\\nContent Statistics:`)\n console.log(` User files: ${stats.userFiles}`)\n console.log(` Context7 files: ${stats.context7Files}`)\n console.log(` Total: ${stats.totalFiles}\\n`)\n\n // List content\n const sourceFilter = options.source === 'all' ? undefined : options.source\n const contentList = contentManager.listContent(sourceFilter)\n\n if (contentList.length === 0) {\n console.log('No content found.')\n return\n }\n\n console.log(\n `${'Title'.padEnd(40)} ${'Source'.padEnd(10)} ${'Size'.padEnd(10)} ${'Modified'.padEnd(20)}`\n )\n console.log('-'.repeat(80))\n\n contentList.forEach((item) => {\n console.log(\n `${item.title.padEnd(40)} ${item.source.padEnd(10)} ${String(item.size).padEnd(10)} ${item.modified.toLocaleString().padEnd(20)}`\n )\n })\n}\n","/**\n * Execute skill scripts - simplified version using individual command files\n */\n\nimport { searchContent } from '../commands/searchContent.js'\nimport { addContent } from '../commands/addContent.js'\nimport { downloadContext7 } from '../commands/downloadContext7.js'\nimport { init } from '../commands/init.js'\nimport { buildIndex } from '../commands/buildIndex.js'\nimport { listSkills } from '../commands/listSkills.js'\nimport { removeSkill } from '../commands/removeSkill.js'\n\ntype CommandFunction = (args: string[]) => Promise<unknown>\n\nconst commands: Record<string, CommandFunction> = {\n 'search-skill': searchContent,\n add: addContent,\n 'add-skill': addContent,\n 'download-context7': downloadContext7,\n init: init,\n 'build-index': buildIndex,\n 'list-skills': listSkills,\n 'list-content': listSkills, // Backward compatibility\n 'remove-skill': removeSkill,\n}\n\nexport async function runScript(script: string, args: string[]): Promise<unknown> {\n // Normalize script name\n const normalizedScript = script.toLowerCase()\n\n // Find the command\n const command = commands[normalizedScript] || commands[script]\n\n if (!command) {\n console.error(`❌ Unknown script: ${script}`)\n console.error(`Available scripts: ${Object.keys(commands).join(', ')}`)\n process.exit(1)\n }\n\n try {\n return await command(args)\n } catch (error) {\n console.error(`❌ Error executing ${script}:`, error)\n process.exit(1)\n }\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{t as e}from"./package-CFJazwTO.mjs";import t,{join as n}from"node:path";import{existsSync as r,readFileSync as i,readdirSync as a,realpathSync as o}from"node:fs";import{homedir as s}from"node:os";function c(e){let n=t.basename(e),r=n.lastIndexOf(`@`);if(!(r<=0||r===n.length-1))return n.slice(r+1)}function l(e){let t=n(e,`SKILL.md`);if(!r(t))return{};let a=i(t,`utf-8`).match(/<skill-package\s+name="([^"]*)"\s+version="([^"]*)">\s*<\/skill-package>/);if(!a)return{};let[,o,s]=a;return{packageName:o||void 0,versionHint:s||void 0}}function u(e,t){if(!r(e))return;let i=a(e,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(t=>n(e,t.name));for(let e of i)if(l(e).packageName===t)return e}function d(t,i){if(!r(t))return;let o=e.normalizePackageName(i),s=a(t,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name).filter(e=>e.toLowerCase().includes(o));return s.length>0?n(t,s[0]):void 0}function f(e=process.cwd()){return[n(e,`.claude`,`skills`),n(s(),`.claude`,`skills`)]}function p(e,t,n=process.cwd()){let r=e.pwd||t.pwd;if(r)return m(r);if(!e.package)throw Error(`Could not find skill directory. Please provide --pwd or a valid --package.`);let i=f(n),a=(i.map(t=>u(t,e.package)).find(Boolean)??void 0)||i.map(t=>d(t,e.package)).find(Boolean);if(a)return m(a);throw Error(`Could not find skill directory. Please provide --pwd or a valid --package.`)}function m(e){try{return o.native(e)}catch{return t.resolve(e)}}function h(e){return r(n(e,`.claude`,`agents`,`skill-creator.md`))}function g(e){return h(e)?`current`:`user`}function _(e,n,r=e){return e===`auto`?_(g(n),n,r):e===`user`?{requestedScope:r,resolvedScope:`user`,scopePath:t.join(s(),`.claude`,`skills`)}:e===`current`?{requestedScope:r,resolvedScope:`current`,scopePath:t.join(n,`.claude`,`skills`)}:{requestedScope:r,resolvedScope:`custom`,scopePath:e}}function v(e,t,r=e){if(e===`auto`)return v(g(t),t,r);if(e===`user`){let e=n(s(),`.claude`,`agents`);return{requestedScope:r,resolvedScope:`user`,targetDir:e,targetFile:n(e,`skill-creator.md`)}}if(e===`current`){let e=n(t,`.claude`,`agents`);return{requestedScope:r,resolvedScope:`current`,targetDir:e,targetFile:n(e,`skill-creator.md`)}}throw Error(`❌ Invalid scope value. Use: user, current, or auto`)}export{c as a,l as i,v as n,p as o,_ as r,g as t};
2
- //# sourceMappingURL=scopeSelection-BWteJQSv.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scopeSelection-BWteJQSv.mjs","names":[],"sources":["../src/utils/skillIdentity.ts","../src/utils/scopeSelection.ts"],"sourcesContent":["import path, { join } from 'node:path'\nimport { readdirSync, existsSync, readFileSync, realpathSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { PackageUtils } from './package.js'\n\nexport interface SkillPackageMetadata {\n packageName?: string\n versionHint?: string\n}\n\nexport function inferVersionHintFromSkillDirectory(skillDir: string): string | undefined {\n const skillDirName = path.basename(skillDir)\n const versionSeparator = skillDirName.lastIndexOf('@')\n\n if (versionSeparator <= 0 || versionSeparator === skillDirName.length - 1) {\n return undefined\n }\n\n return skillDirName.slice(versionSeparator + 1)\n}\n\nexport function inferPackageMetadataFromSkill(skillDir: string): SkillPackageMetadata {\n const skillMdPath = join(skillDir, 'SKILL.md')\n if (!existsSync(skillMdPath)) {\n return {}\n }\n\n const skillMdContent = readFileSync(skillMdPath, 'utf-8')\n const packageTagMatch = skillMdContent.match(\n /<skill-package\\s+name=\"([^\"]*)\"\\s+version=\"([^\"]*)\">\\s*<\\/skill-package>/\n )\n\n if (!packageTagMatch) {\n return {}\n }\n\n const [, packageName, versionHint] = packageTagMatch\n return {\n packageName: packageName || undefined,\n versionHint: versionHint || undefined,\n }\n}\n\nexport function findSkillDirectoryByPackageMetadata(\n base: string,\n packageName: string\n): string | undefined {\n if (!existsSync(base)) return undefined\n\n const dirs = readdirSync(base, { withFileTypes: true })\n .filter((dirent) => dirent.isDirectory())\n .map((dirent) => join(base, dirent.name))\n\n for (const dir of dirs) {\n const metadata = inferPackageMetadataFromSkill(dir)\n if (metadata.packageName === packageName) {\n return dir\n }\n }\n\n return undefined\n}\n\nexport function findSkillDirectoryByName(base: string, packageName: string): string | undefined {\n if (!existsSync(base)) return undefined\n\n const normalizedPackageName = PackageUtils.normalizePackageName(packageName)\n const dirs = readdirSync(base, { withFileTypes: true })\n .filter((dirent) => dirent.isDirectory())\n .map((dirent) => dirent.name)\n .filter((name) => name.toLowerCase().includes(normalizedPackageName))\n\n return dirs.length > 0 ? join(base, dirs[0]) : undefined\n}\n\nexport function getSkillSearchBases(cwd: string = process.cwd()): string[] {\n return [join(cwd, '.claude', 'skills'), join(homedir(), '.claude', 'skills')]\n}\n\nexport function resolveSkillDirectoryFromOptions(\n commandOptions: {\n pwd?: string\n package?: string\n },\n globalOptions: {\n pwd?: string\n },\n cwd: string = process.cwd()\n): string {\n const pwd = commandOptions.pwd || globalOptions.pwd\n\n if (pwd) {\n return resolveCanonicalPath(pwd)\n }\n\n if (!commandOptions.package) {\n throw new Error('Could not find skill directory. Please provide --pwd or a valid --package.')\n }\n\n const searchBases = getSkillSearchBases(cwd)\n const metadataMatchedSkillDir =\n searchBases\n .map((base) => findSkillDirectoryByPackageMetadata(base, commandOptions.package as string))\n .find(Boolean) ?? undefined\n\n const skillDir =\n metadataMatchedSkillDir ||\n searchBases.map((base) => findSkillDirectoryByName(base, commandOptions.package as string)).find(Boolean)\n\n if (skillDir) {\n return resolveCanonicalPath(skillDir)\n }\n\n throw new Error('Could not find skill directory. Please provide --pwd or a valid --package.')\n}\n\nfunction resolveCanonicalPath(targetPath: string): string {\n try {\n return realpathSync.native(targetPath)\n } catch {\n return path.resolve(targetPath)\n }\n}\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport path, { join } from 'node:path'\n\nexport type DefaultScopedLocation = 'current' | 'user'\nexport type ResolvedStorageScope = DefaultScopedLocation | 'custom'\n\nexport function hasProjectSkillCreatorAgent(cwd: string): boolean {\n return existsSync(join(cwd, '.claude', 'agents', 'skill-creator.md'))\n}\n\nexport function getDefaultScopedLocation(cwd: string): DefaultScopedLocation {\n return hasProjectSkillCreatorAgent(cwd) ? 'current' : 'user'\n}\n\nexport function resolveStorageScopeSelection(\n scope: string,\n cwd: string,\n requestedScope: string = scope\n): {\n requestedScope: string\n resolvedScope: ResolvedStorageScope\n scopePath: string\n} {\n if (scope === 'auto') {\n return resolveStorageScopeSelection(getDefaultScopedLocation(cwd), cwd, requestedScope)\n }\n\n if (scope === 'user') {\n return {\n requestedScope,\n resolvedScope: 'user',\n scopePath: path.join(homedir(), '.claude', 'skills'),\n }\n }\n\n if (scope === 'current') {\n return {\n requestedScope,\n resolvedScope: 'current',\n scopePath: path.join(cwd, '.claude', 'skills'),\n }\n }\n\n return {\n requestedScope,\n resolvedScope: 'custom',\n scopePath: scope,\n }\n}\n\nexport function resolveAgentInstallScopeSelection(\n scope: string,\n cwd: string,\n requestedScope: string = scope\n): {\n requestedScope: string\n resolvedScope: DefaultScopedLocation\n targetDir: string\n targetFile: string\n} {\n if (scope === 'auto') {\n return resolveAgentInstallScopeSelection(getDefaultScopedLocation(cwd), cwd, requestedScope)\n }\n\n if (scope === 'user') {\n const targetDir = join(homedir(), '.claude', 'agents')\n return {\n requestedScope,\n resolvedScope: 'user',\n targetDir,\n targetFile: join(targetDir, 'skill-creator.md'),\n }\n }\n\n if (scope === 'current') {\n const targetDir = join(cwd, '.claude', 'agents')\n return {\n requestedScope,\n resolvedScope: 'current',\n targetDir,\n targetFile: join(targetDir, 'skill-creator.md'),\n }\n }\n\n throw new Error('❌ Invalid scope value. Use: user, current, or auto')\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- function e(e,u){if(e.length===0)return{overallScore:0,reason:`No results found`,maxScore:0,averageScore:0,results:[]};let d=e.map(e=>e.score),f=Math.max(...d),p=Math.min(...d),m=d.reduce((e,t)=>e+t,0)/d.length,h=a(u??``),g=o(h),_=Math.max(1,e.length-1),v=e.map((o,c)=>{let u=r(o),d=i(o.score,u),m=f===p?e.length===1?1:l(1-c/_):l((o.score-p)/(f-p)),v=a(o.title),y=a(o.content),b=s(v,g),x=s(y,g),S=Math.max(b,x),C=h.length>0&&v.includes(h),w=h.length>0&&y.includes(h);return{result:o,index:c,backendId:u,calibratedScore:d,displayScore:n({calibratedScore:d,relativeScore:m,queryCoverage:S,exactTitleMatch:C,exactPhraseMatch:w}),relativeScore:m,titleCoverage:b,contentCoverage:x,queryCoverage:S,exactTitleMatch:C,exactPhraseMatch:w,displayTier:t({index:c,calibratedScore:d,relativeScore:m,queryCoverage:S,exactTitleMatch:C,exactPhraseMatch:w})}}),y=v[0],b=v.filter(e=>e.displayTier!==`metadata-only`),x=Math.max(y.calibratedScore,y.queryCoverage,y.exactTitleMatch?1:0,y.exactPhraseMatch?.85:0),S=b.length/Math.min(v.length,3),C=l(x*.7+S*.2+y.relativeScore*.1);return y.queryCoverage===0&&!y.exactTitleMatch&&!y.exactPhraseMatch&&y.calibratedScore<.25&&(C=Math.min(C,.25)),{overallScore:C,reason:c(y,b.length),maxScore:f,averageScore:m,results:v}}function t(e){return e.index===0?`full`:e.exactTitleMatch||e.exactPhraseMatch||e.queryCoverage>=.5||e.relativeScore>=.75||e.calibratedScore>=.8?`preview`:`metadata-only`}function n(e){let t=e.exactTitleMatch?.05:e.exactPhraseMatch?.025:0;return l(e.calibratedScore*.5+e.relativeScore*.25+e.queryCoverage*.2+t)}function r(e){let t=(e.metadata??{}).backendId;return t===`minisearch`||t===`ufuzzy`||t===`sqlite-vec`?t:t===`direct-user-match`?`unknown`:e.score>1?`minisearch`:`unknown`}function i(e,t){return l(t===`minisearch`?e/(e+3):e)}function a(e){return e.toLowerCase()}function o(e){return e.match(/[\p{L}\p{N}]+/gu)??[]}function s(e,t){if(t.length===0)return 0;let n=0;for(let r of t)e.includes(r)&&(n+=1);return n/t.length}function c(e,t){return e.exactTitleMatch?`Exact title match found`:e.exactPhraseMatch?`Exact content phrase match found`:e.queryCoverage>=.75?`Strong query coverage in top result`:t>=2&&e.relativeScore>=.75?`Multiple supporting results found`:e.calibratedScore<.25&&e.queryCoverage===0?`Weak full-text confidence`:`Moderate search confidence`}function l(e){return Number.isNaN(e)||e<0?0:e>1?1:e}export{e as t};
2
- //# sourceMappingURL=searchQuality-DVdHmamh.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"searchQuality-DVdHmamh.mjs","names":[],"sources":["../src/core/searchQuality.ts"],"sourcesContent":["import type { SearchBackendId, SearchResult } from './searchAdapter.js'\n\nexport type SearchDisplayTier = 'full' | 'preview' | 'metadata-only'\n\nexport interface SearchResultQuality {\n result: SearchResult\n index: number\n backendId: SearchBackendId | 'unknown'\n calibratedScore: number\n displayScore: number\n relativeScore: number\n titleCoverage: number\n contentCoverage: number\n queryCoverage: number\n exactTitleMatch: boolean\n exactPhraseMatch: boolean\n displayTier: SearchDisplayTier\n}\n\nexport interface SearchQualitySummary {\n overallScore: number\n reason: string\n maxScore: number\n averageScore: number\n results: SearchResultQuality[]\n}\n\nconst MINI_SEARCH_SOFT_CAP = 3\n\nexport function analyzeSearchQuality(\n results: SearchResult[],\n query?: string\n): SearchQualitySummary {\n if (results.length === 0) {\n return {\n overallScore: 0,\n reason: 'No results found',\n maxScore: 0,\n averageScore: 0,\n results: [],\n }\n }\n\n const rawScores = results.map((result) => result.score)\n const maxScore = Math.max(...rawScores)\n const minScore = Math.min(...rawScores)\n const averageScore = rawScores.reduce((sum, score) => sum + score, 0) / rawScores.length\n\n const normalizedQuery = normalizeText(query ?? '')\n const queryTokens = tokenize(normalizedQuery)\n const lastIndex = Math.max(1, results.length - 1)\n\n const qualityResults = results.map((result, index) => {\n const backendId = resolveBackendId(result)\n const calibratedScore = calibrateScore(result.score, backendId)\n const relativeScore =\n maxScore === minScore\n ? results.length === 1\n ? 1\n : clamp(1 - index / lastIndex)\n : clamp((result.score - minScore) / (maxScore - minScore))\n\n const titleText = normalizeText(result.title)\n const contentText = normalizeText(result.content)\n const titleCoverage = calculateCoverage(titleText, queryTokens)\n const contentCoverage = calculateCoverage(contentText, queryTokens)\n const queryCoverage = Math.max(titleCoverage, contentCoverage)\n const exactTitleMatch = normalizedQuery.length > 0 && titleText.includes(normalizedQuery)\n const exactPhraseMatch = normalizedQuery.length > 0 && contentText.includes(normalizedQuery)\n const displayScore = calculateDisplayScore({\n calibratedScore,\n relativeScore,\n queryCoverage,\n exactTitleMatch,\n exactPhraseMatch,\n })\n\n return {\n result,\n index,\n backendId,\n calibratedScore,\n displayScore,\n relativeScore,\n titleCoverage,\n contentCoverage,\n queryCoverage,\n exactTitleMatch,\n exactPhraseMatch,\n displayTier: recommendDisplayTier({\n index,\n calibratedScore,\n relativeScore,\n queryCoverage,\n exactTitleMatch,\n exactPhraseMatch,\n }),\n } satisfies SearchResultQuality\n })\n\n const topResult = qualityResults[0]\n const supportiveResults = qualityResults.filter((result) => result.displayTier !== 'metadata-only')\n const topSignal = Math.max(\n topResult.calibratedScore,\n topResult.queryCoverage,\n topResult.exactTitleMatch ? 1 : 0,\n topResult.exactPhraseMatch ? 0.85 : 0\n )\n const supportScore = supportiveResults.length / Math.min(qualityResults.length, 3)\n\n let overallScore = clamp(topSignal * 0.7 + supportScore * 0.2 + topResult.relativeScore * 0.1)\n\n if (\n topResult.queryCoverage === 0 &&\n !topResult.exactTitleMatch &&\n !topResult.exactPhraseMatch &&\n topResult.calibratedScore < 0.25\n ) {\n overallScore = Math.min(overallScore, 0.25)\n }\n\n return {\n overallScore,\n reason: describeQuality(topResult, supportiveResults.length),\n maxScore,\n averageScore,\n results: qualityResults,\n }\n}\n\nfunction recommendDisplayTier(input: {\n index: number\n calibratedScore: number\n relativeScore: number\n queryCoverage: number\n exactTitleMatch: boolean\n exactPhraseMatch: boolean\n}): SearchDisplayTier {\n if (input.index === 0) {\n return 'full'\n }\n\n if (\n input.exactTitleMatch ||\n input.exactPhraseMatch ||\n input.queryCoverage >= 0.5 ||\n input.relativeScore >= 0.75 ||\n input.calibratedScore >= 0.8\n ) {\n return 'preview'\n }\n\n return 'metadata-only'\n}\n\nfunction calculateDisplayScore(input: {\n calibratedScore: number\n relativeScore: number\n queryCoverage: number\n exactTitleMatch: boolean\n exactPhraseMatch: boolean\n}): number {\n const exactBonus =\n input.exactTitleMatch ? 0.05 :\n input.exactPhraseMatch ? 0.025 :\n 0\n\n return clamp(\n input.calibratedScore * 0.5 + input.relativeScore * 0.25 + input.queryCoverage * 0.2 + exactBonus\n )\n}\n\nfunction resolveBackendId(result: SearchResult): SearchBackendId | 'unknown' {\n const metadata = result.metadata ?? {}\n const backendId = metadata['backendId']\n\n if (\n backendId === 'minisearch' ||\n backendId === 'ufuzzy' ||\n backendId === 'sqlite-vec'\n ) {\n return backendId\n }\n\n if (backendId === 'direct-user-match') {\n return 'unknown'\n }\n\n return result.score > 1 ? 'minisearch' : 'unknown'\n}\n\nfunction calibrateScore(score: number, backendId: SearchBackendId | 'unknown'): number {\n if (backendId === 'minisearch') {\n return clamp(score / (score + MINI_SEARCH_SOFT_CAP))\n }\n\n return clamp(score)\n}\n\nfunction normalizeText(value: string): string {\n return value.toLowerCase()\n}\n\nfunction tokenize(value: string): string[] {\n return value.match(/[\\p{L}\\p{N}]+/gu) ?? []\n}\n\nfunction calculateCoverage(text: string, queryTokens: string[]): number {\n if (queryTokens.length === 0) {\n return 0\n }\n\n let matched = 0\n for (const token of queryTokens) {\n if (text.includes(token)) {\n matched += 1\n }\n }\n\n return matched / queryTokens.length\n}\n\nfunction describeQuality(topResult: SearchResultQuality, supportiveCount: number): string {\n if (topResult.exactTitleMatch) {\n return 'Exact title match found'\n }\n\n if (topResult.exactPhraseMatch) {\n return 'Exact content phrase match found'\n }\n\n if (topResult.queryCoverage >= 0.75) {\n return 'Strong query coverage in top result'\n }\n\n if (supportiveCount >= 2 && topResult.relativeScore >= 0.75) {\n return 'Multiple supporting results found'\n }\n\n if (topResult.calibratedScore < 0.25 && topResult.queryCoverage === 0) {\n return 'Weak full-text confidence'\n }\n\n return 'Moderate search confidence'\n}\n\nfunction clamp(value: number): number {\n if (Number.isNaN(value)) return 0\n if (value < 0) return 0\n if (value > 1) return 1\n return value\n}\n"],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- import{t as e}from"./searchQuality-DVdHmamh.mjs";import{relative as t}from"node:path";var n=class{getName(){return`list`}getDescription(){return`Simple list format with basic preview`}format(t,n){let r=n.maxPreviewLength||200,i=e(t,n.query);return t.map((e,t)=>{let a=i.results[t],o=e;this.getRelativePath(o,n.skillPath);let s=e.content;if(o.fullContent){let e=o.fullContent.match(/^<content lines="\d+">\n(.*)\n<\/content>$/s);e&&(s=e[1])}let c=this.createPreview(s,r);return o.metadata={...o.metadata,displayRank:t+1,displayScore:Number(((a?.displayScore??0)*100).toFixed(2)),sourceRank:t===0?`primary`:`secondary`},{result:o,content:c,contentType:`preview`,priority:t}})}getRelativePath(e,n){return e.relativePath||t(n,e.file_path)}createPreview(e,t){return e.length<=t?e.replace(/\n/g,` `):e.substring(0,t).replace(/\n/g,` `)+`...`}},r=class{getName(){return`enhanced`}getDescription(){return`Three-tier enhanced format with intelligent content display`}format(t,n){if(t.length===0)return[];let r=e(t,n.query);return this.enhanceResults(r,n).map((e,t)=>({result:e,content:this.formatByTier(e,n),contentType:this.getContentType(e),priority:t}))}enhanceResults(e,n){let{skillPath:r}=n;return e.results.map(n=>{let i=n.result,a=i,o,s;return n.displayTier===`full`?o=this.wrapContent(i.content,`content`):n.displayTier===`preview`&&(s=this.createEnhancedPreview(i.content)),a.relativePath=t(r,i.file_path),a.metadata={...i.metadata,displayRank:n.index+1,displayScore:Number((n.displayScore*100).toFixed(2)),sourceRank:n.index===0?`primary`:`secondary`,displayTier:n.displayTier,maxScore:e.maxScore,averageScore:e.averageScore,qualityScore:n.calibratedScore,relativeScore:n.relativeScore,queryCoverage:n.queryCoverage},o&&(a.fullContent=o),s&&(a.preview=s),a})}formatByTier(e,t){switch(e.metadata.displayTier){case`full`:return e.fullContent||``;case`preview`:return e.preview||``;case`metadata-only`:return`Content: (No preview - metadata only)`;default:return`${e.content.substring(0,200).replace(/\n/g,` `)}...`}}getContentType(e){switch(e.metadata.displayTier){case`full`:return`full-content`;case`preview`:return`preview`;default:return`metadata-only`}}createEnhancedPreview(e){let t=e.split(`
2
- `),n=[],r=[];if(t.length>0&&(r.push(t[0]),n.push(1)),t.length>2){let e=Math.floor(t.length/2);r.push(t[e]),n.push(e+1)}t.length>1&&(r.push(t[t.length-1]),n.push(t.length));let i=r.join(`
3
- `),a=n.join(`,`);return this.wrapContent(i,`limit-content`,a)}wrapContent(e,t,n){return t===`limit-content`&&n?`<${t} lines-indexs="${n}">\n${e}\n</${t}>`:t===`content`?`<${t} lines="${e.split(`
4
- `).length}">\n${e}\n</${t}>`:e}};function i(e){switch(e){case`list`:return new n;case`enhanced`:return new r;default:throw Error(`Unknown formatter type: ${e}`)}}export{i as t};
5
- //# sourceMappingURL=search_format-RyjXACJa.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"search_format-RyjXACJa.mjs","names":["fullContent: string | undefined","preview: string | undefined","lineNumbers: number[]","selectedLines: string[]"],"sources":["../src/search_format/listFormatter.ts","../src/search_format/enhancedFormatter.ts","../src/search_format/index.ts"],"sourcesContent":["/**\n * Simple list formatter for search results\n * Shows basic information with minimal preview\n */\n\nimport type {\n SearchResult,\n FormattableSearchResult,\n FormattingOptions,\n FormattedResult,\n SearchFormatter,\n} from './types.js'\nimport { relative } from 'node:path'\nimport { analyzeSearchQuality } from '../core/searchQuality.js'\n\n/**\n * List formatter - simple, clean display with basic preview\n */\nexport class ListFormatter implements SearchFormatter {\n getName(): string {\n return 'list'\n }\n\n getDescription(): string {\n return 'Simple list format with basic preview'\n }\n\n format(results: SearchResult[], options: FormattingOptions): FormattedResult[] {\n const maxPreviewLength = options.maxPreviewLength || 200\n const qualitySummary = analyzeSearchQuality(results, options.query)\n\n return results.map((result, index) => {\n const qualityResult = qualitySummary.results[index]\n const formattableResult = result as FormattableSearchResult\n const relativePath = this.getRelativePath(formattableResult, options.skillPath)\n\n // Extract content for preview\n let previewContent = result.content\n if (formattableResult.fullContent) {\n // Extract original content from <content lines=\"N\">...</content> format\n const match = formattableResult.fullContent.match(\n /^<content lines=\"\\d+\">\\n(.*)\\n<\\/content>$/s\n )\n if (match) {\n previewContent = match[1]\n }\n }\n\n // Create preview\n const preview = this.createPreview(previewContent, maxPreviewLength)\n formattableResult.metadata = {\n ...formattableResult.metadata,\n displayRank: index + 1,\n displayScore: Number(((qualityResult?.displayScore ?? 0) * 100).toFixed(2)),\n sourceRank: index === 0 ? 'primary' : 'secondary',\n }\n\n return {\n result: formattableResult,\n content: preview,\n contentType: 'preview',\n priority: index,\n }\n })\n }\n\n private getRelativePath(result: FormattableSearchResult, skillPath: string): string {\n return result.relativePath || relative(skillPath, result.file_path)\n }\n\n private createPreview(content: string, maxLength: number): string {\n if (content.length <= maxLength) {\n return content.replace(/\\n/g, ' ')\n }\n\n const preview = content.substring(0, maxLength)\n return preview.replace(/\\n/g, ' ') + '...'\n }\n}\n","import type {\n SearchResult,\n FormattableSearchResult,\n FormattingOptions,\n FormattedResult,\n SearchFormatter,\n} from './types.js'\nimport { relative } from 'node:path'\nimport { analyzeSearchQuality } from '../core/searchQuality.js'\n\n/**\n * Enhanced formatter - user-facing three-tier display driven by shared search quality signals.\n */\nexport class EnhancedFormatter implements SearchFormatter {\n getName(): string {\n return 'enhanced'\n }\n\n getDescription(): string {\n return 'Three-tier enhanced format with intelligent content display'\n }\n\n format(results: SearchResult[], options: FormattingOptions): FormattedResult[] {\n if (results.length === 0) {\n return []\n }\n\n const qualitySummary = analyzeSearchQuality(results, options.query)\n const enhancedResults = this.enhanceResults(qualitySummary, options)\n\n // Format based on display tiers\n return enhancedResults.map((result, index) => {\n const formattedContent = this.formatByTier(result, options)\n const contentType = this.getContentType(result)\n\n return {\n result,\n content: formattedContent,\n contentType,\n priority: index,\n }\n })\n }\n\n private enhanceResults(\n qualitySummary: ReturnType<typeof analyzeSearchQuality>,\n options: FormattingOptions\n ): FormattableSearchResult[] {\n const { skillPath } = options\n\n return qualitySummary.results.map((qualityResult) => {\n const result = qualityResult.result\n const enhancedResult = result as FormattableSearchResult\n let fullContent: string | undefined\n let preview: string | undefined\n\n if (qualityResult.displayTier === 'full') {\n fullContent = this.wrapContent(result.content, 'content')\n } else if (qualityResult.displayTier === 'preview') {\n preview = this.createEnhancedPreview(result.content)\n }\n\n // 设置相对路径\n enhancedResult.relativePath = relative(skillPath, result.file_path)\n\n // 添加质量元数据\n enhancedResult.metadata = {\n ...result.metadata,\n displayRank: qualityResult.index + 1,\n displayScore: Number((qualityResult.displayScore * 100).toFixed(2)),\n sourceRank: qualityResult.index === 0 ? 'primary' : 'secondary',\n displayTier: qualityResult.displayTier,\n maxScore: qualitySummary.maxScore,\n averageScore: qualitySummary.averageScore,\n qualityScore: qualityResult.calibratedScore,\n relativeScore: qualityResult.relativeScore,\n queryCoverage: qualityResult.queryCoverage,\n }\n\n if (fullContent) enhancedResult.fullContent = fullContent\n if (preview) enhancedResult.preview = preview\n\n return enhancedResult\n })\n }\n\n /**\n * Format content based on display tier\n */\n private formatByTier(result: FormattableSearchResult, options: FormattingOptions): string {\n const tier = result.metadata.displayTier\n\n switch (tier) {\n case 'full':\n return result.fullContent || ''\n\n case 'preview':\n return result.preview || ''\n\n case 'metadata-only':\n return 'Content: (No preview - metadata only)'\n\n default:\n return `${result.content.substring(0, 200).replace(/\\n/g, ' ')}...`\n }\n }\n\n /**\n * Get content type for styling\n */\n private getContentType(result: FormattableSearchResult): FormattedResult['contentType'] {\n switch (result.metadata.displayTier) {\n case 'full':\n return 'full-content'\n case 'preview':\n return 'preview'\n default:\n return 'metadata-only'\n }\n }\n\n /**\n * Create enhanced preview with line numbers\n */\n private createEnhancedPreview(content: string): string {\n const lines = content.split('\\n')\n const lineNumbers: number[] = []\n\n // Select representative lines (first, middle, last)\n const selectedLines: string[] = []\n if (lines.length > 0) {\n selectedLines.push(lines[0])\n lineNumbers.push(1)\n }\n\n if (lines.length > 2) {\n const middleLine = Math.floor(lines.length / 2)\n selectedLines.push(lines[middleLine])\n lineNumbers.push(middleLine + 1)\n }\n\n if (lines.length > 1) {\n selectedLines.push(lines[lines.length - 1])\n lineNumbers.push(lines.length)\n }\n\n const previewContent = selectedLines.join('\\n')\n const lineIndexes = lineNumbers.join(',')\n\n return this.wrapContent(previewContent, 'limit-content', lineIndexes)\n }\n\n /**\n * Wrap content in appropriate tags\n */\n private wrapContent(content: string, tag: string, lineIndexes?: string): string {\n if (tag === 'limit-content' && lineIndexes) {\n return `<${tag} lines-indexs=\"${lineIndexes}\">\\n${content}\\n</${tag}>`\n } else if (tag === 'content') {\n const lines = content.split('\\n').length\n return `<${tag} lines=\"${lines}\">\\n${content}\\n</${tag}>`\n }\n return content\n }\n}\n","/**\n * Search result formatting module\n * Provides various formatting options for search results\n */\n\nexport type {\n FormattableSearchResult,\n FormattingOptions,\n FormattedResult,\n SearchFormatter,\n} from './types.js'\n\nexport { ListFormatter } from './listFormatter.js'\nexport { EnhancedFormatter } from './enhancedFormatter.js'\n\n/**\n * Factory function to create appropriate formatter\n */\nimport { ListFormatter } from './listFormatter.js'\nimport { EnhancedFormatter } from './enhancedFormatter.js'\nimport type { SearchFormatter } from './types.js'\n\nexport function createFormatter(type: 'list' | 'enhanced'): SearchFormatter {\n switch (type) {\n case 'list':\n return new ListFormatter()\n case 'enhanced':\n return new EnhancedFormatter()\n default:\n throw new Error(`Unknown formatter type: ${type}`)\n }\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{join as e}from"node:path";function t(e,t){let n={};for(let r=0;r<e.length;r++){let i=e[r];if(i.startsWith(`--`)){let a=i.slice(2),o=t.find(e=>e.name===a||e.alias===a);if(o){if(o.type===`boolean`)n[a]=!0;else if(r+1<e.length){let t=e[++r];n[a]=o.type===`number`?Number(t):t}}}else if(i.startsWith(`-`)){let a=i.slice(1),o=t.find(e=>e.alias===a);if(o){if(o.type===`boolean`)n[o.name]=!0;else if(r+1<e.length){let t=e[++r];n[o.name]=o.type===`number`?Number(t):t}}}}for(let e of t)e.required&&!(e.name in n)&&(console.error(`❌ Required argument --${e.name} is missing`),process.exit(1));for(let e of t)!(e.name in n)&&e.default!==void 0&&(n[e.name]=e.default);return n}async function n(t={}){let{searchMode:n=`auto`,useFormatting:r=!0,vectorEmbedder:i}=t,{UnifiedSearchEngine:a}=await import(`./unifiedSearch-DCFPrtzZ.mjs`);return new a({mode:n,skillDir:e(process.cwd(),`assets`),referencesDir:e(process.cwd(),`assets`,`references`),config:{},skillPath:process.cwd(),format:r?`enhanced`:void 0,adapterOptions:{qualityThreshold:.55,vectorEmbedder:i},formatting:{maxPreviewLength:200,showFullContentThreshold:.8,minScoreForPreview:.3,showLineNumbers:!0}})}function r(e){if(e===`chroma`)return`vector`;if(e===`auto`||e===`fulltext`||e===`fuzzy`||e===`vector`)return e;console.error(`❌ Invalid search mode. Use: auto, fulltext, fuzzy, or vector`),process.exit(1)}export{r as n,t as r,n as t};
2
- //# sourceMappingURL=shared-DsVh4gOV.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shared-DsVh4gOV.mjs","names":["result: Record<string, any>"],"sources":["../src/commands/shared.ts"],"sourcesContent":["/**\n * Shared utilities for commands\n */\n\nimport { join } from 'node:path'\nimport type { SearchMode } from '../core/searchAdapter.js'\n\n/**\n * Parse command line arguments\n */\nexport function parseArgs(\n args: string[],\n definitions: Array<{\n name: string\n alias?: string\n type: 'string' | 'number' | 'boolean'\n required?: boolean\n default?: any\n }>\n): Record<string, any> {\n const result: Record<string, any> = {}\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]\n\n if (arg.startsWith('--')) {\n const key = arg.slice(2)\n const def = definitions.find((d) => d.name === key || d.alias === key)\n\n if (def) {\n if (def.type === 'boolean') {\n result[key] = true\n } else if (i + 1 < args.length) {\n const value = args[++i]\n result[key] = def.type === 'number' ? Number(value) : value\n }\n }\n } else if (arg.startsWith('-')) {\n const key = arg.slice(1)\n const def = definitions.find((d) => d.alias === key)\n\n if (def) {\n if (def.type === 'boolean') {\n result[def.name] = true\n } else if (i + 1 < args.length) {\n const value = args[++i]\n result[def.name] = def.type === 'number' ? Number(value) : value\n }\n }\n }\n }\n\n // Check for required arguments\n for (const def of definitions) {\n if (def.required && !(def.name in result)) {\n console.error(`❌ Required argument --${def.name} is missing`)\n process.exit(1)\n }\n }\n\n // Apply defaults\n for (const def of definitions) {\n if (!(def.name in result) && def.default !== undefined) {\n result[def.name] = def.default\n }\n }\n\n return result\n}\n\n/**\n * Create search engine instance\n */\nexport async function createSearchEngine(\n options: {\n searchMode?: SearchMode\n useFormatting?: boolean\n vectorEmbedder?: string\n } = {}\n) {\n const { searchMode = 'auto', useFormatting = true, vectorEmbedder } = options\n const { UnifiedSearchEngine } = await import('../core/unifiedSearch.js')\n\n return new UnifiedSearchEngine({\n mode: searchMode,\n skillDir: join(process.cwd(), 'assets'),\n referencesDir: join(process.cwd(), 'assets', 'references'),\n config: {}, // No longer needed\n skillPath: process.cwd(),\n format: useFormatting ? 'enhanced' : undefined,\n adapterOptions: {\n qualityThreshold: 0.55,\n vectorEmbedder,\n },\n formatting: {\n maxPreviewLength: 200,\n showFullContentThreshold: 0.8,\n minScoreForPreview: 0.3,\n showLineNumbers: true,\n },\n })\n}\n\nexport function normalizeSearchMode(mode: string): Exclude<SearchMode, 'chroma'> {\n if (mode === 'chroma') return 'vector'\n if (mode === 'auto' || mode === 'fulltext' || mode === 'fuzzy' || mode === 'vector') {\n return mode\n }\n\n console.error('❌ Invalid search mode. Use: auto, fulltext, fuzzy, or vector')\n process.exit(1)\n}\n"],"mappings":"iCAUA,SAAgB,EACd,EACA,EAOqB,CACrB,IAAMA,EAA8B,EAAE,CAEtC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,IAAM,EAAM,EAAK,GAEjB,GAAI,EAAI,WAAW,KAAK,CAAE,CACxB,IAAM,EAAM,EAAI,MAAM,EAAE,CAClB,EAAM,EAAY,KAAM,GAAM,EAAE,OAAS,GAAO,EAAE,QAAU,EAAI,CAEtE,GAAI,MACE,EAAI,OAAS,UACf,EAAO,GAAO,WACL,EAAI,EAAI,EAAK,OAAQ,CAC9B,IAAM,EAAQ,EAAK,EAAE,GACrB,EAAO,GAAO,EAAI,OAAS,SAAW,OAAO,EAAM,CAAG,YAGjD,EAAI,WAAW,IAAI,CAAE,CAC9B,IAAM,EAAM,EAAI,MAAM,EAAE,CAClB,EAAM,EAAY,KAAM,GAAM,EAAE,QAAU,EAAI,CAEpD,GAAI,MACE,EAAI,OAAS,UACf,EAAO,EAAI,MAAQ,WACV,EAAI,EAAI,EAAK,OAAQ,CAC9B,IAAM,EAAQ,EAAK,EAAE,GACrB,EAAO,EAAI,MAAQ,EAAI,OAAS,SAAW,OAAO,EAAM,CAAG,KAOnE,IAAK,IAAM,KAAO,EACZ,EAAI,UAAY,EAAE,EAAI,QAAQ,KAChC,QAAQ,MAAM,yBAAyB,EAAI,KAAK,aAAa,CAC7D,QAAQ,KAAK,EAAE,EAKnB,IAAK,IAAM,KAAO,EACZ,EAAE,EAAI,QAAQ,IAAW,EAAI,UAAY,IAAA,KAC3C,EAAO,EAAI,MAAQ,EAAI,SAI3B,OAAO,EAMT,eAAsB,EACpB,EAII,EAAE,CACN,CACA,GAAM,CAAE,aAAa,OAAQ,gBAAgB,GAAM,kBAAmB,EAChE,CAAE,uBAAwB,MAAM,OAAO,gCAE7C,OAAO,IAAI,EAAoB,CAC7B,KAAM,EACN,SAAU,EAAK,QAAQ,KAAK,CAAE,SAAS,CACvC,cAAe,EAAK,QAAQ,KAAK,CAAE,SAAU,aAAa,CAC1D,OAAQ,EAAE,CACV,UAAW,QAAQ,KAAK,CACxB,OAAQ,EAAgB,WAAa,IAAA,GACrC,eAAgB,CACd,iBAAkB,IAClB,iBACD,CACD,WAAY,CACV,iBAAkB,IAClB,yBAA0B,GAC1B,mBAAoB,GACpB,gBAAiB,GAClB,CACF,CAAC,CAGJ,SAAgB,EAAoB,EAA6C,CAC/E,GAAI,IAAS,SAAU,MAAO,SAC9B,GAAI,IAAS,QAAU,IAAS,YAAc,IAAS,SAAW,IAAS,SACzE,OAAO,EAGT,QAAQ,MAAM,+DAA+D,CAC7E,QAAQ,KAAK,EAAE"}
@@ -1,2 +0,0 @@
1
- import{n as e}from"./package-CFJazwTO.mjs";import{join as t}from"node:path";import{existsSync as n,mkdirSync as r,readFileSync as i,readdirSync as a,writeFileSync as o}from"node:fs";import{match as s}from"ts-pattern";var c=class{templateDir;constructor(){this.templateDir=e(`templates`)}async createSkill(e){let i={created:!1,message:``};try{let o=t(e.baseDir,e.skillDirname);if(n(o)){let t=a(o).filter(e=>e!==`.gitkeep`);if(t.length>0&&!e.force)return i.message=`Skill directory already exists and is not empty: ${o}`,i;t.length>0&&e.force&&console.log(`⚠️ Skill directory exists, forcing overwrite of existing files: ${o}`)}return r(o,{recursive:!0}),this.createDirectoryStructure(o),await this.createSkillMdFromTemplate(o,e),i.created=!0,i.skillPath=o,i.message=`Skill created successfully: ${o}`,i}catch(e){return i.message=`Failed to create skill: ${e instanceof Error?e.stack??e.message:String(e)}`,i}}createDirectoryStructure(e){for(let n of[`assets/references/context7`,`assets/references/user`,`assets/search`,`assets/logs`]){let i=t(e,n);r(i,{recursive:!0}),o(t(i,`.gitkeep`),``)}}async createSkillMdFromTemplate(e,r){let a=t(this.templateDir,`SKILL.md`);if(!n(a))throw Error(`SKILL.md template not found at ${a}`);let c=i(a,`utf-8`);c=c.replace(/\{\{(.+?)\}\}/g,(t,n)=>(n=n.trim().toLowerCase(),s(n).with(`name`,()=>r.skillName).with(`description`,()=>r.skillDescription??`Specialized ${r.skillName} expert assistant providing comprehensive technical support`).with(`package_name`,()=>r.sourcePackageName??r.skillName).with(`package_version_hint`,()=>r.sourcePackageVersionHint??this.inferVersionHint(r.skillDirname)).with(`skill_path`,()=>e).otherwise(()=>t))),o(t(e,`SKILL.md`),c)}inferVersionHint(e){let t=e.lastIndexOf(`@`);return t<=0||t===e.length-1?``:e.slice(t+1)}};export{c as t};
2
- //# sourceMappingURL=skillCreator-BomXoqdw.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"skillCreator-BomXoqdw.mjs","names":["result: CreateSkillResult"],"sources":["../src/core/skillCreator.ts"],"sourcesContent":["/**\n * Main skill creator class\n */\n\nimport { join } from 'node:path'\nimport { existsSync, mkdirSync, writeFileSync, readdirSync, readFileSync } from 'node:fs'\nimport type { CreateSkillOptions, CreateSkillResult } from '../types/index.js'\nimport { match } from 'ts-pattern'\nimport { rootResolver } from '../utils/path.js'\n\nexport class SkillCreator {\n private templateDir: string\n\n constructor() {\n this.templateDir = rootResolver('templates')\n }\n\n async createSkill(options: CreateSkillOptions): Promise<CreateSkillResult> {\n const result: CreateSkillResult = {\n created: false,\n message: '',\n }\n\n try {\n // Create skill directory\n const skillDir = join(options.baseDir, options.skillDirname)\n\n if (existsSync(skillDir)) {\n const files = readdirSync(skillDir)\n // Filter out .gitkeep files\n const realFiles = files.filter((f) => f !== '.gitkeep')\n if (realFiles.length > 0 && !options.force) {\n result.message = `Skill directory already exists and is not empty: ${skillDir}`\n return result\n } else if (realFiles.length > 0 && options.force) {\n console.log(\n `⚠️ Skill directory exists, forcing overwrite of existing files: ${skillDir}`\n )\n }\n }\n\n mkdirSync(skillDir, { recursive: true })\n\n // Create directory structure\n this.createDirectoryStructure(skillDir)\n\n // Create SKILL.md from template\n await this.createSkillMdFromTemplate(skillDir, options)\n\n result.created = true\n result.skillPath = skillDir\n result.message = `Skill created successfully: ${skillDir}`\n\n return result\n } catch (error) {\n result.message = `Failed to create skill: ${error instanceof Error ? (error.stack ?? error.message) : String(error)}`\n return result\n }\n }\n\n private createDirectoryStructure(skillDir: string): void {\n const dirs = [\n 'assets/references/context7', // Base directory for all context7 projects\n 'assets/references/user', // User-created content\n 'assets/search', // Backend-neutral search runtime data\n 'assets/logs', // Logs\n ]\n\n for (const dir of dirs) {\n const dirPath = join(skillDir, dir)\n mkdirSync(dirPath, { recursive: true })\n // Only add .gitkeep to empty directories that should exist\n writeFileSync(join(dirPath, '.gitkeep'), '')\n }\n }\n\n private async createSkillMdFromTemplate(\n skillDir: string,\n options: CreateSkillOptions\n ): Promise<void> {\n const templatePath = join(this.templateDir, 'SKILL.md')\n\n if (!existsSync(templatePath)) {\n throw new Error(`SKILL.md template not found at ${templatePath}`)\n }\n\n let templateContent = readFileSync(templatePath, 'utf-8')\n\n // Replace template variables with options data\n templateContent = templateContent.replace(/\\{\\{(.+?)\\}\\}/g, (_, key) => {\n key = key.trim().toLowerCase()\n return match(key)\n .with('name', () => options.skillName)\n .with(\n 'description',\n () =>\n options.skillDescription ??\n `Specialized ${options.skillName} expert assistant providing comprehensive technical support`\n )\n .with('package_name', () => options.sourcePackageName ?? options.skillName)\n .with(\n 'package_version_hint',\n () => options.sourcePackageVersionHint ?? this.inferVersionHint(options.skillDirname)\n )\n .with('skill_path', () => skillDir)\n .otherwise(() => _)\n })\n\n writeFileSync(join(skillDir, 'SKILL.md'), templateContent)\n }\n\n private inferVersionHint(skillDirname: string): string {\n const versionSeparator = skillDirname.lastIndexOf('@')\n\n if (versionSeparator <= 0 || versionSeparator === skillDirname.length - 1) {\n return ''\n }\n\n return skillDirname.slice(versionSeparator + 1)\n }\n}\n"],"mappings":"yNAUA,IAAa,EAAb,KAA0B,CACxB,YAEA,aAAc,CACZ,KAAK,YAAc,EAAa,YAAY,CAG9C,MAAM,YAAY,EAAyD,CACzE,IAAMA,EAA4B,CAChC,QAAS,GACT,QAAS,GACV,CAED,GAAI,CAEF,IAAM,EAAW,EAAK,EAAQ,QAAS,EAAQ,aAAa,CAE5D,GAAI,EAAW,EAAS,CAAE,CAGxB,IAAM,EAFQ,EAAY,EAAS,CAEX,OAAQ,GAAM,IAAM,WAAW,CACvD,GAAI,EAAU,OAAS,GAAK,CAAC,EAAQ,MAEnC,MADA,GAAO,QAAU,oDAAoD,IAC9D,EACE,EAAU,OAAS,GAAK,EAAQ,OACzC,QAAQ,IACN,oEAAoE,IACrE,CAgBL,OAZA,EAAU,EAAU,CAAE,UAAW,GAAM,CAAC,CAGxC,KAAK,yBAAyB,EAAS,CAGvC,MAAM,KAAK,0BAA0B,EAAU,EAAQ,CAEvD,EAAO,QAAU,GACjB,EAAO,UAAY,EACnB,EAAO,QAAU,+BAA+B,IAEzC,QACA,EAAO,CAEd,MADA,GAAO,QAAU,2BAA2B,aAAiB,MAAS,EAAM,OAAS,EAAM,QAAW,OAAO,EAAM,GAC5G,GAIX,yBAAiC,EAAwB,CAQvD,IAAK,IAAM,IAPE,CACX,6BACA,yBACA,gBACA,cACD,CAEuB,CACtB,IAAM,EAAU,EAAK,EAAU,EAAI,CACnC,EAAU,EAAS,CAAE,UAAW,GAAM,CAAC,CAEvC,EAAc,EAAK,EAAS,WAAW,CAAE,GAAG,EAIhD,MAAc,0BACZ,EACA,EACe,CACf,IAAM,EAAe,EAAK,KAAK,YAAa,WAAW,CAEvD,GAAI,CAAC,EAAW,EAAa,CAC3B,MAAU,MAAM,kCAAkC,IAAe,CAGnE,IAAI,EAAkB,EAAa,EAAc,QAAQ,CAGzD,EAAkB,EAAgB,QAAQ,kBAAmB,EAAG,KAC9D,EAAM,EAAI,MAAM,CAAC,aAAa,CACvB,EAAM,EAAI,CACd,KAAK,WAAc,EAAQ,UAAU,CACrC,KACC,kBAEE,EAAQ,kBACR,eAAe,EAAQ,UAAU,6DACpC,CACA,KAAK,mBAAsB,EAAQ,mBAAqB,EAAQ,UAAU,CAC1E,KACC,2BACM,EAAQ,0BAA4B,KAAK,iBAAiB,EAAQ,aAAa,CACtF,CACA,KAAK,iBAAoB,EAAS,CAClC,cAAgB,EAAE,EACrB,CAEF,EAAc,EAAK,EAAU,WAAW,CAAE,EAAgB,CAG5D,iBAAyB,EAA8B,CACrD,IAAM,EAAmB,EAAa,YAAY,IAAI,CAMtD,OAJI,GAAoB,GAAK,IAAqB,EAAa,OAAS,EAC/D,GAGF,EAAa,MAAM,EAAmB,EAAE"}
@@ -1,7 +0,0 @@
1
- import{readFileSync as e,writeFileSync as t}from"node:fs";function n(e){let t=[],n=/<user-skills(?:\s+baseDir="([^"]+)")?>(\s[\s\S]*?)<\/user-skills>/g,r;for(;(r=n.exec(e))!==null;)t.push({tagName:`user-skills`,baseDir:r[1]||`assets/references/user`,content:r[2].trim(),startIndex:r.index,endIndex:r.index+r[0].length});let i=/<context7-skills\s+id="([^"]+)"(?:\s+baseDir="([^"]+)")?>(\s[\s\S]*?)<\/context7-skills>/g;for(;(r=i.exec(e))!==null;){let e=r[1];t.push({tagName:`context7-skills`,id:e,baseDir:r[2]||`assets/references/context7/${e}`,content:r[3].trim(),startIndex:r.index,endIndex:r.index+r[0].length})}return t.sort((e,t)=>e.startIndex-t.startIndex)}function r(e){let t=e.match(/<skill-package\s+name="([^"]*)"\s+version="([^"]*)">\s*<\/skill-package>/);if(!t||t.index==null)return;let[,n,r]=t;return{name:n,version:r,startIndex:t.index,endIndex:t.index+t[0].length}}function i(e,t){let n=r(e);if(!n)return e;let i=`<skill-package name="${t.name}" version="${t.version??``}">\n</skill-package>`;return e.slice(0,n.startIndex)+i+e.slice(n.endIndex)}function a(e,t,r,i,a){let o=n(e),s=o.find(e=>e.tagName===t&&(t===`user-skills`||e.id===i));if(s){let n=a||s.baseDir,o;o=t===`user-skills`?n?`<user-skills baseDir="${n}">`:`<user-skills>`:n?`<context7-skills id="${i}" baseDir="${n}">`:`<context7-skills id="${i}">`;let c=`</${t}>`,l=`${o}\n${r}\n${c}`;return e.slice(0,s.startIndex)+l+e.slice(s.endIndex)}else if(t===`context7-skills`&&i){let t=e.match(/## Context7 Documentation[\s\S]*?(?=\n##|$)/);if(t){let n=e.indexOf(t[0]),s=n+t[0].length,c=o.filter(e=>e.tagName===`context7-skills`),l=s;if(c.length>0)l=c[c.length-1].endIndex;else{let r=e.indexOf(`
2
- `,n+t[0].indexOf(`
3
- `)),i=e.indexOf(`-->`,r);l=i>r?i+3:r}let u=a||`assets/references/context7/${i}`,d=`\n\n${u?`<context7-skills id="${i}" baseDir="${u}">`:`<context7-skills id="${i}">`}\n${r}\n</context7-skills>`;return e.slice(0,l)+d+e.slice(l)}}return e}function o(e,t){let r=n(e).find(e=>e.tagName===`context7-skills`&&e.id===t);if(!r)return e;let i=r.startIndex,a=r.endIndex;for(;i>0&&e[i-1]===`
4
- `&&(i--,!(i>0&&e[i-1]===`
5
- `)););for(;a<e.length&&e[a]===`
6
- `;)a++;return e.slice(0,i)+e.slice(a)}function s(n,r,i,o,s){t(n,a(e(n,`utf-8`),r,i,o,s),`utf-8`)}function c(n,r){t(n,i(e(n,`utf-8`),r),`utf-8`)}function l(n,r){t(n,o(e(n,`utf-8`),r),`utf-8`)}export{s as n,c as r,l as t};
7
- //# sourceMappingURL=skillMdManager-DGBZ6M5J.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"skillMdManager-DGBZ6M5J.mjs","names":["tags: TagContent[]","tagStart: string"],"sources":["../src/utils/skillMdManager.ts"],"sourcesContent":["/**\n * SKILL.md tag management utilities\n * Manages <user-skills> and <context7-skills> tags in SKILL.md file\n */\n\nimport { readFileSync, writeFileSync } from 'node:fs'\n\nexport interface TagContent {\n tagName: string\n id?: string\n baseDir?: string\n content: string\n startIndex: number\n endIndex: number\n}\n\nexport interface SkillPackageTag {\n name: string\n version: string\n startIndex: number\n endIndex: number\n}\n\n/**\n * Parse all tags from SKILL.md content\n */\nexport function parseSkillMdTags(content: string): TagContent[] {\n const tags: TagContent[] = []\n\n // Match <user-skills baseDir=\"...\">...</user-skills>\n const userSkillsRegex = /<user-skills(?:\\s+baseDir=\"([^\"]+)\")?>(\\s[\\s\\S]*?)<\\/user-skills>/g\n let match\n\n while ((match = userSkillsRegex.exec(content)) !== null) {\n tags.push({\n tagName: 'user-skills',\n baseDir: match[1] || 'assets/references/user', // Default baseDir\n content: match[2].trim(),\n startIndex: match.index,\n endIndex: match.index + match[0].length,\n })\n }\n\n // Match <context7-skills id=\"xxx\" baseDir=\"...\">...</context7-skills>\n const context7Regex =\n /<context7-skills\\s+id=\"([^\"]+)\"(?:\\s+baseDir=\"([^\"]+)\")?>(\\s[\\s\\S]*?)<\\/context7-skills>/g\n\n while ((match = context7Regex.exec(content)) !== null) {\n const projectId = match[1]\n tags.push({\n tagName: 'context7-skills',\n id: projectId,\n baseDir: match[2] || `assets/references/context7/${projectId}`, // Default baseDir with project ID\n content: match[3].trim(),\n startIndex: match.index,\n endIndex: match.index + match[0].length,\n })\n }\n\n return tags.sort((a, b) => a.startIndex - b.startIndex)\n}\n\nexport function parseSkillPackageTag(content: string): SkillPackageTag | undefined {\n const match = content.match(\n /<skill-package\\s+name=\"([^\"]*)\"\\s+version=\"([^\"]*)\">\\s*<\\/skill-package>/\n )\n\n if (!match || match.index == null) {\n return undefined\n }\n\n const [, name, version] = match\n return {\n name,\n version,\n startIndex: match.index,\n endIndex: match.index + match[0].length,\n }\n}\n\nexport function updateSkillPackageTag(\n content: string,\n metadata: {\n name: string\n version?: string\n }\n): string {\n const existingTag = parseSkillPackageTag(content)\n if (!existingTag) {\n return content\n }\n\n const updatedTag = `<skill-package name=\"${metadata.name}\" version=\"${metadata.version ?? ''}\">\\n</skill-package>`\n return content.slice(0, existingTag.startIndex) + updatedTag + content.slice(existingTag.endIndex)\n}\n\n/**\n * Update or create a tag in SKILL.md content\n */\nexport function updateSkillMdTag(\n content: string,\n tagName: 'user-skills' | 'context7-skills',\n newContent: string,\n id?: string,\n baseDir?: string\n): string {\n const tags = parseSkillMdTags(content)\n\n // Find existing tag\n const existingTag = tags.find(\n (t) => t.tagName === tagName && (tagName === 'user-skills' || t.id === id)\n )\n\n if (existingTag) {\n // Replace existing tag content, preserving or updating baseDir\n const finalBaseDir = baseDir || existingTag.baseDir\n let tagStart: string\n if (tagName === 'user-skills') {\n tagStart = finalBaseDir ? `<user-skills baseDir=\"${finalBaseDir}\">` : `<user-skills>`\n } else {\n tagStart = finalBaseDir\n ? `<context7-skills id=\"${id}\" baseDir=\"${finalBaseDir}\">`\n : `<context7-skills id=\"${id}\">`\n }\n const tagEnd = `</${tagName}>`\n const newTag = `${tagStart}\\n${newContent}\\n${tagEnd}`\n\n return content.slice(0, existingTag.startIndex) + newTag + content.slice(existingTag.endIndex)\n } else if (tagName === 'context7-skills' && id) {\n // Add new context7-skills tag\n // Find the Context7 Documentation section\n const context7SectionRegex = /## Context7 Documentation[\\s\\S]*?(?=\\n##|$)/\n const sectionMatch = content.match(context7SectionRegex)\n\n if (sectionMatch) {\n const sectionStart = content.indexOf(sectionMatch[0])\n const sectionEnd = sectionStart + sectionMatch[0].length\n\n // Find the end of existing context7-skills tags\n const existingContext7Tags = tags.filter((t) => t.tagName === 'context7-skills')\n let insertPosition = sectionEnd\n\n if (existingContext7Tags.length > 0) {\n const lastTag = existingContext7Tags[existingContext7Tags.length - 1]\n insertPosition = lastTag.endIndex\n } else {\n // Insert after the section header and comment\n const headerEnd = content.indexOf('\\n', sectionStart + sectionMatch[0].indexOf('\\n'))\n const commentEnd = content.indexOf('-->', headerEnd)\n insertPosition = commentEnd > headerEnd ? commentEnd + 3 : headerEnd\n }\n\n const finalBaseDir = baseDir || `assets/references/context7/${id}`\n const tagStart = finalBaseDir\n ? `<context7-skills id=\"${id}\" baseDir=\"${finalBaseDir}\">`\n : `<context7-skills id=\"${id}\">`\n const newTag = `\\n\\n${tagStart}\\n${newContent}\\n</context7-skills>`\n\n return content.slice(0, insertPosition) + newTag + content.slice(insertPosition)\n }\n }\n\n return content\n}\n\n/**\n * Remove a context7-skills tag from SKILL.md\n */\nexport function removeContext7Tag(content: string, projectId: string): string {\n const tags = parseSkillMdTags(content)\n const tagToRemove = tags.find((t) => t.tagName === 'context7-skills' && t.id === projectId)\n\n if (!tagToRemove) {\n return content\n }\n\n // Remove the tag and any surrounding whitespace\n let startIndex = tagToRemove.startIndex\n let endIndex = tagToRemove.endIndex\n\n // Remove leading newlines\n while (startIndex > 0 && content[startIndex - 1] === '\\n') {\n startIndex--\n if (startIndex > 0 && content[startIndex - 1] === '\\n') break // Keep one newline\n }\n\n // Remove trailing newlines\n while (endIndex < content.length && content[endIndex] === '\\n') {\n endIndex++\n }\n\n return content.slice(0, startIndex) + content.slice(endIndex)\n}\n\n/**\n * Get all context7 project IDs from SKILL.md\n */\nexport function getContext7ProjectIds(content: string): string[] {\n const tags = parseSkillMdTags(content)\n return tags.filter((t) => t.tagName === 'context7-skills' && t.id).map((t) => t.id as string)\n}\n\n/**\n * Get user skills files from SKILL.md\n */\nexport function getUserSkillsFiles(content: string): string[] {\n const tags = parseSkillMdTags(content)\n const userSkillsTag = tags.find((t) => t.tagName === 'user-skills')\n\n if (!userSkillsTag || !userSkillsTag.content) {\n return []\n }\n\n // Parse markdown list items\n return userSkillsTag.content\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.startsWith('-'))\n .map((line) => line.slice(1).trim())\n .filter(Boolean)\n}\n\n/**\n * Get context7 files for a specific project from SKILL.md\n */\nexport function getContext7Files(content: string, projectId: string): string[] {\n const tags = parseSkillMdTags(content)\n const projectTag = tags.find((t) => t.tagName === 'context7-skills' && t.id === projectId)\n\n if (!projectTag || !projectTag.content) {\n return []\n }\n\n // Parse markdown list items\n return projectTag.content\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.startsWith('-'))\n .map((line) => line.slice(1).trim())\n .filter(Boolean)\n}\n\n/**\n * Update SKILL.md file with new tag content\n */\nexport function updateSkillMdFile(\n filePath: string,\n tagName: 'user-skills' | 'context7-skills',\n newContent: string,\n id?: string,\n baseDir?: string\n): void {\n const content = readFileSync(filePath, 'utf-8')\n const updated = updateSkillMdTag(content, tagName, newContent, id, baseDir)\n writeFileSync(filePath, updated, 'utf-8')\n}\n\nexport function updateSkillPackageMetadataFile(\n filePath: string,\n metadata: {\n name: string\n version?: string\n }\n): void {\n const content = readFileSync(filePath, 'utf-8')\n const updated = updateSkillPackageTag(content, metadata)\n writeFileSync(filePath, updated, 'utf-8')\n}\n\n/**\n * Remove context7 tag from SKILL.md file\n */\nexport function removeContext7TagFromFile(filePath: string, projectId: string): void {\n const content = readFileSync(filePath, 'utf-8')\n const updated = removeContext7Tag(content, projectId)\n writeFileSync(filePath, updated, 'utf-8')\n}\n"],"mappings":"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"}
@@ -1,28 +0,0 @@
1
- import{a as e,n as t,r as n,t as r}from"./referenceSearchUtils-DZgupMZp.mjs";import{basename as i,join as a}from"node:path";import{existsSync as o,mkdirSync as s,readFileSync as c,rmSync as l,writeFileSync as u}from"node:fs";import{glob as d}from"glob";import{createHash as f}from"node:crypto";const p=/[\p{L}\p{N}]+/gu;function m(e,t){let n=(t??process.env.SKILL_CREATOR_VECTOR_EMBEDDER)?.trim().toLowerCase();return n===`deterministic`||n===`local`?h(e):null}function h(e){let t=Math.max(1,Math.trunc(e));return{async generate(e){return e.map(e=>g(e,t))}}}function g(t,n){let r=e(t).toLowerCase(),i=r.match(p)??[],a=[r||`__empty__`,...i,..._(i)],o=Array(n).fill(0);if(a.length===0)return o[0]=1,o;for(let e=0;e<a.length;e++){let t=a[e];v(o,t,e===0?.75:e<=i.length?1:.6)}let s=Math.hypot(...o);return s===0?(o[0]=1,o):o.map(e=>e/s)}function _(e){let t=[];for(let n=0;n<e.length-1;n++)t.push(`${e[n]} ${e[n+1]}`);return t}function v(e,t,n){let r=f(`sha256`).update(t).digest();for(let t=0;t<4;t++){let i=(r.readUInt16BE(t*2)+t*17)%e.length,a=r[16+t]&1?-1:1,o=1-t*.15;e[i]+=a*n*o}}var y=class{options;db=null;indexState=null;embedder=null;constructor(e){this.options=e,this.embedder=e.embeddingFunction??null}async initialize(){if(this.db)return;this.ensureSearchDir();let e=await this.loadRuntimeDependencies();this.db=new e.DatabaseSync(this.getDbPath(),{allowExtension:!0}),this.db.enableLoadExtension(!0),e.sqliteVec.load(this.db),this.prepareSchema(),this.loadIndexState()}async buildIndex(e){if(await this.initialize(),!this.db)return;let t=await this.loadDocuments(e),n=this.calculateReferencesHash(t);if(this.indexState?.referencesHash===n)return;this.db.exec(`delete from vec_docs; delete from doc_meta;`);let i=this.db.prepare(`insert into vec_docs (id, embedding) values (?, ?)`),a=this.db.prepare(`insert into doc_meta (id, title, content, source, file_path) values (?, ?, ?, ?, ?)`),o=await(await this.ensureEmbedder()).generate(t.map(e=>`${e.searchable_title}\n${e.searchable_content}`));for(let e=0;e<t.length;e++){let n=t[e];i.run(n.id,JSON.stringify(o[e])),a.run(n.id,n.title,n.content,n.source,n.file_path)}this.indexState={backendId:`sqlite-vec`,referencesHash:n,builtAt:new Date().toISOString(),documentCount:t.length,rulesetVersion:r.sqliteVec},this.persistIndexState()}async search(e,t={}){if(await this.initialize(),!this.db)return[];let{topK:n=5,where:r}=t,i=Math.max(n*(this.options.candidateMultiplier??6),this.options.minCandidateLimit??24),[a]=await(await this.ensureEmbedder()).generate([e]),o=this.db.prepare(`
2
- select
3
- vec_docs.id as id,
4
- doc_meta.title as title,
5
- doc_meta.content as content,
6
- doc_meta.source as source,
7
- doc_meta.file_path as file_path,
8
- vec_distance_cosine(vec_docs.embedding, ?) as distance
9
- from vec_docs
10
- join doc_meta on doc_meta.id = vec_docs.id
11
- ${r?.source?`where doc_meta.source = ?`:``}
12
- order by distance asc
13
- limit ?
14
- `).all(...r?.source?[JSON.stringify(a),r.source,i]:[JSON.stringify(a),i]);return this.rerankRows(o,e).slice(0,n).map(e=>({id:e.id,title:e.title,content:e.content,source:e.source,file_path:e.file_path,score:1-e.distance,metadata:{backendId:`sqlite-vec`,distance:e.distance,rerankScore:e.rerankScore,titleCoverage:e.titleCoverage,contentCoverage:e.contentCoverage,pathCoverage:e.pathCoverage,phraseCoverage:e.phraseCoverage,proximityScore:e.proximityScore}}))}getBackendInfo(){return{backendId:`sqlite-vec`,mode:`vector`,supportsPersistence:!0,supportsEmbeddings:!0}}isBuilt(){return this.indexState?.documentCount!=null&&this.indexState.documentCount>0}async getStats(){return await this.initialize(),this.db?{totalDocuments:this.db.prepare(`select count(*) as count from doc_meta`).get().count}:{totalDocuments:0}}async getIndexState(){return this.indexState??{backendId:`sqlite-vec`}}clearIndex(){this.db&&=(this.db.exec(`delete from vec_docs; delete from doc_meta;`),this.db.close(),null),this.indexState=null,l(this.getDbPath(),{force:!0}),l(this.getStateFilePath(),{force:!0})}getSearchDir(){return a(this.options.skillDir,`search`)}getEmbeddingDimensions(){return this.options.embeddingDimensions??384}ensureSearchDir(){s(this.getSearchDir(),{recursive:!0})}getDbPath(){return a(this.getSearchDir(),`vector-index.db`)}getStateFilePath(){return a(this.getSearchDir(),`vector-index-state.json`)}prepareSchema(){this.db&&this.db.exec(`
15
- create virtual table if not exists vec_docs using vec0(
16
- id text primary key,
17
- embedding float[${this.getEmbeddingDimensions()}]
18
- );
19
- create table if not exists doc_meta (
20
- id text primary key,
21
- title text not null,
22
- content text not null,
23
- source text not null,
24
- file_path text not null
25
- );
26
- `)}loadIndexState(){let e=this.getStateFilePath();if(o(e))try{this.indexState=JSON.parse(c(e,`utf-8`)),this.indexState.rulesetVersion!==r.sqliteVec&&(this.indexState=null)}catch{this.indexState=null}}persistIndexState(){this.indexState&&u(this.getStateFilePath(),JSON.stringify(this.indexState,null,2))}async loadDocuments(t){return(await d(`**/*.md`,{cwd:t})).map(r=>{let o=a(t,r),s=c(o,`utf-8`),l=this.normalizeDocumentContent(s),u=s.split(`
27
- `)[0]?.replace(/^#+\s*/,``).trim()||i(r,`.md`).replace(/[-_]/g,` `);return{id:r,title:u,content:s,searchable_title:e(u),searchable_content:l,source:n(r),file_path:o}})}calculateReferencesHash(e){return t(e.flatMap(e=>[e.id,e.title,e.content,e.source,r.sqliteVec]))}async loadRuntimeDependencies(){try{let[e,t]=await Promise.all([import(`node:sqlite`),import(`sqlite-vec`)]);return{DatabaseSync:e.DatabaseSync,sqliteVec:t}}catch(e){throw Error(`Vector mode requires node:sqlite support and sqlite-vec at runtime. ${e instanceof Error?e.message:String(e)}`)}}static async isRuntimeSupported(){try{return await Promise.all([import(`node:sqlite`),import(`sqlite-vec`)]),!0}catch{return!1}}async ensureEmbedder(){if(this.embedder)return this.embedder;let e=m(this.getEmbeddingDimensions(),this.options.embedderMode);if(e)return this.embedder=e,this.embedder;let{DefaultEmbeddingFunction:t}=await import(`@chroma-core/default-embed`);return this.embedder=new t({modelName:`Xenova/all-MiniLM-L6-v2`,quantized:!0,wasm:!0}),this.embedder}rerankRows(t,n){let r=this.normalizeQueryTokens(n),i=this.extractQueryPhrases(r);return t.map(t=>{let n=t.searchable_title??e(t.title),a=t.searchable_content??this.normalizeDocumentContent(t.content),o=this.calculateCoverage(n,r),s=this.calculateCoverage(a,r),c=this.calculatePathCoverage(t.id,r),l=this.calculatePhraseCoverage(n,a,i),u=this.calculateProximityScore(a,r),d=(1-t.distance)*.45+o*.12+s*.12+c*.18+l*.08+u*.05;return{...t,rerankScore:d,titleCoverage:o,contentCoverage:s,pathCoverage:c,phraseCoverage:l,proximityScore:u}}).sort((e,t)=>t.rerankScore===e.rerankScore?e.distance-t.distance:t.rerankScore-e.rerankScore)}normalizeQueryTokens(e){let t=new Set([`a`,`an`,`and`,`for`,`how`,`in`,`of`,`on`,`or`,`the`,`to`,`with`]);return(e.toLowerCase().match(/[\p{L}\p{N}]+/gu)??[]).filter(e=>!t.has(e))}extractQueryPhrases(e){return e.length<2?[]:e.slice(0,-1).map((t,n)=>`${t} ${e[n+1]}`).filter(e=>e.length>=8)}calculateCoverage(e,t){if(t.length===0)return 0;let n=e.toLowerCase().match(/[\p{L}\p{N}]+/gu)??[];if(n.length===0)return 0;let r=0;for(let e of t)r+=Math.max(...n.map(t=>this.scoreTokenMatch(t,e)),0);return r/t.length}calculatePathCoverage(e,t){if(t.length===0)return 0;let n=e.toLowerCase().replace(/\.md$/g,``).split(/[^a-z0-9]+/g).filter(Boolean),r=0;for(let e of t)r+=Math.max(...n.map(t=>this.scoreTokenMatch(t,e)),0);return r/t.length}calculatePhraseCoverage(e,t,n){if(n.length===0)return 0;let r=e.toLowerCase(),i=t.toLowerCase(),a=0;for(let e of n){if(r.includes(e)){a+=1;continue}i.includes(e)&&(a+=.8)}return Math.min(a/n.length,1)}calculateProximityScore(e,t){if(t.length<2)return 0;let n=e.toLowerCase(),r=t.map(e=>this.findSubstringPositions(n,e)).filter(e=>e.length>0);if(r.length<2)return 0;let i=1/0;for(let e=0;e<r.length-1;e++)for(let t of r[e])for(let n of r[e+1]){let e=Math.abs(n-t);e<i&&(i=e)}return Number.isFinite(i)?1/(1+i/24):0}findSubstringPositions(e,t){let n=[],r=0;for(;r<e.length;){let i=e.indexOf(t,r);if(i===-1)break;n.push(i),r=i+1}return n}tokensLooselyMatch(e,t){return this.scoreTokenMatch(e,t)>0}scoreTokenMatch(e,t){if(e===t)return 1;if(e===t.slice(0,-1)||t===e.slice(0,-1))return .8;if(e.length>=5&&t.length>=5){let[n,r]=e.length<=t.length?[e,t]:[t,e];if(r.startsWith(n)&&r.length-n.length<=3)return .65}return 0}normalizeDocumentContent(t){return e(t)}};export{y as t};
28
- //# sourceMappingURL=sqliteVectorSearchAdapter-56kZjbUT.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sqliteVectorSearchAdapter-56kZjbUT.mjs","names":["result: string[]","path","positions: number[]"],"sources":["../src/core/embeddingFunctions.ts","../src/core/sqliteVectorSearchAdapter.ts"],"sourcesContent":["import { createHash } from 'node:crypto'\nimport { normalizeSearchableText } from './referenceSearchUtils.js'\n\nexport interface EmbeddingFunction {\n generate(input: string[]): Promise<number[][]>\n}\n\nconst TOKEN_PATTERN = /[\\p{L}\\p{N}]+/gu\n\nexport function createEmbeddingFunctionFromEnvironment(\n dimensions: number,\n explicitMode?: string\n): EmbeddingFunction | null {\n const configuredMode = (\n explicitMode ?? process.env.SKILL_CREATOR_VECTOR_EMBEDDER\n )?.trim().toLowerCase()\n\n if (configuredMode === 'deterministic' || configuredMode === 'local') {\n return createDeterministicEmbeddingFunction(dimensions)\n }\n\n return null\n}\n\nexport function createDeterministicEmbeddingFunction(dimensions: number): EmbeddingFunction {\n const resolvedDimensions = Math.max(1, Math.trunc(dimensions))\n\n return {\n async generate(input: string[]) {\n return input.map((text) => createDeterministicVector(text, resolvedDimensions))\n },\n }\n}\n\nfunction createDeterministicVector(text: string, dimensions: number): number[] {\n const normalized = normalizeSearchableText(text).toLowerCase()\n const tokens = normalized.match(TOKEN_PATTERN) ?? []\n const features = [\n normalized || '__empty__',\n ...tokens,\n ...createBigrams(tokens),\n ]\n\n const vector = new Array<number>(dimensions).fill(0)\n\n if (features.length === 0) {\n vector[0] = 1\n return vector\n }\n\n for (let index = 0; index < features.length; index++) {\n const feature = features[index]!\n const weight =\n index === 0 ? 0.75 :\n index <= tokens.length ? 1 :\n 0.6\n applyFeature(vector, feature, weight)\n }\n\n const magnitude = Math.hypot(...vector)\n if (magnitude === 0) {\n vector[0] = 1\n return vector\n }\n\n return vector.map((value) => value / magnitude)\n}\n\nfunction createBigrams(tokens: string[]): string[] {\n const result: string[] = []\n for (let index = 0; index < tokens.length - 1; index++) {\n result.push(`${tokens[index]} ${tokens[index + 1]}`)\n }\n return result\n}\n\nfunction applyFeature(vector: number[], feature: string, weight: number): void {\n const digest = createHash('sha256').update(feature).digest()\n\n for (let slot = 0; slot < 4; slot++) {\n const position = (digest.readUInt16BE(slot * 2) + slot * 17) % vector.length\n const sign = (digest[16 + slot]! & 1) === 0 ? 1 : -1\n const scale = 1 - slot * 0.15\n vector[position] += sign * weight * scale\n }\n}\n","import { glob } from 'glob'\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport { basename, join } from 'node:path'\nimport type { DatabaseSync } from 'node:sqlite'\nimport type {\n SearchBackendInfo,\n SearchEngine,\n SearchIndexState,\n SearchOptions,\n SearchResult,\n} from './searchAdapter.js'\nimport {\n SEARCH_RULESET_VERSIONS,\n createSearchRulesetHash,\n detectReferenceSource,\n normalizeSearchableText,\n} from './referenceSearchUtils.js'\nimport {\n createEmbeddingFunctionFromEnvironment,\n type EmbeddingFunction,\n} from './embeddingFunctions.js'\n\ninterface VectorDocumentRecord {\n id: string\n title: string\n content: string\n searchable_title: string\n searchable_content: string\n source: 'user' | 'context7'\n file_path: string\n}\n\nexport interface SqliteVectorSearchAdapterOptions {\n skillDir: string\n embeddingDimensions?: number\n embeddingFunction?: EmbeddingFunction\n embedderMode?: string\n candidateMultiplier?: number\n minCandidateLimit?: number\n}\n\nexport class SqliteVectorSearchAdapter implements SearchEngine {\n private readonly options: SqliteVectorSearchAdapterOptions\n private db: DatabaseSync | null = null\n private indexState: SearchIndexState | null = null\n private embedder: EmbeddingFunction | null = null\n\n constructor(options: SqliteVectorSearchAdapterOptions) {\n this.options = options\n this.embedder = options.embeddingFunction ?? null\n }\n\n async initialize(): Promise<void> {\n if (this.db) return\n\n this.ensureSearchDir()\n const runtime = await this.loadRuntimeDependencies()\n this.db = new runtime.DatabaseSync(this.getDbPath(), { allowExtension: true })\n this.db.enableLoadExtension(true)\n runtime.sqliteVec.load(this.db)\n this.prepareSchema()\n this.loadIndexState()\n }\n\n async buildIndex(referencesDir: string): Promise<void> {\n await this.initialize()\n if (!this.db) return\n\n const documents = await this.loadDocuments(referencesDir)\n const referencesHash = this.calculateReferencesHash(documents)\n\n if (this.indexState?.referencesHash === referencesHash) {\n return\n }\n\n this.db.exec('delete from vec_docs; delete from doc_meta;')\n\n const insertVec = this.db.prepare('insert into vec_docs (id, embedding) values (?, ?)')\n const insertMeta = this.db.prepare(\n 'insert into doc_meta (id, title, content, source, file_path) values (?, ?, ?, ?, ?)'\n )\n\n const embeddings = await (await this.ensureEmbedder()).generate(\n documents.map((doc) => `${doc.searchable_title}\\n${doc.searchable_content}`)\n )\n\n for (let i = 0; i < documents.length; i++) {\n const doc = documents[i]\n insertVec.run(doc.id, JSON.stringify(embeddings[i]))\n insertMeta.run(doc.id, doc.title, doc.content, doc.source, doc.file_path)\n }\n\n this.indexState = {\n backendId: 'sqlite-vec',\n referencesHash,\n builtAt: new Date().toISOString(),\n documentCount: documents.length,\n rulesetVersion: SEARCH_RULESET_VERSIONS.sqliteVec,\n }\n\n this.persistIndexState()\n }\n\n async search(query: string, options: SearchOptions = {}): Promise<SearchResult[]> {\n await this.initialize()\n if (!this.db) return []\n\n const { topK = 5, where } = options\n const candidateLimit = Math.max(\n topK * (this.options.candidateMultiplier ?? 6),\n this.options.minCandidateLimit ?? 24\n )\n const [embedding] = await (await this.ensureEmbedder()).generate([query])\n const rows = this.db\n .prepare(\n `\n select\n vec_docs.id as id,\n doc_meta.title as title,\n doc_meta.content as content,\n doc_meta.source as source,\n doc_meta.file_path as file_path,\n vec_distance_cosine(vec_docs.embedding, ?) as distance\n from vec_docs\n join doc_meta on doc_meta.id = vec_docs.id\n ${where?.source ? 'where doc_meta.source = ?' : ''}\n order by distance asc\n limit ?\n `\n )\n .all(\n ...(where?.source\n ? [JSON.stringify(embedding), where.source, candidateLimit]\n : [JSON.stringify(embedding), candidateLimit])\n ) as Array<{\n id: string\n title: string\n content: string\n source: 'user' | 'context7'\n file_path: string\n distance: number\n }>\n\n const reranked = this.rerankRows(rows, query).slice(0, topK)\n\n return reranked.map((row) => ({\n id: row.id,\n title: row.title,\n content: row.content,\n source: row.source,\n file_path: row.file_path,\n score: 1 - row.distance,\n metadata: {\n backendId: 'sqlite-vec',\n distance: row.distance,\n rerankScore: row.rerankScore,\n titleCoverage: row.titleCoverage,\n contentCoverage: row.contentCoverage,\n pathCoverage: row.pathCoverage,\n phraseCoverage: row.phraseCoverage,\n proximityScore: row.proximityScore,\n },\n }))\n }\n\n getBackendInfo(): SearchBackendInfo {\n return {\n backendId: 'sqlite-vec',\n mode: 'vector',\n supportsPersistence: true,\n supportsEmbeddings: true,\n }\n }\n\n isBuilt(): boolean {\n return this.indexState?.documentCount != null && this.indexState.documentCount > 0\n }\n\n async getStats(): Promise<{ totalDocuments: number }> {\n await this.initialize()\n if (!this.db) return { totalDocuments: 0 }\n const result = this.db.prepare('select count(*) as count from doc_meta').get() as { count: number }\n return { totalDocuments: result.count }\n }\n\n async getIndexState(): Promise<SearchIndexState> {\n return this.indexState ?? { backendId: 'sqlite-vec' }\n }\n\n clearIndex(): void {\n if (this.db) {\n this.db.exec('delete from vec_docs; delete from doc_meta;')\n this.db.close()\n this.db = null\n }\n this.indexState = null\n rmSync(this.getDbPath(), { force: true })\n rmSync(this.getStateFilePath(), { force: true })\n }\n\n private getSearchDir(): string {\n return join(this.options.skillDir, 'search')\n }\n\n private getEmbeddingDimensions(): number {\n return this.options.embeddingDimensions ?? 384\n }\n\n private ensureSearchDir(): void {\n mkdirSync(this.getSearchDir(), { recursive: true })\n }\n\n private getDbPath(): string {\n return join(this.getSearchDir(), 'vector-index.db')\n }\n\n private getStateFilePath(): string {\n return join(this.getSearchDir(), 'vector-index-state.json')\n }\n\n private prepareSchema(): void {\n if (!this.db) return\n this.db.exec(`\n create virtual table if not exists vec_docs using vec0(\n id text primary key,\n embedding float[${this.getEmbeddingDimensions()}]\n );\n create table if not exists doc_meta (\n id text primary key,\n title text not null,\n content text not null,\n source text not null,\n file_path text not null\n );\n `)\n }\n\n private loadIndexState(): void {\n const stateFile = this.getStateFilePath()\n if (!existsSync(stateFile)) return\n try {\n this.indexState = JSON.parse(readFileSync(stateFile, 'utf-8')) as SearchIndexState\n if (\n (this.indexState as SearchIndexState & { rulesetVersion?: string }).rulesetVersion !==\n SEARCH_RULESET_VERSIONS.sqliteVec\n ) {\n this.indexState = null\n }\n } catch {\n this.indexState = null\n }\n }\n\n private persistIndexState(): void {\n if (!this.indexState) return\n writeFileSync(this.getStateFilePath(), JSON.stringify(this.indexState, null, 2))\n }\n\n private async loadDocuments(referencesDir: string): Promise<VectorDocumentRecord[]> {\n const files = await glob('**/*.md', { cwd: referencesDir })\n return files.map((relativePath) => {\n const fullPath = join(referencesDir, relativePath)\n const rawContent = readFileSync(fullPath, 'utf-8')\n const normalizedContent = this.normalizeDocumentContent(rawContent)\n const title =\n rawContent.split('\\n')[0]?.replace(/^#+\\s*/, '').trim() ||\n basename(relativePath, '.md').replace(/[-_]/g, ' ')\n return {\n id: relativePath,\n title,\n content: rawContent,\n searchable_title: normalizeSearchableText(title),\n searchable_content: normalizedContent,\n source: detectReferenceSource(relativePath),\n file_path: fullPath,\n }\n })\n }\n\n private calculateReferencesHash(documents: VectorDocumentRecord[]): string {\n return createSearchRulesetHash(\n documents.flatMap((document) => [\n document.id,\n document.title,\n document.content,\n document.source,\n SEARCH_RULESET_VERSIONS.sqliteVec,\n ])\n )\n }\n\n private async loadRuntimeDependencies(): Promise<{\n DatabaseSync: typeof import('node:sqlite').DatabaseSync\n sqliteVec: typeof import('sqlite-vec')\n }> {\n try {\n const [sqlite, sqliteVec] = await Promise.all([import('node:sqlite'), import('sqlite-vec')])\n return {\n DatabaseSync: sqlite.DatabaseSync,\n sqliteVec,\n }\n } catch (error) {\n throw new Error(\n `Vector mode requires node:sqlite support and sqlite-vec at runtime. ${\n error instanceof Error ? error.message : String(error)\n }`\n )\n }\n }\n\n static async isRuntimeSupported(): Promise<boolean> {\n try {\n await Promise.all([import('node:sqlite'), import('sqlite-vec')])\n return true\n } catch {\n return false\n }\n }\n\n private async ensureEmbedder(): Promise<EmbeddingFunction> {\n if (this.embedder) {\n return this.embedder\n }\n\n const environmentEmbedder = createEmbeddingFunctionFromEnvironment(\n this.getEmbeddingDimensions(),\n this.options.embedderMode\n )\n if (environmentEmbedder) {\n this.embedder = environmentEmbedder\n return this.embedder\n }\n\n const { DefaultEmbeddingFunction } = await import('@chroma-core/default-embed')\n this.embedder = new DefaultEmbeddingFunction({\n modelName: 'Xenova/all-MiniLM-L6-v2',\n quantized: true,\n wasm: true,\n })\n return this.embedder\n }\n\n private rerankRows(\n rows: Array<{\n id: string\n title: string\n content: string\n searchable_title?: string\n searchable_content?: string\n source: 'user' | 'context7'\n file_path: string\n distance: number\n }>,\n query: string\n ): Array<\n {\n id: string\n title: string\n content: string\n searchable_title?: string\n searchable_content?: string\n source: 'user' | 'context7'\n file_path: string\n distance: number\n } & {\n rerankScore: number\n titleCoverage: number\n contentCoverage: number\n pathCoverage: number\n phraseCoverage: number\n proximityScore: number\n }\n > {\n const queryTokens = this.normalizeQueryTokens(query)\n const queryPhrases = this.extractQueryPhrases(queryTokens)\n\n return rows\n .map((row) => {\n const searchableTitle = row.searchable_title ?? normalizeSearchableText(row.title)\n const searchableContent = row.searchable_content ?? this.normalizeDocumentContent(row.content)\n const titleCoverage = this.calculateCoverage(searchableTitle, queryTokens)\n const contentCoverage = this.calculateCoverage(searchableContent, queryTokens)\n const pathCoverage = this.calculatePathCoverage(row.id, queryTokens)\n const phraseCoverage = this.calculatePhraseCoverage(searchableTitle, searchableContent, queryPhrases)\n const proximityScore = this.calculateProximityScore(searchableContent, queryTokens)\n const semanticScore = 1 - row.distance\n\n const rerankScore =\n semanticScore * 0.45 +\n titleCoverage * 0.12 +\n contentCoverage * 0.12 +\n pathCoverage * 0.18 +\n phraseCoverage * 0.08 +\n proximityScore * 0.05\n\n return {\n ...row,\n rerankScore,\n titleCoverage,\n contentCoverage,\n pathCoverage,\n phraseCoverage,\n proximityScore,\n }\n })\n .sort((left, right) => {\n if (right.rerankScore !== left.rerankScore) {\n return right.rerankScore - left.rerankScore\n }\n return left.distance - right.distance\n })\n }\n\n private normalizeQueryTokens(query: string): string[] {\n const stopwords = new Set(['a', 'an', 'and', 'for', 'how', 'in', 'of', 'on', 'or', 'the', 'to', 'with'])\n return (query.toLowerCase().match(/[\\p{L}\\p{N}]+/gu) ?? []).filter((token) => !stopwords.has(token))\n }\n\n private extractQueryPhrases(queryTokens: string[]): string[] {\n if (queryTokens.length < 2) {\n return []\n }\n\n return queryTokens\n .slice(0, -1)\n .map((token, index) => `${token} ${queryTokens[index + 1]}`)\n .filter((phrase) => phrase.length >= 8)\n }\n\n private calculateCoverage(text: string, queryTokens: string[]): number {\n if (queryTokens.length === 0) {\n return 0\n }\n\n const words = text.toLowerCase().match(/[\\p{L}\\p{N}]+/gu) ?? []\n if (words.length === 0) {\n return 0\n }\n\n let matched = 0\n for (const token of queryTokens) {\n matched += Math.max(...words.map((word) => this.scoreTokenMatch(word, token)), 0)\n }\n\n return matched / queryTokens.length\n }\n\n private calculatePathCoverage(path: string, queryTokens: string[]): number {\n if (queryTokens.length === 0) {\n return 0\n }\n\n const pathTokens = path\n .toLowerCase()\n .replace(/\\.md$/g, '')\n .split(/[^a-z0-9]+/g)\n .filter(Boolean)\n\n let matched = 0\n for (const token of queryTokens) {\n matched += Math.max(...pathTokens.map((pathToken) => this.scoreTokenMatch(pathToken, token)), 0)\n }\n\n return matched / queryTokens.length\n }\n\n private calculatePhraseCoverage(title: string, content: string, phrases: string[]): number {\n if (phrases.length === 0) {\n return 0\n }\n\n const titleText = title.toLowerCase()\n const contentText = content.toLowerCase()\n let matched = 0\n for (const phrase of phrases) {\n if (titleText.includes(phrase)) {\n matched += 1\n continue\n }\n if (contentText.includes(phrase)) {\n matched += 0.8\n }\n }\n\n return Math.min(matched / phrases.length, 1)\n }\n\n private calculateProximityScore(content: string, queryTokens: string[]): number {\n if (queryTokens.length < 2) {\n return 0\n }\n\n const text = content.toLowerCase()\n const positions = queryTokens\n .map((token) => this.findSubstringPositions(text, token))\n .filter((hits) => hits.length > 0)\n\n if (positions.length < 2) {\n return 0\n }\n\n let bestSpan = Number.POSITIVE_INFINITY\n for (let i = 0; i < positions.length - 1; i++) {\n for (const start of positions[i]) {\n for (const end of positions[i + 1]) {\n const span = Math.abs(end - start)\n if (span < bestSpan) {\n bestSpan = span\n }\n }\n }\n }\n\n if (!Number.isFinite(bestSpan)) {\n return 0\n }\n\n return 1 / (1 + bestSpan / 24)\n }\n\n private findSubstringPositions(text: string, token: string): number[] {\n const positions: number[] = []\n let startIndex = 0\n\n while (startIndex < text.length) {\n const matchIndex = text.indexOf(token, startIndex)\n if (matchIndex === -1) {\n break\n }\n positions.push(matchIndex)\n startIndex = matchIndex + 1\n }\n\n return positions\n }\n\n private tokensLooselyMatch(left: string, right: string): boolean {\n return this.scoreTokenMatch(left, right) > 0\n }\n\n private scoreTokenMatch(left: string, right: string): number {\n if (left === right) {\n return 1\n }\n\n if (left === right.slice(0, -1) || right === left.slice(0, -1)) {\n return 0.8\n }\n\n if (left.length >= 5 && right.length >= 5) {\n const [shorter, longer] = left.length <= right.length ? [left, right] : [right, left]\n if (longer.startsWith(shorter) && longer.length - shorter.length <= 3) {\n return 0.65\n }\n }\n\n return 0\n }\n\n private normalizeDocumentContent(content: string): string {\n return normalizeSearchableText(content)\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- import"./referenceSearchUtils-DZgupMZp.mjs";import{t as e}from"./sqliteVectorSearchAdapter-56kZjbUT.mjs";export{e as SqliteVectorSearchAdapter};