skilld 1.5.5 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +32 -23
  2. package/dist/_chunks/agent.mjs +2 -78
  3. package/dist/_chunks/agent.mjs.map +1 -1
  4. package/dist/_chunks/assemble.mjs +1 -18
  5. package/dist/_chunks/assemble.mjs.map +1 -1
  6. package/dist/_chunks/author-group.mjs +17 -0
  7. package/dist/_chunks/author-group.mjs.map +1 -0
  8. package/dist/_chunks/author.mjs +8 -24
  9. package/dist/_chunks/author.mjs.map +1 -1
  10. package/dist/_chunks/cache.mjs +1 -73
  11. package/dist/_chunks/cache.mjs.map +1 -1
  12. package/dist/_chunks/cache2.mjs +84 -17
  13. package/dist/_chunks/cache2.mjs.map +1 -1
  14. package/dist/_chunks/cli-helpers.mjs +3 -166
  15. package/dist/_chunks/cli-helpers.mjs.map +1 -1
  16. package/dist/_chunks/cli-helpers2.mjs +0 -11
  17. package/dist/_chunks/config.mjs +119 -54
  18. package/dist/_chunks/config.mjs.map +1 -1
  19. package/dist/_chunks/core.mjs +9 -0
  20. package/dist/_chunks/detect.mjs +29 -226
  21. package/dist/_chunks/detect.mjs.map +1 -1
  22. package/dist/_chunks/embedding-cache.mjs +0 -5
  23. package/dist/_chunks/embedding-cache2.mjs +2 -3
  24. package/dist/_chunks/formatting.mjs +0 -6
  25. package/dist/_chunks/formatting.mjs.map +1 -1
  26. package/dist/_chunks/index.d.mts +0 -10
  27. package/dist/_chunks/index.d.mts.map +1 -1
  28. package/dist/_chunks/index2.d.mts +3 -6
  29. package/dist/_chunks/index2.d.mts.map +1 -1
  30. package/dist/_chunks/index3.d.mts +81 -109
  31. package/dist/_chunks/index3.d.mts.map +1 -1
  32. package/dist/_chunks/install.mjs +85 -550
  33. package/dist/_chunks/install.mjs.map +1 -1
  34. package/dist/_chunks/install2.mjs +554 -0
  35. package/dist/_chunks/install2.mjs.map +1 -0
  36. package/dist/_chunks/libs/@sinclair/typebox.mjs +0 -444
  37. package/dist/_chunks/libs/@sinclair/typebox.mjs.map +1 -1
  38. package/dist/_chunks/list.mjs +0 -16
  39. package/dist/_chunks/list.mjs.map +1 -1
  40. package/dist/_chunks/lockfile.mjs +2 -10
  41. package/dist/_chunks/lockfile.mjs.map +1 -1
  42. package/dist/_chunks/markdown.mjs +0 -9
  43. package/dist/_chunks/markdown.mjs.map +1 -1
  44. package/dist/_chunks/package-json.mjs +0 -25
  45. package/dist/_chunks/package-json.mjs.map +1 -1
  46. package/dist/_chunks/package-registry.mjs +465 -0
  47. package/dist/_chunks/package-registry.mjs.map +1 -0
  48. package/dist/_chunks/pool2.mjs +0 -2
  49. package/dist/_chunks/pool2.mjs.map +1 -1
  50. package/dist/_chunks/prefix.mjs +108 -0
  51. package/dist/_chunks/prefix.mjs.map +1 -0
  52. package/dist/_chunks/prepare.mjs +14 -9
  53. package/dist/_chunks/prepare.mjs.map +1 -1
  54. package/dist/_chunks/prepare2.mjs +1 -19
  55. package/dist/_chunks/prepare2.mjs.map +1 -1
  56. package/dist/_chunks/prompts.mjs +6 -201
  57. package/dist/_chunks/prompts.mjs.map +1 -1
  58. package/dist/_chunks/retriv.mjs +23 -24
  59. package/dist/_chunks/retriv.mjs.map +1 -1
  60. package/dist/_chunks/rolldown-runtime.mjs +0 -2
  61. package/dist/_chunks/sanitize.mjs +0 -78
  62. package/dist/_chunks/sanitize.mjs.map +1 -1
  63. package/dist/_chunks/search-helpers.mjs +99 -0
  64. package/dist/_chunks/search-helpers.mjs.map +1 -0
  65. package/dist/_chunks/search-interactive.mjs +1 -18
  66. package/dist/_chunks/search-interactive.mjs.map +1 -1
  67. package/dist/_chunks/search.mjs +218 -19
  68. package/dist/_chunks/search.mjs.map +1 -0
  69. package/dist/_chunks/setup.mjs +0 -13
  70. package/dist/_chunks/setup.mjs.map +1 -1
  71. package/dist/_chunks/shared.mjs +1 -473
  72. package/dist/_chunks/shared.mjs.map +1 -1
  73. package/dist/_chunks/skills.mjs +3 -3
  74. package/dist/_chunks/skills.mjs.map +1 -1
  75. package/dist/_chunks/sources.mjs +1179 -1440
  76. package/dist/_chunks/sources.mjs.map +1 -1
  77. package/dist/_chunks/sync-registry.mjs +59 -0
  78. package/dist/_chunks/sync-registry.mjs.map +1 -0
  79. package/dist/_chunks/sync-shared.mjs +0 -16
  80. package/dist/_chunks/sync-shared2.mjs +10 -49
  81. package/dist/_chunks/sync-shared2.mjs.map +1 -1
  82. package/dist/_chunks/sync.mjs +209 -120
  83. package/dist/_chunks/sync.mjs.map +1 -1
  84. package/dist/_chunks/sync2.mjs +1 -21
  85. package/dist/_chunks/types.d.mts +0 -2
  86. package/dist/_chunks/types.d.mts.map +1 -1
  87. package/dist/_chunks/uninstall.mjs +3 -27
  88. package/dist/_chunks/uninstall.mjs.map +1 -1
  89. package/dist/_chunks/upload.mjs +152 -0
  90. package/dist/_chunks/upload.mjs.map +1 -0
  91. package/dist/_chunks/validate.mjs +1 -8
  92. package/dist/_chunks/validate.mjs.map +1 -1
  93. package/dist/_chunks/version.mjs +30 -0
  94. package/dist/_chunks/version.mjs.map +1 -0
  95. package/dist/_chunks/wizard.mjs +2 -3
  96. package/dist/_chunks/yaml.mjs +0 -21
  97. package/dist/_chunks/yaml.mjs.map +1 -1
  98. package/dist/agent/index.d.mts +0 -24
  99. package/dist/agent/index.d.mts.map +1 -1
  100. package/dist/agent/index.mjs +2 -9
  101. package/dist/cache/index.mjs +1 -3
  102. package/dist/cli-entry.mjs +0 -6
  103. package/dist/cli-entry.mjs.map +1 -1
  104. package/dist/cli.mjs +48 -33
  105. package/dist/cli.mjs.map +1 -1
  106. package/dist/index.d.mts +1 -1
  107. package/dist/index.mjs +2 -8
  108. package/dist/prepare.mjs +0 -12
  109. package/dist/prepare.mjs.map +1 -1
  110. package/dist/retriv/index.mjs +0 -2
  111. package/dist/retriv/worker.d.mts +0 -3
  112. package/dist/retriv/worker.d.mts.map +1 -1
  113. package/dist/retriv/worker.mjs +0 -2
  114. package/dist/retriv/worker.mjs.map +1 -1
  115. package/dist/sources/index.d.mts +2 -2
  116. package/dist/sources/index.mjs +3 -7
  117. package/dist/types.d.mts +1 -1
  118. package/package.json +20 -21
  119. package/dist/_chunks/search2.mjs +0 -319
  120. package/dist/_chunks/search2.mjs.map +0 -1
