skilld 1.1.1 → 1.1.2

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 (60) hide show
  1. package/dist/_chunks/agent.mjs +13 -1
  2. package/dist/_chunks/agent.mjs.map +1 -1
  3. package/dist/_chunks/assemble.mjs +2 -0
  4. package/dist/_chunks/assemble.mjs.map +1 -1
  5. package/dist/_chunks/cache.mjs +2 -0
  6. package/dist/_chunks/cache.mjs.map +1 -1
  7. package/dist/_chunks/cache2.mjs +3 -1
  8. package/dist/_chunks/cache2.mjs.map +1 -1
  9. package/dist/_chunks/chunk.mjs +2 -0
  10. package/dist/_chunks/config.mjs +4 -0
  11. package/dist/_chunks/config.mjs.map +1 -1
  12. package/dist/_chunks/detect.mjs +30 -0
  13. package/dist/_chunks/detect.mjs.map +1 -1
  14. package/dist/_chunks/embedding-cache.mjs +6 -6
  15. package/dist/_chunks/embedding-cache.mjs.map +1 -1
  16. package/dist/_chunks/formatting.mjs +9 -1
  17. package/dist/_chunks/formatting.mjs.map +1 -1
  18. package/dist/_chunks/index2.d.mts.map +1 -1
  19. package/dist/_chunks/install.mjs +3 -1
  20. package/dist/_chunks/install.mjs.map +1 -1
  21. package/dist/_chunks/list.mjs +2 -0
  22. package/dist/_chunks/list.mjs.map +1 -1
  23. package/dist/_chunks/markdown.mjs +2 -0
  24. package/dist/_chunks/markdown.mjs.map +1 -1
  25. package/dist/_chunks/pool.mjs +2 -0
  26. package/dist/_chunks/pool.mjs.map +1 -1
  27. package/dist/_chunks/prompts.mjs +16 -0
  28. package/dist/_chunks/prompts.mjs.map +1 -1
  29. package/dist/_chunks/sanitize.mjs +3 -1
  30. package/dist/_chunks/sanitize.mjs.map +1 -1
  31. package/dist/_chunks/search-interactive.mjs +3 -1
  32. package/dist/_chunks/search-interactive.mjs.map +1 -1
  33. package/dist/_chunks/search.mjs +183 -8
  34. package/dist/_chunks/search.mjs.map +1 -0
  35. package/dist/_chunks/shared.mjs +4 -0
  36. package/dist/_chunks/shared.mjs.map +1 -1
  37. package/dist/_chunks/skills.mjs +4 -0
  38. package/dist/_chunks/skills.mjs.map +1 -1
  39. package/dist/_chunks/sources.mjs +88 -5
  40. package/dist/_chunks/sources.mjs.map +1 -1
  41. package/dist/_chunks/sync.mjs +23 -12
  42. package/dist/_chunks/sync.mjs.map +1 -1
  43. package/dist/_chunks/uninstall.mjs +3 -1
  44. package/dist/_chunks/uninstall.mjs.map +1 -1
  45. package/dist/_chunks/validate.mjs +2 -0
  46. package/dist/_chunks/validate.mjs.map +1 -1
  47. package/dist/_chunks/yaml.mjs +2 -0
  48. package/dist/_chunks/yaml.mjs.map +1 -1
  49. package/dist/agent/index.d.mts.map +1 -1
  50. package/dist/cli.mjs +19 -9
  51. package/dist/cli.mjs.map +1 -1
  52. package/dist/retriv/index.mjs +5 -3
  53. package/dist/retriv/index.mjs.map +1 -1
  54. package/dist/retriv/worker.mjs +2 -0
  55. package/dist/retriv/worker.mjs.map +1 -1
  56. package/dist/types.d.mts +0 -1
  57. package/package.json +10 -10
  58. package/dist/_chunks/search2.mjs +0 -180
  59. package/dist/_chunks/search2.mjs.map +0 -1
  60. package/dist/_chunks/sync2.mjs +0 -15
@@ -1,4 +1,5 @@
1
1
  import { createRequire } from "node:module";
2
+ //#region \0rolldown/runtime.js
2
3
  var __defProp = Object.defineProperty;
