@easbot/skills 0.3.11 → 0.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.en.md +167 -60
  2. package/README.md +173 -63
  3. package/dist/chunks/blob-3PZEQWTP.mjs +1 -0
  4. package/dist/chunks/blob-ZDEX2HRV.cjs +1 -0
  5. package/dist/chunks/chunk-4D5RQDWJ.mjs +5 -0
  6. package/dist/chunks/chunk-5BL3KG26.cjs +5 -0
  7. package/dist/chunks/chunk-5W7HC7BY.mjs +22 -0
  8. package/dist/chunks/chunk-CFMOYU7R.mjs +2 -0
  9. package/dist/chunks/chunk-CXH3OTTQ.cjs +22 -0
  10. package/dist/chunks/chunk-CY6UI6SJ.cjs +1 -0
  11. package/dist/chunks/chunk-E7AHWFZN.cjs +2 -0
  12. package/dist/chunks/chunk-ISMGLHYS.cjs +1 -0
  13. package/dist/chunks/chunk-K2XGYOXP.mjs +267 -0
  14. package/dist/chunks/chunk-ML6B4IQL.mjs +1 -0
  15. package/dist/chunks/chunk-NKIQLESR.mjs +3 -0
  16. package/dist/chunks/chunk-ROCFLAYZ.mjs +2 -0
  17. package/dist/chunks/chunk-RVR3DSD2.cjs +2 -0
  18. package/dist/chunks/chunk-RWZ4LFSN.mjs +1 -0
  19. package/dist/chunks/chunk-S6YNGR7S.cjs +2 -0
  20. package/dist/chunks/chunk-SXUY2J75.cjs +3 -0
  21. package/dist/chunks/chunk-UJWB7QQ6.cjs +267 -0
  22. package/dist/chunks/chunk-VRHWDHQV.cjs +1 -0
  23. package/dist/chunks/chunk-WQGSYA5D.mjs +1 -0
  24. package/dist/chunks/chunk-XGUPIAAF.cjs +1 -0
  25. package/dist/chunks/chunk-ZBKGF7PA.mjs +1 -0
  26. package/dist/chunks/chunk-ZYDDQV73.mjs +2 -0
  27. package/dist/chunks/cli-handler-667TYY4I.cjs +1 -0
  28. package/dist/chunks/cli-handler-YSDUNKKZ.mjs +1 -0
  29. package/dist/chunks/installer-REG45DC2.mjs +1 -0
  30. package/dist/chunks/installer-SOVGUW3M.cjs +1 -0
  31. package/dist/chunks/interfaces-S47ZGORM.mjs +1 -0
  32. package/dist/chunks/interfaces-UIS44Q7A.cjs +1 -0
  33. package/dist/chunks/local-lock-AWD3LLEY.mjs +1 -0
  34. package/dist/chunks/local-lock-GIZDVF3X.cjs +1 -0
  35. package/dist/chunks/scan-57D2H7LP.cjs +1 -0
  36. package/dist/chunks/scan-WAXGJM5N.mjs +1 -0
  37. package/dist/chunks/skill-lock-DZMA75MY.mjs +1 -0
  38. package/dist/chunks/skill-lock-XTWQYBRG.cjs +1 -0
  39. package/dist/chunks/store-F7PGGZIO.cjs +1 -0
  40. package/dist/chunks/store-IVDLGLET.mjs +1 -0
  41. package/dist/chunks/telemetry-7T6MUW5A.mjs +1 -0
  42. package/dist/chunks/telemetry-LCGTSJDM.cjs +1 -0
  43. package/dist/cli.cjs +1 -1
  44. package/dist/cli.mjs +1 -1
  45. package/dist/index.cjs +1 -1
  46. package/dist/index.d.cts +288 -129
  47. package/dist/index.d.ts +288 -129
  48. package/dist/index.mjs +1 -1
  49. package/package.json +4 -5
  50. package/dist/chunks/blob-LYSE5I24.mjs +0 -1
  51. package/dist/chunks/blob-NYUAIVUS.cjs +0 -1
  52. package/dist/chunks/chunk-4IO7TNWC.mjs +0 -223
  53. package/dist/chunks/chunk-IWCI7DET.mjs +0 -6
  54. package/dist/chunks/chunk-KJPMAUXZ.cjs +0 -1
  55. package/dist/chunks/chunk-L6KE3VIY.mjs +0 -2
  56. package/dist/chunks/chunk-PGDLW2JN.cjs +0 -2
  57. package/dist/chunks/chunk-S76WRD5J.cjs +0 -6
  58. package/dist/chunks/chunk-WQJKBJSM.cjs +0 -223
  59. package/dist/chunks/chunk-Y2X6FBMZ.mjs +0 -1
  60. package/dist/chunks/scan-47YPOLJX.mjs +0 -1
  61. package/dist/chunks/scan-5G765ZEF.cjs +0 -1
package/README.md CHANGED
@@ -2,19 +2,34 @@
2
2
 
3
3
  # @easbot/skills
4
4
 
5
- EASBot 技能包管理子系统:负责从 GitHub / Well-Known / 本地路径发现、安装、移除、搜索、更新、同步与一次性使用技能(SKILL.md)。
5
+ EASBot 技能管理子系统。负责技能(SKILL.md)的发现、安装、移除、搜索、更新、一次性使用(use),以及 store / cache / index 的运维管理。同时承担 **Plugin Source 注册中心**角色(决策 0044),把 well-known / marketplace / 本地 plugins 等源抽象为 `PluginSource`,供 `@easbot/agent` 注入 `PluginDefinition.skills`。
6
6
 
7
- 既可作为独立 CLI(`easbot skills ...`),也可被 `@easbot/agent` 主 CLI 通过 Commander.js 委派调用,实现 `easbot agent skills ...` 与 `easbot skills ...` 等价。
7
+ 既可作为独立 CLI(`easbot-skills`),也可被 `@easbot/agent` 主 CLI 通过 Commander.js 委派调用,`easbot skills ...` 与 `easbot-skills ...` 等价。
8
+
9
+ ## 版本
10
+
11
+ v0.3.11
12
+
13
+ ## 目标文件
14
+
15
+ 包中只操作 **SKILL.md**(以及可选的本地 `plugin.json`):
16
+ - 技能名来自 `SKILL.md` frontmatter 的 `name` 字段
17
+ - 插件清单来自 `plugin.json`(若存在,否则默认为 `*.md`)
8
18
 
9
19
  ## 特性
10
20
 
11
- - **类型安全**:完整 TypeScript 类型 + Zod frontmatter 校验
12
- - **多源支持**:GitHub 仓库 shorthand / HTTPS / SSH / Well-Known / 本地路径
13
- - **多 Agent 兼容**:Claude Code、Cursor、AiderDesk、Amp、Antigravity、Zed、Codex、Hermes、Vibe、AutoHand、Eve
14
- - **依赖注入**:`setGlobalAdapter / setInstanceAdapter / setAgentAdapter` 让宿主(agent / gateway)注入 `IGlobal.Path`、`IInstance.directory`、SubAgentRunner / LocalAgentRunner,统一数据树
15
- - **增量同步**:基于本地 SHA-256 锁文件的 `add / remove / update / sync` 增量操作
16
- - **i18n**:内置 zh-CN / en-US 两套翻译,所有面向用户文案走 `t()`,未命中 key 时回退原文
17
- - **遥测与安全审计**:内置 `skills.sh` partner audit 上报与 OpenClaw 风险提示
21
+ - **类型安全**:完整 TypeScript 类型 + Zod frontmatter 校验 + Zod remote-skill payload 校验
22
+ - **多源支持**:GitHub 仓库 shorthand(`owner/repo`)/ HTTPS / SSH / Well-Known 索引 / 本地路径 / GitHub API blob 回退
23
+ - **多 Agent 兼容**:72+ Agent 类型(`easbot`, `claude-code`, `cursor`, `codex`, `amp`, `eve`, `gemini-cli`, `github-copilot`, `opencode`, `qwen-code`, `trae`, `trae-cn`, `windsurf`, `zed`, `roo`, `cline`, `iflow-cli`, `kimi-code-cli`, `augment`, `devin`, `goose`, `dexto` 等)
24
+ - **Universal 共享路径**:`eve` / `amp` / `gemini-cli` / `github-copilot` / `qwen-code` / `roo` / `windsurf` / `zed` / `claude-code` 等 16 个 agent 通过 `"universal"` 作用域共享 `.agents/skills` 目录
25
+ - **Non-universal agent**:各自维护独立技能目录
26
+ - **安装矩阵 / 后安装核对**:`AgentInstallMatrix`(agent × skill 二维表,`probeCell` 逐单元格判定),安装后对每个 cell 做 reconcile(缺失补链接,多余移除)
27
+ - **依赖注入** (决策 0043):通过 `setGlobalAdapter` / `setInstanceAdapter` / `setAgentAdapter` 注入 `IGlobal.Path` / `IInstance.directory`,让 skills 统一使用宿主的 XDG 数据树
28
+ - **增量同步**:基于本地 SHA-256 密文锁文件的 `add` / `remove` / `update` / `store` 增量操作(`skill-lock.ts` / `local-lock.ts`)
29
+ - **store 视角运维** (决策 36A):`skills store list / clean / update / remove` 管理 store 物理 + index + cache,**不**动 agent 前端分发
30
+ - **local 源硬保护**:`store clean --force` / `store remove` 对 local 源拒绝删 cache / 用户原目录
31
+ - **i18n**:内置 zh-CN / en-US 两套翻译;所有用户简文走 `t()`,未命中 key 时回退英文原文
32
+ - **遥测 + 安全审计**:内置 `skills.sh` partner audit 上报、OpenClaw 风险提示、遥测可冲刷(`flushTelemetry`)
18
33
 
19
34
  ## 安装
20
35
 
@@ -32,41 +47,104 @@ pnpm add @easbot/skills
32
47
  }
33
48
  ```
34
49
 
50
+ ## 目录结构
51
+
52
+ ```
53
+ src/
54
+ ├── types.ts # AgentType、Skill、AgentConfig、ParsedSource、RemoteSkill
55
+ ├── agents.ts # Agent 配置矩阵(72+ 个)与分类函数
56
+ ├── skills.ts # 技能发现: parseSkillMd、discoverSkills、filterSkills
57
+ ├── installer/
58
+ │ ├── installer.ts # 物理安装:installSkillForAgent、installRemoteSkillForAgent、installBlobSkillForAgent
59
+ │ ├── post-install.ts # 安装后核对矩阵:planActions、buildMatrix、probeCell
60
+ │ ├── store.ts # Store 三层职责(source→cache→install):ensureCachedSource、acquireSourceClone、cleanCache
61
+ │ └── types.ts # InstallMode、InstalledSkill 等
62
+ ├── add.ts # 添加技能主流程
63
+ ├── find.ts # 搜索技能(skills.sh / fuzzy filter / 本地 store 查询)
64
+ ├── list.ts # 列出已安装技能(项目/全局/按 agent 过滤)
65
+ ├── remove.ts # 移除技能
66
+ ├── update.ts # 增量更新(按 filter 更新一个或多个技能)
67
+ ├── use.ts # 一次性使用(materializeUseSkill、buildUsePrompt、launchAgentInteractively)
68
+ ├── doctor.ts # 检查 + 清理断链与坏符号链接
69
+ ├── store-cmd.ts # store 运维子命令(list / clean / update / remove)
70
+ ├── init-template.ts # 根据 locale 模板创建新技能
71
+ ├── sanitize.ts # 控制字符净化:sanitizeMetadata、stripTerminalEscapes
72
+ ├── telemetry.ts # 遥测发送:track、flushTelemetry、fetchAuditData、setVersion
73
+ ├── detect-agent.ts # 探测运行的 AI Agent(detectAgent、isRunningInAgent)
74
+ ├── skill-lock.ts # 全局安装锁定文件读写(skill-lock.json)
75
+ ├── local-lock.ts # 项目级锁定文件(skills-lock.json)与文件夹 SHA-256
76
+ ├── git.ts # 仓库克隆 / cleanupTempDir / parseGitHubRepoUrl
77
+ ├── blob.ts # GitHub API 回退:fetchRepoTree、tryBlobInstall、toSkillSlug
78
+ ├── source-parser.ts # 来源标准化:parseSource、parseOwnerRepo、sanitizeSubpath、isRepoPrivate
79
+ ├── interfaces.ts # 依赖注入:setGlobalAdapter / setInstanceAdapter / getGlobal / getXdgData
80
+ ├── constants.ts # AGENTS_DIR / SKILLS_SUBDIR / UNIVERSAL_SKILLS_DIR
81
+ ├── frontmatter.ts # YAML frontmatter 解析
82
+ ├── format.ts # ANSI 辅助函数(颜色)
83
+ ├── providers/
84
+ │ ├── wellknown.ts # WellKnownProvider: fetch index + scan + 加载
85
+ │ └── registry.ts # Provider 注册中心 + HostProvider 接口
86
+ ├── sources/
87
+ │ ├── index.ts # PluginSource 入口:createWellKnownSource / createLocalPluginSource 工厂
88
+ │ ├── registry.ts # 注册中心:registerSource / listSources / findSource / listAllEntries
89
+ │ ├── wellknown.ts # wellknown 源适配
90
+ │ ├── local.ts # 本地插件目录(plugin.json)适配
91
+ │ └── types.ts # PluginSource / PluginSourceCategory / PluginSourceEntry 接口
92
+ ├── i18n/ # 国际化全套(zh-CN / en-US)
93
+ ├── prompts/ # 搜索多选提示
94
+ ├── utils/ # 辅助工具(ansi / format)
95
+ ├── cli.ts # 独立CLI 入口(easbot-skills)
96
+ ├── cli-handler.ts # CLI 处理器(供 agent 复用)
97
+ └── src/sources/ # PluginSource 注册中心 (决策 0044)
98
+ ```
99
+
35
100
  ## CLI 用法
36
101
 
37
102
  ### 独立 CLI
38
103
 
39
104
  ```bash
40
105
  # 添加技能
41
- easbot skills add houjallen/agent-skills
42
- easbot skills add https://github.com/houjallen/agent-skills -g
106
+ easbot-skills add houjallen/agent-skills
107
+ easbot-skills add https://github.com/houjallen/agent-skills -g
43
108
 
44
- # 搜索
45
- easbot skills find typescript --owner houjallen
109
+ # 搜索(交互式 fzf 选出)
110
+ easbot-skills find typescript --owner houjallen
46
111
 
47
- # 列出已安装
48
- easbot skills list --json
112
+ # 列出已安装(项目级/全局)
113
+ easbot-skills list --json
114
+ easbot-skills ls -g -a claude-code
49
115
 
50
116
  # 移除
51
- easbot skills remove my-skill -y
117
+ easbot-skills remove my-skill -y
118
+ easbot-skills rm --agent claude-code my-skill
52
119
 
53
120
  # 更新