@@ -1,57 +1,122 @@
1
+ import { n as yamlParseKV, r as yamlUnescape, t as yamlEscape } from "./yaml.mjs";
1
2
  import { homedir } from "node:os";
2
- import { join, resolve } from "pathe";
3
- //#region src/cache/version.ts
4
- /**
5
- * Version utilities
6
- */
7
- /** Validate npm package name (scoped or unscoped) */
8
- const VALID_PKG_NAME = /^(?:@[a-z0-9][-a-z0-9._]*\/)?[a-z0-9][-a-z0-9._]*$/;
9
- /** Validate version string (semver-ish, no path separators) */
10
- const VALID_VERSION = /^[a-z0-9][-\w.+]*$/i;
11
- /**
12
- * Get exact version key for cache keying
13
- */
14
- function getVersionKey(version) {
15
- return version;
16
- }
17
- /**
18
- * Get cache key for a package: name@version
19
- */
20
- function getCacheKey(name, version) {
21
- return `${name}@${getVersionKey(version)}`;
22
- }
23
- /**
24
- * Get path to cached package references.
25
- * Validates name/version to prevent path traversal.
26
- */
27
- function getCacheDir(name, version) {
28
- if (!VALID_PKG_NAME.test(name)) throw new Error(`Invalid package name: ${name}`);
29
- if (!VALID_VERSION.test(version)) throw new Error(`Invalid version: ${version}`);
30
- const dir = resolve(REFERENCES_DIR, getCacheKey(name, version));
31
- if (!dir.startsWith(REFERENCES_DIR)) throw new Error(`Path traversal detected: ${dir}`);
32
- return dir;
33
- }
34
- //#endregion
35
- //#region src/cache/config.ts
36
- /**
37
- * Cache configuration
38
- */
39
- /** Global cache directory */
40
- const CACHE_DIR = join(homedir(), ".skilld");
41
- /** References subdirectory */
42
- const REFERENCES_DIR = join(CACHE_DIR, "references");
43
- /** Repo-level cache (issues, discussions, releases shared across monorepo packages) */
44
- const REPOS_DIR = join(CACHE_DIR, "repos");
45
- /** Get repo cache dir for owner/repo with path traversal validation */
46
- function getRepoCacheDir(owner, repo) {
47
- if (owner.includes("..") || repo.includes("..") || owner.includes("/") || repo.includes("/")) throw new Error(`Invalid repo path: ${owner}/${repo}`);
48
- return join(REPOS_DIR, owner, repo);
49
- }
50
- /** Get search DB path for a specific package@version */
51
- function getPackageDbPath(name, version) {
52
- return join(REFERENCES_DIR, getCacheKey(name, version), "search.db");
53
- }
54
- //#endregion
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 };
3
+ import { join } from "pathe";
4
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
+ const defaultFeatures = {
6
+ search: true,
7
+ issues: true,
8
+ discussions: true,
9
+ releases: true
10
+ };
11
+ const CONFIG_DIR = join(homedir(), ".skilld");
12
+ const CONFIG_PATH = join(CONFIG_DIR, "config.yaml");
13
+ let configCache;
14
+ function hasConfig() {
15
+ return existsSync(CONFIG_PATH);
16
+ }
17
+ function hasCompletedWizard() {
18
+ if (!existsSync(CONFIG_PATH)) return false;
19
+ const config = readConfig();
20
+ return config.features !== void 0 || config.model !== void 0 || config.skipLlm !== void 0;
21
+ }
22
+ function readConfig() {
23
+ if (configCache) return {
24
+ ...configCache,
25
+ features: configCache.features ? { ...configCache.features } : void 0,
26
+ projects: configCache.projects ? [...configCache.projects] : void 0
27
+ };
28
+ if (!existsSync(CONFIG_PATH)) return {};
29
+ const content = readFileSync(CONFIG_PATH, "utf-8");
30
+ const config = {};
31
+ let inBlock = null;
32
+ const projects = [];
33
+ const features = {};
34
+ for (const line of content.split("\n")) {
35
+ if (line.startsWith("projects:")) {
36
+ inBlock = "projects";
37
+ continue;
38
+ }
39
+ if (line.startsWith("features:")) {
40
+ inBlock = "features";
41
+ continue;
42
+ }
43
+ if (inBlock === "projects") {
44
+ if (line.startsWith(" - ")) {
45
+ projects.push(yamlUnescape(line.slice(4)));
46
+ continue;
47
+ }
48
+ inBlock = null;
49
+ }
50
+ if (inBlock === "features") {
51
+ const m = line.match(/^ {2}(\w+):\s*(.+)/);
52
+ if (m) {
53
+ const key = m[1];
54
+ if (key in defaultFeatures) features[key] = m[2] === "true";
55
+ continue;
56
+ }
57
+ inBlock = null;
58
+ }
59
+ const kv = yamlParseKV(line);
60
+ if (!kv) continue;
61
+ const [key, value] = kv;
62
+ if (key === "model" && value) config.model = value;
63
+ if (key === "agent" && value) config.agent = value;
64
+ if (key === "skipLlm") config.skipLlm = value === "true";
65
+ }
66
+ if (projects.length > 0) config.projects = projects;
67
+ if (Object.keys(features).length > 0) config.features = {
68
+ ...defaultFeatures,
69
+ ...features
70
+ };
71
+ configCache = config;
72
+ return config;
73
+ }
74
+ function writeConfig(config) {
75
+ mkdirSync(CONFIG_DIR, {
76
+ recursive: true,
77
+ mode: 448
78
+ });
79
+ let yaml = "";
80
+ if (config.model) yaml += `model: ${config.model}\n`;
81
+ if (config.agent) yaml += `agent: ${config.agent}\n`;
82
+ if (config.skipLlm) yaml += `skipLlm: true\n`;
83
+ if (config.features) {
84
+ yaml += "features:\n";
85
+ for (const [k, v] of Object.entries(config.features)) yaml += ` ${k}: ${v}\n`;
86
+ }
87
+ if (config.projects?.length) {
88
+ yaml += "projects:\n";
89
+ for (const p of config.projects) yaml += ` - ${yamlEscape(p)}\n`;
90
+ }
91
+ writeFileSync(CONFIG_PATH, yaml, { mode: 384 });
92
+ configCache = void 0;
93
+ }
94
+ function updateConfig(updates) {
95
+ writeConfig({
96
+ ...readConfig(),
97
+ ...updates
98
+ });
99
+ }
100
+ function registerProject(projectPath) {
101
+ const config = readConfig();
102
+ const projects = new Set(config.projects || []);
103
+ projects.add(projectPath);
104
+ writeConfig({
105
+ ...config,
106
+ projects: [...projects]
107
+ });
108
+ }
109
+ function unregisterProject(projectPath) {
110
+ const config = readConfig();
111
+ const projects = (config.projects || []).filter((p) => p !== projectPath);
112
+ writeConfig({
113
+ ...config,
114
+ projects
115
+ });
116
+ }
117
+ function getRegisteredProjects() {
118
+ return readConfig().projects || [];
119
+ }
120
+ export { readConfig as a, updateConfig as c, hasConfig as i, getRegisteredProjects as n, registerProject as o, hasCompletedWizard as r, unregisterProject as s, defaultFeatures as t };
56
121
 