3
4
  var __exportAll = (all, no_symbols) => {
4
5
  let target = {};
@@ -10,4 +11,5 @@ var __exportAll = (all, no_symbols) => {
10
11
  return target;
11
12
  };
12
13
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
14
+ //#endregion
13
15
  export { __require as n, __exportAll as t };
@@ -1,5 +1,6 @@
1
1
  import { homedir } from "node:os";
2
2
  import { join, resolve } from "pathe";
3
+ //#region src/cache/version.ts
3
4
  /**
4
5
  * Version utilities
5
6
  */
@@ -30,6 +31,8 @@ function getCacheDir(name, version) {
30
31
  if (!dir.startsWith(REFERENCES_DIR)) throw new Error(`Path traversal detected: ${dir}`);
31
32
  return dir;
32
33
  }
34
+ //#endregion
35
+ //#region src/cache/config.ts
33
36
  /**
34
37
  * Cache configuration
35
38
  */
@@ -48,6 +51,7 @@ function getRepoCacheDir(owner, repo) {
48
51
  function getPackageDbPath(name, version) {
49
52
  return join(REFERENCES_DIR, getCacheKey(name, version), "search.db");
50
53
  }
54
+ //#endregion
51
55
  export { getRepoCacheDir as a, getVersionKey as c, getPackageDbPath as i, REFERENCES_DIR as n, getCacheDir as o, REPOS_DIR as r, getCacheKey as s, CACHE_DIR as t };
52
56
 
53
57
  //# sourceMappingURL=config.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.mjs","names":[],"sources":["../../src/cache/version.ts","../../src/cache/config.ts"],"sourcesContent":["/**\n * Version utilities\n */\n\nimport { resolve } from 'pathe'\nimport { REFERENCES_DIR } from './config.ts'\n\n/** Validate npm package name (scoped or unscoped) */\nconst VALID_PKG_NAME = /^(?:@[a-z0-9][-a-z0-9._]*\\/)?[a-z0-9][-a-z0-9._]*$/\n\n/** Validate version string (semver-ish, no path separators) */\nconst VALID_VERSION = /^[a-z0-9][-\\w.+]*$/i\n\n/**\n * Get exact version key for cache keying\n */\nexport function getVersionKey(version: string): string {\n return version\n}\n\n/**\n * Get cache key for a package: name@version\n */\nexport function getCacheKey(name: string, version: string): string {\n return `${name}@${getVersionKey(version)}`\n}\n\n/**\n * Get path to cached package references.\n * Validates name/version to prevent path traversal.\n */\nexport function getCacheDir(name: string, version: string): string {\n if (!VALID_PKG_NAME.test(name))\n throw new Error(`Invalid package name: ${name}`)\n if (!VALID_VERSION.test(version))\n throw new Error(`Invalid version: ${version}`)\n\n const dir = resolve(REFERENCES_DIR, getCacheKey(name, version))\n if (!dir.startsWith(REFERENCES_DIR))\n throw new Error(`Path traversal detected: ${dir}`)\n return dir\n}\n","/**\n * Cache configuration\n */\n\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { getCacheKey } from './version.ts'\n\n/** Global cache directory */\nexport const CACHE_DIR = join(homedir(), '.skilld')\n\n/** References subdirectory */\nexport const REFERENCES_DIR = join(CACHE_DIR, 'references')\n\n/** Repo-level cache (issues, discussions, releases shared across monorepo packages) */\nexport const REPOS_DIR = join(CACHE_DIR, 'repos')\n\n/** Get repo cache dir for owner/repo with path traversal validation */\nexport function getRepoCacheDir(owner: string, repo: string): string {\n if (owner.includes('..') || repo.includes('..') || owner.includes('/') || repo.includes('/'))\n throw new Error(`Invalid repo path: ${owner}/${repo}`)\n return join(REPOS_DIR, owner, repo)\n}\n\n/** Get search DB path for a specific package@version */\nexport function getPackageDbPath(name: string, version: string): string {\n return join(REFERENCES_DIR, getCacheKey(name, version), 'search.db')\n}\n"],"mappings":";;;;;;AAQA,MAAM,iBAAiB;;AAGvB,MAAM,gBAAgB;;;;AAKtB,SAAgB,cAAc,SAAyB;AACrD,QAAO;;;;;AAMT,SAAgB,YAAY,MAAc,SAAyB;AACjE,QAAO,GAAG,KAAK,GAAG,cAAc,QAAQ;;;;;;AAO1C,SAAgB,YAAY,MAAc,SAAyB;AACjE,KAAI,CAAC,eAAe,KAAK,KAAK,CAC5B,OAAM,IAAI,MAAM,yBAAyB,OAAO;AAClD,KAAI,CAAC,cAAc,KAAK,QAAQ,CAC9B,OAAM,IAAI,MAAM,oBAAoB,UAAU;CAEhD,MAAM,MAAM,QAAQ,gBAAgB,YAAY,MAAM,QAAQ,CAAC;AAC/D,KAAI,CAAC,IAAI,WAAW,eAAe,CACjC,OAAM,IAAI,MAAM,4BAA4B,MAAM;AACpD,QAAO;;;;;;AC/BT,MAAa,YAAY,KAAK,SAAS,EAAE,UAAU;;AAGnD,MAAa,iBAAiB,KAAK,WAAW,aAAa;;AAG3D,MAAa,YAAY,KAAK,WAAW,QAAQ;;AAGjD,SAAgB,gBAAgB,OAAe,MAAsB;AACnE,KAAI,MAAM,SAAS,KAAK,IAAI,KAAK,SAAS,KAAK,IAAI,MAAM,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,CAC1F,OAAM,IAAI,MAAM,sBAAsB,MAAM,GAAG,OAAO;AACxD,QAAO,KAAK,WAAW,OAAO,KAAK;;;AAIrC,SAAgB,iBAAiB,MAAc,SAAyB;AACtE,QAAO,KAAK,gBAAgB,YAAY,MAAM,QAAQ,EAAE,YAAY"}
1
+ {"version":3,"file":"config.mjs","names":[],"sources":["../../src/cache/version.ts","../../src/cache/config.ts"],"sourcesContent":["/**\n * Version utilities\n */\n\nimport { resolve } from 'pathe'\nimport { REFERENCES_DIR } from './config.ts'\n\n/** Validate npm package name (scoped or unscoped) */\nconst VALID_PKG_NAME = /^(?:@[a-z0-9][-a-z0-9._]*\\/)?[a-z0-9][-a-z0-9._]*$/\n\n/** Validate version string (semver-ish, no path separators) */\nconst VALID_VERSION = /^[a-z0-9][-\\w.+]*$/i\n\n/**\n * Get exact version key for cache keying\n */\nexport function getVersionKey(version: string): string {\n return version\n}\n\n/**\n * Get cache key for a package: name@version\n */\nexport function getCacheKey(name: string, version: string): string {\n return `${name}@${getVersionKey(version)}`\n}\n\n/**\n * Get path to cached package references.\n * Validates name/version to prevent path traversal.\n */\nexport function getCacheDir(name: string, version: string): string {\n if (!VALID_PKG_NAME.test(name))\n throw new Error(`Invalid package name: ${name}`)\n if (!VALID_VERSION.test(version))\n throw new Error(`Invalid version: ${version}`)\n\n const dir = resolve(REFERENCES_DIR, getCacheKey(name, version))\n if (!dir.startsWith(REFERENCES_DIR))\n throw new Error(`Path traversal detected: ${dir}`)\n return dir\n}\n","/**\n * Cache configuration\n */\n\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { getCacheKey } from './version.ts'\n\n/** Global cache directory */\nexport const CACHE_DIR = join(homedir(), '.skilld')\n\n/** References subdirectory */\nexport const REFERENCES_DIR = join(CACHE_DIR, 'references')\n\n/** Repo-level cache (issues, discussions, releases shared across monorepo packages) */\nexport const REPOS_DIR = join(CACHE_DIR, 'repos')\n\n/** Get repo cache dir for owner/repo with path traversal validation */\nexport function getRepoCacheDir(owner: string, repo: string): string {\n if (owner.includes('..') || repo.includes('..') || owner.includes('/') || repo.includes('/'))\n throw new Error(`Invalid repo path: ${owner}/${repo}`)\n return join(REPOS_DIR, owner, repo)\n}\n\n/** Get search DB path for a specific package@version */\nexport function getPackageDbPath(name: string, version: string): string {\n return join(REFERENCES_DIR, getCacheKey(name, version), 'search.db')\n}\n"],"mappings":";;;;;;;AAQA,MAAM,iBAAiB;;AAGvB,MAAM,gBAAgB;;;;AAKtB,SAAgB,cAAc,SAAyB;AACrD,QAAO;;;;;AAMT,SAAgB,YAAY,MAAc,SAAyB;AACjE,QAAO,GAAG,KAAK,GAAG,cAAc,QAAQ;;;;;;AAO1C,SAAgB,YAAY,MAAc,SAAyB;AACjE,KAAI,CAAC,eAAe,KAAK,KAAK,CAC5B,OAAM,IAAI,MAAM,yBAAyB,OAAO;AAClD,KAAI,CAAC,cAAc,KAAK,QAAQ,CAC9B,OAAM,IAAI,MAAM,oBAAoB,UAAU;CAEhD,MAAM,MAAM,QAAQ,gBAAgB,YAAY,MAAM,QAAQ,CAAC;AAC/D,KAAI,CAAC,IAAI,WAAW,eAAe,CACjC,OAAM,IAAI,MAAM,4BAA4B,MAAM;AACpD,QAAO;;;;;;;;AC/BT,MAAa,YAAY,KAAK,SAAS,EAAE,UAAU;;AAGnD,MAAa,iBAAiB,KAAK,WAAW,aAAa;;AAG3D,MAAa,YAAY,KAAK,WAAW,QAAQ;;AAGjD,SAAgB,gBAAgB,OAAe,MAAsB;AACnE,KAAI,MAAM,SAAS,KAAK,IAAI,KAAK,SAAS,KAAK,IAAI,MAAM,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,CAC1F,OAAM,IAAI,MAAM,sBAAsB,MAAM,GAAG,OAAO;AACxD,QAAO,KAAK,WAAW,OAAO,KAAK;;;AAIrC,SAAgB,iBAAiB,MAAc,SAAyB;AACtE,QAAO,KAAK,gBAAgB,YAAY,MAAM,QAAQ,EAAE,YAAY"}
@@ -4,6 +4,7 @@ import { join } from "pathe";
4
4
  import { existsSync } from "node:fs";
5
5
  import { spawnSync } from "node:child_process";
6
6
  import { isWindows } from "std-env";
7
+ //#region src/agent/targets/base.ts
7
8
  /** Common frontmatter fields from agentskills.io spec */
8
9
  const SPEC_FRONTMATTER = {
9
10
  "name": {
@@ -56,6 +57,8 @@ function defineTarget(target) {
56
57
  ...target
57
58
  };
58
59
  }
60
+ //#endregion
61
+ //#region src/agent/targets/amp.ts
59
62
  const configHome$2 = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
60
63
  /**
61
64
  * Amp (Sourcegraph)
@@ -102,6 +105,8 @@ const amp = defineTarget({
102
105
  "AGENTS.md files with globs frontmatter are conditionally included only when Amp reads matching files."
103
106
  ]
104
107
  });
108
+ //#endregion
109
+ //#region src/agent/targets/antigravity.ts
105
110
  const home$6 = homedir();
106
111
  /**
107
112
  * Antigravity (Google)
@@ -142,6 +147,8 @@ const antigravity = defineTarget({
142
147
  "GEMINI.md instruction file is shared with Gemini CLI. .agent/rules/*.md for always-on workspace rules."
143
148
  ]
144
149
  });
150
+ //#endregion
151
+ //#region src/agent/targets/claude-code.ts
145
152
  const claudeHome = process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
146
153
  /**
147
154
  * Claude Code (Anthropic CLI)
@@ -235,6 +242,8 @@ const claudeCode = defineTarget({
235
242
  "Supporting dirs: scripts/, references/, assets/ alongside SKILL.md."
236
243
  ]
237
244
  });
245
+ //#endregion
246
+ //#region src/agent/targets/cline.ts
238
247
  const home$5 = homedir();
239
248
  /**
240
249
  * Cline (VS Code extension)
@@ -278,6 +287,8 @@ const cline = defineTarget({
278
287
  "Supporting dirs: docs/, scripts/, templates/ alongside SKILL.md."
279
288
  ]
280
289
  });
290
+ //#endregion
291
+ //#region src/agent/targets/codex.ts
281
292
  const codexHome = process.env.CODEX_HOME || join(homedir(), ".codex");
282
293
  /**
283
294
  * OpenAI Codex CLI
@@ -336,6 +347,8 @@ const codex = defineTarget({
336
347
  "Size limit: 32 KiB default (project_doc_max_bytes), configurable in ~/.codex/config.toml."
337
348
  ]
338
349
  });
350
+ //#endregion
351
+ //#region src/agent/targets/cursor.ts
339
352
  const home$4 = homedir();
340
353
  /**
341
354
  * Cursor (AI code editor)
@@ -392,6 +405,8 @@ const cursor = defineTarget({
392
405
  "Supporting dirs: scripts/, references/, assets/ alongside SKILL.md."
393
406
  ]
394
407
  });
408
+ //#endregion
409
+ //#region src/agent/targets/gemini-cli.ts
395
410
  const home$3 = homedir();
396
411
  /**
397
412
  * Google Gemini CLI
@@ -437,6 +452,8 @@ const geminiCli = defineTarget({
437
452
  "scripts/, references/, assets/ directories are defined by spec but implementation is still incomplete (issue #15895)."
438
453
  ]
439
454
  });
455
+ //#endregion
456
+ //#region src/agent/targets/github-copilot.ts
440
457
  const home$2 = homedir();
441
458
  /**
442
459
  * GitHub Copilot
@@ -487,6 +504,8 @@ const githubCopilot = defineTarget({
487
504
  "Keep SKILL.md under 500 lines / 5000 tokens for optimal loading."
488
505
  ]
489
506
  });
507
+ //#endregion
508
+ //#region src/agent/targets/goose.ts
490
509
  const configHome$1 = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
491
510
  /**
492
511
  * Goose (Block)
@@ -530,6 +549,8 @@ const goose = defineTarget({
530
549
  "Supporting files alongside SKILL.md (scripts, templates, configs) are accessible."
531
550
  ]
532
551
  });
552
+ //#endregion
553
+ //#region src/agent/targets/opencode.ts
533
554
  const configHome = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
534
555
  /**
535
556
  * OpenCode (SST)
@@ -583,6 +604,8 @@ const opencode = defineTarget({
583
604
  "AGENTS.md (or CLAUDE.md fallback) for general instructions."
584
605
  ]
585
606
  });
607
+ //#endregion
608
+ //#region src/agent/targets/roo.ts
586
609
  const home$1 = homedir();
587
610
  /**
588
611
  * Roo Code (VS Code extension)
@@ -627,6 +650,8 @@ const roo = defineTarget({
627
650
  "Skills manageable from Settings panel (v3.46.0+)."
628
651
  ]
629
652
  });
653
+ //#endregion
654
+ //#region src/agent/targets/windsurf.ts
630
655
  const home = homedir();
631
656
  /**
632
657
  * Windsurf (Codeium editor)
@@ -669,6 +694,8 @@ const windsurf = defineTarget({
669
694
  "Supporting files alongside SKILL.md are loaded via progressive disclosure."
670
695
  ]
671
696
  });
697
+ //#endregion
698
+ //#region src/agent/targets/registry.ts
672
699
  const targets = {
673
700
  "claude-code": claudeCode,
674
701
  "cursor": cursor,
@@ -683,6 +710,8 @@ const targets = {
683
710
  "roo": roo,
684
711
  "antigravity": antigravity
685
712
  };
713
+ //#endregion
714
+ //#region src/agent/detect.ts
686
715
  var detect_exports = /* @__PURE__ */ __exportAll({
687
716
  detectInstalledAgents: () => detectInstalledAgents,
688
717
  detectTargetAgent: () => detectTargetAgent,
@@ -732,6 +761,7 @@ function getAgentVersion(agentType) {
732
761
  return null;
733
762
  }
734
763
  }
764
+ //#endregion
735
765
  export { targets as a, getAgentVersion as i, detectTargetAgent as n, detect_exports as r, detectInstalledAgents as t };
736
766
 
737
767
  //# sourceMappingURL=detect.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"detect.mjs","names":["configHome","home","home","home","home","home","configHome","home","agents"],"sources":["../../src/agent/targets/base.ts","../../src/agent/targets/amp.ts","../../src/agent/targets/antigravity.ts","../../src/agent/targets/claude-code.ts","../../src/agent/targets/cline.ts","../../src/agent/targets/codex.ts","../../src/agent/targets/cursor.ts","../../src/agent/targets/gemini-cli.ts","../../src/agent/targets/github-copilot.ts","../../src/agent/targets/goose.ts","../../src/agent/targets/opencode.ts","../../src/agent/targets/roo.ts","../../src/agent/targets/windsurf.ts","../../src/agent/targets/registry.ts","../../src/agent/detect.ts"],"sourcesContent":["/**\n * Shared defaults and factory for agent target definitions.\n * All targets share identical skillFilename, nameMatchesDir, namePattern,\n * and common frontmatter fields from the agentskills.io spec.\n */\n\nimport type { AgentTarget, FrontmatterField } from './types.ts'\n\n/** Common frontmatter fields from agentskills.io spec */\nexport const SPEC_FRONTMATTER: Record<string, FrontmatterField> = {\n 'name': { name: 'name', required: true, description: 'Skill identifier. Must match parent directory name.', constraints: '1-64 chars, lowercase alphanumeric + hyphens' },\n 'description': { name: 'description', required: true, description: 'What the skill does and when to use it.', constraints: '1-1024 chars' },\n 'license': { name: 'license', required: false, description: 'License reference' },\n 'compatibility': { name: 'compatibility', required: false, description: 'Environment requirements', constraints: 'max 500 chars' },\n 'metadata': { name: 'metadata', required: false, description: 'Arbitrary key-value pairs' },\n 'allowed-tools': { name: 'allowed-tools', required: false, description: 'Space-delimited pre-approved tools (experimental)' },\n}\n\n/** Shared defaults for all agent targets */\nconst BASE_DEFAULTS = {\n skillFilename: 'SKILL.md' as const,\n nameMatchesDir: true,\n namePattern: '^[a-z0-9]+(-[a-z0-9]+)*$',\n additionalSkillsDirs: [] as string[],\n extensions: [] as string[],\n notes: [] as string[],\n} satisfies Partial<AgentTarget>\n\ntype DefaultedFields = 'skillFilename' | 'nameMatchesDir' | 'namePattern' | 'additionalSkillsDirs' | 'extensions' | 'notes'\n\n/** Define an agent target with shared defaults applied */\nexport function defineTarget(\n target: Omit<AgentTarget, DefaultedFields> & Partial<Pick<AgentTarget, DefaultedFields>>,\n): AgentTarget {\n return { ...BASE_DEFAULTS, ...target }\n}\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst configHome = process.env.XDG_CONFIG_HOME || join(homedir(), '.config')\n\n/**\n * Amp (Sourcegraph)\n *\n * Uses .agents/skills/ as primary project path. Also reads .claude/skills/.\n * Skills can bundle MCP servers via mcp.json in the skill directory.\n *\n * AGENTS.md (or AGENT.md / CLAUDE.md fallback) for general instructions,\n * supports @-mentions to reference other files and glob-based conditional includes.\n *\n * @see https://ampcode.com/news/agent-skills\n * @see https://ampcode.com/manual\n */\nexport const amp = defineTarget({\n agent: 'amp',\n displayName: 'Amp',\n detectInstalled: () => existsSync(join(configHome, 'amp')),\n detectEnv: () => !!process.env.AMP_SESSION,\n detectProject: cwd => existsSync(join(cwd, '.agents', 'AGENTS.md')),\n instructionFile: 'AGENTS.md',\n\n skillsDir: '.agents/skills',\n globalSkillsDir: join(configHome, 'agents/skills'),\n additionalSkillsDirs: [\n '.claude/skills',\n '~/.config/amp/skills',\n '~/.claude/skills',\n ],\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Unique identifier. Project skills override user-wide ones with same name.' },\n { ...SPEC_FRONTMATTER.description!, description: 'Always visible to the model; determines when skill is invoked.' },\n ],\n\n discoveryStrategy: 'lazy',\n discoveryNotes: 'Names + descriptions visible at startup. Full SKILL.md body loads only when agent decides to invoke based on description match.',\n\n agentSkillsSpec: false,\n extensions: [\n 'mcp.json for bundling MCP server configurations',\n ],\n\n docs: 'https://ampcode.com/news/agent-skills',\n notes: [\n 'Reads .claude/skills/ natively — emitting there covers Claude Code, Cursor, Cline, Copilot, AND Amp.',\n 'Skills can bundle MCP servers via mcp.json in the skill directory.',\n 'AGENTS.md supports @-mentions to reference files (e.g. @doc/style.md, @doc/*.md globs).',\n 'AGENTS.md files with globs frontmatter are conditionally included only when Amp reads matching files.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * Antigravity (Google)\n *\n * Agent-first IDE (VS Code fork) powered by Gemini. Skills live in\n * .agent/skills/ (workspace) or ~/.gemini/antigravity/skills/ (global).\n * Uses semantic matching on description to auto-invoke skills.\n *\n * Adopted the Agent Skills open standard (agentskills.io) in Jan 2026.\n * Only `name` and `description` are used for routing; body loads on demand.\n *\n * @see https://antigravity.google/docs/skills\n * @see https://codelabs.developers.google.com/getting-started-with-antigravity-skills\n */\nexport const antigravity = defineTarget({\n agent: 'antigravity',\n displayName: 'Antigravity',\n detectInstalled: () => existsSync(join(home, '.gemini/antigravity')),\n detectEnv: () => !!process.env.ANTIGRAVITY_CLI_ALIAS,\n detectProject: cwd => existsSync(join(cwd, '.agent')),\n instructionFile: 'GEMINI.md',\n\n skillsDir: '.agent/skills',\n globalSkillsDir: join(home, '.gemini/antigravity/skills'),\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Skill identifier. Defaults to directory name if omitted.' },\n { ...SPEC_FRONTMATTER.description!, description: 'Semantic trigger for agent routing. Must be descriptive enough for LLM matching.' },\n ],\n\n discoveryStrategy: 'lazy',\n discoveryNotes: 'Indexes name + description at startup. Full SKILL.md body loads on demand when agent semantic-matches description against user prompt.',\n\n agentSkillsSpec: true,\n\n docs: 'https://antigravity.google/docs/skills',\n notes: [\n 'Only `name` and `description` are used for routing; other frontmatter fields are accepted but not used for matching.',\n 'Skill directories can include scripts/, resources/, and assets/ subdirectories for supporting files.',\n 'GEMINI.md instruction file is shared with Gemini CLI. .agent/rules/*.md for always-on workspace rules.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst claudeHome = process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude')\n\n/**\n * Claude Code (Anthropic CLI)\n *\n * Follows the Agent Skills open standard (agentskills.io) plus Claude-specific\n * extensions like `disable-model-invocation`, `user-invocable`, `context`, etc.\n *\n * Skills are discovered at startup — only `name` + `description` are read initially.\n * Full SKILL.md body loads when the agent invokes the skill (via Skill tool or auto-match).\n *\n * @see https://code.claude.com/docs/en/skills\n * @see https://agentskills.io/specification\n */\nexport const claudeCode = defineTarget({\n agent: 'claude-code',\n displayName: 'Claude Code',\n detectInstalled: () => existsSync(claudeHome),\n detectEnv: () => !!(process.env.CLAUDE_CODE || process.env.CLAUDECODE || process.env.CLAUDE_CODE_ENTRYPOINT || process.env.CLAUDE_CONFIG_DIR),\n detectProject: cwd => existsSync(join(cwd, '.claude')) || existsSync(join(cwd, 'CLAUDE.md')),\n cli: 'claude',\n instructionFile: 'CLAUDE.md',\n\n skillsDir: '.claude/skills',\n globalSkillsDir: join(claudeHome, 'skills'),\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, required: false, description: 'Skill identifier, becomes /slash-command. Defaults to directory name if omitted.', constraints: '1-64 chars, ^[a-z0-9]+(-[a-z0-9]+)*$' },\n { ...SPEC_FRONTMATTER.description!, description: 'What the skill does and when to use it. Used for auto-discovery matching.' },\n SPEC_FRONTMATTER.license!,\n SPEC_FRONTMATTER.compatibility!,\n SPEC_FRONTMATTER.metadata!,\n SPEC_FRONTMATTER['allowed-tools']!,\n { name: 'disable-model-invocation', required: false, description: 'When true, skill only loads via explicit /name invocation' },\n { name: 'user-invocable', required: false, description: 'When false, hides from / menu but still auto-loads' },\n { name: 'argument-hint', required: false, description: 'Hint shown during autocomplete, e.g. [issue-number]' },\n { name: 'model', required: false, description: 'Model to use when skill is active' },\n { name: 'context', required: false, description: 'Set to \"fork\" to run in a forked subagent context' },\n { name: 'agent', required: false, description: 'Subagent type when context: fork (e.g. Explore, Plan)' },\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'Scans skill dirs at startup, reads name + description only. Full body loads on invocation. Budget: 2% of context window for all skill descriptions.',\n\n agentSkillsSpec: true,\n extensions: [\n 'disable-model-invocation',\n 'user-invocable',\n 'argument-hint',\n 'model',\n 'context',\n 'agent',\n 'hooks',\n '$ARGUMENTS substitution',\n '!`command` dynamic context',\n ],\n\n docs: 'https://code.claude.com/docs/en/skills',\n notes: [\n '`globs` is NOT a valid frontmatter field for skills (only for rules). Unknown fields are silently ignored.',\n '`version` and `generated_by` should go under `metadata` map, not as top-level fields.',\n 'Skill descriptions have a char budget of 2% of context window (~16k chars fallback). Override with SLASH_COMMAND_TOOL_CHAR_BUDGET env var.',\n 'Keep SKILL.md under 500 lines. Move detailed reference to separate files.',\n 'Supports monorepo auto-discovery: nested .claude/skills/ dirs in subdirectories.',\n 'Supporting dirs: scripts/, references/, assets/ alongside SKILL.md.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * Cline (VS Code extension)\n *\n * Has TWO systems: Rules (.clinerules/) and Skills (.cline/skills/).\n * We target Skills. Cline also reads .claude/skills/ as a fallback,\n * so emitting to .claude/skills/ covers both Claude Code and Cline.\n *\n * Only `name` and `description` are parsed from frontmatter.\n * All other fields are stripped/ignored.\n *\n * @see https://docs.cline.bot/features/skills\n * @see https://docs.cline.bot/features/cline-rules\n */\nexport const cline = defineTarget({\n agent: 'cline',\n displayName: 'Cline',\n detectInstalled: () => existsSync(join(home, '.cline')),\n detectEnv: () => !!process.env.CLINE_TASK_ID,\n detectProject: cwd => existsSync(join(cwd, '.cline')),\n instructionFile: '.clinerules',\n\n skillsDir: '.cline/skills',\n globalSkillsDir: join(home, '.cline/skills'),\n additionalSkillsDirs: [\n '.clinerules/skills',\n '.claude/skills',\n ],\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Must exactly match the directory name.' },\n { ...SPEC_FRONTMATTER.description!, description: 'When to activate. Used for matching.' },\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'At startup reads name + description from each skill. Full content loads on-demand via use_skill tool. Dozens of skills have near-zero context cost.',\n\n agentSkillsSpec: false,\n\n docs: 'https://docs.cline.bot/features/skills',\n notes: [\n 'Only `name` and `description` are parsed. `version`, `globs`, etc. are silently ignored.',\n 'Cline reads .claude/skills/ as a fallback — emitting there covers both Claude Code and Cline.',\n 'Rules system (.clinerules/) is separate: always-on behavioral constraints with globs/tags frontmatter.',\n 'Global skills override project skills when names conflict.',\n 'Supporting dirs: docs/, scripts/, templates/ alongside SKILL.md.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst codexHome = process.env.CODEX_HOME || join(homedir(), '.codex')\n\n/**\n * OpenAI Codex CLI\n *\n * IMPORTANT: Codex uses `.agents/skills/` for project-level skills,\n * NOT `.codex/skills/`. The `.codex/` directory is for config (config.toml).\n * `~/.codex/skills/` works only as a legacy user-global path.\n *\n * Codex also has AGENTS.md (or AGENTS.override.md) for general instructions,\n * which walks from git root to CWD concatenating found files.\n *\n * @see https://developers.openai.com/codex/skills\n * @see https://developers.openai.com/codex/guides/agents-md/\n */\nexport const codex = defineTarget({\n agent: 'codex',\n displayName: 'Codex',\n detectInstalled: () => existsSync(codexHome),\n detectEnv: () => !!(process.env.CODEX_HOME || process.env.CODEX_SESSION),\n detectProject: cwd => existsSync(join(cwd, '.codex')),\n cli: 'codex',\n instructionFile: 'AGENTS.md',\n\n skillsDir: '.agents/skills',\n globalSkillsDir: join(homedir(), '.agents/skills'),\n additionalSkillsDirs: [\n '~/.codex/skills',\n '/etc/codex/skills',\n ],\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Skill identifier.', constraints: '1-64 chars, ^[a-z0-9-]+$, no leading/trailing/consecutive hyphens' },\n { ...SPEC_FRONTMATTER.description!, description: 'Must include when-to-use criteria. Primary triggering mechanism.', constraints: '1-1024 chars, no angle brackets (< or >)' },\n SPEC_FRONTMATTER.license!,\n SPEC_FRONTMATTER['allowed-tools']!,\n SPEC_FRONTMATTER.metadata!,\n ],\n\n discoveryStrategy: 'lazy',\n discoveryNotes: 'Startup scan reads name + description + optional agents/openai.yaml. Full body loads only on invocation. Supports $1-$9 and $ARGUMENTS placeholders.',\n\n agentSkillsSpec: true,\n extensions: [\n 'agents/openai.yaml (UI metadata + MCP dependencies)',\n '$1-$9 positional argument placeholders',\n 'AGENTS.override.md for temporary overrides',\n ],\n\n docs: 'https://developers.openai.com/codex/skills',\n notes: [\n 'BUG IN CURRENT CODE: skillsDir is .codex/skills/ but should be .agents/skills/. The .codex/ directory is for config, not skills.',\n 'Description field cannot contain angle brackets (< or >).',\n 'Optional agents/openai.yaml provides UI metadata: display_name, icon, brand_color, default_prompt.',\n 'AGENTS.md walks from git root to CWD, concatenating all found files.',\n 'Live reload: detects skill file changes without restart (v0.95.0+).',\n 'Size limit: 32 KiB default (project_doc_max_bytes), configurable in ~/.codex/config.toml.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * Cursor (AI code editor)\n *\n * Has TWO systems: Rules (.cursor/rules/*.mdc) and Skills (.cursor/skills/).\n * We target the Skills system which follows the Agent Skills spec.\n *\n * Cursor natively scans .claude/skills/ and .codex/skills/ in addition to\n * its own .cursor/skills/ — so .claude/skills/ output works for both\n * Claude Code and Cursor with zero duplication.\n *\n * @see https://cursor.com/docs/context/skills\n * @see https://cursor.com/docs/context/rules\n */\nexport const cursor = defineTarget({\n agent: 'cursor',\n displayName: 'Cursor',\n detectInstalled: () => existsSync(join(home, '.cursor')),\n detectEnv: () => !!(process.env.CURSOR_SESSION || process.env.CURSOR_TRACE_ID),\n detectProject: cwd => existsSync(join(cwd, '.cursor')) || existsSync(join(cwd, '.cursorrules')),\n instructionFile: '.cursorrules',\n\n skillsDir: '.cursor/skills',\n globalSkillsDir: join(home, '.cursor/skills'),\n additionalSkillsDirs: [\n '.claude/skills',\n '.codex/skills',\n '~/.claude/skills',\n '~/.codex/skills',\n ],\n\n frontmatter: [\n SPEC_FRONTMATTER.name!,\n { ...SPEC_FRONTMATTER.description!, description: 'Agent uses this to decide relevance for auto-invocation.' },\n SPEC_FRONTMATTER.license!,\n SPEC_FRONTMATTER.compatibility!,\n SPEC_FRONTMATTER.metadata!,\n { name: 'disable-model-invocation', required: false, description: 'When true, only loads via explicit /skill-name' },\n ],\n\n discoveryStrategy: 'lazy',\n discoveryNotes: 'Reads name + description at conversation start. Full SKILL.md body loads only when agent determines relevance. Users can also invoke via /skill-name.',\n\n agentSkillsSpec: true,\n extensions: [\n 'disable-model-invocation',\n ],\n\n docs: 'https://cursor.com/docs/context/skills',\n notes: [\n 'Cursor scans .claude/skills/ and .codex/skills/ natively — emitting to .claude/skills/ covers both Claude Code and Cursor.',\n 'The Rules system (.cursor/rules/*.mdc) is separate and uses different frontmatter (trigger, globs, alwaysApply).',\n 'Skills appear in Settings > Rules > Agent Decides section.',\n 'Supporting dirs: scripts/, references/, assets/ alongside SKILL.md.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * Google Gemini CLI\n *\n * Follows the Agent Skills open standard (agentskills.io).\n * Skills are activated via `activate_skill` tool with user confirmation.\n *\n * Also has GEMINI.md context files (analogous to CLAUDE.md) which support\n * @file.md import syntax for modular composition.\n *\n * @see https://geminicli.com/docs/cli/skills/\n * @see https://geminicli.com/docs/cli/creating-skills/\n */\nexport const geminiCli = defineTarget({\n agent: 'gemini-cli',\n displayName: 'Gemini CLI',\n detectInstalled: () => existsSync(join(home, '.gemini')),\n detectEnv: () => !!(process.env.GEMINI_API_KEY && process.env.GEMINI_SESSION),\n detectProject: cwd => existsSync(join(cwd, '.gemini')) || existsSync(join(cwd, 'AGENTS.md')),\n cli: 'gemini',\n instructionFile: 'GEMINI.md',\n\n skillsDir: '.gemini/skills',\n globalSkillsDir: join(home, '.gemini/skills'),\n\n frontmatter: [\n SPEC_FRONTMATTER.name!,\n { ...SPEC_FRONTMATTER.description!, description: 'Primary trigger — agent uses this to match tasks.' },\n SPEC_FRONTMATTER.license!,\n SPEC_FRONTMATTER.compatibility!,\n SPEC_FRONTMATTER.metadata!,\n SPEC_FRONTMATTER['allowed-tools']!,\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'Scans at session start, injects ~100 tokens per skill (name+description). Activation via activate_skill tool requires user confirmation. Skill stays active for session duration.',\n\n agentSkillsSpec: true,\n\n docs: 'https://geminicli.com/docs/cli/skills/',\n notes: [\n 'Management commands: /skills list, /skills enable <name>, /skills disable <name>, /skills reload.',\n 'GEMINI.md context files are separate from skills — support @file.md import syntax.',\n 'settings.json can configure additional context filenames: [\"AGENTS.md\", \"CONTEXT.md\", \"GEMINI.md\"].',\n 'scripts/, references/, assets/ directories are defined by spec but implementation is still incomplete (issue #15895).',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * GitHub Copilot\n *\n * Has TWO systems: Instructions (.github/instructions/*.instructions.md)\n * and Skills (.github/skills/). We target Skills.\n *\n * Copilot also auto-detects .claude/skills/ as a legacy path,\n * so .claude/skills/ output works for Claude Code, Cursor, Cline, AND Copilot.\n *\n * @see https://docs.github.com/en/copilot/concepts/agents/about-agent-skills\n * @see https://docs.github.com/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot\n */\nexport const githubCopilot = defineTarget({\n agent: 'github-copilot',\n displayName: 'GitHub Copilot',\n detectInstalled: () => existsSync(join(home, '.copilot')),\n detectEnv: () => !!process.env.GITHUB_COPILOT_SESSION,\n detectProject: cwd => existsSync(join(cwd, '.github', 'copilot-instructions.md')),\n instructionFile: '.github/copilot-instructions.md',\n\n skillsDir: '.github/skills',\n globalSkillsDir: join(home, '.copilot/skills'),\n additionalSkillsDirs: [\n '.claude/skills',\n '~/.claude/skills',\n ],\n\n frontmatter: [\n SPEC_FRONTMATTER.name!,\n { ...SPEC_FRONTMATTER.description!, description: 'What the skill does AND when to use it.' },\n SPEC_FRONTMATTER.license!,\n SPEC_FRONTMATTER.compatibility!,\n { ...SPEC_FRONTMATTER.metadata!, description: 'Arbitrary key-value pairs (e.g. version, author)' },\n SPEC_FRONTMATTER['allowed-tools']!,\n ],\n\n discoveryStrategy: 'lazy',\n discoveryNotes: '3-level progressive disclosure: (1) ~100 tokens for name+description, (2) full SKILL.md body <5000 tokens on activation, (3) resources from scripts/references/assets/ on demand.',\n\n agentSkillsSpec: true,\n\n docs: 'https://docs.github.com/en/copilot/concepts/agents/about-agent-skills',\n notes: [\n 'Copilot auto-detects .claude/skills/ as a legacy path — emitting there covers multiple agents.',\n 'Instructions system (.github/instructions/*.instructions.md) is separate, uses applyTo globs.',\n 'copilot-instructions.md at .github/ root is always applied (repo-wide).',\n 'AGENTS.md also recognized as of Aug 2025.',\n 'excludeAgent property in instructions can hide from code-review or coding-agent.',\n 'Keep SKILL.md under 500 lines / 5000 tokens for optimal loading.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst configHome = process.env.XDG_CONFIG_HOME || join(homedir(), '.config')\n\n/**\n * Goose (Block)\n *\n * Scans 6 directories for skills, including .claude/skills/ and .agents/skills/\n * for cross-agent compatibility. Later directories override earlier ones on\n * name conflict.\n *\n * @see https://block.github.io/goose/docs/guides/context-engineering/using-skills/\n */\nexport const goose = defineTarget({\n agent: 'goose',\n displayName: 'Goose',\n detectInstalled: () => existsSync(join(configHome, 'goose')),\n detectEnv: () => !!process.env.GOOSE_SESSION,\n detectProject: cwd => existsSync(join(cwd, '.goose')),\n cli: 'goose',\n instructionFile: '.goosehints',\n\n skillsDir: '.goose/skills',\n globalSkillsDir: join(configHome, 'goose/skills'),\n additionalSkillsDirs: [\n '.claude/skills',\n '.agents/skills',\n '~/.claude/skills',\n '~/.config/agents/skills',\n ],\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Skill identifier.' },\n { ...SPEC_FRONTMATTER.description!, description: 'Brief purpose statement; used for matching.' },\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'Scans all 6 directories at startup, merges discovered skills. Later directories override earlier ones on name conflict.',\n\n agentSkillsSpec: false,\n\n docs: 'https://block.github.io/goose/docs/guides/context-engineering/using-skills/',\n notes: [\n 'Reads .claude/skills/ natively — emitting there covers both Claude Code and Goose.',\n 'Also supports .goosehints / .goosehints.local for general project instructions (separate from skills).',\n 'Supporting files alongside SKILL.md (scripts, templates, configs) are accessible.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst configHome = process.env.XDG_CONFIG_HOME || join(homedir(), '.config')\n\n/**\n * OpenCode (SST)\n *\n * Walks from CWD up to git worktree root searching for skill dirs.\n * Reads .claude/skills/ and .agents/skills/ in addition to .opencode/skills/.\n *\n * Has a rich agent system: .opencode/agents/ with per-agent model/tool configuration.\n * Skills can be permission-controlled per-agent with allow/deny/ask + glob patterns.\n *\n * @see https://opencode.ai/docs/skills/\n * @see https://opencode.ai/docs/rules/\n */\nexport const opencode = defineTarget({\n agent: 'opencode',\n displayName: 'OpenCode',\n detectInstalled: () => existsSync(join(configHome, 'opencode')),\n detectEnv: () => !!process.env.OPENCODE_SESSION,\n detectProject: cwd => existsSync(join(cwd, '.opencode')),\n instructionFile: 'AGENTS.md',\n\n skillsDir: '.opencode/skills',\n globalSkillsDir: join(configHome, 'opencode/skills'),\n additionalSkillsDirs: [\n '.claude/skills',\n '.agents/skills',\n '~/.claude/skills',\n '~/.agents/skills',\n ],\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Must match directory name.' },\n { ...SPEC_FRONTMATTER.description!, description: 'Used for matching.' },\n SPEC_FRONTMATTER.license!,\n SPEC_FRONTMATTER.compatibility!,\n SPEC_FRONTMATTER.metadata!,\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'Walks from CWD to git worktree root, then loads global definitions. Agents access skills via native skill tool. Skills can be permission-controlled per-agent.',\n\n agentSkillsSpec: true,\n extensions: [\n 'Per-agent skill permissions (allow/deny/ask with glob patterns)',\n ],\n\n docs: 'https://opencode.ai/docs/skills/',\n notes: [\n 'Reads .claude/skills/ and .agents/skills/ natively — emitting to .claude/skills/ covers multiple agents.',\n 'Custom agents in .opencode/agents/ have rich config: model, temperature, tools, permission, color.',\n 'opencode.json supports an instructions field with glob patterns pointing to instruction files.',\n 'AGENTS.md (or CLAUDE.md fallback) for general instructions.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * Roo Code (VS Code extension)\n *\n * IMPORTANT: Roo does NOT read .claude/skills/ or .agents/skills/.\n * It requires its own .roo/skills/ directory — no cross-compat shortcuts.\n *\n * Unique feature: mode-specific skill directories (.roo/skills-{modeSlug}/)\n * allow targeting skills to specific modes (code, architect, etc.).\n *\n * @see https://docs.roocode.com/features/skills\n * @see https://docs.roocode.com/features/custom-instructions\n */\nexport const roo = defineTarget({\n agent: 'roo',\n displayName: 'Roo Code',\n detectInstalled: () => existsSync(join(home, '.roo')),\n detectEnv: () => !!process.env.ROO_SESSION,\n detectProject: cwd => existsSync(join(cwd, '.roo')),\n instructionFile: '.roorules',\n\n skillsDir: '.roo/skills',\n globalSkillsDir: join(home, '.roo/skills'),\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Must exactly match the directory name.' },\n { ...SPEC_FRONTMATTER.description!, description: 'When to activate.' },\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'Reads all SKILL.md files at startup. File watchers detect changes during session. Uses read_file to load full content on activation.',\n\n agentSkillsSpec: false,\n extensions: [\n 'Mode-specific skill directories: .roo/skills-{modeSlug}/',\n ],\n\n docs: 'https://docs.roocode.com/features/skills',\n notes: [\n 'Does NOT read .claude/skills/ or .agents/skills/ — requires its own .roo/skills/ directory.',\n 'Mode-specific dirs: .roo/skills-code/, .roo/skills-architect/ etc. target specific modes.',\n 'Override priority: project mode-specific > project generic > global mode-specific > global generic.',\n 'Supports symlinks for shared skill libraries across projects.',\n 'Rules system (.roo/rules/) is separate — .md/.txt files loaded alphabetically into system prompt.',\n 'Legacy fallback: .roorules file if .roo/rules/ is empty.',\n 'Skills manageable from Settings panel (v3.46.0+).',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * Windsurf (Codeium editor)\n *\n * Has TWO systems: Rules (.windsurf/rules/*.md) and Skills (.windsurf/skills/).\n * We target Skills. Rules have a separate frontmatter schema with trigger/globs.\n *\n * Skills only document `name` and `description` as frontmatter fields.\n * Cascade uses \"progressive disclosure\" for supporting files.\n *\n * @see https://docs.windsurf.com/windsurf/cascade/skills\n * @see https://docs.windsurf.com/windsurf/cascade/memories\n */\nexport const windsurf = defineTarget({\n agent: 'windsurf',\n displayName: 'Windsurf',\n detectInstalled: () => existsSync(join(home, '.codeium/windsurf')),\n detectEnv: () => !!process.env.WINDSURF_SESSION,\n detectProject: cwd => existsSync(join(cwd, '.windsurf')) || existsSync(join(cwd, '.windsurfrules')),\n instructionFile: '.windsurfrules',\n\n skillsDir: '.windsurf/skills',\n globalSkillsDir: join(home, '.codeium/windsurf/skills'),\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Skill identifier.', constraints: 'Lowercase, numbers, hyphens only' },\n { ...SPEC_FRONTMATTER.description!, description: 'Used by Cascade for automatic invocation matching.' },\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'Cascade matches description against user requests for auto-invocation. Manual invocation via @skill-name.',\n\n agentSkillsSpec: false,\n\n docs: 'https://docs.windsurf.com/windsurf/cascade/skills',\n notes: [\n 'Only `name` and `description` are documented as frontmatter fields. Other fields may be silently ignored.',\n 'Rules system is separate: .windsurf/rules/*.md with trigger/globs/alwaysApply frontmatter.',\n 'Rules have a 6,000 char per-file limit and 12,000 char total limit. Skills have no documented limit.',\n 'Legacy .windsurfrules at project root still supported but deprecated.',\n 'Supporting files alongside SKILL.md are loaded via progressive disclosure.',\n ],\n})\n","/**\n * Agent targets registry — all supported agents and their skill conventions\n */\n\nimport type { AgentType } from '../types.ts'\nimport type { AgentTarget } from './types.ts'\nimport { amp } from './amp.ts'\nimport { antigravity } from './antigravity.ts'\nimport { claudeCode } from './claude-code.ts'\nimport { cline } from './cline.ts'\nimport { codex } from './codex.ts'\nimport { cursor } from './cursor.ts'\nimport { geminiCli } from './gemini-cli.ts'\nimport { githubCopilot } from './github-copilot.ts'\nimport { goose } from './goose.ts'\nimport { opencode } from './opencode.ts'\nimport { roo } from './roo.ts'\nimport { windsurf } from './windsurf.ts'\n\nexport const targets: Record<AgentType, AgentTarget> = {\n 'claude-code': claudeCode,\n 'cursor': cursor,\n 'windsurf': windsurf,\n 'cline': cline,\n 'codex': codex,\n 'github-copilot': githubCopilot,\n 'gemini-cli': geminiCli,\n 'goose': goose,\n 'amp': amp,\n 'opencode': opencode,\n 'roo': roo,\n 'antigravity': antigravity,\n}\n","/**\n * Agent detection - identify installed and active agents\n */\n\nimport type { AgentType } from './types.ts'\nimport { spawnSync } from 'node:child_process'\nimport { isWindows } from 'std-env'\nimport { agents } from './registry.ts'\n\n/**\n * Detect which agents are installed on the system\n */\nexport function detectInstalledAgents(): AgentType[] {\n return Object.entries(agents)\n .filter(([_, config]) => config.detectInstalled())\n .map(([type]) => type as AgentType)\n}\n\n/**\n * Detect the target agent (where skills are installed) from env vars and cwd.\n * This is NOT the generator LLM — it determines the skills directory.\n *\n * Priority: env vars first (running inside agent), then project dirs.\n * Iteration order of the agents record determines priority.\n */\nexport function detectTargetAgent(): AgentType | null {\n for (const [type, target] of Object.entries(agents)) {\n if (target.detectEnv())\n return type as AgentType\n }\n\n const cwd = process.cwd()\n for (const [type, target] of Object.entries(agents)) {\n if (target.detectProject(cwd))\n return type as AgentType\n }\n\n return null\n}\n\n/**\n * Get the version of an agent's CLI (if available)\n */\nexport function getAgentVersion(agentType: AgentType): string | null {\n const agent = agents[agentType]\n if (!agent.cli)\n return null\n\n try {\n const result = spawnSync(agent.cli, ['--version'], {\n encoding: 'utf-8',\n timeout: 3000,\n stdio: ['pipe', 'pipe', 'pipe'],\n shell: isWindows,\n })\n if (result.status !== 0)\n return null\n const output = (result.stdout || '').trim()\n\n // Extract version number from output\n // Common formats: \"v1.2.3\", \"1.2.3\", \"cli 1.2.3\", \"name v1.2.3\"\n const match = output.match(/v?(\\d+\\.\\d+\\.\\d+(?:-[a-z0-9.]+)?)/)\n return match ? match[1] : output.split('\\n')[0]\n }\n catch {\n return null\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"detect.mjs","names":["configHome","home","home","home","home","home","configHome","home","agents"],"sources":["../../src/agent/targets/base.ts","../../src/agent/targets/amp.ts","../../src/agent/targets/antigravity.ts","../../src/agent/targets/claude-code.ts","../../src/agent/targets/cline.ts","../../src/agent/targets/codex.ts","../../src/agent/targets/cursor.ts","../../src/agent/targets/gemini-cli.ts","../../src/agent/targets/github-copilot.ts","../../src/agent/targets/goose.ts","../../src/agent/targets/opencode.ts","../../src/agent/targets/roo.ts","../../src/agent/targets/windsurf.ts","../../src/agent/targets/registry.ts","../../src/agent/detect.ts"],"sourcesContent":["/**\n * Shared defaults and factory for agent target definitions.\n * All targets share identical skillFilename, nameMatchesDir, namePattern,\n * and common frontmatter fields from the agentskills.io spec.\n */\n\nimport type { AgentTarget, FrontmatterField } from './types.ts'\n\n/** Common frontmatter fields from agentskills.io spec */\nexport const SPEC_FRONTMATTER: Record<string, FrontmatterField> = {\n 'name': { name: 'name', required: true, description: 'Skill identifier. Must match parent directory name.', constraints: '1-64 chars, lowercase alphanumeric + hyphens' },\n 'description': { name: 'description', required: true, description: 'What the skill does and when to use it.', constraints: '1-1024 chars' },\n 'license': { name: 'license', required: false, description: 'License reference' },\n 'compatibility': { name: 'compatibility', required: false, description: 'Environment requirements', constraints: 'max 500 chars' },\n 'metadata': { name: 'metadata', required: false, description: 'Arbitrary key-value pairs' },\n 'allowed-tools': { name: 'allowed-tools', required: false, description: 'Space-delimited pre-approved tools (experimental)' },\n}\n\n/** Shared defaults for all agent targets */\nconst BASE_DEFAULTS = {\n skillFilename: 'SKILL.md' as const,\n nameMatchesDir: true,\n namePattern: '^[a-z0-9]+(-[a-z0-9]+)*$',\n additionalSkillsDirs: [] as string[],\n extensions: [] as string[],\n notes: [] as string[],\n} satisfies Partial<AgentTarget>\n\ntype DefaultedFields = 'skillFilename' | 'nameMatchesDir' | 'namePattern' | 'additionalSkillsDirs' | 'extensions' | 'notes'\n\n/** Define an agent target with shared defaults applied */\nexport function defineTarget(\n target: Omit<AgentTarget, DefaultedFields> & Partial<Pick<AgentTarget, DefaultedFields>>,\n): AgentTarget {\n return { ...BASE_DEFAULTS, ...target }\n}\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst configHome = process.env.XDG_CONFIG_HOME || join(homedir(), '.config')\n\n/**\n * Amp (Sourcegraph)\n *\n * Uses .agents/skills/ as primary project path. Also reads .claude/skills/.\n * Skills can bundle MCP servers via mcp.json in the skill directory.\n *\n * AGENTS.md (or AGENT.md / CLAUDE.md fallback) for general instructions,\n * supports @-mentions to reference other files and glob-based conditional includes.\n *\n * @see https://ampcode.com/news/agent-skills\n * @see https://ampcode.com/manual\n */\nexport const amp = defineTarget({\n agent: 'amp',\n displayName: 'Amp',\n detectInstalled: () => existsSync(join(configHome, 'amp')),\n detectEnv: () => !!process.env.AMP_SESSION,\n detectProject: cwd => existsSync(join(cwd, '.agents', 'AGENTS.md')),\n instructionFile: 'AGENTS.md',\n\n skillsDir: '.agents/skills',\n globalSkillsDir: join(configHome, 'agents/skills'),\n additionalSkillsDirs: [\n '.claude/skills',\n '~/.config/amp/skills',\n '~/.claude/skills',\n ],\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Unique identifier. Project skills override user-wide ones with same name.' },\n { ...SPEC_FRONTMATTER.description!, description: 'Always visible to the model; determines when skill is invoked.' },\n ],\n\n discoveryStrategy: 'lazy',\n discoveryNotes: 'Names + descriptions visible at startup. Full SKILL.md body loads only when agent decides to invoke based on description match.',\n\n agentSkillsSpec: false,\n extensions: [\n 'mcp.json for bundling MCP server configurations',\n ],\n\n docs: 'https://ampcode.com/news/agent-skills',\n notes: [\n 'Reads .claude/skills/ natively — emitting there covers Claude Code, Cursor, Cline, Copilot, AND Amp.',\n 'Skills can bundle MCP servers via mcp.json in the skill directory.',\n 'AGENTS.md supports @-mentions to reference files (e.g. @doc/style.md, @doc/*.md globs).',\n 'AGENTS.md files with globs frontmatter are conditionally included only when Amp reads matching files.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * Antigravity (Google)\n *\n * Agent-first IDE (VS Code fork) powered by Gemini. Skills live in\n * .agent/skills/ (workspace) or ~/.gemini/antigravity/skills/ (global).\n * Uses semantic matching on description to auto-invoke skills.\n *\n * Adopted the Agent Skills open standard (agentskills.io) in Jan 2026.\n * Only `name` and `description` are used for routing; body loads on demand.\n *\n * @see https://antigravity.google/docs/skills\n * @see https://codelabs.developers.google.com/getting-started-with-antigravity-skills\n */\nexport const antigravity = defineTarget({\n agent: 'antigravity',\n displayName: 'Antigravity',\n detectInstalled: () => existsSync(join(home, '.gemini/antigravity')),\n detectEnv: () => !!process.env.ANTIGRAVITY_CLI_ALIAS,\n detectProject: cwd => existsSync(join(cwd, '.agent')),\n instructionFile: 'GEMINI.md',\n\n skillsDir: '.agent/skills',\n globalSkillsDir: join(home, '.gemini/antigravity/skills'),\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Skill identifier. Defaults to directory name if omitted.' },\n { ...SPEC_FRONTMATTER.description!, description: 'Semantic trigger for agent routing. Must be descriptive enough for LLM matching.' },\n ],\n\n discoveryStrategy: 'lazy',\n discoveryNotes: 'Indexes name + description at startup. Full SKILL.md body loads on demand when agent semantic-matches description against user prompt.',\n\n agentSkillsSpec: true,\n\n docs: 'https://antigravity.google/docs/skills',\n notes: [\n 'Only `name` and `description` are used for routing; other frontmatter fields are accepted but not used for matching.',\n 'Skill directories can include scripts/, resources/, and assets/ subdirectories for supporting files.',\n 'GEMINI.md instruction file is shared with Gemini CLI. .agent/rules/*.md for always-on workspace rules.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst claudeHome = process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude')\n\n/**\n * Claude Code (Anthropic CLI)\n *\n * Follows the Agent Skills open standard (agentskills.io) plus Claude-specific\n * extensions like `disable-model-invocation`, `user-invocable`, `context`, etc.\n *\n * Skills are discovered at startup — only `name` + `description` are read initially.\n * Full SKILL.md body loads when the agent invokes the skill (via Skill tool or auto-match).\n *\n * @see https://code.claude.com/docs/en/skills\n * @see https://agentskills.io/specification\n */\nexport const claudeCode = defineTarget({\n agent: 'claude-code',\n displayName: 'Claude Code',\n detectInstalled: () => existsSync(claudeHome),\n detectEnv: () => !!(process.env.CLAUDE_CODE || process.env.CLAUDECODE || process.env.CLAUDE_CODE_ENTRYPOINT || process.env.CLAUDE_CONFIG_DIR),\n detectProject: cwd => existsSync(join(cwd, '.claude')) || existsSync(join(cwd, 'CLAUDE.md')),\n cli: 'claude',\n instructionFile: 'CLAUDE.md',\n\n skillsDir: '.claude/skills',\n globalSkillsDir: join(claudeHome, 'skills'),\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, required: false, description: 'Skill identifier, becomes /slash-command. Defaults to directory name if omitted.', constraints: '1-64 chars, ^[a-z0-9]+(-[a-z0-9]+)*$' },\n { ...SPEC_FRONTMATTER.description!, description: 'What the skill does and when to use it. Used for auto-discovery matching.' },\n SPEC_FRONTMATTER.license!,\n SPEC_FRONTMATTER.compatibility!,\n SPEC_FRONTMATTER.metadata!,\n SPEC_FRONTMATTER['allowed-tools']!,\n { name: 'disable-model-invocation', required: false, description: 'When true, skill only loads via explicit /name invocation' },\n { name: 'user-invocable', required: false, description: 'When false, hides from / menu but still auto-loads' },\n { name: 'argument-hint', required: false, description: 'Hint shown during autocomplete, e.g. [issue-number]' },\n { name: 'model', required: false, description: 'Model to use when skill is active' },\n { name: 'context', required: false, description: 'Set to \"fork\" to run in a forked subagent context' },\n { name: 'agent', required: false, description: 'Subagent type when context: fork (e.g. Explore, Plan)' },\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'Scans skill dirs at startup, reads name + description only. Full body loads on invocation. Budget: 2% of context window for all skill descriptions.',\n\n agentSkillsSpec: true,\n extensions: [\n 'disable-model-invocation',\n 'user-invocable',\n 'argument-hint',\n 'model',\n 'context',\n 'agent',\n 'hooks',\n '$ARGUMENTS substitution',\n '!`command` dynamic context',\n ],\n\n docs: 'https://code.claude.com/docs/en/skills',\n notes: [\n '`globs` is NOT a valid frontmatter field for skills (only for rules). Unknown fields are silently ignored.',\n '`version` and `generated_by` should go under `metadata` map, not as top-level fields.',\n 'Skill descriptions have a char budget of 2% of context window (~16k chars fallback). Override with SLASH_COMMAND_TOOL_CHAR_BUDGET env var.',\n 'Keep SKILL.md under 500 lines. Move detailed reference to separate files.',\n 'Supports monorepo auto-discovery: nested .claude/skills/ dirs in subdirectories.',\n 'Supporting dirs: scripts/, references/, assets/ alongside SKILL.md.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * Cline (VS Code extension)\n *\n * Has TWO systems: Rules (.clinerules/) and Skills (.cline/skills/).\n * We target Skills. Cline also reads .claude/skills/ as a fallback,\n * so emitting to .claude/skills/ covers both Claude Code and Cline.\n *\n * Only `name` and `description` are parsed from frontmatter.\n * All other fields are stripped/ignored.\n *\n * @see https://docs.cline.bot/features/skills\n * @see https://docs.cline.bot/features/cline-rules\n */\nexport const cline = defineTarget({\n agent: 'cline',\n displayName: 'Cline',\n detectInstalled: () => existsSync(join(home, '.cline')),\n detectEnv: () => !!process.env.CLINE_TASK_ID,\n detectProject: cwd => existsSync(join(cwd, '.cline')),\n instructionFile: '.clinerules',\n\n skillsDir: '.cline/skills',\n globalSkillsDir: join(home, '.cline/skills'),\n additionalSkillsDirs: [\n '.clinerules/skills',\n '.claude/skills',\n ],\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Must exactly match the directory name.' },\n { ...SPEC_FRONTMATTER.description!, description: 'When to activate. Used for matching.' },\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'At startup reads name + description from each skill. Full content loads on-demand via use_skill tool. Dozens of skills have near-zero context cost.',\n\n agentSkillsSpec: false,\n\n docs: 'https://docs.cline.bot/features/skills',\n notes: [\n 'Only `name` and `description` are parsed. `version`, `globs`, etc. are silently ignored.',\n 'Cline reads .claude/skills/ as a fallback — emitting there covers both Claude Code and Cline.',\n 'Rules system (.clinerules/) is separate: always-on behavioral constraints with globs/tags frontmatter.',\n 'Global skills override project skills when names conflict.',\n 'Supporting dirs: docs/, scripts/, templates/ alongside SKILL.md.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst codexHome = process.env.CODEX_HOME || join(homedir(), '.codex')\n\n/**\n * OpenAI Codex CLI\n *\n * IMPORTANT: Codex uses `.agents/skills/` for project-level skills,\n * NOT `.codex/skills/`. The `.codex/` directory is for config (config.toml).\n * `~/.codex/skills/` works only as a legacy user-global path.\n *\n * Codex also has AGENTS.md (or AGENTS.override.md) for general instructions,\n * which walks from git root to CWD concatenating found files.\n *\n * @see https://developers.openai.com/codex/skills\n * @see https://developers.openai.com/codex/guides/agents-md/\n */\nexport const codex = defineTarget({\n agent: 'codex',\n displayName: 'Codex',\n detectInstalled: () => existsSync(codexHome),\n detectEnv: () => !!(process.env.CODEX_HOME || process.env.CODEX_SESSION),\n detectProject: cwd => existsSync(join(cwd, '.codex')),\n cli: 'codex',\n instructionFile: 'AGENTS.md',\n\n skillsDir: '.agents/skills',\n globalSkillsDir: join(homedir(), '.agents/skills'),\n additionalSkillsDirs: [\n '~/.codex/skills',\n '/etc/codex/skills',\n ],\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Skill identifier.', constraints: '1-64 chars, ^[a-z0-9-]+$, no leading/trailing/consecutive hyphens' },\n { ...SPEC_FRONTMATTER.description!, description: 'Must include when-to-use criteria. Primary triggering mechanism.', constraints: '1-1024 chars, no angle brackets (< or >)' },\n SPEC_FRONTMATTER.license!,\n SPEC_FRONTMATTER['allowed-tools']!,\n SPEC_FRONTMATTER.metadata!,\n ],\n\n discoveryStrategy: 'lazy',\n discoveryNotes: 'Startup scan reads name + description + optional agents/openai.yaml. Full body loads only on invocation. Supports $1-$9 and $ARGUMENTS placeholders.',\n\n agentSkillsSpec: true,\n extensions: [\n 'agents/openai.yaml (UI metadata + MCP dependencies)',\n '$1-$9 positional argument placeholders',\n 'AGENTS.override.md for temporary overrides',\n ],\n\n docs: 'https://developers.openai.com/codex/skills',\n notes: [\n 'BUG IN CURRENT CODE: skillsDir is .codex/skills/ but should be .agents/skills/. The .codex/ directory is for config, not skills.',\n 'Description field cannot contain angle brackets (< or >).',\n 'Optional agents/openai.yaml provides UI metadata: display_name, icon, brand_color, default_prompt.',\n 'AGENTS.md walks from git root to CWD, concatenating all found files.',\n 'Live reload: detects skill file changes without restart (v0.95.0+).',\n 'Size limit: 32 KiB default (project_doc_max_bytes), configurable in ~/.codex/config.toml.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * Cursor (AI code editor)\n *\n * Has TWO systems: Rules (.cursor/rules/*.mdc) and Skills (.cursor/skills/).\n * We target the Skills system which follows the Agent Skills spec.\n *\n * Cursor natively scans .claude/skills/ and .codex/skills/ in addition to\n * its own .cursor/skills/ — so .claude/skills/ output works for both\n * Claude Code and Cursor with zero duplication.\n *\n * @see https://cursor.com/docs/context/skills\n * @see https://cursor.com/docs/context/rules\n */\nexport const cursor = defineTarget({\n agent: 'cursor',\n displayName: 'Cursor',\n detectInstalled: () => existsSync(join(home, '.cursor')),\n detectEnv: () => !!(process.env.CURSOR_SESSION || process.env.CURSOR_TRACE_ID),\n detectProject: cwd => existsSync(join(cwd, '.cursor')) || existsSync(join(cwd, '.cursorrules')),\n instructionFile: '.cursorrules',\n\n skillsDir: '.cursor/skills',\n globalSkillsDir: join(home, '.cursor/skills'),\n additionalSkillsDirs: [\n '.claude/skills',\n '.codex/skills',\n '~/.claude/skills',\n '~/.codex/skills',\n ],\n\n frontmatter: [\n SPEC_FRONTMATTER.name!,\n { ...SPEC_FRONTMATTER.description!, description: 'Agent uses this to decide relevance for auto-invocation.' },\n SPEC_FRONTMATTER.license!,\n SPEC_FRONTMATTER.compatibility!,\n SPEC_FRONTMATTER.metadata!,\n { name: 'disable-model-invocation', required: false, description: 'When true, only loads via explicit /skill-name' },\n ],\n\n discoveryStrategy: 'lazy',\n discoveryNotes: 'Reads name + description at conversation start. Full SKILL.md body loads only when agent determines relevance. Users can also invoke via /skill-name.',\n\n agentSkillsSpec: true,\n extensions: [\n 'disable-model-invocation',\n ],\n\n docs: 'https://cursor.com/docs/context/skills',\n notes: [\n 'Cursor scans .claude/skills/ and .codex/skills/ natively — emitting to .claude/skills/ covers both Claude Code and Cursor.',\n 'The Rules system (.cursor/rules/*.mdc) is separate and uses different frontmatter (trigger, globs, alwaysApply).',\n 'Skills appear in Settings > Rules > Agent Decides section.',\n 'Supporting dirs: scripts/, references/, assets/ alongside SKILL.md.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * Google Gemini CLI\n *\n * Follows the Agent Skills open standard (agentskills.io).\n * Skills are activated via `activate_skill` tool with user confirmation.\n *\n * Also has GEMINI.md context files (analogous to CLAUDE.md) which support\n * @file.md import syntax for modular composition.\n *\n * @see https://geminicli.com/docs/cli/skills/\n * @see https://geminicli.com/docs/cli/creating-skills/\n */\nexport const geminiCli = defineTarget({\n agent: 'gemini-cli',\n displayName: 'Gemini CLI',\n detectInstalled: () => existsSync(join(home, '.gemini')),\n detectEnv: () => !!(process.env.GEMINI_API_KEY && process.env.GEMINI_SESSION),\n detectProject: cwd => existsSync(join(cwd, '.gemini')) || existsSync(join(cwd, 'AGENTS.md')),\n cli: 'gemini',\n instructionFile: 'GEMINI.md',\n\n skillsDir: '.gemini/skills',\n globalSkillsDir: join(home, '.gemini/skills'),\n\n frontmatter: [\n SPEC_FRONTMATTER.name!,\n { ...SPEC_FRONTMATTER.description!, description: 'Primary trigger — agent uses this to match tasks.' },\n SPEC_FRONTMATTER.license!,\n SPEC_FRONTMATTER.compatibility!,\n SPEC_FRONTMATTER.metadata!,\n SPEC_FRONTMATTER['allowed-tools']!,\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'Scans at session start, injects ~100 tokens per skill (name+description). Activation via activate_skill tool requires user confirmation. Skill stays active for session duration.',\n\n agentSkillsSpec: true,\n\n docs: 'https://geminicli.com/docs/cli/skills/',\n notes: [\n 'Management commands: /skills list, /skills enable <name>, /skills disable <name>, /skills reload.',\n 'GEMINI.md context files are separate from skills — support @file.md import syntax.',\n 'settings.json can configure additional context filenames: [\"AGENTS.md\", \"CONTEXT.md\", \"GEMINI.md\"].',\n 'scripts/, references/, assets/ directories are defined by spec but implementation is still incomplete (issue #15895).',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * GitHub Copilot\n *\n * Has TWO systems: Instructions (.github/instructions/*.instructions.md)\n * and Skills (.github/skills/). We target Skills.\n *\n * Copilot also auto-detects .claude/skills/ as a legacy path,\n * so .claude/skills/ output works for Claude Code, Cursor, Cline, AND Copilot.\n *\n * @see https://docs.github.com/en/copilot/concepts/agents/about-agent-skills\n * @see https://docs.github.com/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot\n */\nexport const githubCopilot = defineTarget({\n agent: 'github-copilot',\n displayName: 'GitHub Copilot',\n detectInstalled: () => existsSync(join(home, '.copilot')),\n detectEnv: () => !!process.env.GITHUB_COPILOT_SESSION,\n detectProject: cwd => existsSync(join(cwd, '.github', 'copilot-instructions.md')),\n instructionFile: '.github/copilot-instructions.md',\n\n skillsDir: '.github/skills',\n globalSkillsDir: join(home, '.copilot/skills'),\n additionalSkillsDirs: [\n '.claude/skills',\n '~/.claude/skills',\n ],\n\n frontmatter: [\n SPEC_FRONTMATTER.name!,\n { ...SPEC_FRONTMATTER.description!, description: 'What the skill does AND when to use it.' },\n SPEC_FRONTMATTER.license!,\n SPEC_FRONTMATTER.compatibility!,\n { ...SPEC_FRONTMATTER.metadata!, description: 'Arbitrary key-value pairs (e.g. version, author)' },\n SPEC_FRONTMATTER['allowed-tools']!,\n ],\n\n discoveryStrategy: 'lazy',\n discoveryNotes: '3-level progressive disclosure: (1) ~100 tokens for name+description, (2) full SKILL.md body <5000 tokens on activation, (3) resources from scripts/references/assets/ on demand.',\n\n agentSkillsSpec: true,\n\n docs: 'https://docs.github.com/en/copilot/concepts/agents/about-agent-skills',\n notes: [\n 'Copilot auto-detects .claude/skills/ as a legacy path — emitting there covers multiple agents.',\n 'Instructions system (.github/instructions/*.instructions.md) is separate, uses applyTo globs.',\n 'copilot-instructions.md at .github/ root is always applied (repo-wide).',\n 'AGENTS.md also recognized as of Aug 2025.',\n 'excludeAgent property in instructions can hide from code-review or coding-agent.',\n 'Keep SKILL.md under 500 lines / 5000 tokens for optimal loading.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst configHome = process.env.XDG_CONFIG_HOME || join(homedir(), '.config')\n\n/**\n * Goose (Block)\n *\n * Scans 6 directories for skills, including .claude/skills/ and .agents/skills/\n * for cross-agent compatibility. Later directories override earlier ones on\n * name conflict.\n *\n * @see https://block.github.io/goose/docs/guides/context-engineering/using-skills/\n */\nexport const goose = defineTarget({\n agent: 'goose',\n displayName: 'Goose',\n detectInstalled: () => existsSync(join(configHome, 'goose')),\n detectEnv: () => !!process.env.GOOSE_SESSION,\n detectProject: cwd => existsSync(join(cwd, '.goose')),\n cli: 'goose',\n instructionFile: '.goosehints',\n\n skillsDir: '.goose/skills',\n globalSkillsDir: join(configHome, 'goose/skills'),\n additionalSkillsDirs: [\n '.claude/skills',\n '.agents/skills',\n '~/.claude/skills',\n '~/.config/agents/skills',\n ],\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Skill identifier.' },\n { ...SPEC_FRONTMATTER.description!, description: 'Brief purpose statement; used for matching.' },\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'Scans all 6 directories at startup, merges discovered skills. Later directories override earlier ones on name conflict.',\n\n agentSkillsSpec: false,\n\n docs: 'https://block.github.io/goose/docs/guides/context-engineering/using-skills/',\n notes: [\n 'Reads .claude/skills/ natively — emitting there covers both Claude Code and Goose.',\n 'Also supports .goosehints / .goosehints.local for general project instructions (separate from skills).',\n 'Supporting files alongside SKILL.md (scripts, templates, configs) are accessible.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst configHome = process.env.XDG_CONFIG_HOME || join(homedir(), '.config')\n\n/**\n * OpenCode (SST)\n *\n * Walks from CWD up to git worktree root searching for skill dirs.\n * Reads .claude/skills/ and .agents/skills/ in addition to .opencode/skills/.\n *\n * Has a rich agent system: .opencode/agents/ with per-agent model/tool configuration.\n * Skills can be permission-controlled per-agent with allow/deny/ask + glob patterns.\n *\n * @see https://opencode.ai/docs/skills/\n * @see https://opencode.ai/docs/rules/\n */\nexport const opencode = defineTarget({\n agent: 'opencode',\n displayName: 'OpenCode',\n detectInstalled: () => existsSync(join(configHome, 'opencode')),\n detectEnv: () => !!process.env.OPENCODE_SESSION,\n detectProject: cwd => existsSync(join(cwd, '.opencode')),\n instructionFile: 'AGENTS.md',\n\n skillsDir: '.opencode/skills',\n globalSkillsDir: join(configHome, 'opencode/skills'),\n additionalSkillsDirs: [\n '.claude/skills',\n '.agents/skills',\n '~/.claude/skills',\n '~/.agents/skills',\n ],\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Must match directory name.' },\n { ...SPEC_FRONTMATTER.description!, description: 'Used for matching.' },\n SPEC_FRONTMATTER.license!,\n SPEC_FRONTMATTER.compatibility!,\n SPEC_FRONTMATTER.metadata!,\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'Walks from CWD to git worktree root, then loads global definitions. Agents access skills via native skill tool. Skills can be permission-controlled per-agent.',\n\n agentSkillsSpec: true,\n extensions: [\n 'Per-agent skill permissions (allow/deny/ask with glob patterns)',\n ],\n\n docs: 'https://opencode.ai/docs/skills/',\n notes: [\n 'Reads .claude/skills/ and .agents/skills/ natively — emitting to .claude/skills/ covers multiple agents.',\n 'Custom agents in .opencode/agents/ have rich config: model, temperature, tools, permission, color.',\n 'opencode.json supports an instructions field with glob patterns pointing to instruction files.',\n 'AGENTS.md (or CLAUDE.md fallback) for general instructions.',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * Roo Code (VS Code extension)\n *\n * IMPORTANT: Roo does NOT read .claude/skills/ or .agents/skills/.\n * It requires its own .roo/skills/ directory — no cross-compat shortcuts.\n *\n * Unique feature: mode-specific skill directories (.roo/skills-{modeSlug}/)\n * allow targeting skills to specific modes (code, architect, etc.).\n *\n * @see https://docs.roocode.com/features/skills\n * @see https://docs.roocode.com/features/custom-instructions\n */\nexport const roo = defineTarget({\n agent: 'roo',\n displayName: 'Roo Code',\n detectInstalled: () => existsSync(join(home, '.roo')),\n detectEnv: () => !!process.env.ROO_SESSION,\n detectProject: cwd => existsSync(join(cwd, '.roo')),\n instructionFile: '.roorules',\n\n skillsDir: '.roo/skills',\n globalSkillsDir: join(home, '.roo/skills'),\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Must exactly match the directory name.' },\n { ...SPEC_FRONTMATTER.description!, description: 'When to activate.' },\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'Reads all SKILL.md files at startup. File watchers detect changes during session. Uses read_file to load full content on activation.',\n\n agentSkillsSpec: false,\n extensions: [\n 'Mode-specific skill directories: .roo/skills-{modeSlug}/',\n ],\n\n docs: 'https://docs.roocode.com/features/skills',\n notes: [\n 'Does NOT read .claude/skills/ or .agents/skills/ — requires its own .roo/skills/ directory.',\n 'Mode-specific dirs: .roo/skills-code/, .roo/skills-architect/ etc. target specific modes.',\n 'Override priority: project mode-specific > project generic > global mode-specific > global generic.',\n 'Supports symlinks for shared skill libraries across projects.',\n 'Rules system (.roo/rules/) is separate — .md/.txt files loaded alphabetically into system prompt.',\n 'Legacy fallback: .roorules file if .roo/rules/ is empty.',\n 'Skills manageable from Settings panel (v3.46.0+).',\n ],\n})\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { defineTarget, SPEC_FRONTMATTER } from './base.ts'\n\nconst home = homedir()\n\n/**\n * Windsurf (Codeium editor)\n *\n * Has TWO systems: Rules (.windsurf/rules/*.md) and Skills (.windsurf/skills/).\n * We target Skills. Rules have a separate frontmatter schema with trigger/globs.\n *\n * Skills only document `name` and `description` as frontmatter fields.\n * Cascade uses \"progressive disclosure\" for supporting files.\n *\n * @see https://docs.windsurf.com/windsurf/cascade/skills\n * @see https://docs.windsurf.com/windsurf/cascade/memories\n */\nexport const windsurf = defineTarget({\n agent: 'windsurf',\n displayName: 'Windsurf',\n detectInstalled: () => existsSync(join(home, '.codeium/windsurf')),\n detectEnv: () => !!process.env.WINDSURF_SESSION,\n detectProject: cwd => existsSync(join(cwd, '.windsurf')) || existsSync(join(cwd, '.windsurfrules')),\n instructionFile: '.windsurfrules',\n\n skillsDir: '.windsurf/skills',\n globalSkillsDir: join(home, '.codeium/windsurf/skills'),\n\n frontmatter: [\n { ...SPEC_FRONTMATTER.name!, description: 'Skill identifier.', constraints: 'Lowercase, numbers, hyphens only' },\n { ...SPEC_FRONTMATTER.description!, description: 'Used by Cascade for automatic invocation matching.' },\n ],\n\n discoveryStrategy: 'eager',\n discoveryNotes: 'Cascade matches description against user requests for auto-invocation. Manual invocation via @skill-name.',\n\n agentSkillsSpec: false,\n\n docs: 'https://docs.windsurf.com/windsurf/cascade/skills',\n notes: [\n 'Only `name` and `description` are documented as frontmatter fields. Other fields may be silently ignored.',\n 'Rules system is separate: .windsurf/rules/*.md with trigger/globs/alwaysApply frontmatter.',\n 'Rules have a 6,000 char per-file limit and 12,000 char total limit. Skills have no documented limit.',\n 'Legacy .windsurfrules at project root still supported but deprecated.',\n 'Supporting files alongside SKILL.md are loaded via progressive disclosure.',\n ],\n})\n","/**\n * Agent targets registry — all supported agents and their skill conventions\n */\n\nimport type { AgentType } from '../types.ts'\nimport type { AgentTarget } from './types.ts'\nimport { amp } from './amp.ts'\nimport { antigravity } from './antigravity.ts'\nimport { claudeCode } from './claude-code.ts'\nimport { cline } from './cline.ts'\nimport { codex } from './codex.ts'\nimport { cursor } from './cursor.ts'\nimport { geminiCli } from './gemini-cli.ts'\nimport { githubCopilot } from './github-copilot.ts'\nimport { goose } from './goose.ts'\nimport { opencode } from './opencode.ts'\nimport { roo } from './roo.ts'\nimport { windsurf } from './windsurf.ts'\n\nexport const targets: Record<AgentType, AgentTarget> = {\n 'claude-code': claudeCode,\n 'cursor': cursor,\n 'windsurf': windsurf,\n 'cline': cline,\n 'codex': codex,\n 'github-copilot': githubCopilot,\n 'gemini-cli': geminiCli,\n 'goose': goose,\n 'amp': amp,\n 'opencode': opencode,\n 'roo': roo,\n 'antigravity': antigravity,\n}\n","/**\n * Agent detection - identify installed and active agents\n */\n\nimport type { AgentType } from './types.ts'\nimport { spawnSync } from 'node:child_process'\nimport { isWindows } from 'std-env'\nimport { agents } from './registry.ts'\n\n/**\n * Detect which agents are installed on the system\n */\nexport function detectInstalledAgents(): AgentType[] {\n return Object.entries(agents)\n .filter(([_, config]) => config.detectInstalled())\n .map(([type]) => type as AgentType)\n}\n\n/**\n * Detect the target agent (where skills are installed) from env vars and cwd.\n * This is NOT the generator LLM — it determines the skills directory.\n *\n * Priority: env vars first (running inside agent), then project dirs.\n * Iteration order of the agents record determines priority.\n */\nexport function detectTargetAgent(): AgentType | null {\n for (const [type, target] of Object.entries(agents)) {\n if (target.detectEnv())\n return type as AgentType\n }\n\n const cwd = process.cwd()\n for (const [type, target] of Object.entries(agents)) {\n if (target.detectProject(cwd))\n return type as AgentType\n }\n\n return null\n}\n\n/**\n * Get the version of an agent's CLI (if available)\n */\nexport function getAgentVersion(agentType: AgentType): string | null {\n const agent = agents[agentType]\n if (!agent.cli)\n return null\n\n try {\n const result = spawnSync(agent.cli, ['--version'], {\n encoding: 'utf-8',\n timeout: 3000,\n stdio: ['pipe', 'pipe', 'pipe'],\n shell: isWindows,\n })\n if (result.status !== 0)\n return null\n const output = (result.stdout || '').trim()\n\n // Extract version number from output\n // Common formats: \"v1.2.3\", \"1.2.3\", \"cli 1.2.3\", \"name v1.2.3\"\n const match = output.match(/v?(\\d+\\.\\d+\\.\\d+(?:-[a-z0-9.]+)?)/)\n return match ? match[1] : output.split('\\n')[0]\n }\n catch {\n return null\n }\n}\n"],"mappings":"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"}
@@ -1,11 +1,10 @@
1
- import { n as __require, t as __exportAll } from "./chunk.mjs";
1
+ import { n as __require } from "./chunk.mjs";
2
2
  import { t as CACHE_DIR } from "./config.mjs";
3
+ import "./sanitize.mjs";
4
+ import "./cache.mjs";
3
5
  import { join } from "pathe";
4
6
  import { rmSync } from "node:fs";
5
- var embedding_cache_exports = /* @__PURE__ */ __exportAll({
6
- cachedEmbeddings: () => cachedEmbeddings,
7
- clearEmbeddingCache: () => clearEmbeddingCache
8
- });
7
+ //#region src/retriv/embedding-cache.ts
9
8
  const EMBEDDINGS_DB_PATH = join(CACHE_DIR, "embeddings.db");
10
9
  function openDb() {
11
10
  const { DatabaseSync: DB } = __require("node:sqlite");
@@ -49,6 +48,7 @@ async function cachedEmbeddings(config) {
49
48
  function clearEmbeddingCache() {
50
49
  rmSync(EMBEDDINGS_DB_PATH, { force: true });
51
50
  }
52
- export { embedding_cache_exports as n, clearEmbeddingCache as t };
51
+ //#endregion
52
+ export { cachedEmbeddings, clearEmbeddingCache };
53
53
 
54
54
  //# sourceMappingURL=embedding-cache.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"embedding-cache.mjs","names":[],"sources":["../../src/retriv/embedding-cache.ts"],"sourcesContent":["import type { DatabaseSync } from 'node:sqlite'\nimport type { Embedding } from 'retriv'\nimport { rmSync } from 'node:fs'\nimport { join } from 'pathe'\nimport { CACHE_DIR } from '../cache/index.ts'\n\ninterface EmbeddingConfig {\n resolve: () => Promise<{ embedder: (texts: string[]) => Promise<Embedding[]>, dimensions: number, maxTokens?: number }>\n}\n\nconst EMBEDDINGS_DB_PATH = join(CACHE_DIR, 'embeddings.db')\n\nfunction openDb(): DatabaseSync {\n // eslint-disable-next-line ts/no-require-imports\n const { DatabaseSync: DB } = require('node:sqlite') as typeof import('node:sqlite')\n const db = new DB(EMBEDDINGS_DB_PATH)\n db.exec('PRAGMA journal_mode=WAL')\n db.exec('PRAGMA busy_timeout=5000')\n db.exec(`CREATE TABLE IF NOT EXISTS embeddings (text_hash TEXT PRIMARY KEY, embedding BLOB NOT NULL)`)\n db.exec(`CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)`)\n return db\n}\n\nfunction createSqliteStorage(db: DatabaseSync) {\n const getStmt = db.prepare('SELECT embedding FROM embeddings WHERE text_hash = ?')\n const setStmt = db.prepare('INSERT OR IGNORE INTO embeddings (text_hash, embedding) VALUES (?, ?)')\n\n return {\n get: (hash: string): Embedding | null => {\n const row = getStmt.get(hash) as { embedding: Buffer } | undefined\n if (!row)\n return null\n return new Float32Array(row.embedding.buffer, row.embedding.byteOffset, row.embedding.byteLength / 4)\n },\n set: (hash: string, embedding: Embedding): void => {\n const arr = embedding instanceof Float32Array ? embedding : new Float32Array(embedding)\n setStmt.run(hash, Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength))\n },\n }\n}\n\nexport async function cachedEmbeddings(config: EmbeddingConfig): Promise<EmbeddingConfig> {\n const { cachedEmbeddings: retrivCached } = await import('retriv/embeddings/cached')\n const db = openDb()\n const storage = createSqliteStorage(db)\n\n const originalResolve = config.resolve\n const validatedConfig: EmbeddingConfig = {\n async resolve() {\n const resolved = await originalResolve()\n const getMetaStmt = db.prepare('SELECT value FROM meta WHERE key = ?')\n const setMetaStmt = db.prepare('INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)')\n\n const storedDims = getMetaStmt.get('dimensions') as { value: string } | undefined\n if (storedDims && Number(storedDims.value) !== resolved.dimensions) {\n db.exec('DELETE FROM embeddings')\n }\n setMetaStmt.run('dimensions', String(resolved.dimensions))\n\n return resolved\n },\n }\n\n return retrivCached(validatedConfig, { storage })\n}\n\nexport function clearEmbeddingCache(): void {\n rmSync(EMBEDDINGS_DB_PATH, { force: true })\n}\n"],"mappings":";;;;;;;;AAUA,MAAM,qBAAqB,KAAK,WAAW,gBAAgB;AAE3D,SAAS,SAAuB;CAE9B,MAAM,EAAE,cAAc,OAAA,UAAe,cAAc;CACnD,MAAM,KAAK,IAAI,GAAG,mBAAmB;AACrC,IAAG,KAAK,0BAA0B;AAClC,IAAG,KAAK,2BAA2B;AACnC,IAAG,KAAK,8FAA8F;AACtG,IAAG,KAAK,8EAA8E;AACtF,QAAO;;AAGT,SAAS,oBAAoB,IAAkB;CAC7C,MAAM,UAAU,GAAG,QAAQ,uDAAuD;CAClF,MAAM,UAAU,GAAG,QAAQ,wEAAwE;AAEnG,QAAO;EACL,MAAM,SAAmC;GACvC,MAAM,MAAM,QAAQ,IAAI,KAAK;AAC7B,OAAI,CAAC,IACH,QAAO;AACT,UAAO,IAAI,aAAa,IAAI,UAAU,QAAQ,IAAI,UAAU,YAAY,IAAI,UAAU,aAAa,EAAE;;EAEvG,MAAM,MAAc,cAA+B;GACjD,MAAM,MAAM,qBAAqB,eAAe,YAAY,IAAI,aAAa,UAAU;AACvF,WAAQ,IAAI,MAAM,OAAO,KAAK,IAAI,QAAQ,IAAI,YAAY,IAAI,WAAW,CAAC;;EAE7E;;AAGH,eAAsB,iBAAiB,QAAmD;CACxF,MAAM,EAAE,kBAAkB,iBAAiB,MAAM,OAAO;CACxD,MAAM,KAAK,QAAQ;CACnB,MAAM,UAAU,oBAAoB,GAAG;CAEvC,MAAM,kBAAkB,OAAO;AAiB/B,QAAO,aAhBkC,EACvC,MAAM,UAAU;EACd,MAAM,WAAW,MAAM,iBAAiB;EACxC,MAAM,cAAc,GAAG,QAAQ,uCAAuC;EACtE,MAAM,cAAc,GAAG,QAAQ,yDAAyD;EAExF,MAAM,aAAa,YAAY,IAAI,aAAa;AAChD,MAAI,cAAc,OAAO,WAAW,MAAM,KAAK,SAAS,WACtD,IAAG,KAAK,yBAAyB;AAEnC,cAAY,IAAI,cAAc,OAAO,SAAS,WAAW,CAAC;AAE1D,SAAO;IAEV,EAEoC,EAAE,SAAS,CAAC;;AAGnD,SAAgB,sBAA4B;AAC1C,QAAO,oBAAoB,EAAE,OAAO,MAAM,CAAC"}
1
+ {"version":3,"file":"embedding-cache.mjs","names":[],"sources":["../../src/retriv/embedding-cache.ts"],"sourcesContent":["import type { DatabaseSync } from 'node:sqlite'\nimport type { Embedding } from 'retriv'\nimport { rmSync } from 'node:fs'\nimport { join } from 'pathe'\nimport { CACHE_DIR } from '../cache/index.ts'\n\ninterface EmbeddingConfig {\n resolve: () => Promise<{ embedder: (texts: string[]) => Promise<Embedding[]>, dimensions: number, maxTokens?: number }>\n}\n\nconst EMBEDDINGS_DB_PATH = join(CACHE_DIR, 'embeddings.db')\n\nfunction openDb(): DatabaseSync {\n // eslint-disable-next-line ts/no-require-imports\n const { DatabaseSync: DB } = require('node:sqlite') as typeof import('node:sqlite')\n const db = new DB(EMBEDDINGS_DB_PATH)\n db.exec('PRAGMA journal_mode=WAL')\n db.exec('PRAGMA busy_timeout=5000')\n db.exec(`CREATE TABLE IF NOT EXISTS embeddings (text_hash TEXT PRIMARY KEY, embedding BLOB NOT NULL)`)\n db.exec(`CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)`)\n return db\n}\n\nfunction createSqliteStorage(db: DatabaseSync) {\n const getStmt = db.prepare('SELECT embedding FROM embeddings WHERE text_hash = ?')\n const setStmt = db.prepare('INSERT OR IGNORE INTO embeddings (text_hash, embedding) VALUES (?, ?)')\n\n return {\n get: (hash: string): Embedding | null => {\n const row = getStmt.get(hash) as { embedding: Buffer } | undefined\n if (!row)\n return null\n return new Float32Array(row.embedding.buffer, row.embedding.byteOffset, row.embedding.byteLength / 4)\n },\n set: (hash: string, embedding: Embedding): void => {\n const arr = embedding instanceof Float32Array ? embedding : new Float32Array(embedding)\n setStmt.run(hash, Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength))\n },\n }\n}\n\nexport async function cachedEmbeddings(config: EmbeddingConfig): Promise<EmbeddingConfig> {\n const { cachedEmbeddings: retrivCached } = await import('retriv/embeddings/cached')\n const db = openDb()\n const storage = createSqliteStorage(db)\n\n const originalResolve = config.resolve\n const validatedConfig: EmbeddingConfig = {\n async resolve() {\n const resolved = await originalResolve()\n const getMetaStmt = db.prepare('SELECT value FROM meta WHERE key = ?')\n const setMetaStmt = db.prepare('INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)')\n\n const storedDims = getMetaStmt.get('dimensions') as { value: string } | undefined\n if (storedDims && Number(storedDims.value) !== resolved.dimensions) {\n db.exec('DELETE FROM embeddings')\n }\n setMetaStmt.run('dimensions', String(resolved.dimensions))\n\n return resolved\n },\n }\n\n return retrivCached(validatedConfig, { storage })\n}\n\nexport function clearEmbeddingCache(): void {\n rmSync(EMBEDDINGS_DB_PATH, { force: true })\n}\n"],"mappings":";;;;;;;AAUA,MAAM,qBAAqB,KAAK,WAAW,gBAAgB;AAE3D,SAAS,SAAuB;CAE9B,MAAM,EAAE,cAAc,OAAA,UAAe,cAAc;CACnD,MAAM,KAAK,IAAI,GAAG,mBAAmB;AACrC,IAAG,KAAK,0BAA0B;AAClC,IAAG,KAAK,2BAA2B;AACnC,IAAG,KAAK,8FAA8F;AACtG,IAAG,KAAK,8EAA8E;AACtF,QAAO;;AAGT,SAAS,oBAAoB,IAAkB;CAC7C,MAAM,UAAU,GAAG,QAAQ,uDAAuD;CAClF,MAAM,UAAU,GAAG,QAAQ,wEAAwE;AAEnG,QAAO;EACL,MAAM,SAAmC;GACvC,MAAM,MAAM,QAAQ,IAAI,KAAK;AAC7B,OAAI,CAAC,IACH,QAAO;AACT,UAAO,IAAI,aAAa,IAAI,UAAU,QAAQ,IAAI,UAAU,YAAY,IAAI,UAAU,aAAa,EAAE;;EAEvG,MAAM,MAAc,cAA+B;GACjD,MAAM,MAAM,qBAAqB,eAAe,YAAY,IAAI,aAAa,UAAU;AACvF,WAAQ,IAAI,MAAM,OAAO,KAAK,IAAI,QAAQ,IAAI,YAAY,IAAI,WAAW,CAAC;;EAE7E;;AAGH,eAAsB,iBAAiB,QAAmD;CACxF,MAAM,EAAE,kBAAkB,iBAAiB,MAAM,OAAO;CACxD,MAAM,KAAK,QAAQ;CACnB,MAAM,UAAU,oBAAoB,GAAG;CAEvC,MAAM,kBAAkB,OAAO;AAiB/B,QAAO,aAhBkC,EACvC,MAAM,UAAU;EACd,MAAM,WAAW,MAAM,iBAAiB;EACxC,MAAM,cAAc,GAAG,QAAQ,uCAAuC;EACtE,MAAM,cAAc,GAAG,QAAQ,yDAAyD;EAExF,MAAM,aAAa,YAAY,IAAI,aAAa;AAChD,MAAI,cAAc,OAAO,WAAW,MAAM,KAAK,SAAS,WACtD,IAAG,KAAK,yBAAyB;AAEnC,cAAY,IAAI,cAAc,OAAO,SAAS,WAAW,CAAC;AAE1D,SAAO;IAEV,EAEoC,EAAE,SAAS,CAAC;;AAGnD,SAAgB,sBAA4B;AAC1C,QAAO,oBAAoB,EAAE,OAAO,MAAM,CAAC"}
@@ -8,6 +8,7 @@ import { fileURLToPath } from "node:url";
8
8
  import * as p from "@clack/prompts";
9
9
  import { detectCurrentAgent } from "unagent/env";
10
10
  import { dirname as dirname$1, resolve as resolve$1 } from "node:path";
11
+ //#region src/core/config.ts
11
12
  const defaultFeatures = {
12
13
  search: true,
13
14
  issues: true,
@@ -116,6 +117,8 @@ function unregisterProject(projectPath) {
116
117
  function getRegisteredProjects() {
117
118
  return readConfig().projects || [];
118
119
  }
120
+ //#endregion
121
+ //#region src/version.ts
119
122
  function findPackageJson() {
120
123
  let dir = dirname$1(fileURLToPath(import.meta.url));
121
124
  for (let i = 0; i < 5; i++) {
@@ -129,6 +132,8 @@ function findPackageJson() {
129
132
  return "{\"version\":\"0.0.0\"}";
130
133
  }
131
134
  const version = JSON.parse(findPackageJson()).version;
135
+ //#endregion
136
+ //#region src/cli-helpers.ts
132
137
  const sharedArgs = {
133
138
  global: {
134
139
  type: "boolean",
@@ -278,6 +283,8 @@ function getRepoHint(name, cwd) {
278
283
  if (!url) return void 0;
279
284
  return url.replace(/^git\+/, "").replace(/\.git$/, "").replace(/^git:\/\//, "https://").replace(/^ssh:\/\/git@github\.com/, "https://github.com").replace(/^https?:\/\/(www\.)?github\.com\//, "");
280
285
  }
286
+ //#endregion
287
+ //#region src/core/formatting.ts
281
288
  function timeAgo(iso) {
282
289
  if (!iso) return "";
283
290
  const diff = Date.now() - new Date(iso).getTime();
@@ -316,7 +323,7 @@ function timedSpinner() {
316
323
  }
317
324
  function highlightTerms(content, terms) {
318
325
  if (terms.length === 0) return content;
319
- const sorted = [...terms].sort((a, b) => b.length - a.length);
326
+ const sorted = terms.toSorted((a, b) => b.length - a.length);
320
327
  const pattern = new RegExp(`(${sorted.map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})`, "gi");
321
328
  return content.replace(pattern, "\x1B[33m$1\x1B[0m");
322
329
  }
@@ -360,6 +367,7 @@ function formatCompactSnippet(r, cols) {
360
367
  preview: firstLine.length > maxPreview ? `${firstLine.slice(0, maxPreview - 1)}…` : firstLine
361
368
  };
362
369
  }
370
+ //#endregion
363
371
  export { hasCompletedWizard as C, unregisterProject as D, registerProject as E, updateConfig as O, getRegisteredProjects as S, readConfig as T, requireInteractive as _, highlightTerms as a, version as b, timeAgo as c, getInstalledGenerators as d, getRepoHint as f, relativeTime as g, promptForAgent as h, formatSource as i, timedSpinner as l, isInteractive as m, formatDuration as n, normalizeScores as o, introLine as p, formatSnippet as r, scoreLabel as s, formatCompactSnippet as t, formatStatus as u, resolveAgent as v, hasConfig as w, defaultFeatures as x, sharedArgs as y };
364
372
 
365
373
  //# sourceMappingURL=formatting.mjs.map