54
- easbot skills update -g
55
-
56
- # 一次性使用(不修改锁定文件)
57
- easbot skills use houjallen/agent-skills@houjallen
58
-
59
- # node_modules 同步 / 从锁定文件还原
60
- easbot skills experimental_sync
61
- easbot skills experimental_install
62
-
63
- # 初始化新技能
64
- easbot skills init my-skill
121
+ easbot-skills update -g
122
+ easbot-skills update my-skill --all
123
+
124
+ # 一次性使用(不写锁定文件)
125
+ easbot-skills use houjallen/agent-skills@houjallen
126
+ easbot-skills use --skill my-skill --agent claude
127
+
128
+ # store 视角运维(store + cache + index)
129
+ easbot-skills store list [keyword] # 列出 store skills(按 name 过滤)
130
+ easbot-skills store list --json # 完整 index 为 JSON
131
+ easbot-skills store clean # 重置 store(删 store 物理 + 清 index)
132
+ easbot-skills store clean --force # 同上 + 清 cache(local 源保护)
133
+ easbot-skills store remove <sourceKey> # 移除 source
134
+ easbot-skills store remove <sourceKey> --force # 额外清 cache
135
+
136
+ # 健康检查(医生说:检查 + 清理断链符号链接)
137
+ easbot-skills doctor
138
+ easbot-skills doctor -a easbot -y # 检查一个 agent + 自动清理
139
+ easbot-skills dr -g # 仅全局范围
140
+
141
+ # 健康检查(快速)
142
+ easyt-skills init my-skill
65
143
  ```
66
144
 
67
145
  ### 被宿主 CLI 委派
68
146
 
69
- `@easbot/agent` 通过 `handleSkillsCli(args, deps)` 复用所有子命令:
147
+ `@easbot/agent` `easyt skills ...` 负责通过 `handleSkillsCli(args, deps)` 实现全子命令复用。看看源码:
70
148
 
71
149
  ```typescript
72
150
  import { handleSkillsCli, setGlobalAdapter, setInstanceAdapter } from '@easbot/skills';
@@ -74,43 +152,66 @@ import { handleSkillsCli, setGlobalAdapter, setInstanceAdapter } from '@easbot/s
74
152
  setGlobalAdapter({ Path: Global.Path });
75
153
  setInstanceAdapter({ directory: ctx.config.directory, worktree: Instance.worktree });
76
154
 