57
122
  //# 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/core/config.ts"],"sourcesContent":["import type { OptimizeModel } from '../agent/index.ts'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { yamlEscape, yamlParseKV, yamlUnescape } from './yaml.ts'\n\nexport interface FeaturesConfig {\n search: boolean\n issues: boolean\n discussions: boolean\n releases: boolean\n}\n\nexport const defaultFeatures: FeaturesConfig = {\n search: true,\n issues: true,\n discussions: true,\n releases: true,\n}\n\nexport interface SkilldConfig {\n model?: OptimizeModel\n agent?: string\n features?: FeaturesConfig\n projects?: string[]\n skipLlm?: boolean\n}\n\nconst CONFIG_DIR = join(homedir(), '.skilld')\nconst CONFIG_PATH = join(CONFIG_DIR, 'config.yaml')\n\nlet configCache: SkilldConfig | undefined\n\nexport function hasConfig(): boolean {\n return existsSync(CONFIG_PATH)\n}\n\n/** Whether the first-run wizard has been completed (not just agent selection) */\nexport function hasCompletedWizard(): boolean {\n if (!existsSync(CONFIG_PATH))\n return false\n const config = readConfig()\n return config.features !== undefined || config.model !== undefined || config.skipLlm !== undefined\n}\n\nexport function readConfig(): SkilldConfig {\n if (configCache) {\n return {\n ...configCache,\n features: configCache.features ? { ...configCache.features } : undefined,\n projects: configCache.projects ? [...configCache.projects] : undefined,\n }\n }\n if (!existsSync(CONFIG_PATH))\n return {}\n\n const content = readFileSync(CONFIG_PATH, 'utf-8')\n const config: SkilldConfig = {}\n let inBlock: 'projects' | 'features' | null = null\n const projects: string[] = []\n const features: Partial<FeaturesConfig> = {}\n\n for (const line of content.split('\\n')) {\n if (line.startsWith('projects:')) {\n inBlock = 'projects'\n continue\n }\n if (line.startsWith('features:')) {\n inBlock = 'features'\n continue\n }\n if (inBlock === 'projects') {\n if (line.startsWith(' - ')) {\n projects.push(yamlUnescape(line.slice(4)))\n continue\n }\n inBlock = null\n }\n if (inBlock === 'features') {\n const m = line.match(/^ {2}(\\w+):\\s*(.+)/)\n if (m) {\n const key = m[1] as keyof FeaturesConfig\n if (key in defaultFeatures)\n features[key] = m[2] === 'true'\n continue\n }\n inBlock = null\n }\n const kv = yamlParseKV(line)\n if (!kv)\n continue\n const [key, value] = kv\n if (key === 'model' && value)\n config.model = value as OptimizeModel\n if (key === 'agent' && value)\n config.agent = value\n if (key === 'skipLlm')\n config.skipLlm = value === 'true'\n }\n\n if (projects.length > 0)\n config.projects = projects\n if (Object.keys(features).length > 0)\n config.features = { ...defaultFeatures, ...features }\n configCache = config\n return config\n}\n\nexport function writeConfig(config: SkilldConfig): void {\n mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 })\n\n let yaml = ''\n if (config.model)\n yaml += `model: ${config.model}\\n`\n if (config.agent)\n yaml += `agent: ${config.agent}\\n`\n if (config.skipLlm)\n yaml += `skipLlm: true\\n`\n if (config.features) {\n yaml += 'features:\\n'\n for (const [k, v] of Object.entries(config.features)) {\n yaml += ` ${k}: ${v}\\n`\n }\n }\n if (config.projects?.length) {\n yaml += 'projects:\\n'\n for (const p of config.projects) {\n yaml += ` - ${yamlEscape(p)}\\n`\n }\n }\n\n writeFileSync(CONFIG_PATH, yaml, { mode: 0o600 })\n configCache = undefined\n}\n\nexport function updateConfig(updates: Partial<SkilldConfig>): void {\n const config = readConfig()\n writeConfig({ ...config, ...updates })\n}\n\nexport function registerProject(projectPath: string): void {\n const config = readConfig()\n const projects = new Set(config.projects || [])\n projects.add(projectPath)\n writeConfig({ ...config, projects: [...projects] })\n}\n\nexport function unregisterProject(projectPath: string): void {\n const config = readConfig()\n const projects = (config.projects || []).filter(p => p !== projectPath)\n writeConfig({ ...config, projects })\n}\n\nexport function getRegisteredProjects(): string[] {\n return readConfig().projects || []\n}\n"],"mappings":"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"}
@@ -1 +1,10 @@
1
+ import "./package-json.mjs";
2
+ import "./sanitize.mjs";
3
+ import "./yaml.mjs";
4
+ import "./markdown.mjs";
5
+ import "./shared.mjs";
6
+ import "./config.mjs";
7
+ import "./lockfile.mjs";
8
+ import "./skills.mjs";
9
+ import "./formatting.mjs";
1
10
  export {};
@@ -3,8 +3,6 @@ import { join } from "pathe";
3
3
  import { existsSync, readdirSync } from "node:fs";
4
4
  import { spawnSync } from "node:child_process";
5
5
  import { isWindows } from "std-env";
6
- //#region src/agent/targets/base.ts
7
- /** Common frontmatter fields from agentskills.io spec */
8
6
  const SPEC_FRONTMATTER = {
9
7
  "name": {
10
8
  name: "name",
@@ -40,7 +38,6 @@ const SPEC_FRONTMATTER = {
40
38
  description: "Space-delimited pre-approved tools (experimental)"
41
39
  }
42
40
  };
43
- /** Shared defaults for all agent targets */
44
41
  const BASE_DEFAULTS = {
45
42
  skillFilename: "SKILL.md",
46
43
  nameMatchesDir: true,
@@ -49,28 +46,13 @@ const BASE_DEFAULTS = {
49
46
  extensions: [],
50
47
  notes: []
51
48
  };
52
- /** Define an agent target with shared defaults applied */
53
49
  function defineTarget(target) {
54
50
  return {
55
51
  ...BASE_DEFAULTS,
56
52
  ...target
57
53
  };
58
54
  }
59
- //#endregion
60
- //#region src/agent/targets/amp.ts
61
55
  const configHome$2 = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
62
- /**
63
- * Amp (Sourcegraph)
64
- *
65
- * Uses .agents/skills/ as primary project path. Also reads .claude/skills/.
66
- * Skills can bundle MCP servers via mcp.json in the skill directory.
67
- *
68
- * AGENTS.md (or AGENT.md / CLAUDE.md fallback) for general instructions,
69
- * supports @-mentions to reference other files and glob-based conditional includes.
70
- *
71
- * @see https://ampcode.com/news/agent-skills
72
- * @see https://ampcode.com/manual
73
- */
74
56
  const amp = defineTarget({
75
57
  agent: "amp",
76
58
  displayName: "Amp",
@@ -104,22 +86,7 @@ const amp = defineTarget({
104
86
  "AGENTS.md files with globs frontmatter are conditionally included only when Amp reads matching files."
105
87
  ]
106
88
  });
107
- //#endregion
108
- //#region src/agent/targets/antigravity.ts
109
89
  const home$6 = homedir();
110
- /**
111
- * Antigravity (Google)
112
- *
113
- * Agent-first IDE (VS Code fork) powered by Gemini. Skills live in
114
- * .agent/skills/ (workspace) or ~/.gemini/antigravity/skills/ (global).
115
- * Uses semantic matching on description to auto-invoke skills.
116
- *
117
- * Adopted the Agent Skills open standard (agentskills.io) in Jan 2026.
118
- * Only `name` and `description` are used for routing; body loads on demand.
119
- *
120
- * @see https://antigravity.google/docs/skills
121
- * @see https://codelabs.developers.google.com/getting-started-with-antigravity-skills
122
- */
123
90
  const antigravity = defineTarget({
124
91
  agent: "antigravity",
125
92
  displayName: "Antigravity",
@@ -146,21 +113,7 @@ const antigravity = defineTarget({
146
113
  "GEMINI.md instruction file is shared with Gemini CLI. .agent/rules/*.md for always-on workspace rules."
147
114
  ]
148
115
  });
149
- //#endregion
150
- //#region src/agent/targets/claude-code.ts
151
116
  const claudeHome = process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
152
- /**
153
- * Claude Code (Anthropic CLI)
154
- *
155
- * Follows the Agent Skills open standard (agentskills.io) plus Claude-specific
156
- * extensions like `disable-model-invocation`, `user-invocable`, `context`, etc.
157
- *
158
- * Skills are discovered at startup — only `name` + `description` are read initially.
159
- * Full SKILL.md body loads when the agent invokes the skill (via Skill tool or auto-match).
160
- *
161
- * @see https://code.claude.com/docs/en/skills
162
- * @see https://agentskills.io/specification
163
- */
164
117
  const claudeCode = defineTarget({
165
118
  agent: "claude-code",
166
119
  displayName: "Claude Code",
@@ -247,22 +200,7 @@ const claudeCode = defineTarget({
247
200
  "Project detection uses weighted signals: .claude/settings.json, .claude/settings.local.json, .claude/skills/ are strong; bare .claude/ is medium; CLAUDE.md alone is not checked (too many false positives from repo conventions)."
248
201
  ]
249
202
  });
250
- //#endregion
251
- //#region src/agent/targets/cline.ts
252
203
  const home$5 = homedir();
253
- /**
254
- * Cline (VS Code extension)
255
- *
256
- * Has TWO systems: Rules (.clinerules/) and Skills (.cline/skills/).
257
- * We target Skills. Cline also reads .claude/skills/ as a fallback,
258
- * so emitting to .claude/skills/ covers both Claude Code and Cline.
259
- *
260
- * Only `name` and `description` are parsed from frontmatter.
261
- * All other fields are stripped/ignored.
262
- *
263
- * @see https://docs.cline.bot/features/skills
264
- * @see https://docs.cline.bot/features/cline-rules
265
- */
266
204
  const cline = defineTarget({
267
205
  agent: "cline",
268
206
  displayName: "Cline",
@@ -292,22 +230,7 @@ const cline = defineTarget({
292
230
  "Supporting dirs: docs/, scripts/, templates/ alongside SKILL.md."
293
231
  ]
294
232
  });
295
- //#endregion
296
- //#region src/agent/targets/codex.ts
297
233
  const codexHome = process.env.CODEX_HOME || join(homedir(), ".codex");
298
- /**
299
- * OpenAI Codex CLI
300
- *
301
- * IMPORTANT: Codex uses `.agents/skills/` for project-level skills,
302
- * NOT `.codex/skills/`. The `.codex/` directory is for config (config.toml).
303
- * `~/.codex/skills/` works only as a legacy user-global path.
304
- *
305
- * Codex also has AGENTS.md (or AGENTS.override.md) for general instructions,
306
- * which walks from git root to CWD concatenating found files.
307
- *
308
- * @see https://developers.openai.com/codex/skills
309
- * @see https://developers.openai.com/codex/guides/agents-md/
310
- */
311
234
  const codex = defineTarget({
312
235
  agent: "codex",
313
236
  displayName: "Codex",
@@ -352,22 +275,7 @@ const codex = defineTarget({
352
275
  "Size limit: 32 KiB default (project_doc_max_bytes), configurable in ~/.codex/config.toml."
353
276
  ]
354
277
  });
355
- //#endregion
356
- //#region src/agent/targets/cursor.ts
357
278
  const home$4 = homedir();
358
- /**
359
- * Cursor (AI code editor)
360
- *
361
- * Has TWO systems: Rules (.cursor/rules/*.mdc) and Skills (.cursor/skills/).
362
- * We target the Skills system which follows the Agent Skills spec.
363
- *
364
- * Cursor natively scans .claude/skills/ and .codex/skills/ in addition to
365
- * its own .cursor/skills/ — so .claude/skills/ output works for both
366
- * Claude Code and Cursor with zero duplication.
367
- *
368
- * @see https://cursor.com/docs/context/skills
369
- * @see https://cursor.com/docs/context/rules
370
- */
371
279
  const cursor = defineTarget({
372
280
  agent: "cursor",
373
281
  displayName: "Cursor",
@@ -411,21 +319,7 @@ const cursor = defineTarget({
411
319
  "Supporting dirs: scripts/, references/, assets/ alongside SKILL.md."
412
320
  ]
413
321
  });
414
- //#endregion
415
- //#region src/agent/targets/gemini-cli.ts
416
322
  const home$3 = homedir();
417
- /**
418
- * Google Gemini CLI
419
- *
420
- * Follows the Agent Skills open standard (agentskills.io).
421
- * Skills are activated via `activate_skill` tool with user confirmation.
422
- *
423
- * Also has GEMINI.md context files (analogous to CLAUDE.md) which support
424
- * @file.md import syntax for modular composition.
425
- *
426
- * @see https://geminicli.com/docs/cli/skills/
427
- * @see https://geminicli.com/docs/cli/creating-skills/
428
- */
429
323
  const geminiCli = defineTarget({
430
324
  agent: "gemini-cli",
431
325
  displayName: "Gemini CLI",
@@ -461,8 +355,6 @@ const geminiCli = defineTarget({
461
355
  "Also scans .agents/skills/ (Agent Skills spec standard) - skilld deduplicates to avoid conflicts."
462
356
  ]
463
357
  });
464
- //#endregion
465
- //#region src/agent/targets/github-copilot.ts
466
358
  const home$2 = homedir();
467
359
  function hasCopilotExtension() {
468
360
  const extDirs = [
@@ -478,18 +370,6 @@ function hasCopilotExtension() {
478
370
  }
479
371
  return false;
480
372
  }
481
- /**
482
- * GitHub Copilot
483
- *
484
- * Has TWO systems: Instructions (.github/instructions/*.instructions.md)
485
- * and Skills (.github/skills/). We target Skills.
486
- *
487
- * Copilot also auto-detects .claude/skills/ as a legacy path,
488
- * so .claude/skills/ output works for Claude Code, Cursor, Cline, AND Copilot.
489
- *
490
- * @see https://docs.github.com/en/copilot/concepts/agents/about-agent-skills
491
- * @see https://docs.github.com/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot
492
- */
493
373
  const githubCopilot = defineTarget({
494
374
  agent: "github-copilot",
495
375
  displayName: "GitHub Copilot",
@@ -528,18 +408,7 @@ const githubCopilot = defineTarget({
528
408
  "Keep SKILL.md under 500 lines / 5000 tokens for optimal loading."
529
409
  ]
530
410
  });
531
- //#endregion
532
- //#region src/agent/targets/goose.ts
533
411
  const configHome$1 = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
534
- /**
535
- * Goose (Block)
536
- *
537
- * Scans 6 directories for skills, including .claude/skills/ and .agents/skills/
538
- * for cross-agent compatibility. Later directories override earlier ones on
539
- * name conflict.
540
- *
541
- * @see https://block.github.io/goose/docs/guides/context-engineering/using-skills/
542
- */
543
412
  const goose = defineTarget({
544
413
  agent: "goose",
545
414
  displayName: "Goose",
@@ -573,21 +442,7 @@ const goose = defineTarget({
573
442
  "Supporting files alongside SKILL.md (scripts, templates, configs) are accessible."
574
443
  ]
575
444
  });
576
- //#endregion
577
- //#region src/agent/targets/opencode.ts
578
445
  const configHome = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
579
- /**
580
- * OpenCode (SST)
581
- *
582
- * Walks from CWD up to git worktree root searching for skill dirs.
583
- * Reads .claude/skills/ and .agents/skills/ in addition to .opencode/skills/.
584
- *
585
- * Has a rich agent system: .opencode/agents/ with per-agent model/tool configuration.
586
- * Skills can be permission-controlled per-agent with allow/deny/ask + glob patterns.
587
- *
588
- * @see https://opencode.ai/docs/skills/
589
- * @see https://opencode.ai/docs/rules/
590
- */
591
446
  const opencode = defineTarget({
592
447
  agent: "opencode",
593
448
  displayName: "OpenCode",
@@ -628,21 +483,7 @@ const opencode = defineTarget({
628
483
  "AGENTS.md (or CLAUDE.md fallback) for general instructions."
629
484
  ]
630
485
  });
631
- //#endregion
632
- //#region src/agent/targets/roo.ts
633
486
  const home$1 = homedir();
634
- /**
635
- * Roo Code (VS Code extension)
636
- *
637
- * IMPORTANT: Roo does NOT read .claude/skills/ or .agents/skills/.
638
- * It requires its own .roo/skills/ directory — no cross-compat shortcuts.
639
- *
640
- * Unique feature: mode-specific skill directories (.roo/skills-{modeSlug}/)
641
- * allow targeting skills to specific modes (code, architect, etc.).
642
- *
643
- * @see https://docs.roocode.com/features/skills
644
- * @see https://docs.roocode.com/features/custom-instructions
645
- */
646
487
  const roo = defineTarget({
647
488
  agent: "roo",
648
489
  displayName: "Roo Code",
@@ -674,56 +515,39 @@ const roo = defineTarget({
674
515
  "Skills manageable from Settings panel (v3.46.0+)."
675
516
  ]
676
517
  });
677
- //#endregion
678
- //#region src/agent/targets/windsurf.ts
679
518
  const home = homedir();
680
- /**
681
- * Windsurf (Codeium editor)
682
- *
683
- * Has TWO systems: Rules (.windsurf/rules/*.md) and Skills (.windsurf/skills/).
684
- * We target Skills. Rules have a separate frontmatter schema with trigger/globs.
685
- *
686
- * Skills only document `name` and `description` as frontmatter fields.
687
- * Cascade uses "progressive disclosure" for supporting files.
688
- *
689
- * @see https://docs.windsurf.com/windsurf/cascade/skills
690
- * @see https://docs.windsurf.com/windsurf/cascade/memories
691
- */
692
- const windsurf = defineTarget({
693
- agent: "windsurf",
694
- displayName: "Windsurf",
695
- detectInstalled: () => existsSync(join(home, ".codeium/windsurf")),
696
- detectEnv: () => !!process.env.WINDSURF_SESSION,
697
- detectProject: (cwd) => existsSync(join(cwd, ".windsurf")) || existsSync(join(cwd, ".windsurfrules")),
698
- instructionFile: ".windsurfrules",
699
- skillsDir: ".windsurf/skills",
700
- globalSkillsDir: join(home, ".codeium/windsurf/skills"),
701
- frontmatter: [{
702
- ...SPEC_FRONTMATTER.name,
703
- description: "Skill identifier.",
704
- constraints: "Lowercase, numbers, hyphens only"
705
- }, {
706
- ...SPEC_FRONTMATTER.description,
707
- description: "Used by Cascade for automatic invocation matching."
708
- }],
709
- discoveryStrategy: "eager",
710
- discoveryNotes: "Cascade matches description against user requests for auto-invocation. Manual invocation via @skill-name.",
711
- agentSkillsSpec: false,
712
- docs: "https://docs.windsurf.com/windsurf/cascade/skills",
713
- notes: [
714
- "Only `name` and `description` are documented as frontmatter fields. Other fields may be silently ignored.",
715
- "Rules system is separate: .windsurf/rules/*.md with trigger/globs/alwaysApply frontmatter.",
716
- "Rules have a 6,000 char per-file limit and 12,000 char total limit. Skills have no documented limit.",
717
- "Legacy .windsurfrules at project root still supported but deprecated.",
718
- "Supporting files alongside SKILL.md are loaded via progressive disclosure."
719
- ]
720
- });
721
- //#endregion
722
- //#region src/agent/targets/registry.ts
723
519
  const targets = {
724
520
  "claude-code": claudeCode,
725
521
  "cursor": cursor,
726
- "windsurf": windsurf,
522
+ "windsurf": defineTarget({
523
+ agent: "windsurf",
524
+ displayName: "Windsurf",
525
+ detectInstalled: () => existsSync(join(home, ".codeium/windsurf")),
526
+ detectEnv: () => !!process.env.WINDSURF_SESSION,
527
+ detectProject: (cwd) => existsSync(join(cwd, ".windsurf")) || existsSync(join(cwd, ".windsurfrules")),
528
+ instructionFile: ".windsurfrules",
529
+ skillsDir: ".windsurf/skills",
530
+ globalSkillsDir: join(home, ".codeium/windsurf/skills"),
531
+ frontmatter: [{
532
+ ...SPEC_FRONTMATTER.name,
533
+ description: "Skill identifier.",
534
+ constraints: "Lowercase, numbers, hyphens only"
535
+ }, {
536
+ ...SPEC_FRONTMATTER.description,
537
+ description: "Used by Cascade for automatic invocation matching."
538
+ }],
539
+ discoveryStrategy: "eager",
540
+ discoveryNotes: "Cascade matches description against user requests for auto-invocation. Manual invocation via @skill-name.",
541
+ agentSkillsSpec: false,
542
+ docs: "https://docs.windsurf.com/windsurf/cascade/skills",
543
+ notes: [
544
+ "Only `name` and `description` are documented as frontmatter fields. Other fields may be silently ignored.",
545
+ "Rules system is separate: .windsurf/rules/*.md with trigger/globs/alwaysApply frontmatter.",
546
+ "Rules have a 6,000 char per-file limit and 12,000 char total limit. Skills have no documented limit.",
547
+ "Legacy .windsurfrules at project root still supported but deprecated.",
548
+ "Supporting files alongside SKILL.md are loaded via progressive disclosure."
549
+ ]
550
+ }),
727
551
  "cline": cline,
728
552
  "codex": codex,
729
553
  "github-copilot": githubCopilot,
@@ -734,22 +558,9 @@ const targets = {
734
558
  "roo": roo,
735
559
  "antigravity": antigravity
736
560
  };
737
- //#endregion
738
- //#region src/agent/detect.ts
739
- /**
740
- * Detect which agents are installed on the system
741
- */
742
561
  function detectInstalledAgents() {
743
562
  return Object.entries(targets).filter(([_, config]) => config.detectInstalled()).map(([type]) => type);
744
563
  }
745
- /**
746
- * Detect the target agent (where skills are installed) from env vars and cwd.
747
- * This is NOT the generator LLM — it determines the skills directory.
748
- *
749
- * Priority: env vars first (running inside agent = unambiguous), then project dirs.
750
- * When multiple agents match project dirs, returns null to trigger user prompt
751
- * rather than silently picking the first match.
752
- */
753
564
  function detectTargetAgent() {
754
565
  for (const [type, target] of Object.entries(targets)) if (target.detectEnv()) return type;
755
566
  const cwd = process.cwd();
@@ -757,17 +568,10 @@ function detectTargetAgent() {
757
568
  for (const [type, target] of Object.entries(targets)) if (target.detectProject(cwd)) projectMatches.push(type);
758
569
  return projectMatches.length === 1 ? projectMatches[0] : null;
759
570
  }
760
- /**
761
- * Get all agents matching the current project directory.
762
- * Used by promptForAgent to show relevant agents first when disambiguation is needed.
763
- */
764
571
  function detectProjectAgents() {
765
572
  const cwd = process.cwd();
766
573
  return Object.entries(targets).filter(([, target]) => target.detectProject(cwd)).map(([type]) => type);
767
574
  }
768
- /**
769
- * Get the version of an agent's CLI (if available)
770
- */
771
575
  function getAgentVersion(agentType) {
772
576
  const agent = targets[agentType];
773
577
  if (!agent.cli) return null;
@@ -790,7 +594,6 @@ function getAgentVersion(agentType) {
790
594
  return null;
791
595
  }
792
596
  }
793
- //#endregion
794
597
  export { targets as a, getAgentVersion as i, detectProjectAgents as n, detectTargetAgent as r, detectInstalledAgents as t };
795
598
 
796
599
  //# sourceMappingURL=detect.mjs.map