77
- await handleSkillsCli(['add', 'houjallen/agent-skills', '-y'], {
155
+ const result = await handleSkillsCli(['add', 'houjallen/agent-skills', '-y'], {
78
156
  version: ctx.programVersion,
157
+ cwd: ctx.config.directory,
79
158
  });
159
+ // result.code === 0 时退出进程
80
160
  ```
81
161
 
162
+ `easyt skills` 在 `packages/agent/src/cli/commands/skills.ts` 的 `registerSkillsCommand()` 中注册,通过 Commander.js `skills.<subcommand>` 把 flag 转为 argv 后 dispatch 给 `handleSkillsCli`。`skills store` 子族也在同一模块注册,并绑定其中的 `registerSkillsCommand()`。
163
+
82
164
  ## API
83
165
 
84
166
  | 模块 | 导出 | 说明 |
85
167
  |---|---|---|
86
- | `add` | `runAdd / parseAddOptions / initTelemetry` | 技能添加主流程 |
87
- | `remove` | `removeCommand / parseRemoveOptions` | 技能移除 |
88
- | `list` | `runList / parseListOptions` | 列出已安装技能 |
89
- | `find` | `runFind / parseFindOptions / searchSkillsAPI` | skills.sh 搜索 |
90
- | `update` | `runUpdate / parseUpdateOptions` | 增量更新 |
91
- | `install` | `runInstallFromLock` | skills-lock.json 还原 |
92
- | `sync` | `runSync / parseSyncOptions` | node_modules 同步 |
93
- | `use` | `runUse / parseUseOptions / buildUsePrompt` | 一次性使用 |
94
- | `cli-handler` | `handleSkillsCli / renderBanner / renderHelp / SkillsCliDeps / SkillsCliResult` | CLI 桥接 |
95
- | `interfaces` | `setGlobalAdapter / setInstanceAdapter / setAgentAdapter / getGlobal / getInstance / ...` | 依赖注入 |
96
- | `agents` | `agents / detectInstalledAgents / getUniversalAgents / ...` | Agent 元数据 |
97
- | `installer` | `installSkillForAgent / listInstalledSkills / getCanonicalSkillsDir` | 物理安装 |
98
- | `skill-lock` | `readSkillLock / writeSkillLock / addSkillToLock / removeSkillFromLock` | 全局锁定文件 |
99
- | `local-lock` | `readLocalLock / writeLocalLock / computeSkillFolderHash` | 项目级锁定文件 |
100
- | `telemetry` | `track / flushTelemetry / setVersion / fetchAuditData` | 使用统计 + 安全审计 |
101
- | `i18n` | `t / initI18n / registerI18nResources / changeI18nLanguage` | 国际化 |
168
+ | `types` | `AgentType`, `Skill`, `AgentConfig`, `ParsedSource`, `RemoteSkill` | 核心类型定义(70+ 个 AgentType 联合类型) |
169
+ | `agents` | `agents`, `detectInstalledAgents`, `getAgentConfig`, `getAgentSkillDirs`, `getUniversalAgents`, `getAgentGlobalSkillDirs`, `isUniversalAgent`, `matchesUniversalScope` 等 | Agent 元数据矩阵 + 分类函数 |
170
+ | `skills` | `parseSkillMd`, `discoverSkills`, `filterSkills`, `getSkillDisplayName`, `isSubpathSafe`, `shouldInstallInternalSkills` | SKILL.md 发现 / 解析 |
171
+ | `installer` | `installSkillForAgent`, `installRemoteSkillForAgent`, `installBlobSkillForAgent`, `installWellKnownSkillForAgent`, `listInstalledSkills`, `isSkillInstalled`, `getCanonicalSkillsDir`, `getInstallPath`, `sanitizeName` | 物理安装接口 |
172
+ | `installer/post-install` | `buildMatrix`, `planActions`, `applyActions`, `probeCell`, `runPostInstallReconcile` | 安装矩阵生成 / 差异应用 |
173
+ | `installer/store` | `acquireSourceClone`, `ensureCachedSource`, `installFromCache`, `cleanCache`, `getCacheRepoDir`, `getSourceDir` | 三层 source/cache/install 收敛架构 |
174
+ | `add` | `runAdd`, `parseAddOptions`, `initTelemetry`, `AddOptions` | 技能添加 |
175
+ | `find` | `runFind`, `parseFindOptions`, `searchSkillsAPI`, `FindOptions`, `SearchSkill` | 搜索(skills.sh + 本地 store) |
176
+ | `list` | `runList`, `parseListOptions` | 列出 |
177
+ | `remove` | `removeCommand`, `parseRemoveOptions`, `RemoveOptions` | 移除 |
178
+ | `update` | `runUpdate`, `parseUpdateOptions`, `hasProjectSkills`, `matchesSkillFilter`, `resolveUpdateScope`, `UpdateScope` | 增量更新 |
179
+ | `store-cmd` | `runStore`, `parseStoreOptions`, `runStoreList`, `runStoreClean`, `runStoreUpdate`, `runStoreRemove`, `StoreOptions` | 运维:以 store 为视角管理 store / cache / index |
180
+ | `use` | `runUse`, `parseUseOptions`, `buildUsePrompt`, `materializeUseSkill`, `launchAgentInteractively`, `UseOptions`, `MaterializedUseSkill` | 一次性使用 |
181
+ | `doctor` | `runDoctor` | 健康检查 + 断链清理 |
182
+ | `cli-handler` | `handleSkillsCli`, `renderBanner`, `renderHelp`, `SkillsCliDeps`, `SkillsCliResult` | CLI 桥接供 agent 复用 |
183
+ | `interfaces` | `setGlobalAdapter`, `setInstanceAdapter`, `setAgentAdapter`, `getGlobal`, `getInstance`, `getHomeDir`, `getXdgData`, `getXdgConfig`, `getXdgState`, `getXdgCache`, `getProjectDirectory`, `resetGlobalAdapter`, `resetInstanceAdapter`, `hasAgentAdapter` | 路径 / Agent 依赖注入 |
184
+ | `skill-lock` | `readSkillLock`, `writeSkillLock`, `addSkillToLock`, `removeSkillFromLock`, `getSkillFromLock`, `getGitHubToken`, `getAllLockedSkills`, `dismissPrompt`, `isPromptDismissed`, `resetGhAuthWarning` | 全局锁文件 |
185
+ | `local-lock` | `readLocalLock`, `writeLocalLock`, `addSkillToLocalLock`, `removeSkillFromLocalLock`, `computeSkillFolderHash`, `getLocalLockPath` | 项目锁文件 |
186
+ | `git` | `cloneRepo`, `cleanupTempDir`, `parseGitHubRepoUrl`, `isGitHubHttpsCloneUrl`, `isGitHubSsoAuthError`, `GitCloneError` | Git/SSH 回退 / 仓库克隆 |
187
+ | `blob` | `fetchRepoTree`, `findSkillMdPaths`, `getSkillFolderHashFromTree`, `tryBlobInstall`, `toSkillSlug`, `resetRepoTreeAuthState` | GitHub API blob 回退 |
188
+ | `telemetry` | `track`, `flushTelemetry`, `setVersion`, `fetchAuditData`, `setDetectedAgent` | 使用统计 + 安全审计 |
189
+ | `sanitize` | `sanitizeMetadata`, `stripTerminalEscapes` | 输出净化 |
190
+ | `detect-agent` | `detectAgent`, `getAgentName`, `getAgentType`, `isRunningInAgent` | Agent 环境探测 |
191
+ | `providers/wellknown` | `wellKnownProvider`, `WellKnownProvider` | WellKnown 主机提供方:解析索引 + 拉取 SKILL.md |
192
+ | `providers/registry` | `findProvider`, `registerProvider`, `getProviders`, `registry` | 提供方注册中心 + 匹配器 |
193
+ | `sources` | `registerSource`, `listSources`, `findSource`, `findSourcesByCategory`, `listAllEntries`, `createWellKnownSource`, `createLocalPluginSource` | PluginSource 注册中心(决策 0044) |
102
194
  | `frontmatter` | `parseFrontmatter` | YAML frontmatter 解析 |
103
- | `providers` | `wellKnownProvider / registry / findProvider` | Well-Known 等主机提供方 |
195
+ | `constants` | `AGENTS_DIR`, `SKILLS_SUBDIR`, `UNIVERSAL_SKILLS_DIR` | 约定的目录常量 |
196
+ | `utils/ansi` | `BOLD`, `DIM`, `RESET`, `TEXT`, `CYAN` 等 | ANSI 终端辅助函数 |
197
+
198
+ ## 支持的Agent列表(完整)
199
+
200
+ `types.ts` 中的 `AgentType` 联合类型包含 70+ 个 Agent,其中包括:
104
201
 
105
- ## 全局路径注入
202
+ `easbot`, `claude-code`, `cursor`, `codex`, `eve`, `opencode`, `aider-desk`, `amp`, `antigravity`, `astrbot`, `augment`, `autohand-code`, `bob`, `openclaw`, `cline`, `codearts-agent`, `codebuddy`, `codemaker`, `codestudio`, `command-code`, `continue`, `cortex`, `crush`, `deepagents`, `devin`, `dexto`, `droid`, `firebender`, `forgecode`, `gemini-cli`, `github-copilot`, `goose`, `hermes-agent`, `inference-sh`, `iflow-cli`, `jazz`, `junie`, `kilo`, `kimi-code-cli`, `kiro-cli`, `kode`, `lingma`, `loaf`, `zanbura`, `mistral-vibe`, `moxby`, `mux`, `neovate`, `openhands`, `om`, `pi`, `qoder`, `qoder-cn`, `qwen-code`, `replit`, `reasonix`, `roo`, `rovodev`, `tabnine-cli`, `terramind`, `tinycloud`, `trae`, `trae-cn`, `warp`, `windsurf`, `zed`, `zencoder`, `zenflow`, `pochi`, `promptscript`, `adal`, `antigravity-cli`, `mistral`,以及虚拟类型 `universal`。
106
203
 
107
- 为避免与宿主(agent / gateway)抢用 XDG / home 目录,`@easbot/skills` 默认通过依赖注入获取路径:
204
+ 所有这些 Agent 的配置(displayName、skillsDir、globalSkillsDir、是否导入universal、安装判断函数等)都在 `src/agents.ts` 中定义。
205
+
206
+ ## 全局路径依赖注入
207
+
208
+ 为避免与宿主(agent/gateway)抢 XDG/home 目录,`@easbot/skills` 默认通过依赖注入获取路径:
108
209
 
109
210
  ```typescript
110
211
  import {
111
212
  setGlobalAdapter, // 注入 IGlobal.Path
112
213
  setInstanceAdapter, // 注入 IInstance.directory / worktree
113
- setAgentAdapter, // 注入 SubAgentRunner / LocalAgentRunner / triggerEvent
214
+ setAgentAdapter, // 注入 SkillsAgentAdapter (subAgentRunner / localAgentRunner / triggerEvent)
114
215
  getHomeDir,
115
216
  getXdgConfig,
116
217
  getXdgData,
@@ -135,19 +236,28 @@ setInstanceAdapter({
135
236
  });
136
237
  ```
137
238
 
138
- 未注入时,skills 包回退到 `xdg-basedir` + `homedir()`,保持与 v1 CLI 完全兼容。
239
+ 未注入时,skills 包回退到 `xdg-basedir` + `homedir()`,与 v1 独立 CLI 完全兼容。
139
240
 
140
241
  ## 数据目录约定
141
242
 
142
243
  | 路径 | 用途 |
143
244
  |---|---|
144
- | `${Global.Path.data}/skills/` | Agent 运行时加载的技能目录(运行时扫描) |
145
- | `${Global.Path.data}/state/skills/.skill-lock.json` | 全局安装锁定文件 |
146
- | `<cwd>/.agents/skills/` / `<cwd>/skills/` | 项目级技能目录 |
245
+ | `$Global.Path.data/skills/` | Agent 运行时加载的技能目录(运行时扫描) |
246
+ | `$Global.Path.data/skills/.skill-lock.json` | 全局安装锁定文件(与 store 同根) |
247
+ | `$Global.Path.data/skills/store/<sourceKey>/` | **store 物理目录**(按 sourceKey hash 归一化源;add 写一次,update 复用) |
248
+ | `$Global.Path.data/skills/store/index.json` | **store defs 索引**(key = skillName;记录 storeKey / type / url / skillPath / computedHash) |
249
+ | `$Global.Path.cache/skills/cache/<owner>/<repo>/` | **cache 物理**(remote 源下载/物化缓存;local 源 = 用户原目录) |
250
+ | `<cwd>/.agents/skills/` 或 `<cwd>/skills/` | 项目级技能目录 |
147
251
  | `<cwd>/skills-lock.json` | 项目级锁定文件 |
148
252
  | `<home>/.config/easbot/skills/` | XDG 配置兜底 |
149
253
 
150
- > 当被 `@easbot/agent` 委派时,所有路径会落到 `${Global.Path.data}` 这棵统一数据树下,与 Gateway / MCP / Session / Contact 等模块并列。
254
+ > 当被 `@easbot/agent` 委派时,所有路径落到 `{Global.Path.data}` 这颗统一数据树下,与 Gateway / MCP / Session / Contact 等模块并列。
255
+
256
+ ## 链接标头外部审核反馈(skills.sh)
257
+
258
+ `telemetry.ts` 会往回向 skills.sh 发送遥测 / 审计数据(可配置 `SKILLS_API_URL`),用于:
259
+ - skill 审计(`fetchAuditData` 返回技能级的 `PartnerAudit` 信息)
260
+ - 安全 gate 检查(`.dangerously-accept-openclaw-risks` flag 可跳过)
151
261
 
152
262
  ## 开发
153
263
 
@@ -155,13 +265,13 @@ setInstanceAdapter({
155
265
  # 安装依赖
156
266
  pnpm install
157
267
 
158
- # 构建(产出 dist/,同时生成 .d.ts)
268
+ # 构建(产出 dist/ + .d.ts)
159
269
  pnpm build
160
270
 
161
271
  # 监听构建
162
272
  pnpm dev
163
273
 
164
- # 测试(vitest,单跑某个文件:npx vitest run src/__tests__/xxx.test.ts
274
+ # 测试(vitest)
165
275
  pnpm test
166
276
  pnpm test:run
167
277
 
@@ -181,22 +291,22 @@ pnpm clean
181
291
 
182
292
  ```bash
183
293
  # Linux / macOS
184
- pnpm publish:npm # = bash scripts/publish.sh
294
+ bash scripts/publish.sh
185
295
 
186
296
  # Windows PowerShell
187
- pnpm publish:npm:win # = powershell -ExecutionPolicy Bypass -File scripts/publish.ps1
297
+ powershell -ExecutionPolicy Bypass -File scripts/publish.ps1
188
298
 
189
- # 手动等价
299
+ # 等价手动
190
300
  pnpm build
191
301
  pnpm publish --access public --git-checks false --registry https://registry.npmjs.org
192
302
  ```
193
303
 
194
304
  ## 浏览器 / 跨运行时说明
195
305
 
196
- - 内部使用 Node 内置模块(`fs/promises`、`node:os`、`node:path`、`node:child_process`),不能直接在浏览器运行。
197
- - 通过 `simple-git`、`@vercel/detect-agent`、`@clack/prompts`、`picocolors`、`xdg-basedir`、`zod`、`yaml` 等实现 GitHub 拉取、Agent 环境探测、交互问答、终端着色、XDG 解析与 frontmatter 校验。
198
- - `engines.node >= 22.22.3`,推荐 Node 22 LTS
306
+ - 使用 Node 内置模块(`fs/promises`、`node:os`、`node:path`、`node:child_process`),不能在浏览器运行。
307
+ - 依赖 `simple-git`、`@clack/prompts`、`picocolors`、`xdg-basedir`、`zod`、`yaml` 等。
308
+ - `engines.node >= 22.22.3` Node 22 LTS 推荐。
199
309
 
200
310
  ## 许可证
201
311
 
202
- MIT
312
+ MIT
@@ -0,0 +1 @@
1
+ export{d as BLOB_ALLOWED_OWNERS,c as BLOB_ALLOWED_REPOS,h as fetchGitHubMarketSnapshot,g as fetchRepoTree,j as fetchSkillFolderHash,k as findSkillMdPaths,i as getSkillFolderHashFromTree,f as resetRepoTreeAuthState,e as toSkillSlug,l as tryBlobInstall}from'./chunk-ROCFLAYZ.mjs';import'./chunk-ZYDDQV73.mjs';import'./chunk-WQGSYA5D.mjs';
@@ -0,0 +1 @@
1
+ 'use strict';var chunkRVR3DSD2_cjs=require('./chunk-RVR3DSD2.cjs');require('./chunk-E7AHWFZN.cjs'),require('./chunk-VRHWDHQV.cjs');Object.defineProperty(exports,"BLOB_ALLOWED_OWNERS",{enumerable:true,get:function(){return chunkRVR3DSD2_cjs.d}});Object.defineProperty(exports,"BLOB_ALLOWED_REPOS",{enumerable:true,get:function(){return chunkRVR3DSD2_cjs.c}});Object.defineProperty(exports,"fetchGitHubMarketSnapshot",{enumerable:true,get:function(){return chunkRVR3DSD2_cjs.h}});Object.defineProperty(exports,"fetchRepoTree",{enumerable:true,get:function(){return chunkRVR3DSD2_cjs.g}});Object.defineProperty(exports,"fetchSkillFolderHash",{enumerable:true,get:function(){return chunkRVR3DSD2_cjs.j}});Object.defineProperty(exports,"findSkillMdPaths",{enumerable:true,get:function(){return chunkRVR3DSD2_cjs.k}});Object.defineProperty(exports,"getSkillFolderHashFromTree",{enumerable:true,get:function(){return chunkRVR3DSD2_cjs.i}});Object.defineProperty(exports,"resetRepoTreeAuthState",{enumerable:true,get:function(){return chunkRVR3DSD2_cjs.f}});Object.defineProperty(exports,"toSkillSlug",{enumerable:true,get:function(){return chunkRVR3DSD2_cjs.e}});Object.defineProperty(exports,"tryBlobInstall",{enumerable:true,get:function(){return chunkRVR3DSD2_cjs.l}});
@@ -0,0 +1,5 @@
1
+ import {e,o,b,c}from'./chunk-ML6B4IQL.mjs';import {k,p,q}from'./chunk-RWZ4LFSN.mjs';import {a,b as b$1}from'./chunk-ZYDDQV73.mjs';import {mkdir,readdir,writeFile,readFile,cp,lstat,access,rm,realpath,readlink,symlink}from'fs/promises';import {existsSync}from'fs';import {join,basename,dirname,normalize,resolve,sep,relative,extname}from'path';import {homedir,platform}from'os';var V=".agents",X="skills",Se=".agents/skills";async function ge(t){try{return await b$1(t)}catch{return}}async function G(t,e,a,r,n={}){if(n.expectedMode&&n.agentType){let l=await ne(t,n.agentType,{global:a,cwd:r});if(!l.installed||l.mode!==n.expectedMode)return false}let i=await ge(e);if(!i)return false;let s;if(a){let{readSkillLock:l}=await import('./skill-lock-DZMA75MY.mjs');s=(await l()).skills[t]?.computedHash;}else {let{readLocalLock:l}=await import('./local-lock-AWD3LLEY.mjs');s=(await l(r)).skills[t]?.computedHash;}return s?s===i:false}function P(t){return t.toLowerCase().replace(/[^a-z0-9._]+/g,"-").replace(/^[.-]+|[.-]+$/g,"").substring(0,255)||"unnamed-skill"}function w(t,e){let a=normalize(resolve(t)),r=normalize(resolve(e));return r.startsWith(a+sep)||r===a}function Y(t,e){return w(t,e)||w(e,t)}function N(t,e){let a=t?k()||homedir():e||p()||process.cwd();return join(a,V,X)}function te(t,e$1){let a=e$1||p()||process.cwd();return join(a,e,P(t),"skills")}function D(t,e,a,r){if(o(t,e?"global":"project"))return N(e,a);if(t==="eve"&&r)return te(r,a);let n=b[t],i=k()||homedir(),s=e?i:a||p()||process.cwd();return e?n.globalSkillsDir===void 0?join(s,n.skillsDir):n.globalSkillsDir:join(s,n.skillsDir)}function he(t,e){return resolve(dirname(t),e)}async function S(t){try{await rm(t,{recursive:!0,force:!0});}catch{}await mkdir(t,{recursive:true});}async function j(t,e){try{let a=resolve(t),r=resolve(e),[n,i]=await Promise.all([realpath(a).catch(()=>a),realpath(r).catch(()=>r)]);if(n===i)return !0;let s=q(t),l=q(e);if(s===l)return !0;try{if((await lstat(e)).isSymbolicLink()){let d=await readlink(e);if(he(e,d)===a)return !0;await rm(e);}else await rm(e,{recursive:!0});}catch(k){if(k&&typeof k=="object"&&"code"in k&&k.code==="ELOOP")try{await rm(e,{force:!0});}catch{}}let u=dirname(e);await mkdir(u,{recursive:!0});let h=q(u),g=relative(h,t),f=platform()==="win32"?"junction":void 0;return await symlink(f==="junction"?a:g,e,f),!0}catch{return false}}async function Me(t,e,a={}){let r=b[e],n=a.global??false,i=a.cwd||process.cwd(),s=a.eveSubagent;if(n&&r.globalSkillsDir===void 0)return {success:false,path:"",mode:a.mode??"symlink",error:`${r.displayName} does not support global skill installation`};let l=t.name||basename(t.path),u=P(l),h=a.mode??"symlink",f=e==="eve"&&h==="symlink"?D(e,n,i,s):N(n,i),o$1=join(f,u),k=D(e,n,i,s),d=join(k,P(t.name||basename(t.path))),c=q(d),m=q(o$1);if(!w(f,o$1))return {success:false,path:d,mode:h,error:"Invalid skill name: potential path traversal detected"};if(!w(k,d))return {success:false,path:d,mode:h,error:"Invalid skill name: potential path traversal detected"};try{if(Y(t.path,c))return {success:!0,path:c,mode:h,skipped:!0};if(h==="copy")return await G(u,t.path,n,i,{expectedMode:"copy",agentType:e})&&existsSync(c)?{success:!0,path:c,canonicalPath:m,mode:"copy",skipped:!0,skippedReason:"up-to-date"}:(await S(c),await R(t.path,c,e),{success:!0,path:c,canonicalPath:m,mode:"copy"});if(Y(t.path,c))return {success:!0,path:c,canonicalPath:m,mode:"symlink",skipped:!0};if(await G(u,t.path,n,i)&&existsSync(m)||(await S(m),await R(t.path,m,e)),!n&&o(e,"project"))return {success:!0,path:m,canonicalPath:m,mode:"copy"};if(n&&o(e,"global"))return {success:!0,path:m,canonicalPath:m,mode:"symlink"};if(!n){let z=join(i,b[e].skillsDir.split("/")[0]);if(!existsSync(z))return {success:!0,path:m,canonicalPath:m,mode:"symlink",skipped:!0}}return o$1===d?{success:!0,path:d,canonicalPath:o$1,mode:"copy"}:await j(t.path,c)?{success:!0,path:c,canonicalPath:m,mode:"symlink"}:await G(u,t.path,n,i,{expectedMode:"copy",agentType:e})&&existsSync(c)?{success:!0,path:c,canonicalPath:m,mode:"symlink",skipped:!0,skippedReason:"up-to-date"}:(await S(c),await R(t.path,c,e),{success:!0,path:c,canonicalPath:m,mode:"symlink",symlinkFailed:!0})}catch(b){return {success:false,path:c,mode:h,error:b instanceof Error?b.message:"Unknown error"}}}async function je(t,e,a={}){let{isGlobal:r=false,agentType:n,cwd:i,storePath:s}=a,l=q(t),u=q(e);if(l===u)return {success:true,path:u,canonicalPath:t,mode:"copy"};if(!r&&n&&i&&!o(n,"project")){let f=join(i,b[n].skillsDir.split("/")[0]);if(!existsSync(f))return {success:true,path:e,canonicalPath:t,mode:"symlink",skipped:true}}let h=s?q(s):l;return await j(h,u)?{success:true,path:e,canonicalPath:t,mode:"symlink"}:{success:true,path:e,canonicalPath:t,mode:"symlink",symlinkFailed:true}}async function _e(t,e,a={}){let{agentType:r="easbot"}=a,n=q(t),i=q(e);if(n===i)return {success:true,path:i,canonicalPath:t,mode:"copy"};try{return await S(i),await R(n,i,r),{success:!0,path:i,canonicalPath:t,mode:"copy"}}catch(s){return {success:false,path:e,mode:"copy",error:s instanceof Error?s.message:"Unknown error"}}}var ke=new Set(["metadata.json"]),we=new Set([".git","__pycache__","__pypackages__"]),ye=(t,e=false)=>!!(ke.has(t)||e&&we.has(t));function L(t){let{data:e,content:a$1}=a(t),r={};if(typeof e.description=="string"&&(r.description=e.description),typeof e.license=="string"&&(r.license=e.license),e.metadata&&typeof e.metadata=="object"&&!Array.isArray(e.metadata)){let s=Object.fromEntries(Object.entries(e.metadata).filter(l=>typeof l[1]=="string"));Object.keys(s).length>0&&(r.metadata=s);}let n=Object.keys(r);return n.length===0?a$1.replace(/^\r?\n/u,""):`---
2
+ ${n.map(s=>`${s}: ${JSON.stringify(r[s])}`).join(`
3
+ `)}
4
+ ---
5
+ ${a$1.replace(/^\r?\n/u,"")}`}async function R(t,e,a){await mkdir(e,{recursive:true});let r=await readdir(t,{withFileTypes:true});await Promise.all(r.filter(n=>!ye(n.name,n.isDirectory())).map(async n=>{let i=join(t,n.name),s=join(e,n.name);if(n.isDirectory())await R(i,s,a);else try{if(a==="eve"&&n.name.toLowerCase()==="skill.md"){await writeFile(s,L(await readFile(i,"utf-8")));return}await cp(i,s,{dereference:!0,recursive:!0});}catch(l){if(l instanceof Error&&"code"in l&&l.code==="ENOENT"&&n.isSymbolicLink())console.warn(`Skipping broken symlink: ${i}`);else throw l}}));}function be(t){return t.some(e=>basename(e.path).toLowerCase()==="skill.md")}function U(t){return `${P(t)}.md`}function ve(t){let e=t.find(r=>basename(r.path).toLowerCase()==="skill.md");if(e)return L(e.contents);let a=t.find(r=>extname(r.path).toLowerCase()===".md");return a?L(a.contents):""}async function Ue(t,e,a={}){return (await ne(t,e,a)).installed}async function ne(t,e,a={}){let r=b[e],n=P(t);if(a.global&&r.globalSkillsDir===void 0)return {installed:false,mode:null,path:""};let i=a.global?r.globalSkillsDir:e==="eve"&&a.eveSubagent?te(a.eveSubagent,a.cwd):join(a.cwd||process.cwd(),r.skillsDir),s=join(i,n);if(!w(i,s))return {installed:false,mode:null,path:""};try{let l=await lstat(s);return l.isSymbolicLink()?{installed:!0,mode:"symlink",path:s}:l.isDirectory()?{installed:!0,mode:"copy",path:s}:{installed:!1,mode:null,path:s}}catch{return {installed:false,mode:null,path:s}}}function Be(t,e,a={}){let r=P(t),n=D(e,a.global??false,a.cwd,a.eveSubagent),i=join(n,r);if(!w(n,i))throw new Error("Invalid skill name: potential path traversal detected");return i}async function O(t,e){try{return await access(join(t,"SKILL.md")),{created:!1}}catch{}return await mkdir(t,{recursive:true}),await e(t),{created:true}}function $e(t,e={}){let a=P(t),r=e.agent==="eve"?D("eve",e.global??false,e.cwd,e.eveSubagent):N(e.global??false,e.cwd),n=join(r,a);if(!w(r,n))throw new Error("Invalid skill name: potential path traversal detected");return n}async function ze(t,e,a={}){let r=b[e],n=a.global??false,i=a.cwd||process.cwd(),s=a.mode??"symlink",l=a.eveSubagent;if(n&&r.globalSkillsDir===void 0)return {success:false,path:"",mode:s,error:`${r.displayName} does not support global skill installation`};let u=P(t.installName),h=e==="eve"&&s==="symlink"?D(e,n,i,l):N(n,i),g=join(h,u),f=D(e,n,i,l),o$1=join(f,u);if(!w(h,g))return {success:false,path:o$1,mode:s,error:"Invalid skill name: potential path traversal detected"};if(!w(f,o$1))return {success:false,path:o$1,mode:s,error:"Invalid skill name: potential path traversal detected"};try{if(s==="copy"){await S(o$1);let c=e==="eve"?U(t.installName):"SKILL.md",m=join(o$1,c);return await writeFile(m,e==="eve"?L(t.content):t.content,"utf-8"),{success:!0,path:o$1,mode:"copy"}}let k=e==="eve"?U(t.installName):"SKILL.md";if(await O(g,async c=>{let m=join(c,k);await writeFile(m,e==="eve"?L(t.content):t.content,"utf-8");}),n&&o(e,"global"))return {success:!0,path:g,canonicalPath:g,mode:"symlink"};if(!await j(g,o$1)){await S(o$1);let c=e==="eve"?U(t.installName):"SKILL.md",m=join(o$1,c);return await writeFile(m,e==="eve"?L(t.content):t.content,"utf-8"),{success:!0,path:o$1,canonicalPath:g,mode:"symlink",symlinkFailed:!0}}return {success:!0,path:o$1,canonicalPath:g,mode:"symlink"}}catch(k){return {success:false,path:o$1,mode:s,error:k instanceof Error?k.message:"Unknown error"}}}async function Ke(t,e,a={}){let r=b[e],n=a.global??false,i=a.cwd||process.cwd(),s=a.mode??"symlink",l=a.eveSubagent;if(n&&r.globalSkillsDir===void 0)return {success:false,path:"",mode:s,error:`${r.displayName} does not support global skill installation`};let u=P(t.installName),h=e==="eve"&&s==="symlink"?D(e,n,i,l):N(n,i),g=join(h,u),f=D(e,n,i,l),o$1=join(f,u);if(!w(h,g))return {success:false,path:o$1,mode:s,error:"Invalid skill name: potential path traversal detected"};if(!w(f,o$1))return {success:false,path:o$1,mode:s,error:"Invalid skill name: potential path traversal detected"};async function k(d){for(let[c,m]of t.files){let b=join(d,c);if(!w(d,b))continue;let $=dirname(b);$!==d&&await mkdir($,{recursive:true}),await writeFile(b,e==="eve"&&basename(c).toLowerCase()==="skill.md"&&typeof m=="string"?L(m):m);}}try{return s==="copy"?(await S(o$1),await k(o$1),{success:!0,path:o$1,mode:"copy"}):(await O(g,k),n&&o(e,"global")?{success:!0,path:g,canonicalPath:g,mode:"symlink"}:await j(g,o$1)?{success:!0,path:o$1,canonicalPath:g,mode:"symlink"}:(await S(o$1),await k(o$1),{success:!0,path:o$1,canonicalPath:g,mode:"symlink",symlinkFailed:!0}))}catch(d){return {success:false,path:o$1,mode:s,error:d instanceof Error?d.message:"Unknown error"}}}async function Ge(t,e,a={}){let r=b[e],n=a.global??false,i=a.cwd||process.cwd(),s=a.mode??"symlink",l=a.eveSubagent;if(n&&r.globalSkillsDir===void 0)return {success:false,path:"",mode:s,error:`${r.displayName} does not support global skill installation`};let u=P(t.installName),h=D(e,n,i,l);if(e==="eve"&&!be(t.files)){let d=join(h,U(t.installName));if(!w(h,d))return {success:false,path:d,mode:s,error:"Invalid skill name: potential path traversal detected"};try{return await mkdir(h,{recursive:!0}),await rm(d,{recursive:!0,force:!0}),await writeFile(d,ve(t.files),"utf-8"),{success:!0,path:d,mode:"copy"}}catch(c){return {success:false,path:d,mode:s,error:c instanceof Error?c.message:"Unknown error"}}}let g=e==="eve"&&s==="symlink"?D(e,n,i,l):N(n,i),f=join(g,u),o$1=join(h,u);if(!w(g,f))return {success:false,path:o$1,mode:s,error:"Invalid skill name: potential path traversal detected"};if(!w(h,o$1))return {success:false,path:o$1,mode:s,error:"Invalid skill name: potential path traversal detected"};async function k(d){for(let c of t.files){let m=join(d,c.path);if(!w(d,m))continue;let b=dirname(m);b!==d&&await mkdir(b,{recursive:true}),await writeFile(m,e==="eve"&&basename(c.path).toLowerCase()==="skill.md"?L(c.contents):c.contents,"utf-8");}}try{if(s==="copy")return await S(o$1),await k(o$1),{success:!0,path:o$1,mode:"copy"};if(await O(f,k),n&&o(e,"global"))return {success:!0,path:f,canonicalPath:f,mode:"symlink"};if(!n&&!o(e,"project")){let c=join(i,b[e].skillsDir.split("/")[0]);if(!existsSync(c))return {success:!0,path:f,canonicalPath:f,mode:"symlink",skipped:!0}}return await j(f,o$1)?{success:!0,path:o$1,canonicalPath:f,mode:"symlink"}:(await S(o$1),await k(o$1),{success:!0,path:o$1,canonicalPath:f,mode:"symlink",symlinkFailed:!0})}catch(d){return {success:false,path:o$1,mode:s,error:d instanceof Error?d.message:"Unknown error"}}}async function Oe(t={}){let e=t.cwd||process.cwd(),{scanInstalledSkillDirs:a}=await import('./scan-WAXGJM5N.mjs'),r=t.agentFilter?null:await c(),n=t.agentFilter??r??void 0,i=await a({scope:t.scope,cwd:e,agentFilter:n}),s=u=>u.replace(/\\/g,"/").replace(/\/[^/]+\/?$/,"").replace(/\/+$/,""),l=new Map;for(let u of i){let h=s(u.skillDir),g=`${u.scope}::${h}::${u.name}`,f=l.get(g);if(f){for(let o of u.agents)f.agents.includes(o)||f.agents.push(o);continue}l.set(g,{name:u.name,description:"",path:u.skillDir,canonicalPath:u.skillDir,scope:u.scope,agents:[...u.agents]});}return Array.from(l.values())}export{V as a,X as b,Se as c,P as d,N as e,te as f,D as g,Me as h,je as i,_e as j,Ue as k,ne as l,Be as m,O as n,$e as o,ze as p,Ke as q,Ge as r,Oe as s};
@@ -0,0 +1,5 @@
1
+ 'use strict';var chunkISMGLHYS_cjs=require('./chunk-ISMGLHYS.cjs'),chunkXGUPIAAF_cjs=require('./chunk-XGUPIAAF.cjs'),chunkE7AHWFZN_cjs=require('./chunk-E7AHWFZN.cjs'),promises=require('fs/promises'),fs=require('fs'),path=require('path'),os=require('os');var V=".agents",X="skills",ve=".agents/skills";async function fe(t){try{return await chunkE7AHWFZN_cjs.b(t)}catch{return}}async function G(t,e,a,r,n={}){if(n.expectedMode&&n.agentType){let l=await ne(t,n.agentType,{global:a,cwd:r});if(!l.installed||l.mode!==n.expectedMode)return false}let i=await fe(e);if(!i)return false;let s;if(a){let{readSkillLock:l}=await import('./skill-lock-XTWQYBRG.cjs');s=(await l()).skills[t]?.computedHash;}else {let{readLocalLock:l}=await import('./local-lock-GIZDVF3X.cjs');s=(await l(r)).skills[t]?.computedHash;}return s?s===i:false}function P(t){return t.toLowerCase().replace(/[^a-z0-9._]+/g,"-").replace(/^[.-]+|[.-]+$/g,"").substring(0,255)||"unnamed-skill"}function w(t,e){let a=path.normalize(path.resolve(t)),r=path.normalize(path.resolve(e));return r.startsWith(a+path.sep)||r===a}function Y(t,e){return w(t,e)||w(e,t)}function N(t,e){let a=t?chunkXGUPIAAF_cjs.k()||os.homedir():e||chunkXGUPIAAF_cjs.p()||process.cwd();return path.join(a,V,X)}function te(t,e){let a=e||chunkXGUPIAAF_cjs.p()||process.cwd();return path.join(a,chunkISMGLHYS_cjs.e,P(t),"skills")}function D(t,e,a,r){if(chunkISMGLHYS_cjs.o(t,e?"global":"project"))return N(e,a);if(t==="eve"&&r)return te(r,a);let n=chunkISMGLHYS_cjs.b[t],i=chunkXGUPIAAF_cjs.k()||os.homedir(),s=e?i:a||chunkXGUPIAAF_cjs.p()||process.cwd();return e?n.globalSkillsDir===void 0?path.join(s,n.skillsDir):n.globalSkillsDir:path.join(s,n.skillsDir)}function ge(t,e){return path.resolve(path.dirname(t),e)}async function S(t){try{await promises.rm(t,{recursive:!0,force:!0});}catch{}await promises.mkdir(t,{recursive:true});}async function j(t,e){try{let a=path.resolve(t),r=path.resolve(e),[n,i]=await Promise.all([promises.realpath(a).catch(()=>a),promises.realpath(r).catch(()=>r)]);if(n===i)return !0;let s=chunkXGUPIAAF_cjs.q(t),l=chunkXGUPIAAF_cjs.q(e);if(s===l)return !0;try{if((await promises.lstat(e)).isSymbolicLink()){let d=await promises.readlink(e);if(ge(e,d)===a)return !0;await promises.rm(e);}else await promises.rm(e,{recursive:!0});}catch(k){if(k&&typeof k=="object"&&"code"in k&&k.code==="ELOOP")try{await promises.rm(e,{force:!0});}catch{}}let u=path.dirname(e);await promises.mkdir(u,{recursive:!0});let h=chunkXGUPIAAF_cjs.q(u),g=path.relative(h,t),f=os.platform()==="win32"?"junction":void 0;return await promises.symlink(f==="junction"?a:g,e,f),!0}catch{return false}}async function Re(t,e,a={}){let r=chunkISMGLHYS_cjs.b[e],n=a.global??false,i=a.cwd||process.cwd(),s=a.eveSubagent;if(n&&r.globalSkillsDir===void 0)return {success:false,path:"",mode:a.mode??"symlink",error:`${r.displayName} does not support global skill installation`};let l=t.name||path.basename(t.path),u=P(l),h=a.mode??"symlink",f=e==="eve"&&h==="symlink"?D(e,n,i,s):N(n,i),o=path.join(f,u),k=D(e,n,i,s),d=path.join(k,P(t.name||path.basename(t.path))),c=chunkXGUPIAAF_cjs.q(d),m=chunkXGUPIAAF_cjs.q(o);if(!w(f,o))return {success:false,path:d,mode:h,error:"Invalid skill name: potential path traversal detected"};if(!w(k,d))return {success:false,path:d,mode:h,error:"Invalid skill name: potential path traversal detected"};try{if(Y(t.path,c))return {success:!0,path:c,mode:h,skipped:!0};if(h==="copy")return await G(u,t.path,n,i,{expectedMode:"copy",agentType:e})&&fs.existsSync(c)?{success:!0,path:c,canonicalPath:m,mode:"copy",skipped:!0,skippedReason:"up-to-date"}:(await S(c),await R(t.path,c,e),{success:!0,path:c,canonicalPath:m,mode:"copy"});if(Y(t.path,c))return {success:!0,path:c,canonicalPath:m,mode:"symlink",skipped:!0};if(await G(u,t.path,n,i)&&fs.existsSync(m)||(await S(m),await R(t.path,m,e)),!n&&chunkISMGLHYS_cjs.o(e,"project"))return {success:!0,path:m,canonicalPath:m,mode:"copy"};if(n&&chunkISMGLHYS_cjs.o(e,"global"))return {success:!0,path:m,canonicalPath:m,mode:"symlink"};if(!n){let z=path.join(i,chunkISMGLHYS_cjs.b[e].skillsDir.split("/")[0]);if(!fs.existsSync(z))return {success:!0,path:m,canonicalPath:m,mode:"symlink",skipped:!0}}return o===d?{success:!0,path:d,canonicalPath:o,mode:"copy"}:await j(t.path,c)?{success:!0,path:c,canonicalPath:m,mode:"symlink"}:await G(u,t.path,n,i,{expectedMode:"copy",agentType:e})&&fs.existsSync(c)?{success:!0,path:c,canonicalPath:m,mode:"symlink",skipped:!0,skippedReason:"up-to-date"}:(await S(c),await R(t.path,c,e),{success:!0,path:c,canonicalPath:m,mode:"symlink",symlinkFailed:!0})}catch(b){return {success:false,path:c,mode:h,error:b instanceof Error?b.message:"Unknown error"}}}async function Me(t,e,a={}){let{isGlobal:r=false,agentType:n,cwd:i,storePath:s}=a,l=chunkXGUPIAAF_cjs.q(t),u=chunkXGUPIAAF_cjs.q(e);if(l===u)return {success:true,path:u,canonicalPath:t,mode:"copy"};if(!r&&n&&i&&!chunkISMGLHYS_cjs.o(n,"project")){let f=path.join(i,chunkISMGLHYS_cjs.b[n].skillsDir.split("/")[0]);if(!fs.existsSync(f))return {success:true,path:e,canonicalPath:t,mode:"symlink",skipped:true}}let h=s?chunkXGUPIAAF_cjs.q(s):l;return await j(h,u)?{success:true,path:e,canonicalPath:t,mode:"symlink"}:{success:true,path:e,canonicalPath:t,mode:"symlink",symlinkFailed:true}}async function je(t,e,a={}){let{agentType:r="easbot"}=a,n=chunkXGUPIAAF_cjs.q(t),i=chunkXGUPIAAF_cjs.q(e);if(n===i)return {success:true,path:i,canonicalPath:t,mode:"copy"};try{return await S(i),await R(n,i,r),{success:!0,path:i,canonicalPath:t,mode:"copy"}}catch(s){return {success:false,path:e,mode:"copy",error:s instanceof Error?s.message:"Unknown error"}}}var he=new Set(["metadata.json"]),ke=new Set([".git","__pycache__","__pypackages__"]),we=(t,e=false)=>!!(he.has(t)||e&&ke.has(t));function L(t){let{data:e,content:a}=chunkE7AHWFZN_cjs.a(t),r={};if(typeof e.description=="string"&&(r.description=e.description),typeof e.license=="string"&&(r.license=e.license),e.metadata&&typeof e.metadata=="object"&&!Array.isArray(e.metadata)){let s=Object.fromEntries(Object.entries(e.metadata).filter(l=>typeof l[1]=="string"));Object.keys(s).length>0&&(r.metadata=s);}let n=Object.keys(r);return n.length===0?a.replace(/^\r?\n/u,""):`---
2
+ ${n.map(s=>`${s}: ${JSON.stringify(r[s])}`).join(`
3
+ `)}
4
+ ---
5
+ ${a.replace(/^\r?\n/u,"")}`}async function R(t,e,a){await promises.mkdir(e,{recursive:true});let r=await promises.readdir(t,{withFileTypes:true});await Promise.all(r.filter(n=>!we(n.name,n.isDirectory())).map(async n=>{let i=path.join(t,n.name),s=path.join(e,n.name);if(n.isDirectory())await R(i,s,a);else try{if(a==="eve"&&n.name.toLowerCase()==="skill.md"){await promises.writeFile(s,L(await promises.readFile(i,"utf-8")));return}await promises.cp(i,s,{dereference:!0,recursive:!0});}catch(l){if(l instanceof Error&&"code"in l&&l.code==="ENOENT"&&n.isSymbolicLink())console.warn(`Skipping broken symlink: ${i}`);else throw l}}));}function ye(t){return t.some(e=>path.basename(e.path).toLowerCase()==="skill.md")}function U(t){return `${P(t)}.md`}function be(t){let e=t.find(r=>path.basename(r.path).toLowerCase()==="skill.md");if(e)return L(e.contents);let a=t.find(r=>path.extname(r.path).toLowerCase()===".md");return a?L(a.contents):""}async function _e(t,e,a={}){return (await ne(t,e,a)).installed}async function ne(t,e,a={}){let r=chunkISMGLHYS_cjs.b[e],n=P(t);if(a.global&&r.globalSkillsDir===void 0)return {installed:false,mode:null,path:""};let i=a.global?r.globalSkillsDir:e==="eve"&&a.eveSubagent?te(a.eveSubagent,a.cwd):path.join(a.cwd||process.cwd(),r.skillsDir),s=path.join(i,n);if(!w(i,s))return {installed:false,mode:null,path:""};try{let l=await promises.lstat(s);return l.isSymbolicLink()?{installed:!0,mode:"symlink",path:s}:l.isDirectory()?{installed:!0,mode:"copy",path:s}:{installed:!1,mode:null,path:s}}catch{return {installed:false,mode:null,path:s}}}function Ue(t,e,a={}){let r=P(t),n=D(e,a.global??false,a.cwd,a.eveSubagent),i=path.join(n,r);if(!w(n,i))throw new Error("Invalid skill name: potential path traversal detected");return i}async function O(t,e){try{return await promises.access(path.join(t,"SKILL.md")),{created:!1}}catch{}return await promises.mkdir(t,{recursive:true}),await e(t),{created:true}}function Be(t,e={}){let a=P(t),r=e.agent==="eve"?D("eve",e.global??false,e.cwd,e.eveSubagent):N(e.global??false,e.cwd),n=path.join(r,a);if(!w(r,n))throw new Error("Invalid skill name: potential path traversal detected");return n}async function $e(t,e,a={}){let r=chunkISMGLHYS_cjs.b[e],n=a.global??false,i=a.cwd||process.cwd(),s=a.mode??"symlink",l=a.eveSubagent;if(n&&r.globalSkillsDir===void 0)return {success:false,path:"",mode:s,error:`${r.displayName} does not support global skill installation`};let u=P(t.installName),h=e==="eve"&&s==="symlink"?D(e,n,i,l):N(n,i),g=path.join(h,u),f=D(e,n,i,l),o=path.join(f,u);if(!w(h,g))return {success:false,path:o,mode:s,error:"Invalid skill name: potential path traversal detected"};if(!w(f,o))return {success:false,path:o,mode:s,error:"Invalid skill name: potential path traversal detected"};try{if(s==="copy"){await S(o);let c=e==="eve"?U(t.installName):"SKILL.md",m=path.join(o,c);return await promises.writeFile(m,e==="eve"?L(t.content):t.content,"utf-8"),{success:!0,path:o,mode:"copy"}}let k=e==="eve"?U(t.installName):"SKILL.md";if(await O(g,async c=>{let m=path.join(c,k);await promises.writeFile(m,e==="eve"?L(t.content):t.content,"utf-8");}),n&&chunkISMGLHYS_cjs.o(e,"global"))return {success:!0,path:g,canonicalPath:g,mode:"symlink"};if(!await j(g,o)){await S(o);let c=e==="eve"?U(t.installName):"SKILL.md",m=path.join(o,c);return await promises.writeFile(m,e==="eve"?L(t.content):t.content,"utf-8"),{success:!0,path:o,canonicalPath:g,mode:"symlink",symlinkFailed:!0}}return {success:!0,path:o,canonicalPath:g,mode:"symlink"}}catch(k){return {success:false,path:o,mode:s,error:k instanceof Error?k.message:"Unknown error"}}}async function ze(t,e,a={}){let r=chunkISMGLHYS_cjs.b[e],n=a.global??false,i=a.cwd||process.cwd(),s=a.mode??"symlink",l=a.eveSubagent;if(n&&r.globalSkillsDir===void 0)return {success:false,path:"",mode:s,error:`${r.displayName} does not support global skill installation`};let u=P(t.installName),h=e==="eve"&&s==="symlink"?D(e,n,i,l):N(n,i),g=path.join(h,u),f=D(e,n,i,l),o=path.join(f,u);if(!w(h,g))return {success:false,path:o,mode:s,error:"Invalid skill name: potential path traversal detected"};if(!w(f,o))return {success:false,path:o,mode:s,error:"Invalid skill name: potential path traversal detected"};async function k(d){for(let[c,m]of t.files){let b=path.join(d,c);if(!w(d,b))continue;let $=path.dirname(b);$!==d&&await promises.mkdir($,{recursive:true}),await promises.writeFile(b,e==="eve"&&path.basename(c).toLowerCase()==="skill.md"&&typeof m=="string"?L(m):m);}}try{return s==="copy"?(await S(o),await k(o),{success:!0,path:o,mode:"copy"}):(await O(g,k),n&&chunkISMGLHYS_cjs.o(e,"global")?{success:!0,path:g,canonicalPath:g,mode:"symlink"}:await j(g,o)?{success:!0,path:o,canonicalPath:g,mode:"symlink"}:(await S(o),await k(o),{success:!0,path:o,canonicalPath:g,mode:"symlink",symlinkFailed:!0}))}catch(d){return {success:false,path:o,mode:s,error:d instanceof Error?d.message:"Unknown error"}}}async function Ke(t,e,a={}){let r=chunkISMGLHYS_cjs.b[e],n=a.global??false,i=a.cwd||process.cwd(),s=a.mode??"symlink",l=a.eveSubagent;if(n&&r.globalSkillsDir===void 0)return {success:false,path:"",mode:s,error:`${r.displayName} does not support global skill installation`};let u=P(t.installName),h=D(e,n,i,l);if(e==="eve"&&!ye(t.files)){let d=path.join(h,U(t.installName));if(!w(h,d))return {success:false,path:d,mode:s,error:"Invalid skill name: potential path traversal detected"};try{return await promises.mkdir(h,{recursive:!0}),await promises.rm(d,{recursive:!0,force:!0}),await promises.writeFile(d,be(t.files),"utf-8"),{success:!0,path:d,mode:"copy"}}catch(c){return {success:false,path:d,mode:s,error:c instanceof Error?c.message:"Unknown error"}}}let g=e==="eve"&&s==="symlink"?D(e,n,i,l):N(n,i),f=path.join(g,u),o=path.join(h,u);if(!w(g,f))return {success:false,path:o,mode:s,error:"Invalid skill name: potential path traversal detected"};if(!w(h,o))return {success:false,path:o,mode:s,error:"Invalid skill name: potential path traversal detected"};async function k(d){for(let c of t.files){let m=path.join(d,c.path);if(!w(d,m))continue;let b=path.dirname(m);b!==d&&await promises.mkdir(b,{recursive:true}),await promises.writeFile(m,e==="eve"&&path.basename(c.path).toLowerCase()==="skill.md"?L(c.contents):c.contents,"utf-8");}}try{if(s==="copy")return await S(o),await k(o),{success:!0,path:o,mode:"copy"};if(await O(f,k),n&&chunkISMGLHYS_cjs.o(e,"global"))return {success:!0,path:f,canonicalPath:f,mode:"symlink"};if(!n&&!chunkISMGLHYS_cjs.o(e,"project")){let c=path.join(i,chunkISMGLHYS_cjs.b[e].skillsDir.split("/")[0]);if(!fs.existsSync(c))return {success:!0,path:f,canonicalPath:f,mode:"symlink",skipped:!0}}return await j(f,o)?{success:!0,path:o,canonicalPath:f,mode:"symlink"}:(await S(o),await k(o),{success:!0,path:o,canonicalPath:f,mode:"symlink",symlinkFailed:!0})}catch(d){return {success:false,path:o,mode:s,error:d instanceof Error?d.message:"Unknown error"}}}async function Ge(t={}){let e=t.cwd||process.cwd(),{scanInstalledSkillDirs:a}=await import('./scan-57D2H7LP.cjs'),r=t.agentFilter?null:await chunkISMGLHYS_cjs.c(),n=t.agentFilter??r??void 0,i=await a({scope:t.scope,cwd:e,agentFilter:n}),s=u=>u.replace(/\\/g,"/").replace(/\/[^/]+\/?$/,"").replace(/\/+$/,""),l=new Map;for(let u of i){let h=s(u.skillDir),g=`${u.scope}::${h}::${u.name}`,f=l.get(g);if(f){for(let o of u.agents)f.agents.includes(o)||f.agents.push(o);continue}l.set(g,{name:u.name,description:"",path:u.skillDir,canonicalPath:u.skillDir,scope:u.scope,agents:[...u.agents]});}return Array.from(l.values())}exports.a=V;exports.b=X;exports.c=ve;exports.d=P;exports.e=N;exports.f=te;exports.g=D;exports.h=Re;exports.i=Me;exports.j=je;exports.k=_e;exports.l=ne;exports.m=Ue;exports.n=O;exports.o=Be;exports.p=$e;exports.q=ze;exports.r=Ke;exports.s=Ge;
@@ -0,0 +1,22 @@
1
+ import {k}from'./chunk-ML6B4IQL.mjs';import {p,m as m$1,o}from'./chunk-RWZ4LFSN.mjs';import {b as b$1,c,d as d$1,l}from'./chunk-ROCFLAYZ.mjs';import {a,d,b as b$2}from'./chunk-ZYDDQV73.mjs';import {b}from'./chunk-WQGSYA5D.mjs';import {rm,mkdtemp,readFile,rename,mkdir,writeFile,rmdir,cp,readdir,stat}from'fs/promises';import {dirname,join,normalize,resolve,sep,basename,relative,isAbsolute}from'path';import {createHash}from'crypto';import {existsSync}from'fs';import he from'simple-git';import {Filesystem,Glob,Wildcard}from'@easbot/utils';import {tmpdir}from'os';import {execFile}from'child_process';import {promisify}from'util';import {gunzipSync,inflateRawSync}from'zlib';var N=6;function pe(n){let t=n.indexOf(":");return t<0||t===n.length-1?null:{marketId:n.slice(0,t),pluginSlug:n.slice(t+1)}}function de(n){let t=pe(n);return t?`plugins/${t.pluginSlug}`:null}function vt(n,t,e){if(!n.marketId||!n.pluginId)return null;let r=de(n.pluginId);return r?`${t.replace(/\\/g,"/").replace(/\/+$/,"")}/${n.marketId}/${r}/${e}`:null}var At=3e5,nt=(()=>{let n=process.env.SKILLS_CLONE_TIMEOUT;if(!n)return At;let t=Number.parseInt(n,10);return Number.isFinite(t)&&t>0?t:At})(),Wt=promisify(execFile),L=class extends Error{constructor(e,r,s=false,i=false){super(e);b(this,"url");b(this,"isTimeout");b(this,"isAuthError");this.name="GitCloneError",this.url=r,this.isTimeout=s,this.isAuthError=i;}};function be(n){let t=n.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/i);if(t){let e=t[1],r=t[2];return {owner:e,repo:r,slug:`${e}/${r}`,sshUrl:`git@github.com:${e}/${r}.git`}}try{let e=new URL(n);if(e.hostname!=="github.com")return null;let r=e.pathname.match(/^\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/);if(!r)return null;let s=r[1],i=r[2];return {owner:s,repo:i,slug:`${s}/${i}`,sshUrl:`git@github.com:${s}/${i}.git`}}catch{return null}}function Pe(n){try{let t=new URL(n);return t.protocol==="https:"&&t.hostname==="github.com"}catch{return false}}function Ut(n){let t=n.toLowerCase();return t.includes("saml sso")||t.includes("enforced sso")||t.includes("enabled or enforced saml")||t.includes("re-authorize the oauth application")}function Le(n){return n.includes("Authentication failed")||n.includes("could not read Username")||n.includes("Permission denied")||n.includes("Repository not found")||n.includes("requested URL returned error: 403")||Ut(n)}function et(n){let t={...process.env};return delete t.GIT_ASKPASS,delete t.GIT_EDITOR,delete t.GIT_SEQUENCE_EDITOR,delete t.GIT_PAGER,delete t.GIT_SSH_COMMAND,delete t.GIT_CONFIG_GLOBAL,delete t.GIT_CONFIG_SYSTEM,delete t.PAGER,delete t.EDITOR,delete t.VISUAL,t.GIT_TERMINAL_PROMPT="0",t.GIT_LFS_SKIP_SMUDGE="1",Object.assign(t,n),he({timeout:{block:nt},config:["filter.lfs.required=false","protocol.version=2","remote.origin.promisor=false"]}).env(t)}async function Kt(n){try{await rm(n,{recursive:!0,force:!0});}catch{}await mkdir(n,{recursive:true});}async function Ie(n,t,e){let r=n.slug;try{let{stdout:i,stderr:o}=await Wt("gh",["auth","status","-h","github.com"],{timeout:5e3,env:{...process.env,GIT_TERMINAL_PROMPT:"0"}}),l=`${i}${o}`;/Git operations protocol:\s+ssh/i.test(l)&&(r=n.sshUrl);}catch{return false}return await Wt("gh",["repo","clone",r,t,"--",...e?["--depth=1","--branch",e]:["--depth=1"]],{timeout:nt,env:{...process.env,GIT_TERMINAL_PROMPT:"0"}}),true}function ve(n,t,e){return t&&Ut(e)?`GitHub blocked HTTPS access to ${n} because the organization enforces SAML SSO.
2
+ skills tried your existing git credentials and available fallbacks, but none succeeded.
3
+ - Re-authorize your GitHub credentials/app for that org's SSO policy
4
+ - Or rerun with SSH: easbot skills add ${t.sshUrl}
5
+ - Verify access with: gh auth status -h github.com or ssh -T git@github.com`:t?`Authentication failed for ${n}.
6
+ - For private repos, ensure you have access
7
+ - Retry with SSH: easbot skills add ${t.sshUrl}
8
+ - Check access with: gh auth status -h github.com or ssh -T git@github.com`:`Authentication failed for ${n}.
9
+ - For private repos, ensure you have access
10
+ - For SSH: Check your keys with 'ssh -T git@github.com'
11
+ - For HTTPS: Run 'gh auth login' or configure git credentials`}async function Dt(n,t,e){if(e){await Filesystem.mkdir(dirname(e),{recursive:true});let o=t?["--depth","1","--branch",t]:["--depth","1"];try{return await et().clone(n,e,o),e}catch(l){throw await rm(e,{recursive:true,force:true}).catch(()=>{}),l}}let r=await mkdtemp(join(tmpdir(),"skills-")),s=t?["--depth","1","--branch",t]:["--depth","1"],i=be(n);try{return await et().clone(n,r,s),r}catch(o){let l=o instanceof Error?o.message:String(o),a=l.includes("block timeout")||l.includes("timed out"),c=Le(l);if(a){try{await rm(r,{recursive:!0,force:!0});}catch{}let f=Math.round(nt/1e3);throw new L(`Clone timed out after ${f}s. Common causes:
12
+ - Large repository: raise the timeout with SKILLS_CLONE_TIMEOUT=600000 (10m)
13
+ - Slow network: retry, or clone manually and pass the local path to 'skills add'
14
+ - Private repo without credentials: ensure auth is configured
15
+ - For SSH: ssh-add -l (to check loaded keys)
16
+ - For HTTPS: gh auth status (if using GitHub CLI)`,n,true,false)}if(c&&i&&Pe(n)){try{if(await Kt(r),await Ie(i,r,t))return r}catch{}try{return await Kt(r),await et({GIT_SSH_COMMAND:process.env.GIT_SSH_COMMAND??"ssh -o BatchMode=yes"}).clone(i.sshUrl,r,s),r}catch{}}try{await rm(r,{recursive:!0,force:!0});}catch{}if(c)throw new L(ve(n,i,l),n,false,true);let u=l.includes("filter.smudge")?`
17
+ - The repo defines a smudge/clean filter that Git considers unsafe.
18
+ Enable it with: git config --global protocol.allowUnsafeFilter true
19
+ Or upgrade Git, or unset filter.<driver>.* in the source repo.`:"";throw new L(`Failed to clone ${n}: ${l}${u}`,n,false,false)}}async function $n(n){let t=normalize(resolve(n)),e=normalize(resolve(tmpdir()));if(!t.startsWith(e+sep)&&t!==e)throw new Error("Attempted to clean up directory outside of temp directory");await rm(n,{recursive:true,force:true});}function j(n){if(n.type==="local")return null;let t=n.url.match(/^git@[^:]+:(.+)$/);if(t){let e=t[1];return e=e.replace(/\.git$/,""),e.includes("/")?e:null}if(n.url.startsWith("ssh://"))try{let r=new URL(n.url).pathname.slice(1);return r=r.replace(/\.git$/,""),r.includes("/")?r:null}catch{return null}if(!n.url.startsWith("http://")&&!n.url.startsWith("https://"))return null;try{let r=new URL(n.url).pathname.slice(1);if(r=r.replace(/\.git$/,""),r.includes("/"))return r}catch{}return null}function Nn(n){let t=n.match(/^([^/]+)\/([^/]+)$/);return t?{owner:t[1],repo:t[2]}:null}async function Un(n,t){try{let e=await fetch(`https://api.github.com/repos/${n}/${t}`);return e.ok?(await e.json()).private===!0:null}catch{return null}}async function Tt(n,t){try{let e=await fetch(`https://api.github.com/repos/${n}/${t}`,{headers:{Accept:"application/vnd.github+json"}});if(!e.ok)return null;let r=await e.json();return typeof r.default_branch=="string"&&r.default_branch.length>0?r.default_branch:null}catch{return null}}function O(n){let e=n.replace(/\\/g,"/").split("/");for(let r of e)if(r==="..")throw new Error(`Unsafe subpath: "${n}" contains path traversal segments. Subpaths must not contain ".." components.`);return n}function Ae(n){return isAbsolute(n)||n.startsWith("./")||n.startsWith("../")||n==="."||n===".."||/^[a-zA-Z]:[/\\]/.test(n)}var We={"coinbase/agentWallet":"coinbase/agentic-wallet-skills"};function rt(n){try{return decodeURIComponent(n)}catch{return n}}function Ke(n){if(n.startsWith("github:")||n.startsWith("gitlab:")||n.startsWith("git@")||/^ssh:\/\/.+\.git(?:$|[/?])/i.test(n))return true;if(n.startsWith("http://")||n.startsWith("https://"))try{let t=new URL(n),e=t.pathname;if(t.hostname==="github.com")return /^\/[^/]+\/[^/]+(?:\.git)?(?:\/tree\/[^/]+(?:\/.*)?)?\/?$/.test(e);if(t.hostname==="gitlab.com")return /^\/.+?\/[^/]+(?:\.git)?(?:\/-\/tree\/[^/]+(?:\/.*)?)?\/?$/.test(e)}catch{}return /^https?:\/\/.+\.git(?:$|[/?])/i.test(n)?true:!n.includes(":")&&!n.startsWith(".")&&!n.startsWith("/")&&/^([^/]+)\/([^/]+)(?:\/(.+)|@(.+))?$/.test(n)}function Ne(n){let t=n.indexOf("#");if(t<0)return {inputWithoutFragment:n};let e=n.slice(0,t),r=n.slice(t+1);if(!r)return {inputWithoutFragment:e};if(!Ke(e))return {inputWithoutFragment:n};let s=r.indexOf("@");if(s===-1)return {inputWithoutFragment:e,ref:rt(r)};let i=r.slice(0,s),o=r.slice(s+1);return {inputWithoutFragment:e,ref:i?rt(i):void 0,subpath:o?rt(o):void 0}}function Ct(n,t,e){return t?`${n}#${t}${e?`@${e}`:""}`:n}function Ft(n){if(Ae(n)){let d=resolve(n);return {type:"local",url:d,localPath:d}}let{inputWithoutFragment:t,ref:e,subpath:r}=Ne(n);n=t;let s=We[n];s&&(n=s);let i=n.match(/^github:(.+)$/);if(i)return Ft(Ct(i[1],e,r));let o=n.match(/^gitlab:(.+)$/);if(o)return Ft(Ct(`https://gitlab.com/${o[1]}`,e,r));let l=n.match(/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)/);if(l){let[,d,g,w,x]=l;return {type:"github",url:`https://github.com/${d}/${g}.git`,ref:w||e,subpath:x&&O(x)}}let a=n.match(/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)$/);if(a){let[,d,g,w]=a;return {type:"github",url:`https://github.com/${d}/${g}.git`,ref:w||e}}let c=n.match(/github\.com\/([^/]+)\/([^/]+)/);if(c){let[,d,g]=c,w=g.replace(/\.git$/,"");return {type:"github",url:`https://github.com/${d}/${w}.git`,...e?{ref:e}:{}}}let u=n.match(/^(https?):\/\/([^/]+)\/(.+?)\/-\/tree\/([^/]+)\/(.+)/);if(u){let[,d,g,w,x,k]=u;if(g!=="github.com"&&w)return {type:"gitlab",url:`${d}://${g}/${w.replace(/\.git$/,"")}.git`,ref:x||e,subpath:k&&O(k)}}let f=n.match(/^(https?):\/\/([^/]+)\/(.+?)\/-\/tree\/([^/]+)$/);if(f){let[,d,g,w,x]=f;if(g!=="github.com"&&w)return {type:"gitlab",url:`${d}://${g}/${w.replace(/\.git$/,"")}.git`,ref:x||e}}let h=n.match(/gitlab\.com\/(.+?)(?:\.git)?\/?$/);if(h){let d=h[1];if(d.includes("/"))return {type:"gitlab",url:`https://gitlab.com/${d}.git`,...e?{ref:e}:{}}}let y=n.match(/^([^/@]+)\/([^/@]+)@(.+)?$/);if(y&&!n.includes(":")&&!n.startsWith(".")&&!n.startsWith("/")){let d=y[1],g=y[2],w=y[3];if(!w)return {type:"github",url:`https://github.com/${d}/${g}.git`,...e?{ref:e}:{}};let x=O(w);return {type:"github",url:`https://github.com/${d}/${g}.git`,...e?{ref:e}:{},...x?{subpath:x}:{}}}let E=n.match(/^([^/@]+)\/([^/@]+)(?:\/(.+?))?\/?$/);if(E&&!n.includes(":")&&!n.startsWith(".")&&!n.startsWith("/")){let[,d,g,w]=E;return {type:"github",url:`https://github.com/${d}/${g}.git`,...e?{ref:e}:{},subpath:r??(w&&O(w))}}return Ue(n)?{type:"well-known",url:n}:{type:"git",url:n,...e?{ref:e}:{},...r?{subpath:r}:{}}}function Ue(n){if(!n.startsWith("http://")&&!n.startsWith("https://"))return false;try{let t=new URL(n);return !(["github.com","gitlab.com","raw.githubusercontent.com"].includes(t.hostname)||n.endsWith(".git"))}catch{return false}}var Mt="https://schemas.agentskills.io/discovery/0.2.0/schema.json",Te=/\/schemas\/agent-skills\/index\.v1\.json$/,Me=50*1024*1024,_e=1e3;function ze(n,t){let e=n.skillPath;if(typeof e=="string"&&e.trim()!==""&&e!==null)return e.replace(/^\/+/,"").replace(/\/+$/,"");if(typeof n.sourceUrl=="string"&&n.sourceUrl)try{let s=new URL(n.sourceUrl).pathname,i=/\/\.well-known\/(?:agent-skills|skills)\/(.*?)\/SKILL\.md$/,o=s.match(i);if(o?.[1])return o[1];let l=s.match(/^(.*?)\/[^/]+\/SKILL\.md$/);if(l?.[1])return l[1]}catch{}if(typeof n.installName=="string"&&n.installName){let r=n.installName.lastIndexOf("@");if(r>=0){let s=n.installName.slice(r+1);if(s.includes("/"))return s.replace(/^\/+/,"")}}return t}var it=class{constructor(){b(this,"id","well-known");b(this,"displayName","Well-Known Skills");b(this,"WELL_KNOWN_PATHS",[".well-known/agent-skills",".well-known/skills"]);b(this,"INDEX_FILE","index.json");}match(t){if(!t.startsWith("http://")&&!t.startsWith("https://"))return {matches:false};try{let e=new URL(t);return ["github.com","gitlab.com","huggingface.co"].includes(e.hostname)?{matches:!1}:{matches:!0,sourceIdentifier:`wellknown/${e.hostname}`}}catch{return {matches:false}}}async fetchIndex(t){return (await this.fetchIndexCandidates(t))[0]??null}async fetchIndexCandidates(t){try{let e=new URL(t),r=e.pathname.replace(/\/$/,""),s=[],i=r.match(/\/\.well-known\/(agent-skills|skills)\/?$/);if(i?.[1]){let l=`.well-known/${i[1]}`;s.push({indexUrl:`${e.protocol}//${e.host}${r}/${this.INDEX_FILE}`,baseUrl:`${e.protocol}//${e.host}${r.replace(/\/\.well-known\/(?:agent-skills|skills)$/,"")}`,wellKnownPath:l});}for(let l of this.WELL_KNOWN_PATHS)s.push({indexUrl:`${e.protocol}//${e.host}${r}/${l}/${this.INDEX_FILE}`,baseUrl:`${e.protocol}//${e.host}${r}`,wellKnownPath:l}),r&&r!==""&&s.push({indexUrl:`${e.protocol}//${e.host}/${l}/${this.INDEX_FILE}`,baseUrl:`${e.protocol}//${e.host}`,wellKnownPath:l});let o=[];for(let{indexUrl:l,baseUrl:a,wellKnownPath:c}of s)try{let u=await fetch(l);if(!u.ok)continue;let f=await u.json(),h=this.normalizeIndex(f,l,c);if(!h)continue;o.push({index:h.index,entries:h.entries,resolvedBaseUrl:a,resolvedWellKnownPath:c,indexUrl:l});}catch{}return o}catch{return []}}normalizeIndex(t,e,r){if(!t||typeof t!="object")return null;let s=t;if(!Array.isArray(s.skills))return null;let i=s.$schema;if(i===Mt){let a=[],c=[];for(let u of s.skills){if(!this.isValidSkillEntryV2(u))continue;let f=new URL(u.url,e).toString();a.push({version:"0.2.0",name:u.name,description:u.description,type:u.type,artifactUrl:f,digest:u.digest,indexEntry:u}),c.push(u);}return a.length===0?null:{index:{$schema:Mt,skills:c},entries:a}}if(typeof i=="string"&&Te.test(i)){let a=[],c=[];for(let u of s.skills){if(!this.isValidSkillEntryEasbotV1(u))continue;let f=new URL(u.sourceUrl,e).toString();a.push({version:"easbot-v1",name:u.name,description:u.description,skillMdUrl:f,installName:u.installName,indexEntry:u}),c.push(u);}return a.length===0?null:{index:{$schema:i,skills:c},entries:a}}if(i!==void 0)return null;let o=[],l=[];for(let a of s.skills){if(!this.isValidSkillEntryV1(a))return null;o.push(a),l.push({version:"0.1.0",name:a.name,description:a.description,files:a.files,baseUrl:this.getLegacySkillBaseUrl(e,r),wellKnownPath:r,indexEntry:a});}return {index:{skills:o},entries:l}}getLegacySkillBaseUrl(t,e){let r=new URL(t),s=`/${e}/${this.INDEX_FILE}`;return `${r.protocol}//${r.host}${r.pathname.slice(0,-s.length)}`}isValidSkillName(t){return !(typeof t!="string"||t.length===0||t.length>64||!/^[a-z0-9-]+$/.test(t)||t.startsWith("-")||t.endsWith("-")||t.includes("--"))}isSafeLegacyFilePath(t){return !(typeof t!="string"||t.length===0||t.startsWith("/")||t.startsWith("\\")||t.includes("..")||t.includes("\0"))}isValidSkillEntryEasbotV1(t){if(!t||typeof t!="object")return false;let e=t;if(!this.isValidSkillName(e.name)||typeof e.description!="string"||!e.description||e.description.length>1024||typeof e.sourceUrl!="string"||!e.sourceUrl)return false;try{new URL(e.sourceUrl,"https://easbot.cn/.well-known/agent-skills/index.json");}catch{return false}return true}isValidSkillEntryV1(t){if(!t||typeof t!="object")return false;let e=t;if(!this.isValidSkillName(e.name)||typeof e.description!="string"||!e.description||!Array.isArray(e.files)||e.files.length===0)return false;for(let s of e.files)if(!this.isSafeLegacyFilePath(s))return false;return e.files.some(s=>typeof s=="string"&&s.toLowerCase()==="skill.md")}isValidSkillEntryV2(t){if(!t||typeof t!="object")return false;let e=t;if(!this.isValidSkillName(e.name)||typeof e.description!="string"||!e.description||e.description.length>1024||e.type!=="skill-md"&&e.type!=="archive"||typeof e.url!="string"||!e.url||typeof e.digest!="string"||!/^sha256:[a-f0-9]{64}$/.test(e.digest))return false;try{new URL(e.url,"https://example.com/.well-known/agent-skills/index.json");}catch{return false}return true}async fetchSkill(t){try{let e=new URL(t),r=await this.fetchIndexCandidates(t);for(let s of r){let{entries:i}=s,o=null,l=e.pathname.match(/\/.well-known\/(?:agent-skills|skills)\/([^/]+)\/?$/);if(l?.[1]&&l[1]!=="index.json"?o=l[1]:i.length===1&&(o=i[0].name),!o)continue;let a=i.find(u=>u.name===o);if(!a)continue;let c=await this.fetchSkillByEntry(a);if(c)return c}return null}catch{return null}}async fetchSkillByEntry(t,e,r){return typeof t=="string"?e?this.fetchLegacySkillByEntry({version:"0.1.0",name:e.name,description:e.description,files:e.files,baseUrl:t,wellKnownPath:r??this.WELL_KNOWN_PATHS[0],indexEntry:e}):null:t.version==="0.1.0"?this.fetchLegacySkillByEntry(t):t.version==="easbot-v1"?this.fetchEasbotV1SkillByEntry(t):this.fetchArtifactSkillByEntry(t)}async fetchEasbotV1SkillByEntry(t){try{let e=await fetch(t.skillMdUrl);if(!e.ok)return null;let r=await e.text(),{data:s}=a(r);if(typeof s.name!="string"||typeof s.description!="string")return null;let i=new Map;i.set("SKILL.md",r);let o=ze(t.indexEntry,s.name);return this.createSkill({name:s.name,description:s.description,content:r,installName:o,sourceUrl:t.skillMdUrl,metadata:s.metadata,files:i,indexEntry:t.indexEntry})}catch{return null}}async fetchLegacySkillByEntry(t){try{let e=`${t.baseUrl.replace(/\/$/,"")}/${t.wellKnownPath}/${t.name}`,r=`${e}/SKILL.md`,s=await fetch(r);if(!s.ok)return null;let i=await s.text(),{data:o}=a(i);if(typeof o.name!="string"||typeof o.description!="string")return null;let l=new Map;l.set("SKILL.md",i);let c=t.files.filter(f=>f.toLowerCase()!=="skill.md").map(async f=>{try{let h=`${e}/${f}`,y=await fetch(h);if(y.ok){let E=await y.arrayBuffer();return {path:f,content:new Uint8Array(E)}}}catch{}return null}),u=await Promise.all(c);for(let f of u)f&&l.set(f.path,f.content);return this.createSkill({name:o.name,description:o.description,content:i,installName:t.name,sourceUrl:r,metadata:o.metadata,files:l,indexEntry:t.indexEntry})}catch{return null}}async fetchArtifactSkillByEntry(t){try{let e=await fetch(t.artifactUrl);if(!e.ok)return null;let r=e.headers.get("content-type")??"",s=new Uint8Array(await e.arrayBuffer());if(this.computeDigest(s)!==t.digest)return null;if(t.type==="skill-md"){let c=new TextDecoder().decode(s),{data:u}=a(c);if(typeof u.name!="string"||typeof u.description!="string")return null;let f=new Map;return f.set("SKILL.md",c),this.createSkill({name:u.name,description:u.description,content:c,installName:t.name,sourceUrl:t.artifactUrl,metadata:u.metadata,files:f,indexEntry:t.indexEntry})}let i=this.extractArchive(s,t.artifactUrl,r),o=i.get("SKILL.md");if(!o)return null;let l=typeof o=="string"?o:new TextDecoder().decode(o);i.set("SKILL.md",l);let{data:a$1}=a(l);return typeof a$1.name!="string"||typeof a$1.description!="string"?null:this.createSkill({name:a$1.name,description:a$1.description,content:l,installName:t.name,sourceUrl:t.artifactUrl,metadata:a$1.metadata,files:i,indexEntry:t.indexEntry})}catch{return null}}createSkill(t){return {name:b$1(t.name),description:b$1(t.description),content:t.content,installName:t.installName,sourceUrl:t.sourceUrl,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0,files:t.files,indexEntry:t.indexEntry}}async fetchAllSkills(t){try{let e=await this.fetchIndexCandidates(t);for(let r of e){let s=r.entries.map(l=>this.fetchSkillByEntry(l)),o=(await Promise.all(s)).filter(l=>l!==null);if(o.length>0)return o}return []}catch{return []}}computeDigest(t){return `sha256:${createHash("sha256").update(t).digest("hex")}`}extractArchive(t,e,r){if(this.isZipArchive(t,e,r))return this.extractZip(t);if(this.isTarGzArchive(t,e,r))return this.extractTarGz(t);throw new Error("Unsupported archive format")}isZipArchive(t,e,r){return r.includes("application/zip")||e.toLowerCase().endsWith(".zip")||t[0]===80&&t[1]===75}isTarGzArchive(t,e,r){let s=e.toLowerCase();return r.includes("application/gzip")||r.includes("application/x-gzip")||s.endsWith(".tar.gz")||s.endsWith(".tgz")||t[0]===31&&t[1]===139}normalizeArchivePath(t){if(!t||t.includes("\0")||t.startsWith("/")||t.startsWith("\\")||/^[A-Za-z]:/.test(t)||t.includes("\\"))return null;let e=t.split("/").filter(Boolean);return e.length===0||e.some(r=>r==="."||r==="..")?null:e.join("/")}addArchiveFile(t,e,r,s){let i=this.normalizeArchivePath(e);if(!i)throw new Error(`Unsafe archive path: ${e}`);if(s.bytes+=r.byteLength,s.bytes>Me)throw new Error("Archive exceeds maximum unpacked size");if(t.size>=_e)throw new Error("Archive contains too many files");t.set(i,r);}extractTarGz(t){let e=gunzipSync(Buffer.from(t)),r=new Map,s={bytes:0},i=0;for(;i+512<=e.length;){let o=e.subarray(i,i+512);if(o.every(E=>E===0))break;let l=this.readTarString(o,0,100),a=this.readTarString(o,124,12).trim(),c=o[156],u=this.readTarString(o,345,155),f=u?`${u}/${l}`:l,h=Number.parseInt(a||"0",8);if(!Number.isFinite(h)||h<0)throw new Error("Invalid tar entry size");if(i+=512,c===50||c===49)throw new Error("Archive links are not supported");if(c===0||c===48){let E=e.subarray(i,i+h);this.addArchiveFile(r,f,new Uint8Array(E),s);}i+=Math.ceil(h/512)*512;}if(!r.has("SKILL.md"))throw new Error("Archive missing root SKILL.md");return r}readTarString(t,e,r){let s=t.subarray(e,e+r),i=s.indexOf(0);return new TextDecoder().decode(i>=0?s.subarray(0,i):s)}extractZip(t){let e=Buffer.from(t),r=this.findZipEndOfCentralDirectory(e);if(r<0)throw new Error("Invalid zip archive");let s=e.readUInt16LE(r+10),i=e.readUInt32LE(r+16),o=new Map,l={bytes:0},a=i;for(let c=0;c<s;c++){if(e.readUInt32LE(a)!==33639248)throw new Error("Invalid zip directory");let u=e.readUInt16LE(a+8),f=e.readUInt16LE(a+10),h=e.readUInt32LE(a+20),y=e.readUInt32LE(a+24),E=e.readUInt16LE(a+28),d=e.readUInt16LE(a+30),g=e.readUInt16LE(a+32),w=e.readUInt32LE(a+38),x=e.readUInt32LE(a+42),k=a+46,S=e.subarray(k,k+E),b=new TextDecoder(u&2048?"utf-8":void 0).decode(S);if(a=k+E+d+g,b.endsWith("/"))continue;if(u&1)throw new Error("Encrypted zip entries are not supported");let M=w>>>16&61440;if(M===40960||M===4096)throw new Error("Archive links are not supported");if(e.readUInt32LE(x)!==67324752)throw new Error("Invalid zip local header");let _=e.readUInt16LE(x+26),fe=e.readUInt16LE(x+28),wt=x+30+_+fe,yt=e.subarray(wt,wt+h),z;if(f===0)z=yt;else if(f===8)z=inflateRawSync(yt);else throw new Error(`Unsupported zip compression method: ${f}`);if(z.byteLength!==y)throw new Error("Zip entry size mismatch");this.addArchiveFile(o,b,new Uint8Array(z),l);}if(!o.has("SKILL.md"))throw new Error("Archive missing root SKILL.md");return o}findZipEndOfCentralDirectory(t){let e=Math.max(0,t.length-65535-22);for(let r=t.length-22;r>=e;r--)if(t.readUInt32LE(r)===101010256)return r;return -1}toRawUrl(t){try{let e=new URL(t);if(t.toLowerCase().endsWith("/skill.md"))return t;let r=this.WELL_KNOWN_PATHS[0],s=e.pathname.match(/\/.well-known\/(?:agent-skills|skills)\/([^/]+)\/?$/);if(s?.[1]){let o=e.pathname.replace(/\/.well-known\/(?:agent-skills|skills)\/.*$/,"");return `${e.protocol}//${e.host}${o}/${r}/${s[1]}/SKILL.md`}let i=e.pathname.replace(/\/$/,"");return `${e.protocol}//${e.host}${i}/${r}/${this.INDEX_FILE}`}catch{return t}}getSourceIdentifier(t){try{return new URL(t).hostname.replace(/^www\./,"")}catch{return "unknown"}}async hasSkillsIndex(t){return await this.fetchIndex(t)!==null}},_t=new it;function st(n,t){let e=normalize(resolve(t)),r=normalize(resolve(n));return r.startsWith(e+sep)||r===e}function V(n){return n.startsWith("./")}async function Ot(n){let t=new Map;try{let e=await readFile(join(n,".claude-plugin/marketplace.json"),"utf-8"),r=JSON.parse(e),s=r.metadata?.pluginRoot;if(s===void 0||V(s))for(let o of r.plugins??[]){if(!o.name||typeof o.source!="string"&&o.source!==void 0||o.source!==void 0&&!V(o.source))continue;let l=join(n,s??"",o.source??"");if(st(l,n)&&o.skills&&o.skills.length>0)for(let a of o.skills){if(!V(a))continue;let c=join(l,a);st(c,n)&&t.set(resolve(c),o.name);}}}catch{}try{let e=await readFile(join(n,".claude-plugin/plugin.json"),"utf-8"),r=JSON.parse(e);if(r.name&&r.skills&&r.skills.length>0)for(let s of r.skills){if(!V(s))continue;let i=join(n,s);st(i,n)&&t.set(resolve(i),r.name);}}catch{}return t}var Ge=["node_modules",".git","dist","build","__pycache__"];async function Be(n){let t=join(n,".gitignore");try{let e=await readFile(t,"utf-8");return Glob.parseGitignoreContent(e)}catch{return []}}function ot(n){return n.toLowerCase().replace(/[\s_]+/g,"-")}function qe(n){return n.split(sep).join("/").replace(/\/+/g,"/")}function Xe(){let n=process.env.INSTALL_INTERNAL_SKILLS;return n==="1"||n==="true"}async function Jt(n){try{let t=join(n,"SKILL.md");return (await stat(t)).isFile()}catch{return false}}async function Vt(n,t){try{let e=await readFile(n,"utf-8"),{data:r}=a(e);if(!r.name||!r.description||typeof r.name!="string"||typeof r.description!="string")return null;let s=r.metadata&&typeof r.metadata=="object"&&!Array.isArray(r.metadata)?r.metadata:void 0;return s?.internal===!0&&!Xe()&&!t?.includeInternal?null:{name:b$1(r.name),description:b$1(r.description),path:dirname(n),rawContent:e,metadata:s}}catch{return null}}async function Zt(n,t=0,e=5){if(t>e)return [];try{let[r,s]=await Promise.all([Jt(n),readdir(n,{withFileTypes:!0}).catch(()=>[])]),i=r?[n]:[],o=await Promise.all(s.filter(l=>l.isDirectory()&&!Ge.includes(l.name)).map(l=>Zt(join(n,l.name),t+1,e)));return [...i,...o.flat()]}catch{return []}}function Je(n,t){let e=normalize(resolve(n)),r=normalize(resolve(join(n,t)));return r.startsWith(e+sep)||r===e}async function ct(n,t,e){let r=[],s=new Set,i=await q(n),o=new Set(Object.keys(i.skills).map(ot));if(t&&!Je(n,t))throw new Error(`Invalid subpath: "${t}" resolves outside the repository directory. Subpath must not contain ".." segments that escape the base path.`);let l=t?join(n,t):n,a=await Ot(l),c=k=>{let S=resolve(k.path);return a.has(S)&&(k.pluginName=a.get(S)),k},u=k(),f=k=>{if(o.size===0)return false;let S=qe(relative(n,k.path));if(!u.some(_=>S===_||S.startsWith(`${_}/`)))return false;let kt=ot(k.name),M=ot(basename(k.path));return o.has(kt)||o.has(M)},h=async k=>{if(!await Jt(k))return false;let S=await Vt(join(k,"SKILL.md"),e);return !S||s.has(S.name)||f(S)||(S=c(S),r.push(S),s.add(S.name)),true},y=t?t.replace(/^\/+|\/+$/g,"").split("/").filter(k=>k.length>0):[],E=y.length>0?`**/${y.join("/")}/**/SKILL.md`:"**/SKILL.md",d=await Glob.scan(E,{cwd:l,absolute:true,ignore:[...Glob.DEFAULT_IGNORE_PATTERNS,...await Be(l)]}),g="/",w=l.split(sep).join(g);d.sort((k,S)=>k.split(g).length-S.split(g).length);let x=[];for(let k of d){if(x.some(b=>k.startsWith(`${b}${g}`)||k===b))continue;let S=dirname(k);if(await h(S)){let b=S.split(sep).join(g);if(b===w)continue;x.push(b);}}if(r.length===0||e?.fullDepth){let k=await Zt(l);for(let S of k){let b=await Vt(join(S,"SKILL.md"),e);b&&!s.has(b.name)&&!f(b)&&(b=c(b),r.push(b),s.add(b.name));}}return r}function Ze(n){return n.name||(n.path?basename(n.path):"")}function rr(n,t){let e=t.map(r=>r.toLowerCase());return n.filter(r=>{let s=r.name.toLowerCase(),i=Ze(r).toLowerCase();return e.some(o=>o===s||o===i)})}var Yt="*";function ir(n,t){if(!n||n.length===0)return [];let e=new Set(t),r=[];for(let s of n)if(s!==Yt){if(s.includes("/")||s.includes("**")){r.push(s);continue}Qt.test(s)?t.some(i=>Wildcard.match(i,s))||r.push(s):e.has(s)||r.push(s);}return r}function sr(n,t){let e={wildcard:false,matched:[],invalid:[]};if(!n||n.length===0)return e;let r=new Set(t),s=new Set;for(let i of n){if(i===Yt){e.wildcard=true;continue}if(i.includes("/")||i.includes("**")){e.invalid.push(i);continue}if(Qt.test(i))for(let o of t)Wildcard.match(o,i)&&s.add(o);else r.has(i)?s.add(i):e.invalid.push(i);}return e.matched=Array.from(s),e}var Qt=/[*?[{}]/;var ut="houjallen/agent-skills";async function Er(n){let t=n.defaultPlugin;if(!t||typeof t.marketId!="string"||t.marketId.length===0)return ut;let e=n.markets[t.marketId];if(!e)return ut;let r=e.localPath??e.url;if(!r)return ut;let s=r;return e.subpath&&(s=`${s}@${e.subpath}`),e.ref&&(s=`${s}#${e.ref}`),s}function en(n){if(!n||typeof n!="object"||Array.isArray(n))return null;let t=n;if(typeof t.marketId!="string"||t.marketId.length===0)return null;let e={marketId:t.marketId};return typeof t.pluginId=="string"&&t.pluginId.length>0&&(e.pluginId=t.pluginId),e}function m(n){return Filesystem.normalize(n)}function ft(n){if(n==="general"||n==="coder"||n==="all")return n}function nn({scope:n}){let t=n==="project"?p():m$1(),e=Filesystem.join(t,n==="project"?".easbot":"easbot","skills");return Filesystem.normalize(e)}function T(){return Filesystem.join(m$1(),"skills","store")}function ie(){return Filesystem.join(T(),"index.json")}function X(n){let t=`${n.type}|${n.url}|${n.ref??""}`;return createHash("sha256").update(t).digest("hex")}function se(n){let t=X(n);return Filesystem.join(T(),t)}function D(){return Filesystem.join(o(),"skills","cache")}function rn(n,t,e){if(e&&e.length>0)return U(e);let r=sn(n);if(r)return r;if(t?.includes("/")){let s=t.split("/")[0];if(s)return U(s)}return "default"}function sn(n){let t=n.localPath??n.url;if(!t)return null;if(n.type==="well-known")try{let s=new URL(t),i=s.hostname.replace(/^www\./,"").replace(/\./g,"-"),o=s.pathname.replace(/^\/+/,"").split("/")[0]||"";return o&&!i.endsWith(`-${o}`)?U(`${i}-${o}`):U(i)}catch{return null}let e=t.match(/^(?:https?:\/\/[^/]+\/|git@[^:]+:)([^/]+)\/([^/]+?)(?:\.git)?\/?$/);if(e)return U(e[2]??"");let r=t.split(/[\\/]/).filter(Boolean).pop();return r?U(r.replace(/\.git$/,"")):null}function U(n){let t=n.trim().replace(/[:\\/\0]/g,"-").replace(/\.git$/,"").replace(/\s+/g,"-");return t.length>64&&(t=t.slice(0,64)),t.length>0?t:"default"}function gt(n){if(n.type==="well-known")return on(n.url);let t=j(n);if(t)return Filesystem.join(D(),n.type,t);let e=createHash("sha256").update(n.url).digest("hex").slice(0,16);return Filesystem.join(D(),n.type,`unknown-${e}`)}function on(n){let t,e;try{let r=new URL(n);t=r.hostname.replace(/^www\./,"");let s=r.pathname.match(/\/\.well-known\/(agent-skills|skills)/);s?.[1]?e=`.well-known/${s[1]}`:e=".well-known/agent-skills";}catch{let r=createHash("sha256").update(n).digest("hex").slice(0,16);return Filesystem.join(D(),"wellknown",`unknown-${r}`)}return Filesystem.join(D(),"wellknown",t,e)}async function oe(n){n.skillNames??[];if(n.type==="local")return ln(n);let e=n.mode??"install",{cacheDir:r,source:s,cloneError:i}=await an(n,e);return {tempDir:r,cacheHit:false,source:s,cloneError:i}}var dt=class extends Error{constructor(e){super(`Local source path does not exist: ${e}`);b(this,"localPath",e);this.name="LocalPathNotFoundError";}};async function ln(n,t){let e=n.localPath??n.url;if(!existsSync(e))throw new dt(e);let r=se(n);return existsSync(r)&&await le(r)?{tempDir:r,cacheHit:true,source:"local-cp",cloneError:null}:{tempDir:e,cacheHit:false,source:"local-cp",cloneError:null}}async function an(n,t){let e=n.ref;if(!e){let l=j(n);if(l){let[a,c]=l.split("/");if(a&&c){let u=await Tt(a,c);u&&(e=u);}}}e||(e="HEAD");let r=gt(n);if(n.type==="well-known")return existsSync(r)?{cacheDir:r,source:"cache-pull",cloneError:null}:(await Filesystem.mkdir(m(r),{recursive:true}),await pn(n.url,r),{cacheDir:r,source:"well-known-fetch",cloneError:null});if(existsSync(r))try{let l=he(r);return t==="update"?(await l.fetch(),await l.checkout(e),{cacheDir:r,source:"cache-pull",cloneError:null}):(await l.checkout(e),{cacheDir:r,source:"cache-pull",cloneError:null})}catch{return {cacheDir:r,source:"cache-pull",cloneError:null}}async function s(l,a,c){return Dt(l,a,c)}let i=null,o=null;try{return await Filesystem.mkdir(m(Filesystem.dirname(r)),{recursive:!0}),i=`${r}.clone-tmp`,await s(n.url,e,i),await rename(m(i),m(r)),{cacheDir:r,source:"cache-clone",cloneError:null}}catch(l){return l instanceof L?o=l:l instanceof Error&&(o=new L(`Failed to clone ${n.url}: ${l.message}`,n.url,false,false)),await Filesystem.mkdir(m(r),{recursive:true}).catch(()=>{}),{cacheDir:r,source:"cache-pull",cloneError:o}}finally{if(i)try{await rm(m(i),{recursive:!0,force:!0});}catch{}}}async function W(){let n=m(ie()),t;try{t=await Filesystem.readText(n);}catch{return {version:6,markets:{}}}let e;try{e=JSON.parse(t);}catch{try{await rename(m(n),`${m(n)}.corrupt-${Date.now()}`);}catch{}return {version:6,markets:{}}}let r=e;if(r.version!==6||!r.markets)return {version:6,markets:{}};let s={version:6,markets:r.markets};if("defaultPlugin"in r){let i=en(r.defaultPlugin);i&&(s.defaultPlugin=i);}return s}async function Q(n){await Filesystem.writeJson(m(ie()),n);}async function br(){let n=await W(),t={};for(let e of Object.values(n.markets))for(let r of Object.values(e.plugins))for(let[s,i]of Object.entries(r.skills))t[s]={marketId:e.id,pluginId:r.id,pluginName:r.name,storePath:e.storePath,pluginSlug:r.id.split(":").slice(1).join(":")||r.id,url:e.url,type:e.type,localPath:e.localPath,subpath:e.subpath,ref:e.ref,addedAt:e.addedAt,skillPath:i.skillPath,computedHash:i.computedHash,sourceKey:e.id,sourcePath:e.localPath??e.storePath};return t}async function Pr(n,t,e,r,s){let i=await W(),o=i.markets[n];o||(o={...s,id:n,addedAt:s.addedAt??new Date().toISOString(),plugins:{}},i.markets[n]=o);let l=o.plugins[t];l||(l={id:t,name:t.split(":").slice(1).join(":")||t,skills:{}},o.plugins[t]=l),l.skills[e]=r,await Q(i);}async function cn(){let n=await W(),t=[];for(let e of Object.values(n.markets))for(let r of Object.values(e.plugins))for(let s of Object.values(r.skills))t.push({skillName:s.name,marketId:e.id,pluginId:r.id,entry:s});return t.sort((e,r)=>{let s=e.marketId.localeCompare(r.marketId);if(s!==0)return s;let i=e.pluginId.localeCompare(r.pluginId);return i!==0?i:e.skillName.localeCompare(r.skillName)}),t}async function un(n){return (await cn()).filter(e=>e.skillName===n)}async function Lr(n,t,e){let s=(await W()).markets[n];if(!s)return;let i=s.plugins[t];if(!i)return;let o=i.skills[e];if(o)return {skillName:o.name,marketId:n,pluginId:t,entry:o}}async function Ir(n,t,e){let r=await W(),s=r.markets[n];if(!s)return false;let i=s.plugins[t];return !i||!(e in i.skills)?false:(delete i.skills[e],await Q(r),true)}async function fn(n){let t=await un(n);if(t.length===0)return [];let e=await W(),r=[];for(let s of t){let i=e.markets[s.marketId]?.plugins[s.pluginId];i&&n in i.skills&&(delete i.skills[n],r.push(s));}return r.length>0&&await Q(e),r}async function vr(n,t,e,r,s,i,o){await J([{skillName:n,parsed:t,sourceKey:e,sourcePath:r,storePath:s,skillPath:i,...o&&{computedHash:o}}]);}async function J(n){if(n.length===0)return;let t=await W(),e=new Date().toISOString();for(let i of n){let o=i.sourceKey,l=rn(i.parsed,i.skillPath,i.pluginName),a=`${o}:${l}`,c=t.markets[o];if(!c){let h=i.parsed.type==="local"?i.parsed.localPath??i.parsed.url:gt(i.parsed);c={id:o,type:i.parsed.type,url:i.parsed.url,localPath:i.parsed.localPath,subpath:i.parsed.subpath,ref:i.parsed.ref,storePath:i.storePath,cachePath:h,addedAt:e,plugins:{}},t.markets[o]=c;}let u=c.plugins[a];u||(u={id:a,name:l,sourcePath:i.parsed.subpath,skills:{}},c.plugins[a]=u);let f={name:i.skillName,description:i.description??"",skillPath:i.skillPath,computedHash:i.computedHash};i.scope&&(f.scope=i.scope),i.snapshotHash&&(f.snapshotHash=i.snapshotHash),u.skills[i.skillName]=f;}let r=new Set,s=new Map;for(let i of n)r.add(i.sourceKey),i.marketSnapshotHash&&s.set(i.sourceKey,i.marketSnapshotHash);for(let i of r){let o=t.markets[i];if(!o)continue;let l=s.get(i);if(l){o.snapshotHash=l;continue}let a=[];for(let c of Object.values(o.plugins))for(let u of Object.values(c.skills))a.push({name:u.name,snapshotHash:u.snapshotHash});o.snapshotHash=d(a);}await Q(t);}async function $r(n){return (await fn(n)).length>0}async function pn(n,t){let e;try{e=await _t.fetchAllSkills(n);}catch{return}if(e.length!==0)for(let r of e)try{await dn(r,t);}catch{}}async function dn(n,t){let e=Filesystem.join(t,n.installName),r=Filesystem.normalize(e),s=Filesystem.normalize(t);if(!r.startsWith(`${s}/`)&&r!==s)throw new Error(`Unsafe skill dir: ${n.installName}`);await mkdir(m(e),{recursive:true});for(let[i,o]of n.files){let l=Filesystem.join(e,i),a=Filesystem.normalize(l);if(!a.startsWith(`${r}/`)&&a!==r||i.includes("\0"))continue;let c=dirname(m(l));c!==m(e)&&await mkdir(c,{recursive:true}),await writeFile(m(l),typeof o=="string"?o:Buffer.from(o));}}async function Rr(n){return (await oe({type:"git",url:n.url,ref:n.ref})).tempDir}async function Ar(n,t={}){let e=se(n),r=false;if(existsSync(e)&&(r=await le(e),!r))try{await rmdir(m(e));}catch{}if(r){let c=await ct(e,void 0,{includeInternal:t.includeInternal,fullDepth:t.fullDepth});if(c.length>0){let f=await Promise.all(c.map(async h=>{let y=pt(e,h.path);return {skillName:h.name,parsed:n,sourceKey:X(n),sourcePath:e,storePath:e,skillPath:y,description:h.description,scope:ft(h.metadata?.scope),...h.pluginName&&{pluginName:h.pluginName},computedHash:await b$2(h.path)}}));await J(f);}let u=n.type==="local"?"local-cp":"cache-pull";return {storeDir:e,cacheHit:true,source:u,skills:c,blobSkills:[],cloneError:null}}let s=[];if(n.type==="github"&&!t.fullDepth){let c$1=j(n),u=c$1?.split("/")[0]?.toLowerCase(),f=!!c$1&&Object.hasOwn(c,c$1.toLowerCase());if(c$1&&u&&(f||d$1.includes(u))){let h=await l(c$1,{subpath:n.subpath,ref:n.ref,includeInternal:t.includeInternal});if(h&&h.skills.length>0){await hn(h.skills,e);let y=h.skills.map(d=>({...d,path:Filesystem.join(e,d.repoSubpath??"",d.name,"SKILL.md")})),E=await Promise.all(y.map(async(d,g)=>{let w=h.skills[g],x=`${w.repoSubpath??""}${w.repoSubpath?"/":""}${w.name}`;return {skillName:d.name,parsed:n,sourceKey:X(n),sourcePath:e,storePath:e,skillPath:x,description:d.description,scope:ft(d.metadata?.scope),...d.pluginName&&{pluginName:d.pluginName},computedHash:await b$2(Filesystem.dirname(d.path)),snapshotHash:w.snapshotHash,marketSnapshotHash:h.snapshotHash}}));return await J(E),s=h.skills,{storeDir:e,cacheHit:false,source:"blob-fetch",skills:y,blobSkills:s,cloneError:null}}}}let i=await oe(n);await Filesystem.mkdir(m(e),{recursive:true}).catch(()=>{});let o=await ct(i.tempDir,void 0,{includeInternal:t.includeInternal,fullDepth:t.fullDepth}),l$1=[],a=Filesystem.normalize(e).replace(/\\/g,"/");for(let c of o){let u=pt(i.tempDir,c.path),f=Filesystem.join(e,u),h=`${pt(i.tempDir,c.path)}/SKILL.md`,y=Filesystem.normalize(f).replace(/\\/g,"/"),E="/",d=a.endsWith(E)?a:a+E;if(!y.startsWith(d)&&y!==a)throw new Error(`[INVARIANT 0048-yyy] cp target escapes storeRoot: target=${y} storeRoot=${a}
20
+ source skill path=${c.path} (parsed.type=${n.type})
21
+ \u4E1A\u52A1\u4EFB\u4F55\u65F6\u5019\u4E0D\u80FD\u64CD\u4F5C\u7528\u6237\u7684 local \u76EE\u5F55\u6216\u6587\u4EF6\u3002`);let g;try{await Filesystem.mkdir(m(Filesystem.dirname(f)),{recursive:!0}),await cp(m(c.path),m(f),{recursive:!0}),g=await b$2(f);}catch{}c.path=f,l$1.push({skill:c,skillRel:u,sourceSkillPath:h,targetPath:f,computedHash:g});}if(l$1.length>0){let c=l$1.filter(u=>u.computedHash).map(u=>({skillName:u.skill.name,parsed:n,sourceKey:X(n),sourcePath:i.tempDir,storePath:e,skillPath:u.skillRel,description:u.skill.description,scope:ft(u.skill.metadata?.scope),...u.skill.pluginName&&{pluginName:u.skill.pluginName},computedHash:u.computedHash}));await J(c);}return {storeDir:e,cacheHit:i.cacheHit,source:i.source,skills:o,blobSkills:[],cloneError:i.cloneError??null}}async function hn(n,t){let e=Filesystem.normalize(t);for(let r of n){let s=Filesystem.join(t,r.repoSubpath??"",r.name),i=Filesystem.normalize(s);if(!(!i.startsWith(`${e}/`)&&i!==e))try{await mkdir(m(s),{recursive:!0});for(let o of r.files){let l=Filesystem.join(s,o.path),a=Filesystem.normalize(l);if(!a.startsWith(`${i}/`)&&a!==i||o.path.includes("\0"))continue;let c=dirname(m(l));c!==m(s)&&await mkdir(c,{recursive:!0}),await writeFile(m(l),o.contents,"utf-8");}}catch{}}}function pt(n,t){let r=Filesystem.normalize(n).replace(/\\/g,"/"),s=Filesystem.normalize(t).replace(/\\/g,"/"),i=r.toLowerCase();return s.toLowerCase().startsWith(`${i}/`)?s.slice(i.length+1):""}async function le(n){try{return (await readdir(m(n))).length>0}catch{return false}}function Wr(n){try{let t=Filesystem.normalize(n);for(let e of [D(),T()]){let r=Filesystem.normalize(e);if(t===r||t.startsWith(`${r}/`))return !0}return !1}catch{return false}}async function Kr({cachePath:n,skillName:t,scope:e}){let r=Filesystem.join(nn({scope:e}),t);return existsSync(r)&&await rm(m(r),{recursive:true,force:true}),await cp(m(n),m(r),{recursive:true}),r}async function Nr(n){let t=gt(n);existsSync(t)&&await rm(m(t),{recursive:true,force:true});}async function Ur(){let n=D();existsSync(n)&&await rm(m(n),{recursive:true,force:true});}var wn="skills-lock.json",ae=4;function ce(n){return join(n||process.cwd(),wn)}function Hr(n,t){return n?vt(n,T(),t):null}async function q(n){let t=ce(n);try{let e=await readFile(t,"utf-8"),r=JSON.parse(e);return typeof r.version!="number"||!r.skills||r.version<ae?mt():r}catch{return mt()}}async function ue(n,t){let e=ce(t),r={};for(let o of Object.keys(n.skills).sort())r[o]=n.skills[o];let s={version:n.version,skills:r},i=JSON.stringify(s,null,2)+`
22
+ `;await writeFile(e,i,"utf-8");}async function Or(n,t,e){let r=await q(e),s=new Date().toISOString(),i=r.skills[n];r.skills[n]={...t,installedAt:i?.installedAt??s,updatedAt:s},await ue(r,e);}async function jr(n,t){let e=await q(t);return n in e.skills?(delete e.skills[n],await ue(e,t),true):false}function mt(){return {version:ae,skills:{}}}export{vr as $,ct as A,Ze as B,rr as C,ir as D,sr as E,ut as F,Er as G,en as H,nn as I,T as J,ie as K,X as L,se as M,D as N,rn as O,gt as P,oe as Q,dt as R,W as S,Q as T,br as U,Pr as V,cn as W,un as X,Lr as Y,Ir as Z,fn as _,j as a,J as aa,Nn as b,$r as ba,Un as c,Rr as ca,O as d,Ar as da,Ft as e,pt as ea,At as f,le as fa,L as g,Wr as ga,be as h,Kr as ha,Pe as i,Nr as ia,Ut as j,Ur as ja,Dt as k,$n as l,it as m,_t as n,N as o,vt as p,ae as q,ce as r,Hr as s,q as t,ue as u,Or as v,jr as w,Xe as x,Vt as y,Je as z};
@@ -0,0 +1,2 @@
1
+ var u="https://add-skill.vercel.sh/t",m="https://add-skill.vercel.sh/audit",a=null,o=null;function f(t){o=t;}function g(){return !!(process.env.CI||process.env.GITHUB_ACTIONS||process.env.GITLAB_CI||process.env.CIRCLECI||process.env.TRAVIS||process.env.BUILDKITE||process.env.JENKINS_URL||process.env.TEAMCITY_VERSION)}function T(){return !process.env.DISABLE_TELEMETRY&&!process.env.DO_NOT_TRACK}function p(t){a=t;}async function y(t,e,n=3e3){if(e.length===0)return null;try{let s=new URLSearchParams({source:t,skills:e.join(",")}),r=new AbortController,c=setTimeout(()=>r.abort(),n),l=await fetch(`${m}?${s.toString()}`,{signal:r.signal});return clearTimeout(c),l.ok?await l.json():null}catch{return null}}var i=[];function D(t){if(T())try{let e=new URLSearchParams;a&&e.set("v",a),g()&&e.set("ci","1"),o&&e.set("agent",o);for(let[s,r]of Object.entries(t))r!=null&&e.set(s,String(r));let n=fetch(`${u}?${e.toString()}`).catch(()=>{}).then(()=>{});i.push(n);}catch{}}async function C(t=5e3){if(i.length===0)return;let e=new Promise(n=>setTimeout(n,t));await Promise.race([Promise.all(i),e]);}
2
+ export{f as a,p as b,y as c,D as d,C as e};