@braid-cloud/cli 0.1.1 → 0.1.3

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.
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # @braid-cloud/cli
2
2
 
3
- Install [Braid](https://braid.cloud) rules and skills as local files for your AI coding agents.
3
+ Install [Braid](https://braid.cloud) prompts as local files for your AI coding agents.
4
4
 
5
5
  ## What It Does
6
6
 
7
- Syncs your Braid rules and skills to local files that AI coding agents automatically pick up. Works with 30+ agents including Claude Code, Cursor, GitHub Copilot, and more. Once installed, skills work offline.
7
+ Syncs your Braid prompts to local files that AI coding agents automatically pick up. Works with 30+ agents including Claude Code, Cursor, GitHub Copilot, and more. Once installed, skills work offline.
8
8
 
9
9
  ## Quick Start
10
10
 
@@ -26,15 +26,20 @@ braid list
26
26
 
27
27
  ### `braid auth`
28
28
 
29
- Authenticate with your Braid account.
29
+ Authenticate with your Braid account. Runs interactive login by default.
30
30
 
31
31
  ```bash
32
- braid auth # Interactive login
32
+ braid auth # Interactive login (alias for `braid auth login`)
33
33
  braid auth status # Check auth status
34
34
  braid auth logout # Remove stored credentials
35
- braid auth --server https://custom.braid.cloud # Use custom server
36
35
  ```
37
36
 
37
+ The `login` subcommand accepts:
38
+
39
+ | Flag | Description |
40
+ | -------------------- | --------------------------------------------- |
41
+ | `-s, --server <url>` | Braid server URL (for review apps, local dev) |
42
+
38
43
  ### `braid install`
39
44
 
40
45
  Install skills from profiles or projects. Alias: `braid add`
@@ -65,20 +70,20 @@ braid install -p coding-standards --yes
65
70
 
66
71
  **Options:**
67
72
 
68
- | Flag | Description |
69
- | ------------------------------ | ------------------------------------------ |
70
- | `-p, --profile <name>` | Profile to install from |
71
- | `--org-projects <ids>` | Organization project IDs (comma-sep) |
72
- | `--personal-projects <ids>` | Personal project IDs (comma-sep) |
73
- | `--include-user-globals` | Include user's global rules (default: on) |
74
- | `--no-include-user-globals` | Exclude user's global rules |
75
- | `--include-org-globals` | Include org's global rules (default: on) |
76
- | `--no-include-org-globals` | Exclude org's global rules |
77
- | `-a, --agents <list>` | Target specific agents (comma-sep) |
78
- | `-g, --global` | Install to global directories |
79
- | `-l, --list` | Preview skills without installing |
80
- | `-y, --yes` | Skip confirmation prompts |
81
- | `-s, --server <url>` | Override server URL |
73
+ | Flag | Description |
74
+ | --------------------------- | ------------------------------------------- |
75
+ | `-p, --profile <name>` | Profile to install from |
76
+ | `--org-projects <ids>` | Organization project IDs (comma-sep) |
77
+ | `--personal-projects <ids>` | Personal project IDs (comma-sep) |
78
+ | `--include-user-globals` | Include user's global prompts (default: on) |
79
+ | `--no-include-user-globals` | Exclude user's global prompts |
80
+ | `--include-org-globals` | Include org's global prompts (default: on) |
81
+ | `--no-include-org-globals` | Exclude org's global prompts |
82
+ | `-a, --agents <list>` | Target specific agents (comma-sep) |
83
+ | `-g, --global` | Install to global directories |
84
+ | `-l, --list` | Preview skills without installing |
85
+ | `-y, --yes` | Skip confirmation prompts |
86
+ | `-s, --server <url>` | Override server URL |
82
87
 
83
88
  At least one source (`--profile`, `--org-projects`, or `--personal-projects`) is required. The CLI auto-detects installed agents unless `--agents` is specified.
84
89
 
@@ -152,71 +157,71 @@ This lets teams share configuration while each developer uses their own token.
152
157
 
153
158
  Both `braid.json` and `braid.user.json` support these fields. Values in `braid.user.json` override `braid.json`.
154
159
 
155
- | Field | Type | Description |
156
- | ------------------- | -------- | ---------------------------------------- |
157
- | `token` | string | Personal Access Token |
158
- | `serverUrl` | string | Server URL (default: `https://braid.cloud`) |
159
- | `profile` | string | Default profile |
160
- | `orgProjects` | string[] | Organization project IDs |
161
- | `personalProjects` | string[] | Personal project IDs |
162
- | `includeUserGlobal` | boolean | Include user's global rules (default: true) |
163
- | `includeOrgGlobal` | boolean | Include org's global rules (default: true) |
164
- | `agents` | string[] | Target agents |
160
+ | Field | Type | Description |
161
+ | ------------------- | -------- | --------------------------------------------- |
162
+ | `token` | string | Personal Access Token |
163
+ | `serverUrl` | string | Server URL (default: `https://braid.cloud`) |
164
+ | `profile` | string | Default profile |
165
+ | `orgProjects` | string[] | Organization project IDs |
166
+ | `personalProjects` | string[] | Personal project IDs |
167
+ | `includeUserGlobal` | boolean | Include user's global prompts (default: true) |
168
+ | `includeOrgGlobal` | boolean | Include org's global prompts (default: true) |
169
+ | `agents` | string[] | Target agents |
165
170
 
166
171
  ### Environment Variables
167
172
 
168
- | Variable | Description |
169
- | ------------------------- | ----------------------------------------------- |
170
- | `BRAID_API_KEY` | API key (highest priority) |
171
- | `BRAID_SERVER_URL` | Server URL override |
172
- | `BRAID_SKILLS_SERVER_URL` | Override for skills endpoint (falls back to `BRAID_SERVER_URL`) |
173
+ | Variable | Description |
174
+ | ------------------------- | ------------------------------------------------------ |
175
+ | `BRAID_API_KEY` | API key (highest priority) |
176
+ | `BRAID_SERVER_URL` | Server URL override |
177
+ | `BRAID_SKILLS_SERVER_URL` | Skills endpoint URL (falls back to `BRAID_SERVER_URL`) |
173
178
 
174
179
  ## Supported Agents
175
180
 
176
181
  Skills are installed to agent-specific directories. The CLI auto-detects installed agents.
177
182
 
178
- | Agent | Project Path | Global Path |
179
- | --------------- | ---------------------- | -------------------------------------- |
180
- | Claude Code | `.claude/skills/` | `~/.claude/skills/` |
181
- | Cursor | `.cursor/skills/` | `~/.cursor/skills/` |
182
- | GitHub Copilot | `.github/skills/` | `~/.copilot/skills/` |
183
- | OpenCode | `.opencode/skills/` | `~/.config/opencode/skills/` |
184
- | Windsurf | `.windsurf/skills/` | `~/.codeium/windsurf/skills/` |
185
- | Cline | `.cline/skills/` | `~/.cline/skills/` |
186
- | Continue | `.continue/skills/` | `~/.continue/skills/` |
187
- | Gemini CLI | `.gemini/skills/` | `~/.gemini/skills/` |
188
- | Goose | `.goose/skills/` | `~/.config/goose/skills/` |
189
- | Roo Code | `.roo/skills/` | `~/.roo/skills/` |
183
+ | Agent | Project Path | Global Path |
184
+ | -------------- | ------------------- | ----------------------------- |
185
+ | Claude Code | `.claude/skills/` | `~/.claude/skills/` |
186
+ | Cursor | `.cursor/skills/` | `~/.cursor/skills/` |
187
+ | GitHub Copilot | `.github/skills/` | `~/.copilot/skills/` |
188
+ | OpenCode | `.opencode/skills/` | `~/.config/opencode/skills/` |
189
+ | Windsurf | `.windsurf/skills/` | `~/.codeium/windsurf/skills/` |
190
+ | Cline | `.cline/skills/` | `~/.cline/skills/` |
191
+ | Continue | `.continue/skills/` | `~/.continue/skills/` |
192
+ | Gemini CLI | `.gemini/skills/` | `~/.gemini/skills/` |
193
+ | Goose | `.goose/skills/` | `~/.config/goose/skills/` |
194
+ | Roo Code | `.roo/skills/` | `~/.roo/skills/` |
190
195
 
191
196
  <details>
192
197
  <summary>All 30+ supported agents</summary>
193
198
 
194
- | Agent | Project Path | Global Path |
195
- | --------------- | ---------------------- | -------------------------------------- |
196
- | Amp | `.agents/skills/` | `~/.config/agents/skills/` |
197
- | Antigravity | `.agent/skills/` | `~/.gemini/antigravity/global_skills/` |
198
- | CodeBuddy | `.codebuddy/skills/` | `~/.codebuddy/skills/` |
199
- | Codex | `.codex/skills/` | `~/.codex/skills/` |
200
- | Command Code | `.commandcode/skills/` | `~/.commandcode/skills/` |
201
- | Crush | `.crush/skills/` | `~/.config/crush/skills/` |
202
- | Droid | `.factory/skills/` | `~/.factory/skills/` |
203
- | Junie | `.junie/skills/` | `~/.junie/skills/` |
204
- | Kilo Code | `.kilocode/skills/` | `~/.kilocode/skills/` |
205
- | Kimi Code CLI | `.agents/skills/` | `~/.config/agents/skills/` |
206
- | Kiro CLI | `.kiro/skills/` | `~/.kiro/skills/` |
207
- | Kode | `.kode/skills/` | `~/.kode/skills/` |
208
- | MCPJam | `.mcpjam/skills/` | `~/.mcpjam/skills/` |
209
- | Moltbot | `skills/` | `~/.moltbot/skills/` |
210
- | Mux | `.mux/skills/` | `~/.mux/skills/` |
211
- | Neovate | `.neovate/skills/` | `~/.neovate/skills/` |
212
- | OpenHands | `.openhands/skills/` | `~/.openhands/skills/` |
213
- | Pi | `.pi/skills/` | `~/.pi/agent/skills/` |
214
- | Pochi | `.pochi/skills/` | `~/.pochi/skills/` |
215
- | Qoder | `.qoder/skills/` | `~/.qoder/skills/` |
216
- | Qwen Code | `.qwen/skills/` | `~/.qwen/skills/` |
217
- | Trae | `.trae/skills/` | `~/.trae/skills/` |
218
- | Zed | | |
219
- | Zencoder | `.zencoder/skills/` | `~/.zencoder/skills/` |
199
+ | Agent | Project Path | Global Path |
200
+ | ------------- | ---------------------- | -------------------------------------- |
201
+ | Amp | `.agents/skills/` | `~/.config/agents/skills/` |
202
+ | Antigravity | `.agent/skills/` | `~/.gemini/antigravity/global_skills/` |
203
+ | CodeBuddy | `.codebuddy/skills/` | `~/.codebuddy/skills/` |
204
+ | Codex | `.codex/skills/` | `~/.codex/skills/` |
205
+ | Command Code | `.commandcode/skills/` | `~/.commandcode/skills/` |
206
+ | Crush | `.crush/skills/` | `~/.config/crush/skills/` |
207
+ | Droid | `.factory/skills/` | `~/.factory/skills/` |
208
+ | Junie | `.junie/skills/` | `~/.junie/skills/` |
209
+ | Kilo Code | `.kilocode/skills/` | `~/.kilocode/skills/` |
210
+ | Kimi Code CLI | `.agents/skills/` | `~/.config/agents/skills/` |
211
+ | Kiro CLI | `.kiro/skills/` | `~/.kiro/skills/` |
212
+ | Kode | `.kode/skills/` | `~/.kode/skills/` |
213
+ | MCPJam | `.mcpjam/skills/` | `~/.mcpjam/skills/` |
214
+ | Moltbot | `skills/` | `~/.moltbot/skills/` |
215
+ | Mux | `.mux/skills/` | `~/.mux/skills/` |
216
+ | Neovate | `.neovate/skills/` | `~/.neovate/skills/` |
217
+ | OpenHands | `.openhands/skills/` | `~/.openhands/skills/` |
218
+ | Pi | `.pi/skills/` | `~/.pi/agent/skills/` |
219
+ | Pochi | `.pochi/skills/` | `~/.pochi/skills/` |
220
+ | Qoder | `.qoder/skills/` | `~/.qoder/skills/` |
221
+ | Qwen Code | `.qwen/skills/` | `~/.qwen/skills/` |
222
+ | Trae | `.trae/skills/` | `~/.trae/skills/` |
223
+ | Zed | -- | -- |
224
+ | Zencoder | `.zencoder/skills/` | `~/.zencoder/skills/` |
220
225
 
221
226
  </details>
222
227
 
@@ -277,4 +282,4 @@ Installed skills are tracked in `.braidskills-metadata.json` for update detectio
277
282
 
278
283
  ## License
279
284
 
280
- MIT
285
+ Proprietary - see [LICENSE](./LICENSE)
package/dist/index.js CHANGED
@@ -270,6 +270,7 @@ var init_config = __esm({
270
270
 
271
271
  // src/index.ts
272
272
  init_esm_shims();
273
+ import { createRequire } from "module";
273
274
  import { Command } from "commander";
274
275
 
275
276
  // src/commands/auth.ts
@@ -309,7 +310,7 @@ var resolveApiKey = (optionsApiKey) => {
309
310
  Effect2.flatMap(
310
311
  (key) => key ? Effect2.succeed(key) : Effect2.fail(
311
312
  new AuthenticationError({
312
- message: 'No API key configured. Run "pvskills auth" to authenticate.'
313
+ message: 'No API key configured. Run "braid auth" to authenticate.'
313
314
  })
314
315
  )
315
316
  )
@@ -330,7 +331,7 @@ var parseResponse = (response, json) => {
330
331
  if (response.status === 401) {
331
332
  return Effect2.fail(
332
333
  new AuthenticationError({
333
- message: errorResponse.error || "Invalid or expired API key. Run 'pvskills auth' to re-authenticate."
334
+ message: errorResponse.error || "Invalid or expired API key. Run 'braid auth' to re-authenticate."
334
335
  })
335
336
  );
336
337
  }
@@ -2066,10 +2067,12 @@ async function updateCommand(options) {
2066
2067
  }
2067
2068
 
2068
2069
  // src/index.ts
2070
+ var require2 = createRequire(import.meta.url);
2071
+ var { version: PACKAGE_VERSION } = require2("../package.json");
2069
2072
  var program = new Command();
2070
2073
  program.name("braid").description(
2071
2074
  "Install Braid prompts as agent skills to your local development environment"
2072
- ).version("0.1.0");
2075
+ ).version(PACKAGE_VERSION);
2073
2076
  var auth = program.command("auth").description("Configure API key for Braid authentication");
2074
2077
  auth.command("login", { isDefault: true }).description("Configure API key").option("-s, --server <url>", "Braid server URL (for review apps, local dev)").action(authCommand);
2075
2078
  auth.command("status").description("Show current authentication status").action(authStatusCommand);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../node_modules/tsup/assets/esm_shims.js","../src/lib/config.ts","../src/index.ts","../src/commands/auth.ts","../src/lib/api.ts","../src/commands/install.ts","../src/lib/agents.ts","../src/lib/metadata.ts","../src/lib/rule-writer.ts","../src/lib/skill-writer.ts","../src/lib/tui.ts","../src/commands/list.ts","../src/commands/remove.ts","../src/commands/update.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import { existsSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, parse } from \"node:path\";\nimport process from \"node:process\";\nimport { Data, Effect, pipe } from \"effect\";\n\nconst CONFIG_DIR = join(homedir(), \".config\", \"braid\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\nconst PROJECT_CONFIG_FILENAME = \"braid.json\";\nconst USER_CONFIG_FILENAME = \"braid.user.json\";\n\ninterface BraidSkillsConfig {\n apiKey?: string;\n serverUrl?: string;\n}\n\ninterface SkillsConfig {\n serverUrl?: string;\n}\n\ninterface BraidProjectConfig {\n $schema?: string;\n serverUrl?: string;\n profile?: string;\n orgProjects?: string[];\n personalProjects?: string[];\n includeUserGlobal?: boolean;\n includeOrgGlobal?: boolean;\n skills?: SkillsConfig;\n agents?: string[];\n}\n\ninterface BraidUserConfig extends BraidProjectConfig {\n token?: string;\n}\n\ninterface MergedConfig {\n token?: string;\n serverUrl: string;\n profile?: string;\n orgProjects?: string[];\n personalProjects?: string[];\n includeUserGlobal: boolean;\n includeOrgGlobal: boolean;\n agents?: string[];\n}\n\nclass ConfigReadError extends Data.TaggedError(\"ConfigReadError\")<{\n path: string;\n cause: unknown;\n}> {}\n\nclass ConfigWriteError extends Data.TaggedError(\"ConfigWriteError\")<{\n path: string;\n cause: unknown;\n}> {}\n\nconst findConfigFile = (\n filename: string,\n startDir: string = process.cwd()\n): string | undefined => {\n let currentDir = startDir;\n\n while (true) {\n const configPath = join(currentDir, filename);\n if (existsSync(configPath)) {\n return configPath;\n }\n\n const parsed = parse(currentDir);\n if (parsed.root === currentDir) {\n return undefined;\n }\n currentDir = parsed.dir;\n }\n};\n\nconst findProjectConfigFile = (\n startDir: string = process.cwd()\n): string | undefined => findConfigFile(PROJECT_CONFIG_FILENAME, startDir);\n\nconst findUserConfigFile = (\n startDir: string = process.cwd()\n): string | undefined => findConfigFile(USER_CONFIG_FILENAME, startDir);\n\nconst loadProjectConfig = (): Effect.Effect<BraidProjectConfig | undefined> =>\n Effect.tryPromise({\n try: async () => {\n const configPath = await findProjectConfigFile();\n if (!configPath) {\n return undefined;\n }\n const content = await readFile(configPath, \"utf-8\");\n return JSON.parse(content) as BraidProjectConfig;\n },\n catch: () => undefined,\n }).pipe(Effect.orElseSucceed(() => undefined));\n\nconst loadUserConfig = (): Effect.Effect<BraidUserConfig | undefined> =>\n Effect.tryPromise({\n try: async () => {\n const configPath = await findUserConfigFile();\n if (!configPath) {\n return undefined;\n }\n const content = await readFile(configPath, \"utf-8\");\n return JSON.parse(content) as BraidUserConfig;\n },\n catch: () => undefined,\n }).pipe(Effect.orElseSucceed(() => undefined));\n\nconst isValidServerUrl = (url: string): boolean => {\n try {\n const parsed = new URL(url);\n return parsed.protocol === \"https:\" || parsed.protocol === \"http:\";\n } catch {\n return false;\n }\n};\n\nconst resolveServerUrlFromConfig = (\n config: BraidProjectConfig | BraidUserConfig | undefined\n): string | undefined => {\n if (!config) {\n return undefined;\n }\n const url = config.skills?.serverUrl ?? config.serverUrl;\n if (url && !isValidServerUrl(url)) {\n return undefined;\n }\n return url;\n};\n\nconst applyConfigSource = (\n merged: MergedConfig,\n config: BraidProjectConfig | BraidUserConfig | undefined\n): void => {\n if (!config) {\n return;\n }\n\n const serverUrl = resolveServerUrlFromConfig(config);\n if (serverUrl) {\n merged.serverUrl = serverUrl;\n }\n\n if (config.profile) {\n merged.profile = config.profile;\n }\n if (config.orgProjects) {\n merged.orgProjects = config.orgProjects;\n }\n if (config.personalProjects) {\n merged.personalProjects = config.personalProjects;\n }\n if (config.includeUserGlobal !== undefined) {\n merged.includeUserGlobal = config.includeUserGlobal;\n }\n if (config.includeOrgGlobal !== undefined) {\n merged.includeOrgGlobal = config.includeOrgGlobal;\n }\n if (config.agents) {\n merged.agents = config.agents;\n }\n\n if (\"token\" in config && config.token) {\n merged.token = config.token;\n }\n};\n\nconst applyEnvOverrides = (merged: MergedConfig): void => {\n if (process.env.BRAID_API_KEY) {\n merged.token = process.env.BRAID_API_KEY;\n }\n const envServerUrl =\n process.env.BRAID_SKILLS_SERVER_URL ?? process.env.BRAID_SERVER_URL;\n if (envServerUrl && isValidServerUrl(envServerUrl)) {\n merged.serverUrl = envServerUrl;\n }\n};\n\nconst createDefaultMergedConfig = (): MergedConfig => ({\n serverUrl: \"https://braid.cloud\",\n includeUserGlobal: true,\n includeOrgGlobal: true,\n});\n\nconst loadMergedConfig = (): Effect.Effect<MergedConfig> =>\n pipe(\n Effect.all({\n projectConfig: loadProjectConfig(),\n userConfig: loadUserConfig(),\n globalConfig: loadConfig().pipe(\n Effect.orElseSucceed(() => ({}) as BraidSkillsConfig)\n ),\n }),\n Effect.map(({ projectConfig, userConfig, globalConfig }) => {\n const merged = createDefaultMergedConfig();\n\n applyConfigSource(merged, projectConfig);\n\n applyConfigSource(merged, userConfig);\n\n applyEnvOverrides(merged);\n\n if (!merged.token && globalConfig.apiKey) {\n merged.token = globalConfig.apiKey;\n }\n\n return merged;\n })\n );\n\nconst loadConfig = (): Effect.Effect<\n BraidSkillsConfig,\n ConfigReadError | ConfigWriteError\n> =>\n pipe(\n Effect.tryPromise({\n try: () => readFile(CONFIG_FILE, \"utf-8\"),\n catch: (e) => new ConfigReadError({ path: CONFIG_FILE, cause: e }),\n }),\n Effect.flatMap((content) =>\n Effect.try({\n try: () => JSON.parse(content) as BraidSkillsConfig,\n catch: () => ({}) as BraidSkillsConfig,\n })\n ),\n Effect.orElseSucceed(() => ({}) as BraidSkillsConfig)\n );\n\nconst saveConfig = (\n config: BraidSkillsConfig\n): Effect.Effect<void, ConfigWriteError> =>\n pipe(\n Effect.tryPromise({\n try: async () => {\n await mkdir(dirname(CONFIG_FILE), { recursive: true, mode: 0o700 });\n await writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), {\n encoding: \"utf-8\",\n mode: 0o600,\n });\n },\n catch: (e) => new ConfigWriteError({ path: CONFIG_FILE, cause: e }),\n })\n );\n\nconst getApiKey = (): Effect.Effect<\n string | undefined,\n ConfigReadError | ConfigWriteError\n> =>\n pipe(\n Effect.succeed(process.env.BRAID_API_KEY),\n Effect.flatMap((envKey) =>\n envKey\n ? Effect.succeed(envKey)\n : pipe(\n loadUserConfig(),\n Effect.flatMap((userConfig) =>\n userConfig?.token\n ? Effect.succeed(userConfig.token)\n : pipe(\n loadConfig(),\n Effect.map((config) => config.apiKey)\n )\n )\n )\n )\n );\n\nconst setApiKey = (\n apiKey: string\n): Effect.Effect<void, ConfigReadError | ConfigWriteError> =>\n pipe(\n loadConfig(),\n Effect.flatMap((config) => saveConfig({ ...config, apiKey }))\n );\n\nconst getServerUrl = (): Effect.Effect<\n string,\n ConfigReadError | ConfigWriteError\n> =>\n pipe(\n Effect.succeed(process.env.BRAID_SERVER_URL),\n Effect.flatMap((envUrl) =>\n envUrl\n ? Effect.succeed(envUrl)\n : pipe(\n loadUserConfig(),\n Effect.flatMap((userConfig) =>\n userConfig?.serverUrl\n ? Effect.succeed(userConfig.serverUrl)\n : pipe(\n loadConfig(),\n Effect.map(\n (config) => config.serverUrl ?? \"https://braid.cloud\"\n )\n )\n )\n )\n )\n );\n\nconst clearApiKey = (): Effect.Effect<\n void,\n ConfigReadError | ConfigWriteError\n> =>\n pipe(\n loadConfig(),\n Effect.flatMap((config) => {\n const { apiKey: _, ...rest } = config;\n return saveConfig(rest);\n })\n );\n\nconst loadConfigAsync = (): Promise<BraidSkillsConfig> =>\n Effect.runPromise(loadConfig());\n\nconst loadProjectConfigAsync = (): Promise<BraidProjectConfig | undefined> =>\n Effect.runPromise(loadProjectConfig());\n\nconst loadUserConfigAsync = (): Promise<BraidUserConfig | undefined> =>\n Effect.runPromise(loadUserConfig());\n\nconst loadMergedConfigAsync = (): Promise<MergedConfig> =>\n Effect.runPromise(loadMergedConfig());\n\nconst findProjectConfigFileAsync = (startDir?: string): string | undefined =>\n findProjectConfigFile(startDir);\n\nconst findUserConfigFileAsync = (startDir?: string): string | undefined =>\n findUserConfigFile(startDir);\n\nconst saveConfigAsync = (config: BraidSkillsConfig): Promise<void> =>\n Effect.runPromise(saveConfig(config));\n\nconst getApiKeyAsync = (): Promise<string | undefined> =>\n Effect.runPromise(getApiKey());\n\nconst setApiKeyAsync = (apiKey: string): Promise<void> =>\n Effect.runPromise(setApiKey(apiKey));\n\nconst getServerUrlAsync = (): Promise<string> =>\n Effect.runPromise(getServerUrl());\n\nconst clearApiKeyAsync = (): Promise<void> => Effect.runPromise(clearApiKey());\n\nexport type {\n BraidProjectConfig,\n BraidSkillsConfig,\n BraidUserConfig,\n MergedConfig,\n};\nexport {\n clearApiKey,\n clearApiKeyAsync,\n CONFIG_DIR,\n CONFIG_FILE,\n ConfigReadError,\n ConfigWriteError,\n findProjectConfigFile,\n findProjectConfigFileAsync,\n findUserConfigFile,\n findUserConfigFileAsync,\n getApiKey,\n getApiKeyAsync,\n getServerUrl,\n getServerUrlAsync,\n loadConfig,\n loadConfigAsync,\n loadMergedConfig,\n loadMergedConfigAsync,\n loadProjectConfig,\n loadProjectConfigAsync,\n loadUserConfig,\n loadUserConfigAsync,\n PROJECT_CONFIG_FILENAME,\n saveConfig,\n saveConfigAsync,\n setApiKey,\n setApiKeyAsync,\n USER_CONFIG_FILENAME,\n};\n","import { Command } from \"commander\";\nimport {\n authCommand,\n authLogoutCommand,\n authStatusCommand,\n} from \"./commands/auth.ts\";\nimport { installCommand } from \"./commands/install.ts\";\nimport { listCommand } from \"./commands/list.ts\";\nimport { removeCommand } from \"./commands/remove.ts\";\nimport { updateCommand } from \"./commands/update.ts\";\n\nconst program = new Command();\n\nprogram\n .name(\"braid\")\n .description(\n \"Install Braid prompts as agent skills to your local development environment\"\n )\n .version(\"0.1.0\");\n\nconst auth = program\n .command(\"auth\")\n .description(\"Configure API key for Braid authentication\");\n\nauth\n .command(\"login\", { isDefault: true })\n .description(\"Configure API key\")\n .option(\"-s, --server <url>\", \"Braid server URL (for review apps, local dev)\")\n .action(authCommand);\n\nauth\n .command(\"status\")\n .description(\"Show current authentication status\")\n .action(authStatusCommand);\n\nauth\n .command(\"logout\")\n .description(\"Remove stored API key\")\n .action(authLogoutCommand);\n\nprogram\n .command(\"install\")\n .alias(\"add\")\n .description(\"Install skills from a profile or project\")\n .option(\"-p, --profile <name>\", \"Profile name to install from\")\n .option(\n \"--org-projects <ids>\",\n \"Comma-separated organization project IDs to install from\"\n )\n .option(\n \"--personal-projects <ids>\",\n \"Comma-separated personal project IDs to install from\"\n )\n .option(\n \"--include-user-globals\",\n \"Include user's personal global prompts (default: true)\"\n )\n .option(\"--no-include-user-globals\", \"Exclude user's personal global prompts\")\n .option(\n \"--include-org-globals\",\n \"Include organization's global prompts (default: true)\"\n )\n .option(\"--no-include-org-globals\", \"Exclude organization's global prompts\")\n .option(\n \"-a, --agents <list>\",\n \"Comma-separated list of agents (e.g., claude-code,opencode)\"\n )\n .option(\"-g, --global\", \"Install to global agent directories\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"-l, --list\", \"Preview skills without installing\")\n .option(\"-s, --server <url>\", \"Braid server URL (for review apps, local dev)\")\n .action(installCommand);\n\nprogram\n .command(\"list\")\n .alias(\"ls\")\n .description(\"List installed skills\")\n .option(\"-g, --global\", \"List skills in global directories only\")\n .action(listCommand);\n\nprogram\n .command(\"update\")\n .alias(\"up\")\n .description(\"Update installed skills to the latest version\")\n .option(\"-g, --global\", \"Update skills in global directories only\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"-s, --server <url>\", \"Braid server URL (for review apps, local dev)\")\n .action(updateCommand);\n\nprogram\n .command(\"remove\")\n .alias(\"rm\")\n .description(\"Remove installed skills\")\n .option(\"-a, --all\", \"Remove all installed skills\")\n .option(\"-g, --global\", \"Remove skills from global directories only\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"--skill <name>\", \"Remove a specific skill by name\")\n .action(removeCommand);\n\nprogram.parse();\n","import process from \"node:process\";\nimport {\n cancel,\n confirm,\n intro,\n isCancel,\n log,\n outro,\n password,\n spinner,\n} from \"@clack/prompts\";\nimport { validateApiKeyAsync } from \"../lib/api.ts\";\nimport type { MergedConfig } from \"../lib/config.ts\";\nimport {\n CONFIG_FILE,\n findProjectConfigFileAsync,\n findUserConfigFileAsync,\n loadMergedConfigAsync,\n setApiKeyAsync,\n USER_CONFIG_FILENAME,\n} from \"../lib/config.ts\";\n\ninterface AuthOptions {\n server?: string;\n}\n\nexport async function authCommand(options: AuthOptions): Promise<void> {\n intro(\"braid auth\");\n\n const config = await loadMergedConfigAsync();\n if (config.token) {\n const shouldReplace = await confirm({\n message: \"An API key is already configured. Replace it?\",\n initialValue: false,\n });\n\n if (isCancel(shouldReplace) || !shouldReplace) {\n outro(\"Auth cancelled.\");\n return;\n }\n }\n\n const apiKey = await password({\n message: \"Enter your Braid API key:\",\n validate: (value) => {\n if (!value) {\n return \"API key is required\";\n }\n if (!value.startsWith(\"br_\")) {\n return \"API key should start with 'br_'\";\n }\n return undefined;\n },\n });\n\n if (isCancel(apiKey)) {\n cancel(\"Auth cancelled.\");\n process.exit(0);\n }\n\n const authSpinner = spinner();\n authSpinner.start(\"Validating API key...\");\n\n try {\n const serverUrl = options.server ?? \"https://braid.cloud\";\n const isValid = await validateApiKeyAsync(apiKey, serverUrl);\n\n if (!isValid) {\n authSpinner.stop(\"Invalid API key\");\n log.error(\n \"The API key could not be validated. Please check your key and try again.\"\n );\n process.exit(1);\n }\n\n await setApiKeyAsync(apiKey);\n authSpinner.stop(\"API key validated and saved\");\n\n log.success(`Config saved to ${CONFIG_FILE}`);\n outro(\n \"You're authenticated! Run 'braid install --profile <name>' to install skills.\"\n );\n } catch (error) {\n authSpinner.stop(\"Validation failed\");\n const message = error instanceof Error ? error.message : String(error);\n log.error(`Failed to validate API key: ${message}`);\n process.exit(1);\n }\n}\n\nasync function displayTokenSource(masked: string): Promise<void> {\n if (process.env.BRAID_API_KEY) {\n log.info(`Authenticated with key: ${masked}`);\n log.info(\"Source: BRAID_API_KEY environment variable\");\n return;\n }\n\n const userConfigPath = await findUserConfigFileAsync();\n log.info(`Authenticated with key: ${masked}`);\n log.info(`Source: ${userConfigPath ?? CONFIG_FILE}`);\n}\n\nasync function displayProjectConfig(): Promise<void> {\n const projectConfigPath = await findProjectConfigFileAsync();\n if (projectConfigPath) {\n log.info(`Project config: ${projectConfigPath}`);\n }\n}\n\nfunction displayResolvedSettings(config: MergedConfig): void {\n const hasOrgProjects = config.orgProjects && config.orgProjects.length > 0;\n const hasPersonalProjects =\n config.personalProjects && config.personalProjects.length > 0;\n\n if (!(config.profile || hasOrgProjects || hasPersonalProjects)) {\n return;\n }\n\n log.info(\"\");\n\n if (config.profile) {\n log.info(`Default profile: ${config.profile}`);\n }\n if (hasOrgProjects) {\n log.info(`Org projects: ${config.orgProjects?.join(\", \")}`);\n }\n if (hasPersonalProjects) {\n log.info(`Personal projects: ${config.personalProjects?.join(\", \")}`);\n }\n if (config.serverUrl !== \"https://braid.cloud\") {\n log.info(`Server: ${config.serverUrl}`);\n }\n}\n\nexport async function authStatusCommand(): Promise<void> {\n const config = await loadMergedConfigAsync();\n\n if (!config.token) {\n log.warn(\"Not authenticated. Run 'braid auth' to configure your API key.\");\n log.info(\n `Or create a ${USER_CONFIG_FILENAME} file with: { \"token\": \"br_xxx\" }`\n );\n return;\n }\n\n const masked = `${config.token.slice(0, 7)}...${config.token.slice(-4)}`;\n\n await displayTokenSource(masked);\n await displayProjectConfig();\n displayResolvedSettings(config);\n}\n\nexport async function authLogoutCommand(): Promise<void> {\n const { clearApiKeyAsync } = await import(\"../lib/config.ts\");\n await clearApiKeyAsync();\n log.success(\"Logged out. API key removed from config.\");\n}\n","import { Data, Effect, pipe } from \"effect\";\nimport { getApiKeyAsync, getServerUrlAsync } from \"./config.ts\";\n\nconst TRAILING_SLASH_REGEX = /\\/$/;\n\ninterface SkillFile {\n path: string;\n content: string;\n encoding?: \"base64\";\n}\n\ninterface Skill {\n name: string;\n files: SkillFile[];\n}\n\ninterface ExportedRule {\n name: string;\n title: string;\n content: string;\n}\n\ninterface SkillsExportResponse {\n source: {\n type: \"profile\" | \"projects\";\n name: string;\n orgProjects?: string[];\n personalProjects?: string[];\n };\n version: string;\n skills: Skill[];\n rules?: ExportedRule[];\n}\n\ninterface ApiErrorResponse {\n error: string;\n code: string;\n}\n\nclass ApiError extends Data.TaggedError(\"ApiError\")<{\n message: string;\n code: string;\n status: number;\n}> {}\n\nclass AuthenticationError extends Data.TaggedError(\"AuthenticationError\")<{\n message: string;\n}> {}\n\nclass NetworkError extends Data.TaggedError(\"NetworkError\")<{\n message: string;\n cause?: unknown;\n}> {}\n\ntype FetchSkillsError = ApiError | AuthenticationError | NetworkError;\n\ninterface FetchSkillsOptions {\n profile?: string;\n orgProjects?: string[];\n personalProjects?: string[];\n includeUserGlobal?: boolean;\n includeOrgGlobal?: boolean;\n serverUrl?: string;\n apiKey?: string;\n}\n\nconst resolveApiKey = (\n optionsApiKey?: string\n): Effect.Effect<string, AuthenticationError | NetworkError> => {\n if (optionsApiKey) {\n return Effect.succeed(optionsApiKey);\n }\n\n return pipe(\n Effect.tryPromise({\n try: () => getApiKeyAsync(),\n catch: () => new NetworkError({ message: \"Failed to read config\" }),\n }),\n Effect.flatMap((key) =>\n key\n ? Effect.succeed(key)\n : Effect.fail(\n new AuthenticationError({\n message:\n 'No API key configured. Run \"pvskills auth\" to authenticate.',\n })\n )\n )\n );\n};\n\nconst resolveServerUrl = (\n optionsServerUrl?: string\n): Effect.Effect<string, NetworkError> => {\n if (optionsServerUrl) {\n return Effect.succeed(optionsServerUrl);\n }\n\n return Effect.tryPromise({\n try: () => getServerUrlAsync(),\n catch: () => new NetworkError({ message: \"Failed to read config\" }),\n });\n};\n\nconst parseResponse = (\n response: Response,\n json: unknown\n): Effect.Effect<SkillsExportResponse, FetchSkillsError> => {\n if (!response.ok) {\n const errorResponse = json as ApiErrorResponse;\n\n if (response.status === 401) {\n return Effect.fail(\n new AuthenticationError({\n message:\n errorResponse.error ||\n \"Invalid or expired API key. Run 'pvskills auth' to re-authenticate.\",\n })\n );\n }\n\n return Effect.fail(\n new ApiError({\n message: errorResponse.error || \"API request failed\",\n code: errorResponse.code || \"UNKNOWN_ERROR\",\n status: response.status,\n })\n );\n }\n\n return Effect.succeed(json as SkillsExportResponse);\n};\n\n/**\n * Fetches skills from the braid API\n *\n * @param options.profile - Profile name to fetch skills from\n * @param options.orgProjects - Array of org project IDs to fetch skills from\n * @param options.personalProjects - Array of personal project IDs to fetch skills from\n * @param options.serverUrl - Override server URL (for review apps, local dev)\n * @param options.apiKey - Override API key (for testing)\n */\nconst buildApiUrl = (serverUrl: string, path: string): URL => {\n const baseUrl = serverUrl.replace(TRAILING_SLASH_REGEX, \"\");\n return new URL(`${baseUrl}${path}`);\n};\n\nconst buildExportUrl = (\n serverUrl: string,\n options: FetchSkillsOptions\n): URL => {\n const url = buildApiUrl(serverUrl, \"/api/skills/export\");\n\n if (options.profile) {\n url.searchParams.set(\"profile\", options.profile);\n }\n if (options.orgProjects && options.orgProjects.length > 0) {\n url.searchParams.set(\"orgProjects\", options.orgProjects.join(\",\"));\n }\n if (options.personalProjects && options.personalProjects.length > 0) {\n url.searchParams.set(\n \"personalProjects\",\n options.personalProjects.join(\",\")\n );\n }\n if (options.includeUserGlobal !== undefined) {\n url.searchParams.set(\n \"includeUserGlobal\",\n String(options.includeUserGlobal)\n );\n }\n if (options.includeOrgGlobal !== undefined) {\n url.searchParams.set(\"includeOrgGlobal\", String(options.includeOrgGlobal));\n }\n\n return url;\n};\n\nconst executeApiRequest = (\n url: URL,\n apiKey: string,\n serverUrl: string\n): Effect.Effect<SkillsExportResponse, FetchSkillsError> =>\n pipe(\n Effect.tryPromise({\n try: () =>\n fetch(url.toString(), {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n }),\n catch: (e) =>\n new NetworkError({\n message: `Failed to connect to ${serverUrl}`,\n cause: e,\n }),\n }),\n Effect.flatMap((response) =>\n pipe(\n Effect.tryPromise({\n try: () => response.json() as Promise<unknown>,\n catch: () =>\n new NetworkError({ message: \"Failed to parse API response\" }),\n }),\n Effect.flatMap((json) => parseResponse(response, json))\n )\n )\n );\n\nconst fetchSkills = (\n options: FetchSkillsOptions\n): Effect.Effect<SkillsExportResponse, FetchSkillsError> =>\n pipe(\n Effect.all({\n apiKey: resolveApiKey(options.apiKey),\n serverUrl: resolveServerUrl(options.serverUrl),\n }),\n Effect.flatMap(({ apiKey, serverUrl }) => {\n const url = buildExportUrl(serverUrl, options);\n return executeApiRequest(url, apiKey, serverUrl);\n })\n );\n\n/**\n * Validates an API key by making a test request\n *\n * @param apiKey - API key to validate\n * @param serverUrl - Server URL to validate against (defaults to production)\n */\nconst validateApiKey = (\n apiKey: string,\n serverUrl?: string\n): Effect.Effect<boolean, NetworkError> =>\n pipe(\n Effect.tryPromise({\n try: async () => {\n const baseUrl = serverUrl ?? \"https://braid.cloud\";\n const url = buildApiUrl(baseUrl, \"/api/skills/export\");\n url.searchParams.set(\"profile\", \"default\");\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n });\n return response.status !== 401;\n },\n catch: (e) =>\n new NetworkError({\n message: `Failed to connect to ${serverUrl ?? \"https://braid.cloud\"}`,\n cause: e,\n }),\n })\n );\n\nconst fetchSkillsAsync = (\n options: FetchSkillsOptions\n): Promise<SkillsExportResponse> => Effect.runPromise(fetchSkills(options));\n\nconst validateApiKeyAsync = (\n apiKey: string,\n serverUrl?: string\n): Promise<boolean> => Effect.runPromise(validateApiKey(apiKey, serverUrl));\n\nexport type {\n ApiErrorResponse,\n ExportedRule,\n FetchSkillsOptions,\n Skill,\n SkillFile,\n SkillsExportResponse,\n};\nexport {\n ApiError,\n AuthenticationError,\n fetchSkills,\n fetchSkillsAsync,\n NetworkError,\n validateApiKey,\n validateApiKeyAsync,\n};\n","import type { AgentId, DetectedAgent } from \"../lib/agents.ts\";\nimport {\n detectAgentsAsync,\n getAgentById,\n resolveInstallPath,\n resolveRulesInstallPath,\n} from \"../lib/agents.ts\";\nimport type { FetchSkillsOptions, SkillsExportResponse } from \"../lib/api.ts\";\nimport { fetchSkillsAsync } from \"../lib/api.ts\";\nimport type { MergedConfig } from \"../lib/config.ts\";\nimport { loadMergedConfigAsync } from \"../lib/config.ts\";\nimport { updateMetadataAsync } from \"../lib/metadata.ts\";\nimport { writeRulesForAgentAsync } from \"../lib/rule-writer.ts\";\nimport { writeSkillsAsync } from \"../lib/skill-writer.ts\";\nimport {\n cancel,\n intro,\n isCancel,\n log,\n multiselect,\n outro,\n spinner,\n} from \"../lib/tui.ts\";\n\ninterface InstallOptions {\n profile?: string;\n orgProjects?: string;\n personalProjects?: string;\n includeUserGlobals?: boolean;\n includeOrgGlobals?: boolean;\n agents?: string;\n global?: boolean;\n yes?: boolean;\n list?: boolean;\n server?: string;\n}\n\ninterface ResolvedInstallConfig {\n profile: string | undefined;\n serverUrl: string;\n includeUserGlobal: boolean;\n includeOrgGlobal: boolean;\n orgProjects: string[] | undefined;\n personalProjects: string[] | undefined;\n}\n\nfunction resolveInstallConfig(\n options: InstallOptions,\n config: MergedConfig\n): ResolvedInstallConfig {\n const orgProjectsFromFlag = options.orgProjects\n ? options.orgProjects.split(\",\").map((s) => s.trim())\n : undefined;\n const personalProjectsFromFlag = options.personalProjects\n ? options.personalProjects.split(\",\").map((s) => s.trim())\n : undefined;\n\n return {\n profile: options.profile ?? config.profile,\n serverUrl: options.server ?? config.serverUrl,\n includeUserGlobal: options.includeUserGlobals ?? config.includeUserGlobal,\n includeOrgGlobal: options.includeOrgGlobals ?? config.includeOrgGlobal,\n orgProjects: orgProjectsFromFlag ?? config.orgProjects,\n personalProjects: personalProjectsFromFlag ?? config.personalProjects,\n };\n}\n\nfunction validateInstallOptions(resolved: ResolvedInstallConfig): void {\n const { profile, orgProjects, personalProjects } = resolved;\n const hasOrgProjects = orgProjects && orgProjects.length > 0;\n const hasPersonalProjects = personalProjects && personalProjects.length > 0;\n\n if (!(profile || hasOrgProjects || hasPersonalProjects)) {\n log.error(\"No profile or project(s) specified.\");\n log.info(\"Either:\");\n log.info(\n \" - Add 'profile', 'orgProjects', or 'personalProjects' to braid.json/braid.user.json\"\n );\n log.info(\" - Use --profile, --org-projects, or --personal-projects flags\");\n log.info(\"\");\n log.info(\"Examples:\");\n log.info(\" braid install --profile coding-standards\");\n log.info(\" braid install --org-projects proj123,proj456\");\n log.info(\" braid install --personal-projects myproj1\");\n process.exit(1);\n }\n}\n\nfunction buildSourceDescription(resolved: ResolvedInstallConfig): string {\n const { profile, orgProjects, personalProjects } = resolved;\n\n if (profile) {\n return `profile '${profile}'`;\n }\n\n const hasOrgProjects = orgProjects && orgProjects.length > 0;\n const hasPersonalProjects = personalProjects && personalProjects.length > 0;\n\n if (hasOrgProjects || hasPersonalProjects) {\n const totalProjects =\n (orgProjects?.length ?? 0) + (personalProjects?.length ?? 0);\n return totalProjects === 1\n ? `project ${orgProjects?.[0] ?? personalProjects?.[0]}`\n : `${totalProjects} projects`;\n }\n\n return \"unknown source\";\n}\n\nfunction buildFetchOptions(\n resolved: ResolvedInstallConfig\n): FetchSkillsOptions {\n const fetchOptions: FetchSkillsOptions = {\n serverUrl: resolved.serverUrl,\n includeUserGlobal: resolved.includeUserGlobal,\n includeOrgGlobal: resolved.includeOrgGlobal,\n };\n\n if (resolved.profile) {\n fetchOptions.profile = resolved.profile;\n }\n if (resolved.orgProjects && resolved.orgProjects.length > 0) {\n fetchOptions.orgProjects = resolved.orgProjects;\n }\n if (resolved.personalProjects && resolved.personalProjects.length > 0) {\n fetchOptions.personalProjects = resolved.personalProjects;\n }\n\n return fetchOptions;\n}\n\nfunction displaySkillsAndExit(skills: SkillsExportResponse[\"skills\"]): never {\n log.info(\"\\nSkills:\");\n for (const skill of skills) {\n const fileCount = skill.files.length;\n log.info(\n ` ${skill.name} (${fileCount} file${fileCount !== 1 ? \"s\" : \"\"})`\n );\n }\n process.exit(0);\n}\n\nasync function resolveAgents(\n options: InstallOptions,\n installSpinner: ReturnType<typeof spinner>\n): Promise<DetectedAgent[]> {\n if (options.agents) {\n const agentIds = options.agents.split(\",\").map((s) => s.trim() as AgentId);\n const selectedAgents = agentIds\n .map((id) => {\n const agentConfig = getAgentById(id);\n if (!agentConfig) {\n log.warn(`Unknown agent: ${id}`);\n return null;\n }\n return {\n ...agentConfig,\n hasProjectConfig: true,\n hasGlobalConfig: true,\n } as DetectedAgent;\n })\n .filter((a): a is DetectedAgent => a !== null);\n\n if (selectedAgents.length === 0) {\n log.error(\"No valid agents specified.\");\n process.exit(1);\n }\n\n return selectedAgents;\n }\n\n installSpinner.start(\"Detecting installed agents...\");\n const allDetectedAgents = await detectAgentsAsync();\n\n const detectedAgents = allDetectedAgents.filter((agent) =>\n options.global ? agent.hasGlobalConfig : agent.hasProjectConfig\n );\n\n const targetType = options.global ? \"global\" : \"project\";\n installSpinner.stop(\n `Detected ${detectedAgents.length} agent(s) with ${targetType} config`\n );\n\n for (const agent of detectedAgents) {\n const targetPath = options.global ? agent.globalPath : agent.projectPath;\n log.info(` ${agent.name} → ${targetPath}`);\n }\n\n if (detectedAgents.length === 0) {\n log.warn(\"No AI coding agents detected.\");\n log.info(\n \"Supported agents: claude-code, opencode, cursor, windsurf, cline, and more.\"\n );\n log.info(\n \"Use --agents to specify agents manually: braid install -p my-profile -a claude-code\"\n );\n process.exit(1);\n }\n\n return detectedAgents;\n}\n\nasync function selectAgents(\n detectedAgents: DetectedAgent[],\n options: InstallOptions\n): Promise<DetectedAgent[]> {\n if (options.yes) {\n return detectedAgents;\n }\n\n const agentChoices = detectedAgents.map((agent) => ({\n value: agent,\n label: agent.name,\n hint: options.global ? agent.globalPath : agent.projectPath,\n }));\n\n const selected = await multiselect({\n message: \"Select agents to install to:\",\n options: agentChoices,\n initialValues: detectedAgents,\n required: true,\n });\n\n if (isCancel(selected)) {\n cancel(\"Install cancelled.\");\n process.exit(0);\n }\n\n return selected;\n}\n\nasync function installSkillsToAgent(\n agent: DetectedAgent,\n response: SkillsExportResponse,\n installPath: string\n): Promise<{ written: number; errors: number }> {\n if (response.skills.length === 0 || !agent.projectPath) {\n return { written: 0, errors: 0 };\n }\n\n const result = await writeSkillsAsync(installPath, response.skills, agent.id);\n\n for (const err of result.errors) {\n log.warn(` Failed skill: ${err.skill} - ${err.error}`);\n }\n\n return { written: result.written.length, errors: result.errors.length };\n}\n\nasync function installRulesToAgent(\n agent: DetectedAgent,\n response: SkillsExportResponse,\n options: InstallOptions\n): Promise<{ written: number; errors: number }> {\n const rules = response.rules ?? [];\n const rulesPath = resolveRulesInstallPath(agent, {\n global: options.global === true,\n });\n\n if (rules.length === 0 || !rulesPath || !agent.ruleFormat) {\n return { written: 0, errors: 0 };\n }\n\n const result = await writeRulesForAgentAsync(agent, rules, rulesPath);\n\n for (const err of result.errors) {\n log.warn(` Failed rules: ${err.agent} - ${err.error}`);\n }\n\n return { written: result.written, errors: result.errors.length };\n}\n\nfunction formatInstallSummary(\n agentName: string,\n skillsWritten: number,\n rulesWritten: number\n): string {\n const parts: string[] = [];\n if (skillsWritten > 0) {\n parts.push(`${skillsWritten} skills`);\n }\n if (rulesWritten > 0) {\n parts.push(`${rulesWritten} rules`);\n }\n return `${agentName}: ${parts.join(\", \")} installed`;\n}\n\nasync function installToAgent(\n agent: DetectedAgent,\n response: SkillsExportResponse,\n serverUrl: string,\n options: InstallOptions,\n installSpinner: ReturnType<typeof spinner>\n): Promise<{ written: number; errors: number }> {\n const installPath = resolveInstallPath(agent, {\n global: options.global === true,\n });\n\n installSpinner.start(`Installing to ${agent.name}...`);\n\n const skills = installPath\n ? await installSkillsToAgent(agent, response, installPath)\n : { written: 0, errors: 0 };\n const rules = await installRulesToAgent(agent, response, options);\n\n const totalWritten = skills.written + rules.written;\n const totalErrors = skills.errors + rules.errors;\n\n if (totalErrors > 0) {\n installSpinner.stop(\n `${agent.name}: ${totalWritten} installed, ${totalErrors} failed`\n );\n } else {\n installSpinner.stop(\n formatInstallSummary(agent.name, skills.written, rules.written)\n );\n }\n\n if (response.skills.length > 0 && installPath) {\n await updateMetadataAsync(\n installPath,\n response.skills.map((s) => ({\n name: s.name,\n source: response.source,\n version: response.version,\n serverUrl,\n }))\n );\n }\n\n return { written: totalWritten, errors: totalErrors };\n}\n\nexport async function installCommand(options: InstallOptions): Promise<void> {\n const config = await loadMergedConfigAsync();\n const resolved = resolveInstallConfig(options, config);\n\n validateInstallOptions(resolved);\n\n const sourceDesc = buildSourceDescription(resolved);\n intro(`Installing from ${sourceDesc}`);\n\n const installSpinner = spinner();\n installSpinner.start(\"Fetching from Braid...\");\n\n try {\n const fetchOptions = buildFetchOptions(resolved);\n const response = await fetchSkillsAsync(fetchOptions);\n\n const ruleCount = response.rules?.length ?? 0;\n const skillCount = response.skills.length;\n const foundParts: string[] = [];\n if (skillCount > 0) {\n foundParts.push(`${skillCount} skills`);\n }\n if (ruleCount > 0) {\n foundParts.push(`${ruleCount} rules`);\n }\n installSpinner.stop(`Found ${foundParts.join(\", \") || \"nothing\"}`);\n\n if (skillCount === 0 && ruleCount === 0) {\n log.warn(\n \"No skills or rules found. Check that your profile/project has enabled prompts.\"\n );\n process.exit(0);\n }\n\n if (options.list) {\n displaySkillsAndExit(response.skills);\n }\n\n let selectedAgents = await resolveAgents(options, installSpinner);\n if (!options.agents) {\n selectedAgents = await selectAgents(selectedAgents, options);\n }\n\n let totalWritten = 0;\n let totalErrors = 0;\n\n for (const agent of selectedAgents) {\n const result = await installToAgent(\n agent,\n response,\n resolved.serverUrl,\n options,\n installSpinner\n );\n totalWritten += result.written;\n totalErrors += result.errors;\n }\n\n if (totalErrors > 0) {\n outro(`Installed ${totalWritten} items with ${totalErrors} errors.`);\n } else {\n outro(\n `Successfully installed ${totalWritten} items to ${selectedAgents.length} agent(s).`\n );\n }\n\n log.info(\"Run 'braid list' to see installed skills.\");\n } catch (error) {\n installSpinner.stop(\"Install failed\");\n const message = error instanceof Error ? error.message : String(error);\n log.error(message);\n process.exit(1);\n }\n}\n","import { access, constants } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport { Effect, pipe } from \"effect\";\n\ntype AgentId =\n | \"amp\"\n | \"kimi-cli\"\n | \"antigravity\"\n | \"claude-code\"\n | \"moltbot\"\n | \"cline\"\n | \"codebuddy\"\n | \"codex\"\n | \"command-code\"\n | \"continue\"\n | \"crush\"\n | \"cursor\"\n | \"droid\"\n | \"gemini-cli\"\n | \"github-copilot\"\n | \"goose\"\n | \"junie\"\n | \"kilo\"\n | \"kiro-cli\"\n | \"kode\"\n | \"mcpjam\"\n | \"mux\"\n | \"opencode\"\n | \"openhands\"\n | \"pi\"\n | \"qoder\"\n | \"qwen-code\"\n | \"roo\"\n | \"trae\"\n | \"windsurf\"\n | \"zencoder\"\n | \"neovate\"\n | \"pochi\"\n | \"zed\";\n\ntype RuleFormat = \"mdc\" | \"markdown-dir\" | \"append-single\";\n\ninterface AgentConfig {\n id: AgentId;\n name: string;\n projectPath: string;\n globalPath: string;\n rulesProjectPath?: string;\n rulesGlobalPath?: string;\n ruleFormat?: RuleFormat;\n}\n\nconst home = homedir();\n\nconst AGENTS: AgentConfig[] = [\n {\n id: \"amp\",\n name: \"Amp, Kimi Code CLI\",\n projectPath: \".agents/skills\",\n globalPath: join(home, \".config\", \"agents\", \"skills\"),\n },\n {\n id: \"kimi-cli\",\n name: \"Kimi Code CLI\",\n projectPath: \".agents/skills\",\n globalPath: join(home, \".config\", \"agents\", \"skills\"),\n },\n {\n id: \"antigravity\",\n name: \"Antigravity\",\n projectPath: \".agent/skills\",\n globalPath: join(home, \".gemini\", \"antigravity\", \"global_skills\"),\n },\n {\n id: \"claude-code\",\n name: \"Claude Code\",\n projectPath: \".claude/skills\",\n globalPath: join(home, \".claude\", \"skills\"),\n rulesProjectPath: \".claude/rules\",\n rulesGlobalPath: join(home, \".claude\", \"rules\"),\n ruleFormat: \"markdown-dir\",\n },\n {\n id: \"moltbot\",\n name: \"Moltbot\",\n projectPath: \"skills\",\n globalPath: join(home, \".moltbot\", \"skills\"),\n },\n {\n id: \"cline\",\n name: \"Cline\",\n projectPath: \".cline/skills\",\n globalPath: join(home, \".cline\", \"skills\"),\n rulesProjectPath: \".clinerules\",\n ruleFormat: \"append-single\",\n },\n {\n id: \"codebuddy\",\n name: \"CodeBuddy\",\n projectPath: \".codebuddy/skills\",\n globalPath: join(home, \".codebuddy\", \"skills\"),\n },\n {\n id: \"codex\",\n name: \"Codex\",\n projectPath: \".codex/skills\",\n globalPath: join(home, \".codex\", \"skills\"),\n },\n {\n id: \"command-code\",\n name: \"Command Code\",\n projectPath: \".commandcode/skills\",\n globalPath: join(home, \".commandcode\", \"skills\"),\n },\n {\n id: \"continue\",\n name: \"Continue\",\n projectPath: \".continue/skills\",\n globalPath: join(home, \".continue\", \"skills\"),\n },\n {\n id: \"crush\",\n name: \"Crush\",\n projectPath: \".crush/skills\",\n globalPath: join(home, \".config\", \"crush\", \"skills\"),\n },\n {\n id: \"cursor\",\n name: \"Cursor\",\n projectPath: \".cursor/skills\",\n globalPath: join(home, \".cursor\", \"skills\"),\n rulesProjectPath: \".cursor/rules\",\n ruleFormat: \"mdc\",\n },\n {\n id: \"droid\",\n name: \"Droid\",\n projectPath: \".factory/skills\",\n globalPath: join(home, \".factory\", \"skills\"),\n },\n {\n id: \"gemini-cli\",\n name: \"Gemini CLI\",\n projectPath: \".gemini/skills\",\n globalPath: join(home, \".gemini\", \"skills\"),\n },\n {\n id: \"github-copilot\",\n name: \"GitHub Copilot\",\n projectPath: \".github/skills\",\n globalPath: join(home, \".copilot\", \"skills\"),\n rulesProjectPath: \".github/copilot-instructions.md\",\n ruleFormat: \"append-single\",\n },\n {\n id: \"goose\",\n name: \"Goose\",\n projectPath: \".goose/skills\",\n globalPath: join(home, \".config\", \"goose\", \"skills\"),\n },\n {\n id: \"junie\",\n name: \"Junie\",\n projectPath: \".junie/skills\",\n globalPath: join(home, \".junie\", \"skills\"),\n },\n {\n id: \"kilo\",\n name: \"Kilo Code\",\n projectPath: \".kilocode/skills\",\n globalPath: join(home, \".kilocode\", \"skills\"),\n },\n {\n id: \"kiro-cli\",\n name: \"Kiro CLI\",\n projectPath: \".kiro/skills\",\n globalPath: join(home, \".kiro\", \"skills\"),\n },\n {\n id: \"kode\",\n name: \"Kode\",\n projectPath: \".kode/skills\",\n globalPath: join(home, \".kode\", \"skills\"),\n },\n {\n id: \"mcpjam\",\n name: \"MCPJam\",\n projectPath: \".mcpjam/skills\",\n globalPath: join(home, \".mcpjam\", \"skills\"),\n },\n {\n id: \"mux\",\n name: \"Mux\",\n projectPath: \".mux/skills\",\n globalPath: join(home, \".mux\", \"skills\"),\n },\n {\n id: \"opencode\",\n name: \"OpenCode\",\n projectPath: \".opencode/skills\",\n globalPath: join(home, \".config\", \"opencode\", \"skills\"),\n },\n {\n id: \"openhands\",\n name: \"OpenHands\",\n projectPath: \".openhands/skills\",\n globalPath: join(home, \".openhands\", \"skills\"),\n },\n {\n id: \"pi\",\n name: \"Pi\",\n projectPath: \".pi/skills\",\n globalPath: join(home, \".pi\", \"agent\", \"skills\"),\n },\n {\n id: \"qoder\",\n name: \"Qoder\",\n projectPath: \".qoder/skills\",\n globalPath: join(home, \".qoder\", \"skills\"),\n },\n {\n id: \"qwen-code\",\n name: \"Qwen Code\",\n projectPath: \".qwen/skills\",\n globalPath: join(home, \".qwen\", \"skills\"),\n },\n {\n id: \"roo\",\n name: \"Roo Code\",\n projectPath: \".roo/skills\",\n globalPath: join(home, \".roo\", \"skills\"),\n rulesProjectPath: \".roo/rules\",\n rulesGlobalPath: join(home, \".roo\", \"rules\"),\n ruleFormat: \"markdown-dir\",\n },\n {\n id: \"trae\",\n name: \"Trae\",\n projectPath: \".trae/skills\",\n globalPath: join(home, \".trae\", \"skills\"),\n },\n {\n id: \"windsurf\",\n name: \"Windsurf\",\n projectPath: \".windsurf/skills\",\n globalPath: join(home, \".codeium\", \"windsurf\", \"skills\"),\n rulesProjectPath: \".windsurfrules\",\n ruleFormat: \"append-single\",\n },\n {\n id: \"zencoder\",\n name: \"Zencoder\",\n projectPath: \".zencoder/skills\",\n globalPath: join(home, \".zencoder\", \"skills\"),\n },\n {\n id: \"neovate\",\n name: \"Neovate\",\n projectPath: \".neovate/skills\",\n globalPath: join(home, \".neovate\", \"skills\"),\n },\n {\n id: \"pochi\",\n name: \"Pochi\",\n projectPath: \".pochi/skills\",\n globalPath: join(home, \".pochi\", \"skills\"),\n },\n {\n id: \"zed\",\n name: \"Zed\",\n projectPath: \"\",\n globalPath: \"\",\n rulesProjectPath: \".zed/rules\",\n rulesGlobalPath: join(home, \".config\", \"zed\", \"rules\"),\n ruleFormat: \"markdown-dir\",\n },\n];\n\nconst directoryExists = (path: string): Effect.Effect<boolean> =>\n pipe(\n Effect.tryPromise({\n try: () => access(path, constants.F_OK),\n catch: () => false,\n }),\n Effect.map(() => true),\n Effect.orElseSucceed(() => false)\n );\n\ninterface DetectedAgent extends AgentConfig {\n hasProjectConfig: boolean;\n hasGlobalConfig: boolean;\n}\n\ninterface InstalledAgent extends AgentConfig {\n hasProjectInstall: boolean;\n hasGlobalInstall: boolean;\n}\n\nconst METADATA_FILENAME = \".braidskills-metadata.json\";\n\nconst detectAgents = (projectRoot?: string): Effect.Effect<DetectedAgent[]> => {\n const cwd = projectRoot ?? process.cwd();\n\n return pipe(\n Effect.forEach(\n AGENTS,\n (agent) =>\n pipe(\n Effect.all({\n hasProjectConfig: agent.projectPath\n ? directoryExists(join(cwd, agent.projectPath))\n : Effect.succeed(false),\n hasGlobalConfig: agent.globalPath\n ? directoryExists(agent.globalPath)\n : Effect.succeed(false),\n hasRulesProjectConfig: agent.rulesProjectPath\n ? directoryExists(join(cwd, agent.rulesProjectPath))\n : Effect.succeed(false),\n hasRulesGlobalConfig: agent.rulesGlobalPath\n ? directoryExists(agent.rulesGlobalPath)\n : Effect.succeed(false),\n }),\n Effect.map(\n ({\n hasProjectConfig,\n hasGlobalConfig,\n hasRulesProjectConfig,\n hasRulesGlobalConfig,\n }): DetectedAgent => ({\n ...agent,\n hasProjectConfig: hasProjectConfig || hasRulesProjectConfig,\n hasGlobalConfig: hasGlobalConfig || hasRulesGlobalConfig,\n })\n )\n ),\n { concurrency: \"unbounded\" }\n ),\n Effect.map((agents) =>\n agents.filter((a) => a.hasProjectConfig || a.hasGlobalConfig)\n )\n );\n};\n\nconst detectInstalledAgents = (\n projectRoot?: string\n): Effect.Effect<InstalledAgent[]> => {\n const cwd = projectRoot ?? process.cwd();\n\n return pipe(\n Effect.forEach(\n AGENTS,\n (agent) =>\n pipe(\n Effect.all({\n hasProjectInstall: agent.projectPath\n ? directoryExists(join(cwd, agent.projectPath, METADATA_FILENAME))\n : Effect.succeed(false),\n hasGlobalInstall: agent.globalPath\n ? directoryExists(join(agent.globalPath, METADATA_FILENAME))\n : Effect.succeed(false),\n }),\n Effect.map(\n ({ hasProjectInstall, hasGlobalInstall }): InstalledAgent => ({\n ...agent,\n hasProjectInstall,\n hasGlobalInstall,\n })\n )\n ),\n { concurrency: \"unbounded\" }\n ),\n Effect.map((agents) =>\n agents.filter((a) => a.hasProjectInstall || a.hasGlobalInstall)\n )\n );\n};\n\nconst detectInstalledAgentsAsync = (\n projectRoot?: string\n): Promise<InstalledAgent[]> =>\n Effect.runPromise(detectInstalledAgents(projectRoot));\n\ninterface ResolvedAgentsResult {\n agents: AgentConfig[];\n source: \"config\" | \"installed\" | \"detected\" | \"none\";\n}\n\nconst resolveAgents = (options: {\n configAgents?: string[];\n projectRoot?: string;\n global?: boolean;\n}): Effect.Effect<ResolvedAgentsResult> => {\n const { configAgents, projectRoot, global: useGlobal } = options;\n\n if (configAgents && configAgents.length > 0) {\n const agents = configAgents\n .map((id) => getAgentById(id as AgentId))\n .filter((a): a is AgentConfig => a !== undefined);\n\n if (agents.length > 0) {\n return Effect.succeed<ResolvedAgentsResult>({\n agents,\n source: \"config\",\n });\n }\n }\n\n return pipe(\n Effect.all({\n installed: detectInstalledAgents(projectRoot),\n detected: detectAgents(projectRoot),\n }),\n Effect.map(({ installed, detected }): ResolvedAgentsResult => {\n const relevantInstalled = installed.filter((a) =>\n useGlobal ? a.hasGlobalInstall : a.hasProjectInstall\n );\n\n if (relevantInstalled.length > 0) {\n return {\n agents: relevantInstalled,\n source: \"installed\",\n };\n }\n\n const relevantDetected = detected.filter((a) =>\n useGlobal ? a.hasGlobalConfig : a.hasProjectConfig\n );\n\n if (relevantDetected.length > 0) {\n return {\n agents: relevantDetected,\n source: \"detected\",\n };\n }\n\n return { agents: [], source: \"none\" };\n })\n );\n};\n\nconst resolveAgentsAsync = (options: {\n configAgents?: string[];\n projectRoot?: string;\n global?: boolean;\n}): Promise<ResolvedAgentsResult> => Effect.runPromise(resolveAgents(options));\n\nconst getAgentById = (id: AgentId): AgentConfig | undefined =>\n AGENTS.find((a) => a.id === id);\n\nconst getAllAgentIds = (): AgentId[] => AGENTS.map((a) => a.id);\n\nconst detectAgentsAsync = (projectRoot?: string): Promise<DetectedAgent[]> =>\n Effect.runPromise(detectAgents(projectRoot));\n\nconst directoryExistsAsync = (path: string): Promise<boolean> =>\n Effect.runPromise(directoryExists(path));\n\nconst resolveInstallPath = (\n agent: AgentConfig,\n options: { global?: boolean; projectRoot?: string }\n): string | undefined => {\n if (options.global) {\n return agent.globalPath || undefined;\n }\n if (!agent.projectPath) {\n return undefined;\n }\n const cwd = options.projectRoot ?? process.cwd();\n return join(cwd, agent.projectPath);\n};\n\nconst resolveRulesInstallPath = (\n agent: AgentConfig,\n options: { global?: boolean; projectRoot?: string }\n): string | undefined => {\n if (options.global) {\n return agent.rulesGlobalPath;\n }\n if (!agent.rulesProjectPath) {\n return undefined;\n }\n const cwd = options.projectRoot ?? process.cwd();\n return join(cwd, agent.rulesProjectPath);\n};\n\nexport type {\n AgentConfig,\n AgentId,\n DetectedAgent,\n InstalledAgent,\n ResolvedAgentsResult,\n RuleFormat,\n};\nexport {\n AGENTS,\n detectAgents,\n detectAgentsAsync,\n detectInstalledAgents,\n detectInstalledAgentsAsync,\n directoryExists,\n directoryExistsAsync,\n getAgentById,\n getAllAgentIds,\n resolveAgents,\n resolveAgentsAsync,\n resolveInstallPath,\n resolveRulesInstallPath,\n};\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { Data, Effect, pipe } from \"effect\";\n\nconst METADATA_FILENAME = \".braidskills-metadata.json\";\n\ninterface InstalledSkill {\n name: string;\n source: {\n type: \"profile\" | \"projects\";\n name: string;\n orgProjects?: string[];\n personalProjects?: string[];\n };\n version: string;\n installedAt: string;\n serverUrl: string;\n}\n\ninterface SkillsMetadata {\n skills: InstalledSkill[];\n}\n\nclass MetadataReadError extends Data.TaggedError(\"MetadataReadError\")<{\n path: string;\n cause: unknown;\n}> {}\n\nclass MetadataWriteError extends Data.TaggedError(\"MetadataWriteError\")<{\n path: string;\n cause: unknown;\n}> {}\n\nconst getMetadataPath = (skillsDir: string): string =>\n join(skillsDir, METADATA_FILENAME);\n\nconst readMetadata = (\n skillsDir: string\n): Effect.Effect<SkillsMetadata, MetadataReadError> => {\n const metadataPath = getMetadataPath(skillsDir);\n\n return pipe(\n Effect.tryPromise({\n try: () => readFile(metadataPath, \"utf-8\"),\n catch: (e) => new MetadataReadError({ path: metadataPath, cause: e }),\n }),\n Effect.flatMap((content) =>\n Effect.try({\n try: () => JSON.parse(content) as SkillsMetadata,\n catch: () => ({ skills: [] }) as SkillsMetadata,\n })\n ),\n Effect.orElseSucceed(() => ({ skills: [] }) as SkillsMetadata)\n );\n};\n\nconst writeMetadata = (\n skillsDir: string,\n metadata: SkillsMetadata\n): Effect.Effect<void, MetadataWriteError> => {\n const metadataPath = getMetadataPath(skillsDir);\n\n return Effect.tryPromise({\n try: () =>\n writeFile(metadataPath, JSON.stringify(metadata, null, 2), \"utf-8\"),\n catch: (e) => new MetadataWriteError({ path: metadataPath, cause: e }),\n });\n};\n\nconst updateMetadata = (\n skillsDir: string,\n newSkills: Array<{\n name: string;\n source: InstalledSkill[\"source\"];\n version: string;\n serverUrl: string;\n }>\n): Effect.Effect<void, MetadataReadError | MetadataWriteError> =>\n pipe(\n readMetadata(skillsDir),\n Effect.map((existing) => {\n const now = new Date().toISOString();\n const updatedSkills = [...existing.skills];\n\n for (const skill of newSkills) {\n const existingIndex = updatedSkills.findIndex(\n (s) => s.name === skill.name\n );\n const newEntry: InstalledSkill = {\n name: skill.name,\n source: skill.source,\n version: skill.version,\n installedAt: now,\n serverUrl: skill.serverUrl,\n };\n\n if (existingIndex >= 0) {\n updatedSkills[existingIndex] = newEntry;\n } else {\n updatedSkills.push(newEntry);\n }\n }\n\n return { skills: updatedSkills };\n }),\n Effect.flatMap((metadata) => writeMetadata(skillsDir, metadata))\n );\n\nconst getOutdatedSkills = (\n skillsDir: string,\n currentVersion: string\n): Effect.Effect<InstalledSkill[], MetadataReadError> =>\n pipe(\n readMetadata(skillsDir),\n Effect.map((metadata) =>\n metadata.skills.filter((s) => s.version !== currentVersion)\n )\n );\n\nconst removeFromMetadata = (\n skillsDir: string,\n skillName: string\n): Effect.Effect<void, MetadataReadError | MetadataWriteError> =>\n pipe(\n readMetadata(skillsDir),\n Effect.map((metadata) => ({\n skills: metadata.skills.filter((s) => s.name !== skillName),\n })),\n Effect.flatMap((metadata) => writeMetadata(skillsDir, metadata))\n );\n\nconst readMetadataAsync = (skillsDir: string): Promise<SkillsMetadata> =>\n Effect.runPromise(readMetadata(skillsDir));\n\nconst writeMetadataAsync = (\n skillsDir: string,\n metadata: SkillsMetadata\n): Promise<void> => Effect.runPromise(writeMetadata(skillsDir, metadata));\n\nconst updateMetadataAsync = (\n skillsDir: string,\n newSkills: Array<{\n name: string;\n source: InstalledSkill[\"source\"];\n version: string;\n serverUrl: string;\n }>\n): Promise<void> => Effect.runPromise(updateMetadata(skillsDir, newSkills));\n\nconst getOutdatedSkillsAsync = (\n skillsDir: string,\n currentVersion: string\n): Promise<InstalledSkill[]> =>\n Effect.runPromise(getOutdatedSkills(skillsDir, currentVersion));\n\nconst removeFromMetadataAsync = (\n skillsDir: string,\n skillName: string\n): Promise<void> => Effect.runPromise(removeFromMetadata(skillsDir, skillName));\n\nexport type { InstalledSkill, SkillsMetadata };\nexport {\n getMetadataPath,\n getOutdatedSkills,\n getOutdatedSkillsAsync,\n METADATA_FILENAME,\n MetadataReadError,\n MetadataWriteError,\n readMetadata,\n readMetadataAsync,\n removeFromMetadata,\n removeFromMetadataAsync,\n updateMetadata,\n updateMetadataAsync,\n writeMetadata,\n writeMetadataAsync,\n};\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve, sep } from \"node:path\";\nimport { Data, Effect, pipe } from \"effect\";\nimport type { AgentConfig, RuleFormat } from \"./agents.ts\";\nimport type { ExportedRule } from \"./api.ts\";\n\nclass RuleWriteError extends Data.TaggedError(\"RuleWriteError\")<{\n path: string;\n operation: \"mkdir\" | \"write\" | \"read\";\n cause: unknown;\n}> {}\n\nconst createDirectory = (dir: string): Effect.Effect<void, RuleWriteError> =>\n Effect.tryPromise({\n try: () => mkdir(dir, { recursive: true }),\n catch: (e) =>\n new RuleWriteError({ path: dir, operation: \"mkdir\", cause: e }),\n });\n\nconst writeTextFile = (\n fullPath: string,\n content: string\n): Effect.Effect<void, RuleWriteError> =>\n Effect.tryPromise({\n try: () => writeFile(fullPath, content, \"utf-8\"),\n catch: (e) =>\n new RuleWriteError({ path: fullPath, operation: \"write\", cause: e }),\n });\n\nconst readTextFile = (\n fullPath: string\n): Effect.Effect<string, RuleWriteError> =>\n Effect.tryPromise({\n try: () => readFile(fullPath, \"utf-8\"),\n catch: (e) =>\n new RuleWriteError({ path: fullPath, operation: \"read\", cause: e }),\n });\n\nconst assertRulePathWithinBase = (\n basePath: string,\n ruleName: string\n): Effect.Effect<string, RuleWriteError> => {\n const resolvedBase = resolve(basePath);\n const resolvedFull = resolve(basePath, ruleName);\n if (\n resolvedFull !== resolvedBase &&\n !resolvedFull.startsWith(resolvedBase + sep)\n ) {\n return Effect.fail(\n new RuleWriteError({\n path: ruleName,\n operation: \"write\",\n cause: new Error(\n `Path traversal detected: \"${ruleName}\" resolves outside base directory`\n ),\n })\n );\n }\n return Effect.succeed(resolvedFull);\n};\n\nconst BRAID_SECTION_START = \"<!-- braid:rules:start -->\";\nconst BRAID_SECTION_END = \"<!-- braid:rules:end -->\";\nconst YAML_SPECIAL_CHARS = /[\\n\\r:#{}[\\],&*?|>!'\"%@`]/;\n\nfunction escapeYamlValue(value: string): string {\n if (\n YAML_SPECIAL_CHARS.test(value) ||\n value.startsWith(\" \") ||\n value.endsWith(\" \")\n ) {\n return `\"${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n }\n return value;\n}\n\nfunction buildMdcContent(rule: ExportedRule): string {\n const lines: string[] = [\"---\"];\n lines.push(`description: ${escapeYamlValue(rule.title)}`);\n lines.push(\"alwaysApply: true\");\n lines.push(\"---\");\n lines.push(\"\");\n lines.push(`# ${rule.title}`);\n lines.push(\"\");\n lines.push(rule.content);\n return lines.join(\"\\n\");\n}\n\nfunction buildAppendContent(rules: ExportedRule[]): string {\n const lines: string[] = [BRAID_SECTION_START, \"\"];\n\n for (const rule of rules) {\n lines.push(`## ${rule.title}`);\n lines.push(\"\");\n lines.push(rule.content);\n lines.push(\"\");\n }\n\n lines.push(BRAID_SECTION_END);\n return lines.join(\"\\n\");\n}\n\nconst writeMdcRules = (\n basePath: string,\n rules: ExportedRule[]\n): Effect.Effect<void, RuleWriteError> =>\n pipe(\n createDirectory(basePath),\n Effect.flatMap(() =>\n Effect.forEach(\n rules,\n (rule) =>\n pipe(\n assertRulePathWithinBase(basePath, `${rule.name}.mdc`),\n Effect.flatMap((filePath) =>\n writeTextFile(filePath, buildMdcContent(rule))\n )\n ),\n { concurrency: \"unbounded\" }\n )\n ),\n Effect.asVoid\n );\n\nconst writeMarkdownDirRules = (\n basePath: string,\n rules: ExportedRule[]\n): Effect.Effect<void, RuleWriteError> =>\n pipe(\n createDirectory(basePath),\n Effect.flatMap(() =>\n Effect.forEach(\n rules,\n (rule) =>\n pipe(\n assertRulePathWithinBase(basePath, `${rule.name}.md`),\n Effect.flatMap((filePath) =>\n writeTextFile(filePath, `# ${rule.title}\\n\\n${rule.content}`)\n )\n ),\n { concurrency: \"unbounded\" }\n )\n ),\n Effect.asVoid\n );\n\nconst writeAppendSingleRules = (\n filePath: string,\n rules: ExportedRule[]\n): Effect.Effect<void, RuleWriteError> =>\n pipe(\n createDirectory(dirname(filePath)),\n Effect.flatMap(() =>\n pipe(\n readTextFile(filePath),\n Effect.orElseSucceed(() => \"\")\n )\n ),\n Effect.flatMap((existing) => {\n const braidContent = buildAppendContent(rules);\n\n const startIdx = existing.indexOf(BRAID_SECTION_START);\n const endIdx = existing.indexOf(BRAID_SECTION_END);\n\n let newContent: string;\n if (startIdx !== -1 && endIdx !== -1) {\n newContent =\n existing.slice(0, startIdx) +\n braidContent +\n existing.slice(endIdx + BRAID_SECTION_END.length);\n } else {\n newContent = existing ? `${existing}\\n\\n${braidContent}` : braidContent;\n }\n\n return writeTextFile(filePath, newContent);\n })\n );\n\nconst writeRulesForFormat = (\n basePath: string,\n rules: ExportedRule[],\n format: RuleFormat\n): Effect.Effect<void, RuleWriteError> => {\n switch (format) {\n case \"mdc\":\n return writeMdcRules(basePath, rules);\n case \"markdown-dir\":\n return writeMarkdownDirRules(basePath, rules);\n case \"append-single\":\n return writeAppendSingleRules(basePath, rules);\n default:\n return Effect.void;\n }\n};\n\ninterface WriteRulesResult {\n written: number;\n errors: Array<{ agent: string; error: string }>;\n}\n\nconst writeRulesForAgent = (\n agent: AgentConfig,\n rules: ExportedRule[],\n rulesPath: string\n): Effect.Effect<WriteRulesResult, never> => {\n if (!agent.ruleFormat || rules.length === 0) {\n return Effect.succeed({ written: 0, errors: [] });\n }\n\n return pipe(\n writeRulesForFormat(rulesPath, rules, agent.ruleFormat),\n Effect.map(() => ({\n written: rules.length,\n errors: [] as Array<{ agent: string; error: string }>,\n })),\n Effect.catchAll((error) =>\n Effect.succeed({\n written: 0,\n errors: [\n {\n agent: agent.name,\n error:\n error.cause instanceof Error\n ? error.cause.message\n : String(error.cause),\n },\n ],\n })\n )\n );\n};\n\nconst writeRulesForAgentAsync = (\n agent: AgentConfig,\n rules: ExportedRule[],\n rulesPath: string\n): Promise<WriteRulesResult> =>\n Effect.runPromise(writeRulesForAgent(agent, rules, rulesPath));\n\nexport type { WriteRulesResult };\nexport { RuleWriteError, writeRulesForAgent, writeRulesForAgentAsync };\n","import { chmod, mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve, sep } from \"node:path\";\nimport { Data, Effect, pipe } from \"effect\";\nimport type { AgentId } from \"./agents.ts\";\nimport type { Skill, SkillFile } from \"./api.ts\";\n\nclass WriteError extends Data.TaggedError(\"WriteError\")<{\n path: string;\n operation: \"mkdir\" | \"write\" | \"chmod\";\n cause: unknown;\n}> {}\n\nconst createDirectory = (\n dir: string,\n fullPath: string\n): Effect.Effect<void, WriteError> =>\n Effect.tryPromise({\n try: () => mkdir(dir, { recursive: true }),\n catch: (e) =>\n new WriteError({ path: fullPath, operation: \"mkdir\", cause: e }),\n });\n\nconst writeTextFile = (\n fullPath: string,\n content: string\n): Effect.Effect<void, WriteError> =>\n Effect.tryPromise({\n try: () => writeFile(fullPath, content, \"utf-8\"),\n catch: (e) =>\n new WriteError({ path: fullPath, operation: \"write\", cause: e }),\n });\n\nconst writeBinaryFile = (\n fullPath: string,\n content: Buffer\n): Effect.Effect<void, WriteError> =>\n Effect.tryPromise({\n try: () => writeFile(fullPath, content),\n catch: (e) =>\n new WriteError({ path: fullPath, operation: \"write\", cause: e }),\n });\n\nconst makeExecutable = (fullPath: string): Effect.Effect<void, WriteError> =>\n Effect.tryPromise({\n try: () => chmod(fullPath, 0o755),\n catch: (e) =>\n new WriteError({ path: fullPath, operation: \"chmod\", cause: e }),\n });\n\nconst assertWithinBase = (\n basePath: string,\n untrustedPath: string\n): Effect.Effect<string, WriteError> => {\n const resolvedBase = resolve(basePath);\n const resolvedFull = resolve(basePath, untrustedPath);\n if (\n resolvedFull !== resolvedBase &&\n !resolvedFull.startsWith(resolvedBase + sep)\n ) {\n return Effect.fail(\n new WriteError({\n path: untrustedPath,\n operation: \"write\",\n cause: new Error(\n `Path traversal detected: \"${untrustedPath}\" resolves outside base directory`\n ),\n })\n );\n }\n return Effect.succeed(resolvedFull);\n};\n\nconst COMPATIBILITY_REGEX = /^compatibility:\\s*.+$/m;\n\nconst rewriteCompatibility = (content: string, agentId: AgentId): string => {\n return content.replace(COMPATIBILITY_REGEX, `compatibility: ${agentId}`);\n};\n\nconst decodeFileContent = (file: SkillFile, agentId?: AgentId): string => {\n let content: string;\n if (file.encoding === \"base64\") {\n content = Buffer.from(file.content, \"base64\").toString(\"utf-8\");\n } else {\n content = file.content;\n }\n\n if (agentId && file.path === \"SKILL.md\") {\n content = rewriteCompatibility(content, agentId);\n }\n\n return content;\n};\n\nconst decodeFileContentBinary = (file: SkillFile): Buffer => {\n if (file.encoding === \"base64\") {\n return Buffer.from(file.content, \"base64\");\n }\n return Buffer.from(file.content, \"utf-8\");\n};\n\nconst isBinaryFile = (path: string): boolean => {\n const binaryExtensions = [\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".ico\",\n \".bmp\",\n ];\n return binaryExtensions.some((ext) => path.toLowerCase().endsWith(ext));\n};\n\n/**\n * Determines if a file should be made executable based on its path and extension.\n *\n * A file is considered a script if ALL of the following conditions are met:\n * 1. The file path contains \"/scripts/\" (indicating it's in a scripts directory)\n * 2. The file has a recognized script extension (.sh, .bash, .py, .js, .mjs, .rb)\n *\n * **Important behavior notes:**\n * - Files in the scripts/ directory WITHOUT a recognized extension will NOT be executable\n * - Files with script extensions OUTSIDE the scripts/ directory will NOT be executable\n * - No content validation is performed - the decision is purely path and extension based\n * - This follows the Agent Skills standard where executable scripts are placed in scripts/\n *\n * **Security consideration:**\n * This is a defensive approach that requires both correct location AND extension to grant\n * execute permissions. While a user could theoretically place a non-script file with a\n * script extension in scripts/, the dual requirement (path + extension) provides a\n * reasonable safeguard for the expected use case of skill distribution.\n *\n * @param path - The file path relative to the skill root\n * @returns true if the file should receive executable permissions (chmod 0o755)\n *\n * @example\n * isScriptFile(\"scripts/deploy.sh\") // true - in scripts/, has .sh extension\n * isScriptFile(\"scripts/setup.py\") // true - in scripts/, has .py extension\n * isScriptFile(\"src/scripts/deploy.sh\") // true - in nested scripts/, has .sh extension\n * isScriptFile(\"scripts/readme.txt\") // false - in scripts/, but not a script extension\n * isScriptFile(\"src/index.js\") // false - has .js extension, but not in scripts/\n * isScriptFile(\"deploy.sh\") // false - has .sh extension, but not in scripts/\n */\nconst isScriptFile = (path: string): boolean => {\n const scriptExtensions = [\".sh\", \".bash\", \".py\", \".js\", \".mjs\", \".rb\"];\n const lowerPath = path.toLowerCase();\n const inScriptsDir =\n lowerPath.includes(\"/scripts/\") || lowerPath.startsWith(\"scripts/\");\n return (\n inScriptsDir && scriptExtensions.some((ext) => lowerPath.endsWith(ext))\n );\n};\n\nconst writeFileContent = (\n fullPath: string,\n file: SkillFile,\n agentId?: AgentId\n): Effect.Effect<void, WriteError> =>\n isBinaryFile(file.path)\n ? writeBinaryFile(fullPath, decodeFileContentBinary(file))\n : writeTextFile(fullPath, decodeFileContent(file, agentId));\n\n/**\n * Conditionally sets executable permissions on a file if it's identified as a script.\n *\n * This function uses {@link isScriptFile} to determine if the file should be executable.\n * Only files in the scripts/ directory with recognized script extensions will receive\n * executable permissions (chmod 0o755).\n *\n * @param fullPath - The absolute filesystem path where the file is written\n * @param filePath - The relative path within the skill (used for script detection)\n * @returns Effect that succeeds after setting permissions, or immediately if not a script\n */\nconst setExecutableIfScript = (\n fullPath: string,\n filePath: string\n): Effect.Effect<void, WriteError> =>\n isScriptFile(filePath) ? makeExecutable(fullPath) : Effect.void;\n\nconst writeSkillFile = (\n basePath: string,\n file: SkillFile,\n agentId?: AgentId\n): Effect.Effect<void, WriteError> =>\n pipe(\n assertWithinBase(basePath, file.path),\n Effect.flatMap((fullPath) => {\n const dir = dirname(fullPath);\n return pipe(\n createDirectory(dir, fullPath),\n Effect.flatMap(() => writeFileContent(fullPath, file, agentId)),\n Effect.flatMap(() => setExecutableIfScript(fullPath, file.path))\n );\n })\n );\n\nconst writeSkill = (\n basePath: string,\n skill: Skill,\n agentId?: AgentId\n): Effect.Effect<void, WriteError> =>\n pipe(\n assertWithinBase(basePath, skill.name),\n Effect.flatMap((skillDir) =>\n pipe(\n Effect.forEach(\n skill.files,\n (file) => writeSkillFile(skillDir, file, agentId),\n {\n concurrency: \"unbounded\",\n }\n ),\n Effect.map(() => undefined)\n )\n )\n );\n\ninterface WriteSkillsResult {\n written: string[];\n errors: Array<{ skill: string; error: string }>;\n}\n\n/**\n * Writes multiple skills to disk\n *\n * @param basePath - Base directory to write skills to (e.g., \".claude/skills\")\n * @param skills - Skills to write\n * @param agentId - Agent ID to set in compatibility field\n */\nconst writeSkills = (\n basePath: string,\n skills: Skill[],\n agentId?: AgentId\n): Effect.Effect<WriteSkillsResult, never> =>\n pipe(\n Effect.forEach(\n skills,\n (skill) =>\n pipe(\n writeSkill(basePath, skill, agentId),\n Effect.map(() => ({ success: true as const, skill: skill.name })),\n Effect.catchAll((error) =>\n Effect.succeed({\n success: false as const,\n skill: skill.name,\n error:\n error.cause instanceof Error\n ? error.cause.message\n : String(error.cause),\n })\n )\n ),\n { concurrency: \"unbounded\" }\n ),\n Effect.map((results) => ({\n written: results.filter((r) => r.success).map((r) => r.skill),\n errors: results\n .filter(\n (r): r is { success: false; skill: string; error: string } =>\n !r.success\n )\n .map((r) => ({ skill: r.skill, error: r.error })),\n }))\n );\n\nconst writeSkillAsync = (\n basePath: string,\n skill: Skill,\n agentId?: AgentId\n): Promise<void> => Effect.runPromise(writeSkill(basePath, skill, agentId));\n\nconst writeSkillsAsync = (\n basePath: string,\n skills: Skill[],\n agentId?: AgentId\n): Promise<WriteSkillsResult> =>\n Effect.runPromise(writeSkills(basePath, skills, agentId));\n\nexport type { WriteSkillsResult };\nexport {\n decodeFileContent,\n decodeFileContentBinary,\n isBinaryFile,\n isScriptFile,\n WriteError,\n writeSkill,\n writeSkillAsync,\n writeSkillFile,\n writeSkills,\n writeSkillsAsync,\n};\n","import process from \"node:process\";\nimport {\n cancel as clackCancel,\n confirm as clackConfirm,\n group as clackGroup,\n groupMultiselect as clackGroupMultiselect,\n intro as clackIntro,\n isCancel as clackIsCancel,\n log as clackLog,\n multiselect as clackMultiselect,\n note as clackNote,\n outro as clackOutro,\n password as clackPassword,\n select as clackSelect,\n selectKey as clackSelectKey,\n spinner as clackSpinner,\n text as clackText,\n} from \"@clack/prompts\";\n\nconst isTTY = Boolean(process.stdout.isTTY);\n\ninterface NoopSpinner {\n start: (message?: string) => void;\n stop: (message?: string) => void;\n message: (message?: string) => void;\n}\n\nfunction spinner(): NoopSpinner | ReturnType<typeof clackSpinner> {\n if (isTTY) {\n return clackSpinner();\n }\n\n return {\n start: (message?: string) => {\n if (message) {\n process.stdout.write(`${message}\\n`);\n }\n },\n stop: (message?: string) => {\n if (message) {\n process.stdout.write(`${message}\\n`);\n }\n },\n message: (message?: string) => {\n if (message) {\n process.stdout.write(`${message}\\n`);\n }\n },\n };\n}\n\nfunction intro(message: string): void {\n if (isTTY) {\n clackIntro(message);\n } else {\n process.stdout.write(`\\n${message}\\n`);\n }\n}\n\nfunction outro(message: string): void {\n if (isTTY) {\n clackOutro(message);\n } else {\n process.stdout.write(`${message}\\n\\n`);\n }\n}\n\nconst cancel = clackCancel;\nconst confirm = clackConfirm;\nconst group = clackGroup;\nconst groupMultiselect = clackGroupMultiselect;\nconst isCancel = clackIsCancel;\nconst log = clackLog;\nconst multiselect = clackMultiselect;\nconst note = clackNote;\nconst password = clackPassword;\nconst select = clackSelect;\nconst selectKey = clackSelectKey;\nconst text = clackText;\n\nexport {\n cancel,\n confirm,\n group,\n groupMultiselect,\n intro,\n isCancel,\n log,\n multiselect,\n note,\n outro,\n password,\n select,\n selectKey,\n spinner,\n text,\n};\n","import { log, spinner } from \"@clack/prompts\";\nimport type { DetectedAgent } from \"../lib/agents.ts\";\nimport {\n detectAgentsAsync,\n directoryExistsAsync,\n resolveInstallPath,\n} from \"../lib/agents.ts\";\nimport type { InstalledSkill } from \"../lib/metadata.ts\";\nimport { readMetadataAsync } from \"../lib/metadata.ts\";\n\ninterface ListOptions {\n global?: boolean;\n}\n\nfunction formatRelativeTime(isoDate: string): string {\n const date = new Date(isoDate);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60_000);\n const diffHours = Math.floor(diffMins / 60);\n const diffDays = Math.floor(diffHours / 24);\n\n if (diffMins < 1) {\n return \"just now\";\n }\n if (diffMins < 60) {\n return `${diffMins} minute${diffMins !== 1 ? \"s\" : \"\"} ago`;\n }\n if (diffHours < 24) {\n return `${diffHours} hour${diffHours !== 1 ? \"s\" : \"\"} ago`;\n }\n if (diffDays < 30) {\n return `${diffDays} day${diffDays !== 1 ? \"s\" : \"\"} ago`;\n }\n return date.toLocaleDateString();\n}\n\nfunction displayAgentSkills(\n agent: DetectedAgent,\n installPath: string,\n braidSkills: InstalledSkill[]\n): void {\n const nameWidth = 25;\n const sourceWidth = 20;\n const installedWidth = 15;\n\n log.info(\"\");\n log.info(`Agent: ${agent.name} (${installPath})`);\n log.info(\"─\".repeat(60));\n\n const header = [\n \"Skill\".padEnd(nameWidth),\n \"Source\".padEnd(sourceWidth),\n \"Installed\".padEnd(installedWidth),\n ].join(\" \");\n\n log.info(header);\n log.info(\"─\".repeat(60));\n\n for (const skill of braidSkills) {\n const sourceName = skill.source.name;\n\n const row = [\n skill.name.slice(0, nameWidth).padEnd(nameWidth),\n sourceName.slice(0, sourceWidth).padEnd(sourceWidth),\n formatRelativeTime(skill.installedAt).padEnd(installedWidth),\n ].join(\" \");\n\n log.info(row);\n }\n}\n\nexport async function listCommand(options: ListOptions): Promise<void> {\n const listSpinner = spinner();\n listSpinner.start(\"Scanning for installed skills...\");\n\n try {\n const detectedAgents = await detectAgentsAsync();\n\n if (detectedAgents.length === 0) {\n listSpinner.stop(\"No agents detected\");\n log.warn(\"No AI coding agents detected.\");\n return;\n }\n\n listSpinner.stop(`Found ${detectedAgents.length} agent(s)`);\n\n let totalSkills = 0;\n\n for (const agent of detectedAgents) {\n const installPath = resolveInstallPath(agent, {\n global: options.global === true,\n });\n if (!installPath) {\n continue;\n }\n const exists = await directoryExistsAsync(installPath);\n\n if (!exists) {\n continue;\n }\n\n const metadata = await readMetadataAsync(installPath);\n const braidSkills = metadata.skills;\n\n if (braidSkills.length === 0) {\n continue;\n }\n\n totalSkills += braidSkills.length;\n displayAgentSkills(agent, installPath, braidSkills);\n }\n\n if (totalSkills === 0) {\n log.warn(\"\\nNo skills installed via braid.\");\n log.info(\"Run 'braid install --profile <name>' to install skills.\");\n } else {\n log.info(\"\");\n log.info(`Total: ${totalSkills} skill(s) installed`);\n }\n } catch (error) {\n listSpinner.stop(\"List failed\");\n const message = error instanceof Error ? error.message : String(error);\n log.error(message);\n process.exit(1);\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport process from \"node:process\";\nimport type { DetectedAgent } from \"../lib/agents.ts\";\nimport {\n detectAgentsAsync,\n directoryExistsAsync,\n resolveInstallPath,\n} from \"../lib/agents.ts\";\nimport { readMetadataAsync, removeFromMetadataAsync } from \"../lib/metadata.ts\";\nimport {\n cancel,\n confirm,\n isCancel,\n log,\n multiselect,\n outro,\n spinner,\n} from \"../lib/tui.ts\";\n\ninterface RemoveOptions {\n all?: boolean;\n global?: boolean;\n yes?: boolean;\n skill?: string;\n}\n\ninterface SkillToRemove {\n name: string;\n agentName: string;\n installPath: string;\n skillPath: string;\n}\n\nasync function collectInstalledSkills(\n detectedAgents: DetectedAgent[],\n options: RemoveOptions\n): Promise<SkillToRemove[]> {\n const skillsToRemove: SkillToRemove[] = [];\n\n for (const agent of detectedAgents) {\n const installPath = resolveInstallPath(agent, {\n global: options.global === true,\n });\n if (!installPath) {\n continue;\n }\n const exists = await directoryExistsAsync(installPath);\n\n if (!exists) {\n continue;\n }\n\n const metadata = await readMetadataAsync(installPath);\n\n for (const skill of metadata.skills) {\n skillsToRemove.push({\n name: skill.name,\n agentName: agent.name,\n installPath,\n skillPath: join(installPath, skill.name),\n });\n }\n }\n\n return skillsToRemove;\n}\n\nasync function selectSkillsToRemove(\n skillsToRemove: SkillToRemove[],\n options: RemoveOptions\n): Promise<SkillToRemove[]> {\n if (options.skill) {\n const selected = skillsToRemove.filter((s) => s.name === options.skill);\n if (selected.length === 0) {\n log.error(`Skill '${options.skill}' not found.`);\n log.info(\"Run 'braid list' to see installed skills.\");\n process.exit(1);\n }\n return selected;\n }\n\n if (options.all || options.yes) {\n return skillsToRemove;\n }\n\n const choices = skillsToRemove.map((skill) => ({\n value: skill,\n label: skill.name,\n hint: skill.agentName,\n }));\n\n const result = await multiselect({\n message: \"Select skills to remove:\",\n options: choices,\n required: true,\n });\n\n if (isCancel(result)) {\n cancel(\"Remove cancelled.\");\n process.exit(0);\n }\n\n return result;\n}\n\nasync function confirmRemoval(\n selectedCount: number,\n options: RemoveOptions\n): Promise<void> {\n if (options.yes || options.skill || options.all) {\n return;\n }\n\n const confirmed = await confirm({\n message: `Remove ${selectedCount} skill(s)?`,\n initialValue: false,\n });\n\n if (isCancel(confirmed) || !confirmed) {\n cancel(\"Remove cancelled.\");\n process.exit(0);\n }\n}\n\nasync function removeSkill(\n skill: SkillToRemove,\n removeSpinner: ReturnType<typeof spinner>\n): Promise<boolean> {\n removeSpinner.start(`Removing ${skill.name} from ${skill.agentName}...`);\n\n try {\n const resolvedSkillPath = resolve(skill.skillPath);\n const resolvedInstallPath = resolve(skill.installPath);\n if (!resolvedSkillPath.startsWith(`${resolvedInstallPath}/`)) {\n removeSpinner.stop(`Unsafe path for ${skill.name}`);\n log.warn(\" Skill path escapes install directory, skipping.\");\n return false;\n }\n await rm(resolvedSkillPath, { recursive: true, force: true });\n await removeFromMetadataAsync(skill.installPath, skill.name);\n removeSpinner.stop(`Removed ${skill.name} from ${skill.agentName}`);\n return true;\n } catch (error) {\n removeSpinner.stop(`Failed to remove ${skill.name}`);\n const message = error instanceof Error ? error.message : String(error);\n log.warn(` ${message}`);\n return false;\n }\n}\n\nexport async function removeCommand(options: RemoveOptions): Promise<void> {\n const removeSpinner = spinner();\n removeSpinner.start(\"Scanning for installed skills...\");\n\n try {\n const detectedAgents = await detectAgentsAsync();\n\n if (detectedAgents.length === 0) {\n removeSpinner.stop(\"No agents detected\");\n log.warn(\"No AI coding agents detected.\");\n return;\n }\n\n const skillsToRemove = await collectInstalledSkills(\n detectedAgents,\n options\n );\n\n removeSpinner.stop(`Found ${skillsToRemove.length} installed skill(s)`);\n\n if (skillsToRemove.length === 0) {\n log.warn(\"No skills installed via braid.\");\n return;\n }\n\n const selected = await selectSkillsToRemove(skillsToRemove, options);\n await confirmRemoval(selected.length, options);\n\n let removed = 0;\n let errors = 0;\n\n for (const skill of selected) {\n const success = await removeSkill(skill, removeSpinner);\n if (success) {\n removed++;\n } else {\n errors++;\n }\n }\n\n if (errors > 0) {\n outro(`Removed ${removed} skill(s) with ${errors} error(s).`);\n } else {\n outro(`Successfully removed ${removed} skill(s).`);\n }\n } catch (error) {\n removeSpinner.stop(\"Remove failed\");\n const message = error instanceof Error ? error.message : String(error);\n log.error(message);\n process.exit(1);\n }\n}\n","import {\n cancel,\n isCancel,\n log,\n multiselect,\n outro,\n spinner,\n} from \"@clack/prompts\";\nimport { Data, Effect, pipe } from \"effect\";\nimport type { AgentId, DetectedAgent } from \"../lib/agents.ts\";\nimport {\n detectAgentsAsync,\n directoryExistsAsync,\n resolveInstallPath,\n} from \"../lib/agents.ts\";\nimport type { FetchSkillsOptions } from \"../lib/api.ts\";\nimport { fetchSkillsAsync } from \"../lib/api.ts\";\nimport { readMetadataAsync, updateMetadataAsync } from \"../lib/metadata.ts\";\nimport { writeSkillsAsync } from \"../lib/skill-writer.ts\";\n\ninterface UpdateOptions {\n global?: boolean;\n server?: string;\n yes?: boolean;\n}\n\ninterface SourceToUpdate {\n type: \"profile\" | \"projects\";\n name: string;\n orgProjects: string[] | undefined;\n personalProjects: string[] | undefined;\n serverUrl: string;\n agents: Array<{ agentId: AgentId; agentName: string; installPath: string }>;\n}\n\nclass UpdateError extends Data.TaggedError(\"UpdateError\")<{\n message: string;\n source?: string;\n}> {}\n\nclass UserCancelledError extends Data.TaggedError(\"UserCancelledError\")<{\n message: string;\n}> {}\n\nasync function resolveValidInstallPath(\n agent: DetectedAgent,\n options: UpdateOptions\n): Promise<string | null> {\n const installPath = resolveInstallPath(agent, {\n global: options.global === true,\n });\n if (!installPath) {\n return null;\n }\n const exists = await directoryExistsAsync(installPath);\n return exists ? installPath : null;\n}\n\nconst collectSourcesFromAgent = (\n agent: DetectedAgent,\n options: UpdateOptions,\n sourcesToUpdate: Map<string, SourceToUpdate>\n): Effect.Effect<void, UpdateError> =>\n Effect.tryPromise({\n try: async () => {\n const installPath = await resolveValidInstallPath(agent, options);\n if (!installPath) {\n return;\n }\n\n const metadata = await readMetadataAsync(installPath);\n\n for (const skill of metadata.skills) {\n const key =\n skill.source.type === \"profile\"\n ? `profile:${skill.source.name}`\n : `projects:${skill.source.name}`;\n\n if (!sourcesToUpdate.has(key)) {\n sourcesToUpdate.set(key, {\n type: skill.source.type,\n name: skill.source.name,\n orgProjects: skill.source.orgProjects,\n personalProjects: skill.source.personalProjects,\n serverUrl: skill.serverUrl,\n agents: [],\n });\n }\n\n const source = sourcesToUpdate.get(key);\n if (\n source &&\n !source.agents.some((a) => a.installPath === installPath)\n ) {\n source.agents.push({\n agentId: agent.id,\n agentName: agent.name,\n installPath,\n });\n }\n }\n },\n catch: () => new UpdateError({ message: \"Failed to collect sources\" }),\n });\n\nconst collectSources = (\n detectedAgents: DetectedAgent[],\n options: UpdateOptions\n): Effect.Effect<Map<string, SourceToUpdate>, UpdateError> =>\n pipe(\n Effect.succeed(new Map<string, SourceToUpdate>()),\n Effect.tap((sourcesToUpdate) =>\n Effect.forEach(\n detectedAgents,\n (agent) => collectSourcesFromAgent(agent, options, sourcesToUpdate),\n { concurrency: 1 }\n )\n )\n );\n\nconst selectSources = (\n sourcesToUpdate: Map<string, SourceToUpdate>,\n options: UpdateOptions\n): Effect.Effect<Map<string, SourceToUpdate>, UserCancelledError> => {\n if (options.yes) {\n return Effect.succeed(sourcesToUpdate);\n }\n\n return Effect.tryPromise({\n try: async () => {\n const sources = Array.from(sourcesToUpdate.entries()).map(\n ([key, source]) => ({\n value: key,\n label: source.name,\n hint: `${source.agents.length} agent(s)`,\n })\n );\n\n const selected = await multiselect({\n message: \"Select sources to update:\",\n options: sources,\n initialValues: sources.map((s) => s.value),\n required: true,\n });\n\n if (isCancel(selected)) {\n throw new Error(\"cancelled\");\n }\n\n for (const key of sourcesToUpdate.keys()) {\n if (!selected.includes(key)) {\n sourcesToUpdate.delete(key);\n }\n }\n\n return sourcesToUpdate;\n },\n catch: () => new UserCancelledError({ message: \"Update cancelled.\" }),\n });\n};\n\nconst getSourceDesc = (source: SourceToUpdate): string => source.name;\n\nconst buildFetchOptionsForSource = (\n source: SourceToUpdate,\n options: UpdateOptions\n): FetchSkillsOptions | null => {\n const serverUrl = options.server ?? source.serverUrl;\n const fetchOptions: FetchSkillsOptions = { serverUrl };\n\n if (source.type === \"profile\") {\n fetchOptions.profile = source.name;\n } else {\n const orgProjects = source.orgProjects;\n const personalProjects = source.personalProjects;\n const hasOrgProjects = orgProjects !== undefined && orgProjects.length > 0;\n const hasPersonalProjects =\n personalProjects !== undefined && personalProjects.length > 0;\n\n if (!(hasOrgProjects || hasPersonalProjects)) {\n return null;\n }\n\n if (hasOrgProjects) {\n fetchOptions.orgProjects = orgProjects;\n }\n if (hasPersonalProjects) {\n fetchOptions.personalProjects = personalProjects;\n }\n }\n\n return fetchOptions;\n};\n\nconst updateAgentSkills = (\n agentId: AgentId,\n agentName: string,\n installPath: string,\n response: Awaited<ReturnType<typeof fetchSkillsAsync>>,\n serverUrl: string,\n updateSpinner: ReturnType<typeof spinner>\n): Effect.Effect<{ updated: number; errors: number }, UpdateError> =>\n Effect.tryPromise({\n try: async () => {\n updateSpinner.start(`Updating ${agentName}...`);\n\n const result = await writeSkillsAsync(\n installPath,\n response.skills,\n agentId\n );\n\n if (result.errors.length > 0) {\n updateSpinner.stop(\n `${agentName}: ${result.written.length} updated, ${result.errors.length} failed`\n );\n } else {\n updateSpinner.stop(\n `${agentName}: ${result.written.length} skills updated`\n );\n }\n\n await updateMetadataAsync(\n installPath,\n response.skills.map((s) => ({\n name: s.name,\n source: response.source,\n version: response.version,\n serverUrl,\n }))\n );\n\n return { updated: result.written.length, errors: result.errors.length };\n },\n catch: (e) =>\n new UpdateError({\n message: e instanceof Error ? e.message : String(e),\n source: agentName,\n }),\n });\n\nconst updateSource = (\n source: SourceToUpdate,\n options: UpdateOptions,\n updateSpinner: ReturnType<typeof spinner>\n): Effect.Effect<{ updated: number; errors: number }, UpdateError> => {\n const sourceDesc = getSourceDesc(source);\n const serverUrl = options.server ?? source.serverUrl;\n\n const fetchOptions = buildFetchOptionsForSource(source, options);\n if (fetchOptions === null) {\n return Effect.fail(\n new UpdateError({\n message:\n \"Skills installed with legacy metadata format. Please reinstall using 'braid install --profile <name>' or 'braid install --projects <names>'.\",\n source: sourceDesc,\n })\n );\n }\n\n return pipe(\n Effect.tryPromise({\n try: async () => {\n updateSpinner.start(`Fetching latest skills from ${sourceDesc}...`);\n const response = await fetchSkillsAsync(fetchOptions);\n updateSpinner.stop(\n `Fetched ${response.skills.length} skills from ${sourceDesc}`\n );\n return response;\n },\n catch: (e) =>\n new UpdateError({\n message: e instanceof Error ? e.message : String(e),\n source: sourceDesc,\n }),\n }),\n Effect.flatMap((response) =>\n pipe(\n Effect.forEach(\n source.agents,\n ({ agentId, agentName, installPath }) =>\n updateAgentSkills(\n agentId,\n agentName,\n installPath,\n response,\n serverUrl,\n updateSpinner\n ),\n { concurrency: 1 }\n ),\n Effect.map((results) => ({\n updated: results.reduce((sum, r) => sum + r.updated, 0),\n errors: results.reduce((sum, r) => sum + r.errors, 0),\n }))\n )\n )\n );\n};\n\nconst updateAllSources = (\n sources: Map<string, SourceToUpdate>,\n options: UpdateOptions,\n updateSpinner: ReturnType<typeof spinner>\n): Effect.Effect<{ totalUpdated: number; totalErrors: number }> =>\n pipe(\n Effect.forEach(\n Array.from(sources.values()),\n (source) =>\n pipe(\n updateSource(source, options, updateSpinner),\n Effect.catchAll((error) => {\n updateSpinner.stop(\n `Failed to update from ${getSourceDesc(source)}`\n );\n log.error(` ${error.message}`);\n return Effect.succeed({ updated: 0, errors: 1 });\n })\n ),\n { concurrency: 1 }\n ),\n Effect.map((results) => ({\n totalUpdated: results.reduce((sum, r) => sum + r.updated, 0),\n totalErrors: results.reduce((sum, r) => sum + r.errors, 0),\n }))\n );\n\nconst handleUpdateError = (\n error: UpdateError,\n updateSpinner: ReturnType<typeof spinner>\n): void => {\n updateSpinner.stop(\"Update failed\");\n if (error.message === \"No AI coding agents detected.\") {\n log.warn(error.message);\n return;\n }\n if (error.message === \"No skills installed via braid.\") {\n log.warn(error.message);\n log.info(\"Run 'braid install --profile <name>' to install skills first.\");\n return;\n }\n log.error(error.message);\n process.exit(1);\n};\n\nconst handleProgramExit = (\n result: Awaited<\n ReturnType<\n typeof Effect.runPromiseExit<\n { totalUpdated: number; totalErrors: number },\n UpdateError | UserCancelledError\n >\n >\n >,\n updateSpinner: ReturnType<typeof spinner>\n): void => {\n if (result._tag !== \"Failure\") {\n return;\n }\n\n const cause = result.cause;\n if (cause._tag !== \"Fail\") {\n return;\n }\n\n const error = cause.error;\n if (error._tag === \"UserCancelledError\") {\n cancel(error.message);\n process.exit(0);\n }\n if (error._tag === \"UpdateError\") {\n handleUpdateError(error, updateSpinner);\n }\n};\n\nexport async function updateCommand(options: UpdateOptions): Promise<void> {\n const updateSpinner = spinner();\n updateSpinner.start(\"Scanning for installed skills...\");\n\n const program = pipe(\n Effect.tryPromise({\n try: () => detectAgentsAsync(),\n catch: () => new UpdateError({ message: \"Failed to detect agents\" }),\n }),\n Effect.filterOrFail(\n (agents) => agents.length > 0,\n () => new UpdateError({ message: \"No AI coding agents detected.\" })\n ),\n Effect.flatMap((detectedAgents) => collectSources(detectedAgents, options)),\n Effect.tap((sources) => {\n updateSpinner.stop(`Found ${sources.size} source(s) to update`);\n }),\n Effect.filterOrFail(\n (sources) => sources.size > 0,\n () => new UpdateError({ message: \"No skills installed via braid.\" })\n ),\n Effect.flatMap((sources) => selectSources(sources, options)),\n Effect.flatMap((selectedSources) =>\n updateAllSources(selectedSources, options, updateSpinner)\n ),\n Effect.tap(({ totalUpdated, totalErrors }) => {\n if (totalErrors > 0) {\n outro(`Updated ${totalUpdated} skills with ${totalErrors} errors.`);\n } else {\n outro(`Successfully updated ${totalUpdated} skills.`);\n }\n })\n );\n\n const result = await Effect.runPromiseExit(program);\n handleProgramExit(result, updateSpinner);\n}\n"],"mappings":"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","names":["process","process","Data","Effect","pipe","path","process","clearApiKeyAsync","homedir","join","process","Effect","pipe","path","process","pipe","Effect","join","Effect","path","process","join","readFile","writeFile","join","Data","Effect","pipe","pipe","Effect","Effect","Effect","mkdir","readFile","writeFile","dirname","Data","Effect","pipe","mkdir","writeFile","dirname","resolve","sep","Data","Effect","pipe","createDirectory","writeTextFile","path","Effect","process","spinner","intro","outro","cancel","confirm","isCancel","log","log","isCancel","cancel","intro","spinner","outro","log","spinner","log","spinner","join","resolve","process","join","log","process","isCancel","cancel","confirm","resolve","spinner","outro","cancel","isCancel","log","multiselect","outro","spinner","Data","Effect","pipe","Data","Effect","pipe","multiselect","isCancel","log","cancel","spinner","program","outro"]}
1
+ {"version":3,"sources":["../../../node_modules/tsup/assets/esm_shims.js","../src/lib/config.ts","../src/index.ts","../src/commands/auth.ts","../src/lib/api.ts","../src/commands/install.ts","../src/lib/agents.ts","../src/lib/metadata.ts","../src/lib/rule-writer.ts","../src/lib/skill-writer.ts","../src/lib/tui.ts","../src/commands/list.ts","../src/commands/remove.ts","../src/commands/update.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import { existsSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, parse } from \"node:path\";\nimport process from \"node:process\";\nimport { Data, Effect, pipe } from \"effect\";\n\nconst CONFIG_DIR = join(homedir(), \".config\", \"braid\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\nconst PROJECT_CONFIG_FILENAME = \"braid.json\";\nconst USER_CONFIG_FILENAME = \"braid.user.json\";\n\ninterface BraidSkillsConfig {\n apiKey?: string;\n serverUrl?: string;\n}\n\ninterface SkillsConfig {\n serverUrl?: string;\n}\n\ninterface BraidProjectConfig {\n $schema?: string;\n serverUrl?: string;\n profile?: string;\n orgProjects?: string[];\n personalProjects?: string[];\n includeUserGlobal?: boolean;\n includeOrgGlobal?: boolean;\n skills?: SkillsConfig;\n agents?: string[];\n}\n\ninterface BraidUserConfig extends BraidProjectConfig {\n token?: string;\n}\n\ninterface MergedConfig {\n token?: string;\n serverUrl: string;\n profile?: string;\n orgProjects?: string[];\n personalProjects?: string[];\n includeUserGlobal: boolean;\n includeOrgGlobal: boolean;\n agents?: string[];\n}\n\nclass ConfigReadError extends Data.TaggedError(\"ConfigReadError\")<{\n path: string;\n cause: unknown;\n}> {}\n\nclass ConfigWriteError extends Data.TaggedError(\"ConfigWriteError\")<{\n path: string;\n cause: unknown;\n}> {}\n\nconst findConfigFile = (\n filename: string,\n startDir: string = process.cwd()\n): string | undefined => {\n let currentDir = startDir;\n\n while (true) {\n const configPath = join(currentDir, filename);\n if (existsSync(configPath)) {\n return configPath;\n }\n\n const parsed = parse(currentDir);\n if (parsed.root === currentDir) {\n return undefined;\n }\n currentDir = parsed.dir;\n }\n};\n\nconst findProjectConfigFile = (\n startDir: string = process.cwd()\n): string | undefined => findConfigFile(PROJECT_CONFIG_FILENAME, startDir);\n\nconst findUserConfigFile = (\n startDir: string = process.cwd()\n): string | undefined => findConfigFile(USER_CONFIG_FILENAME, startDir);\n\nconst loadProjectConfig = (): Effect.Effect<BraidProjectConfig | undefined> =>\n Effect.tryPromise({\n try: async () => {\n const configPath = await findProjectConfigFile();\n if (!configPath) {\n return undefined;\n }\n const content = await readFile(configPath, \"utf-8\");\n return JSON.parse(content) as BraidProjectConfig;\n },\n catch: () => undefined,\n }).pipe(Effect.orElseSucceed(() => undefined));\n\nconst loadUserConfig = (): Effect.Effect<BraidUserConfig | undefined> =>\n Effect.tryPromise({\n try: async () => {\n const configPath = await findUserConfigFile();\n if (!configPath) {\n return undefined;\n }\n const content = await readFile(configPath, \"utf-8\");\n return JSON.parse(content) as BraidUserConfig;\n },\n catch: () => undefined,\n }).pipe(Effect.orElseSucceed(() => undefined));\n\nconst isValidServerUrl = (url: string): boolean => {\n try {\n const parsed = new URL(url);\n return parsed.protocol === \"https:\" || parsed.protocol === \"http:\";\n } catch {\n return false;\n }\n};\n\nconst resolveServerUrlFromConfig = (\n config: BraidProjectConfig | BraidUserConfig | undefined\n): string | undefined => {\n if (!config) {\n return undefined;\n }\n const url = config.skills?.serverUrl ?? config.serverUrl;\n if (url && !isValidServerUrl(url)) {\n return undefined;\n }\n return url;\n};\n\nconst applyConfigSource = (\n merged: MergedConfig,\n config: BraidProjectConfig | BraidUserConfig | undefined\n): void => {\n if (!config) {\n return;\n }\n\n const serverUrl = resolveServerUrlFromConfig(config);\n if (serverUrl) {\n merged.serverUrl = serverUrl;\n }\n\n if (config.profile) {\n merged.profile = config.profile;\n }\n if (config.orgProjects) {\n merged.orgProjects = config.orgProjects;\n }\n if (config.personalProjects) {\n merged.personalProjects = config.personalProjects;\n }\n if (config.includeUserGlobal !== undefined) {\n merged.includeUserGlobal = config.includeUserGlobal;\n }\n if (config.includeOrgGlobal !== undefined) {\n merged.includeOrgGlobal = config.includeOrgGlobal;\n }\n if (config.agents) {\n merged.agents = config.agents;\n }\n\n if (\"token\" in config && config.token) {\n merged.token = config.token;\n }\n};\n\nconst applyEnvOverrides = (merged: MergedConfig): void => {\n if (process.env.BRAID_API_KEY) {\n merged.token = process.env.BRAID_API_KEY;\n }\n const envServerUrl =\n process.env.BRAID_SKILLS_SERVER_URL ?? process.env.BRAID_SERVER_URL;\n if (envServerUrl && isValidServerUrl(envServerUrl)) {\n merged.serverUrl = envServerUrl;\n }\n};\n\nconst createDefaultMergedConfig = (): MergedConfig => ({\n serverUrl: \"https://braid.cloud\",\n includeUserGlobal: true,\n includeOrgGlobal: true,\n});\n\nconst loadMergedConfig = (): Effect.Effect<MergedConfig> =>\n pipe(\n Effect.all({\n projectConfig: loadProjectConfig(),\n userConfig: loadUserConfig(),\n globalConfig: loadConfig().pipe(\n Effect.orElseSucceed(() => ({}) as BraidSkillsConfig)\n ),\n }),\n Effect.map(({ projectConfig, userConfig, globalConfig }) => {\n const merged = createDefaultMergedConfig();\n\n applyConfigSource(merged, projectConfig);\n\n applyConfigSource(merged, userConfig);\n\n applyEnvOverrides(merged);\n\n if (!merged.token && globalConfig.apiKey) {\n merged.token = globalConfig.apiKey;\n }\n\n return merged;\n })\n );\n\nconst loadConfig = (): Effect.Effect<\n BraidSkillsConfig,\n ConfigReadError | ConfigWriteError\n> =>\n pipe(\n Effect.tryPromise({\n try: () => readFile(CONFIG_FILE, \"utf-8\"),\n catch: (e) => new ConfigReadError({ path: CONFIG_FILE, cause: e }),\n }),\n Effect.flatMap((content) =>\n Effect.try({\n try: () => JSON.parse(content) as BraidSkillsConfig,\n catch: () => ({}) as BraidSkillsConfig,\n })\n ),\n Effect.orElseSucceed(() => ({}) as BraidSkillsConfig)\n );\n\nconst saveConfig = (\n config: BraidSkillsConfig\n): Effect.Effect<void, ConfigWriteError> =>\n pipe(\n Effect.tryPromise({\n try: async () => {\n await mkdir(dirname(CONFIG_FILE), { recursive: true, mode: 0o700 });\n await writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), {\n encoding: \"utf-8\",\n mode: 0o600,\n });\n },\n catch: (e) => new ConfigWriteError({ path: CONFIG_FILE, cause: e }),\n })\n );\n\nconst getApiKey = (): Effect.Effect<\n string | undefined,\n ConfigReadError | ConfigWriteError\n> =>\n pipe(\n Effect.succeed(process.env.BRAID_API_KEY),\n Effect.flatMap((envKey) =>\n envKey\n ? Effect.succeed(envKey)\n : pipe(\n loadUserConfig(),\n Effect.flatMap((userConfig) =>\n userConfig?.token\n ? Effect.succeed(userConfig.token)\n : pipe(\n loadConfig(),\n Effect.map((config) => config.apiKey)\n )\n )\n )\n )\n );\n\nconst setApiKey = (\n apiKey: string\n): Effect.Effect<void, ConfigReadError | ConfigWriteError> =>\n pipe(\n loadConfig(),\n Effect.flatMap((config) => saveConfig({ ...config, apiKey }))\n );\n\nconst getServerUrl = (): Effect.Effect<\n string,\n ConfigReadError | ConfigWriteError\n> =>\n pipe(\n Effect.succeed(process.env.BRAID_SERVER_URL),\n Effect.flatMap((envUrl) =>\n envUrl\n ? Effect.succeed(envUrl)\n : pipe(\n loadUserConfig(),\n Effect.flatMap((userConfig) =>\n userConfig?.serverUrl\n ? Effect.succeed(userConfig.serverUrl)\n : pipe(\n loadConfig(),\n Effect.map(\n (config) => config.serverUrl ?? \"https://braid.cloud\"\n )\n )\n )\n )\n )\n );\n\nconst clearApiKey = (): Effect.Effect<\n void,\n ConfigReadError | ConfigWriteError\n> =>\n pipe(\n loadConfig(),\n Effect.flatMap((config) => {\n const { apiKey: _, ...rest } = config;\n return saveConfig(rest);\n })\n );\n\nconst loadConfigAsync = (): Promise<BraidSkillsConfig> =>\n Effect.runPromise(loadConfig());\n\nconst loadProjectConfigAsync = (): Promise<BraidProjectConfig | undefined> =>\n Effect.runPromise(loadProjectConfig());\n\nconst loadUserConfigAsync = (): Promise<BraidUserConfig | undefined> =>\n Effect.runPromise(loadUserConfig());\n\nconst loadMergedConfigAsync = (): Promise<MergedConfig> =>\n Effect.runPromise(loadMergedConfig());\n\nconst findProjectConfigFileAsync = (startDir?: string): string | undefined =>\n findProjectConfigFile(startDir);\n\nconst findUserConfigFileAsync = (startDir?: string): string | undefined =>\n findUserConfigFile(startDir);\n\nconst saveConfigAsync = (config: BraidSkillsConfig): Promise<void> =>\n Effect.runPromise(saveConfig(config));\n\nconst getApiKeyAsync = (): Promise<string | undefined> =>\n Effect.runPromise(getApiKey());\n\nconst setApiKeyAsync = (apiKey: string): Promise<void> =>\n Effect.runPromise(setApiKey(apiKey));\n\nconst getServerUrlAsync = (): Promise<string> =>\n Effect.runPromise(getServerUrl());\n\nconst clearApiKeyAsync = (): Promise<void> => Effect.runPromise(clearApiKey());\n\nexport type {\n BraidProjectConfig,\n BraidSkillsConfig,\n BraidUserConfig,\n MergedConfig,\n};\nexport {\n clearApiKey,\n clearApiKeyAsync,\n CONFIG_DIR,\n CONFIG_FILE,\n ConfigReadError,\n ConfigWriteError,\n findProjectConfigFile,\n findProjectConfigFileAsync,\n findUserConfigFile,\n findUserConfigFileAsync,\n getApiKey,\n getApiKeyAsync,\n getServerUrl,\n getServerUrlAsync,\n loadConfig,\n loadConfigAsync,\n loadMergedConfig,\n loadMergedConfigAsync,\n loadProjectConfig,\n loadProjectConfigAsync,\n loadUserConfig,\n loadUserConfigAsync,\n PROJECT_CONFIG_FILENAME,\n saveConfig,\n saveConfigAsync,\n setApiKey,\n setApiKeyAsync,\n USER_CONFIG_FILENAME,\n};\n","import { createRequire } from \"node:module\";\nimport { Command } from \"commander\";\n\nconst require = createRequire(import.meta.url);\nconst { version: PACKAGE_VERSION } = require(\"../package.json\");\n\nimport {\n authCommand,\n authLogoutCommand,\n authStatusCommand,\n} from \"./commands/auth.ts\";\nimport { installCommand } from \"./commands/install.ts\";\nimport { listCommand } from \"./commands/list.ts\";\nimport { removeCommand } from \"./commands/remove.ts\";\nimport { updateCommand } from \"./commands/update.ts\";\n\nconst program = new Command();\n\nprogram\n .name(\"braid\")\n .description(\n \"Install Braid prompts as agent skills to your local development environment\"\n )\n .version(PACKAGE_VERSION);\n\nconst auth = program\n .command(\"auth\")\n .description(\"Configure API key for Braid authentication\");\n\nauth\n .command(\"login\", { isDefault: true })\n .description(\"Configure API key\")\n .option(\"-s, --server <url>\", \"Braid server URL (for review apps, local dev)\")\n .action(authCommand);\n\nauth\n .command(\"status\")\n .description(\"Show current authentication status\")\n .action(authStatusCommand);\n\nauth\n .command(\"logout\")\n .description(\"Remove stored API key\")\n .action(authLogoutCommand);\n\nprogram\n .command(\"install\")\n .alias(\"add\")\n .description(\"Install skills from a profile or project\")\n .option(\"-p, --profile <name>\", \"Profile name to install from\")\n .option(\n \"--org-projects <ids>\",\n \"Comma-separated organization project IDs to install from\"\n )\n .option(\n \"--personal-projects <ids>\",\n \"Comma-separated personal project IDs to install from\"\n )\n .option(\n \"--include-user-globals\",\n \"Include user's personal global prompts (default: true)\"\n )\n .option(\"--no-include-user-globals\", \"Exclude user's personal global prompts\")\n .option(\n \"--include-org-globals\",\n \"Include organization's global prompts (default: true)\"\n )\n .option(\"--no-include-org-globals\", \"Exclude organization's global prompts\")\n .option(\n \"-a, --agents <list>\",\n \"Comma-separated list of agents (e.g., claude-code,opencode)\"\n )\n .option(\"-g, --global\", \"Install to global agent directories\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"-l, --list\", \"Preview skills without installing\")\n .option(\"-s, --server <url>\", \"Braid server URL (for review apps, local dev)\")\n .action(installCommand);\n\nprogram\n .command(\"list\")\n .alias(\"ls\")\n .description(\"List installed skills\")\n .option(\"-g, --global\", \"List skills in global directories only\")\n .action(listCommand);\n\nprogram\n .command(\"update\")\n .alias(\"up\")\n .description(\"Update installed skills to the latest version\")\n .option(\"-g, --global\", \"Update skills in global directories only\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"-s, --server <url>\", \"Braid server URL (for review apps, local dev)\")\n .action(updateCommand);\n\nprogram\n .command(\"remove\")\n .alias(\"rm\")\n .description(\"Remove installed skills\")\n .option(\"-a, --all\", \"Remove all installed skills\")\n .option(\"-g, --global\", \"Remove skills from global directories only\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"--skill <name>\", \"Remove a specific skill by name\")\n .action(removeCommand);\n\nprogram.parse();\n","import process from \"node:process\";\nimport {\n cancel,\n confirm,\n intro,\n isCancel,\n log,\n outro,\n password,\n spinner,\n} from \"@clack/prompts\";\nimport { validateApiKeyAsync } from \"../lib/api.ts\";\nimport type { MergedConfig } from \"../lib/config.ts\";\nimport {\n CONFIG_FILE,\n findProjectConfigFileAsync,\n findUserConfigFileAsync,\n loadMergedConfigAsync,\n setApiKeyAsync,\n USER_CONFIG_FILENAME,\n} from \"../lib/config.ts\";\n\ninterface AuthOptions {\n server?: string;\n}\n\nexport async function authCommand(options: AuthOptions): Promise<void> {\n intro(\"braid auth\");\n\n const config = await loadMergedConfigAsync();\n if (config.token) {\n const shouldReplace = await confirm({\n message: \"An API key is already configured. Replace it?\",\n initialValue: false,\n });\n\n if (isCancel(shouldReplace) || !shouldReplace) {\n outro(\"Auth cancelled.\");\n return;\n }\n }\n\n const apiKey = await password({\n message: \"Enter your Braid API key:\",\n validate: (value) => {\n if (!value) {\n return \"API key is required\";\n }\n if (!value.startsWith(\"br_\")) {\n return \"API key should start with 'br_'\";\n }\n return undefined;\n },\n });\n\n if (isCancel(apiKey)) {\n cancel(\"Auth cancelled.\");\n process.exit(0);\n }\n\n const authSpinner = spinner();\n authSpinner.start(\"Validating API key...\");\n\n try {\n const serverUrl = options.server ?? \"https://braid.cloud\";\n const isValid = await validateApiKeyAsync(apiKey, serverUrl);\n\n if (!isValid) {\n authSpinner.stop(\"Invalid API key\");\n log.error(\n \"The API key could not be validated. Please check your key and try again.\"\n );\n process.exit(1);\n }\n\n await setApiKeyAsync(apiKey);\n authSpinner.stop(\"API key validated and saved\");\n\n log.success(`Config saved to ${CONFIG_FILE}`);\n outro(\n \"You're authenticated! Run 'braid install --profile <name>' to install skills.\"\n );\n } catch (error) {\n authSpinner.stop(\"Validation failed\");\n const message = error instanceof Error ? error.message : String(error);\n log.error(`Failed to validate API key: ${message}`);\n process.exit(1);\n }\n}\n\nasync function displayTokenSource(masked: string): Promise<void> {\n if (process.env.BRAID_API_KEY) {\n log.info(`Authenticated with key: ${masked}`);\n log.info(\"Source: BRAID_API_KEY environment variable\");\n return;\n }\n\n const userConfigPath = await findUserConfigFileAsync();\n log.info(`Authenticated with key: ${masked}`);\n log.info(`Source: ${userConfigPath ?? CONFIG_FILE}`);\n}\n\nasync function displayProjectConfig(): Promise<void> {\n const projectConfigPath = await findProjectConfigFileAsync();\n if (projectConfigPath) {\n log.info(`Project config: ${projectConfigPath}`);\n }\n}\n\nfunction displayResolvedSettings(config: MergedConfig): void {\n const hasOrgProjects = config.orgProjects && config.orgProjects.length > 0;\n const hasPersonalProjects =\n config.personalProjects && config.personalProjects.length > 0;\n\n if (!(config.profile || hasOrgProjects || hasPersonalProjects)) {\n return;\n }\n\n log.info(\"\");\n\n if (config.profile) {\n log.info(`Default profile: ${config.profile}`);\n }\n if (hasOrgProjects) {\n log.info(`Org projects: ${config.orgProjects?.join(\", \")}`);\n }\n if (hasPersonalProjects) {\n log.info(`Personal projects: ${config.personalProjects?.join(\", \")}`);\n }\n if (config.serverUrl !== \"https://braid.cloud\") {\n log.info(`Server: ${config.serverUrl}`);\n }\n}\n\nexport async function authStatusCommand(): Promise<void> {\n const config = await loadMergedConfigAsync();\n\n if (!config.token) {\n log.warn(\"Not authenticated. Run 'braid auth' to configure your API key.\");\n log.info(\n `Or create a ${USER_CONFIG_FILENAME} file with: { \"token\": \"br_xxx\" }`\n );\n return;\n }\n\n const masked = `${config.token.slice(0, 7)}...${config.token.slice(-4)}`;\n\n await displayTokenSource(masked);\n await displayProjectConfig();\n displayResolvedSettings(config);\n}\n\nexport async function authLogoutCommand(): Promise<void> {\n const { clearApiKeyAsync } = await import(\"../lib/config.ts\");\n await clearApiKeyAsync();\n log.success(\"Logged out. API key removed from config.\");\n}\n","import { Data, Effect, pipe } from \"effect\";\nimport { getApiKeyAsync, getServerUrlAsync } from \"./config.ts\";\n\nconst TRAILING_SLASH_REGEX = /\\/$/;\n\ninterface SkillFile {\n path: string;\n content: string;\n encoding?: \"base64\";\n}\n\ninterface Skill {\n name: string;\n files: SkillFile[];\n}\n\ninterface ExportedRule {\n name: string;\n title: string;\n content: string;\n}\n\ninterface SkillsExportResponse {\n source: {\n type: \"profile\" | \"projects\";\n name: string;\n orgProjects?: string[];\n personalProjects?: string[];\n };\n version: string;\n skills: Skill[];\n rules?: ExportedRule[];\n}\n\ninterface ApiErrorResponse {\n error: string;\n code: string;\n}\n\nclass ApiError extends Data.TaggedError(\"ApiError\")<{\n message: string;\n code: string;\n status: number;\n}> {}\n\nclass AuthenticationError extends Data.TaggedError(\"AuthenticationError\")<{\n message: string;\n}> {}\n\nclass NetworkError extends Data.TaggedError(\"NetworkError\")<{\n message: string;\n cause?: unknown;\n}> {}\n\ntype FetchSkillsError = ApiError | AuthenticationError | NetworkError;\n\ninterface FetchSkillsOptions {\n profile?: string;\n orgProjects?: string[];\n personalProjects?: string[];\n includeUserGlobal?: boolean;\n includeOrgGlobal?: boolean;\n serverUrl?: string;\n apiKey?: string;\n}\n\nconst resolveApiKey = (\n optionsApiKey?: string\n): Effect.Effect<string, AuthenticationError | NetworkError> => {\n if (optionsApiKey) {\n return Effect.succeed(optionsApiKey);\n }\n\n return pipe(\n Effect.tryPromise({\n try: () => getApiKeyAsync(),\n catch: () => new NetworkError({ message: \"Failed to read config\" }),\n }),\n Effect.flatMap((key) =>\n key\n ? Effect.succeed(key)\n : Effect.fail(\n new AuthenticationError({\n message:\n 'No API key configured. Run \"braid auth\" to authenticate.',\n })\n )\n )\n );\n};\n\nconst resolveServerUrl = (\n optionsServerUrl?: string\n): Effect.Effect<string, NetworkError> => {\n if (optionsServerUrl) {\n return Effect.succeed(optionsServerUrl);\n }\n\n return Effect.tryPromise({\n try: () => getServerUrlAsync(),\n catch: () => new NetworkError({ message: \"Failed to read config\" }),\n });\n};\n\nconst parseResponse = (\n response: Response,\n json: unknown\n): Effect.Effect<SkillsExportResponse, FetchSkillsError> => {\n if (!response.ok) {\n const errorResponse = json as ApiErrorResponse;\n\n if (response.status === 401) {\n return Effect.fail(\n new AuthenticationError({\n message:\n errorResponse.error ||\n \"Invalid or expired API key. Run 'braid auth' to re-authenticate.\",\n })\n );\n }\n\n return Effect.fail(\n new ApiError({\n message: errorResponse.error || \"API request failed\",\n code: errorResponse.code || \"UNKNOWN_ERROR\",\n status: response.status,\n })\n );\n }\n\n return Effect.succeed(json as SkillsExportResponse);\n};\n\n/**\n * Fetches skills from the braid API\n *\n * @param options.profile - Profile name to fetch skills from\n * @param options.orgProjects - Array of org project IDs to fetch skills from\n * @param options.personalProjects - Array of personal project IDs to fetch skills from\n * @param options.serverUrl - Override server URL (for review apps, local dev)\n * @param options.apiKey - Override API key (for testing)\n */\nconst buildApiUrl = (serverUrl: string, path: string): URL => {\n const baseUrl = serverUrl.replace(TRAILING_SLASH_REGEX, \"\");\n return new URL(`${baseUrl}${path}`);\n};\n\nconst buildExportUrl = (\n serverUrl: string,\n options: FetchSkillsOptions\n): URL => {\n const url = buildApiUrl(serverUrl, \"/api/skills/export\");\n\n if (options.profile) {\n url.searchParams.set(\"profile\", options.profile);\n }\n if (options.orgProjects && options.orgProjects.length > 0) {\n url.searchParams.set(\"orgProjects\", options.orgProjects.join(\",\"));\n }\n if (options.personalProjects && options.personalProjects.length > 0) {\n url.searchParams.set(\n \"personalProjects\",\n options.personalProjects.join(\",\")\n );\n }\n if (options.includeUserGlobal !== undefined) {\n url.searchParams.set(\n \"includeUserGlobal\",\n String(options.includeUserGlobal)\n );\n }\n if (options.includeOrgGlobal !== undefined) {\n url.searchParams.set(\"includeOrgGlobal\", String(options.includeOrgGlobal));\n }\n\n return url;\n};\n\nconst executeApiRequest = (\n url: URL,\n apiKey: string,\n serverUrl: string\n): Effect.Effect<SkillsExportResponse, FetchSkillsError> =>\n pipe(\n Effect.tryPromise({\n try: () =>\n fetch(url.toString(), {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n }),\n catch: (e) =>\n new NetworkError({\n message: `Failed to connect to ${serverUrl}`,\n cause: e,\n }),\n }),\n Effect.flatMap((response) =>\n pipe(\n Effect.tryPromise({\n try: () => response.json() as Promise<unknown>,\n catch: () =>\n new NetworkError({ message: \"Failed to parse API response\" }),\n }),\n Effect.flatMap((json) => parseResponse(response, json))\n )\n )\n );\n\nconst fetchSkills = (\n options: FetchSkillsOptions\n): Effect.Effect<SkillsExportResponse, FetchSkillsError> =>\n pipe(\n Effect.all({\n apiKey: resolveApiKey(options.apiKey),\n serverUrl: resolveServerUrl(options.serverUrl),\n }),\n Effect.flatMap(({ apiKey, serverUrl }) => {\n const url = buildExportUrl(serverUrl, options);\n return executeApiRequest(url, apiKey, serverUrl);\n })\n );\n\n/**\n * Validates an API key by making a test request\n *\n * @param apiKey - API key to validate\n * @param serverUrl - Server URL to validate against (defaults to production)\n */\nconst validateApiKey = (\n apiKey: string,\n serverUrl?: string\n): Effect.Effect<boolean, NetworkError> =>\n pipe(\n Effect.tryPromise({\n try: async () => {\n const baseUrl = serverUrl ?? \"https://braid.cloud\";\n const url = buildApiUrl(baseUrl, \"/api/skills/export\");\n url.searchParams.set(\"profile\", \"default\");\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n });\n return response.status !== 401;\n },\n catch: (e) =>\n new NetworkError({\n message: `Failed to connect to ${serverUrl ?? \"https://braid.cloud\"}`,\n cause: e,\n }),\n })\n );\n\nconst fetchSkillsAsync = (\n options: FetchSkillsOptions\n): Promise<SkillsExportResponse> => Effect.runPromise(fetchSkills(options));\n\nconst validateApiKeyAsync = (\n apiKey: string,\n serverUrl?: string\n): Promise<boolean> => Effect.runPromise(validateApiKey(apiKey, serverUrl));\n\nexport type {\n ApiErrorResponse,\n ExportedRule,\n FetchSkillsOptions,\n Skill,\n SkillFile,\n SkillsExportResponse,\n};\nexport {\n ApiError,\n AuthenticationError,\n fetchSkills,\n fetchSkillsAsync,\n NetworkError,\n validateApiKey,\n validateApiKeyAsync,\n};\n","import type { AgentId, DetectedAgent } from \"../lib/agents.ts\";\nimport {\n detectAgentsAsync,\n getAgentById,\n resolveInstallPath,\n resolveRulesInstallPath,\n} from \"../lib/agents.ts\";\nimport type { FetchSkillsOptions, SkillsExportResponse } from \"../lib/api.ts\";\nimport { fetchSkillsAsync } from \"../lib/api.ts\";\nimport type { MergedConfig } from \"../lib/config.ts\";\nimport { loadMergedConfigAsync } from \"../lib/config.ts\";\nimport { updateMetadataAsync } from \"../lib/metadata.ts\";\nimport { writeRulesForAgentAsync } from \"../lib/rule-writer.ts\";\nimport { writeSkillsAsync } from \"../lib/skill-writer.ts\";\nimport {\n cancel,\n intro,\n isCancel,\n log,\n multiselect,\n outro,\n spinner,\n} from \"../lib/tui.ts\";\n\ninterface InstallOptions {\n profile?: string;\n orgProjects?: string;\n personalProjects?: string;\n includeUserGlobals?: boolean;\n includeOrgGlobals?: boolean;\n agents?: string;\n global?: boolean;\n yes?: boolean;\n list?: boolean;\n server?: string;\n}\n\ninterface ResolvedInstallConfig {\n profile: string | undefined;\n serverUrl: string;\n includeUserGlobal: boolean;\n includeOrgGlobal: boolean;\n orgProjects: string[] | undefined;\n personalProjects: string[] | undefined;\n}\n\nfunction resolveInstallConfig(\n options: InstallOptions,\n config: MergedConfig\n): ResolvedInstallConfig {\n const orgProjectsFromFlag = options.orgProjects\n ? options.orgProjects.split(\",\").map((s) => s.trim())\n : undefined;\n const personalProjectsFromFlag = options.personalProjects\n ? options.personalProjects.split(\",\").map((s) => s.trim())\n : undefined;\n\n return {\n profile: options.profile ?? config.profile,\n serverUrl: options.server ?? config.serverUrl,\n includeUserGlobal: options.includeUserGlobals ?? config.includeUserGlobal,\n includeOrgGlobal: options.includeOrgGlobals ?? config.includeOrgGlobal,\n orgProjects: orgProjectsFromFlag ?? config.orgProjects,\n personalProjects: personalProjectsFromFlag ?? config.personalProjects,\n };\n}\n\nfunction validateInstallOptions(resolved: ResolvedInstallConfig): void {\n const { profile, orgProjects, personalProjects } = resolved;\n const hasOrgProjects = orgProjects && orgProjects.length > 0;\n const hasPersonalProjects = personalProjects && personalProjects.length > 0;\n\n if (!(profile || hasOrgProjects || hasPersonalProjects)) {\n log.error(\"No profile or project(s) specified.\");\n log.info(\"Either:\");\n log.info(\n \" - Add 'profile', 'orgProjects', or 'personalProjects' to braid.json/braid.user.json\"\n );\n log.info(\" - Use --profile, --org-projects, or --personal-projects flags\");\n log.info(\"\");\n log.info(\"Examples:\");\n log.info(\" braid install --profile coding-standards\");\n log.info(\" braid install --org-projects proj123,proj456\");\n log.info(\" braid install --personal-projects myproj1\");\n process.exit(1);\n }\n}\n\nfunction buildSourceDescription(resolved: ResolvedInstallConfig): string {\n const { profile, orgProjects, personalProjects } = resolved;\n\n if (profile) {\n return `profile '${profile}'`;\n }\n\n const hasOrgProjects = orgProjects && orgProjects.length > 0;\n const hasPersonalProjects = personalProjects && personalProjects.length > 0;\n\n if (hasOrgProjects || hasPersonalProjects) {\n const totalProjects =\n (orgProjects?.length ?? 0) + (personalProjects?.length ?? 0);\n return totalProjects === 1\n ? `project ${orgProjects?.[0] ?? personalProjects?.[0]}`\n : `${totalProjects} projects`;\n }\n\n return \"unknown source\";\n}\n\nfunction buildFetchOptions(\n resolved: ResolvedInstallConfig\n): FetchSkillsOptions {\n const fetchOptions: FetchSkillsOptions = {\n serverUrl: resolved.serverUrl,\n includeUserGlobal: resolved.includeUserGlobal,\n includeOrgGlobal: resolved.includeOrgGlobal,\n };\n\n if (resolved.profile) {\n fetchOptions.profile = resolved.profile;\n }\n if (resolved.orgProjects && resolved.orgProjects.length > 0) {\n fetchOptions.orgProjects = resolved.orgProjects;\n }\n if (resolved.personalProjects && resolved.personalProjects.length > 0) {\n fetchOptions.personalProjects = resolved.personalProjects;\n }\n\n return fetchOptions;\n}\n\nfunction displaySkillsAndExit(skills: SkillsExportResponse[\"skills\"]): never {\n log.info(\"\\nSkills:\");\n for (const skill of skills) {\n const fileCount = skill.files.length;\n log.info(\n ` ${skill.name} (${fileCount} file${fileCount !== 1 ? \"s\" : \"\"})`\n );\n }\n process.exit(0);\n}\n\nasync function resolveAgents(\n options: InstallOptions,\n installSpinner: ReturnType<typeof spinner>\n): Promise<DetectedAgent[]> {\n if (options.agents) {\n const agentIds = options.agents.split(\",\").map((s) => s.trim() as AgentId);\n const selectedAgents = agentIds\n .map((id) => {\n const agentConfig = getAgentById(id);\n if (!agentConfig) {\n log.warn(`Unknown agent: ${id}`);\n return null;\n }\n return {\n ...agentConfig,\n hasProjectConfig: true,\n hasGlobalConfig: true,\n } as DetectedAgent;\n })\n .filter((a): a is DetectedAgent => a !== null);\n\n if (selectedAgents.length === 0) {\n log.error(\"No valid agents specified.\");\n process.exit(1);\n }\n\n return selectedAgents;\n }\n\n installSpinner.start(\"Detecting installed agents...\");\n const allDetectedAgents = await detectAgentsAsync();\n\n const detectedAgents = allDetectedAgents.filter((agent) =>\n options.global ? agent.hasGlobalConfig : agent.hasProjectConfig\n );\n\n const targetType = options.global ? \"global\" : \"project\";\n installSpinner.stop(\n `Detected ${detectedAgents.length} agent(s) with ${targetType} config`\n );\n\n for (const agent of detectedAgents) {\n const targetPath = options.global ? agent.globalPath : agent.projectPath;\n log.info(` ${agent.name} → ${targetPath}`);\n }\n\n if (detectedAgents.length === 0) {\n log.warn(\"No AI coding agents detected.\");\n log.info(\n \"Supported agents: claude-code, opencode, cursor, windsurf, cline, and more.\"\n );\n log.info(\n \"Use --agents to specify agents manually: braid install -p my-profile -a claude-code\"\n );\n process.exit(1);\n }\n\n return detectedAgents;\n}\n\nasync function selectAgents(\n detectedAgents: DetectedAgent[],\n options: InstallOptions\n): Promise<DetectedAgent[]> {\n if (options.yes) {\n return detectedAgents;\n }\n\n const agentChoices = detectedAgents.map((agent) => ({\n value: agent,\n label: agent.name,\n hint: options.global ? agent.globalPath : agent.projectPath,\n }));\n\n const selected = await multiselect({\n message: \"Select agents to install to:\",\n options: agentChoices,\n initialValues: detectedAgents,\n required: true,\n });\n\n if (isCancel(selected)) {\n cancel(\"Install cancelled.\");\n process.exit(0);\n }\n\n return selected;\n}\n\nasync function installSkillsToAgent(\n agent: DetectedAgent,\n response: SkillsExportResponse,\n installPath: string\n): Promise<{ written: number; errors: number }> {\n if (response.skills.length === 0 || !agent.projectPath) {\n return { written: 0, errors: 0 };\n }\n\n const result = await writeSkillsAsync(installPath, response.skills, agent.id);\n\n for (const err of result.errors) {\n log.warn(` Failed skill: ${err.skill} - ${err.error}`);\n }\n\n return { written: result.written.length, errors: result.errors.length };\n}\n\nasync function installRulesToAgent(\n agent: DetectedAgent,\n response: SkillsExportResponse,\n options: InstallOptions\n): Promise<{ written: number; errors: number }> {\n const rules = response.rules ?? [];\n const rulesPath = resolveRulesInstallPath(agent, {\n global: options.global === true,\n });\n\n if (rules.length === 0 || !rulesPath || !agent.ruleFormat) {\n return { written: 0, errors: 0 };\n }\n\n const result = await writeRulesForAgentAsync(agent, rules, rulesPath);\n\n for (const err of result.errors) {\n log.warn(` Failed rules: ${err.agent} - ${err.error}`);\n }\n\n return { written: result.written, errors: result.errors.length };\n}\n\nfunction formatInstallSummary(\n agentName: string,\n skillsWritten: number,\n rulesWritten: number\n): string {\n const parts: string[] = [];\n if (skillsWritten > 0) {\n parts.push(`${skillsWritten} skills`);\n }\n if (rulesWritten > 0) {\n parts.push(`${rulesWritten} rules`);\n }\n return `${agentName}: ${parts.join(\", \")} installed`;\n}\n\nasync function installToAgent(\n agent: DetectedAgent,\n response: SkillsExportResponse,\n serverUrl: string,\n options: InstallOptions,\n installSpinner: ReturnType<typeof spinner>\n): Promise<{ written: number; errors: number }> {\n const installPath = resolveInstallPath(agent, {\n global: options.global === true,\n });\n\n installSpinner.start(`Installing to ${agent.name}...`);\n\n const skills = installPath\n ? await installSkillsToAgent(agent, response, installPath)\n : { written: 0, errors: 0 };\n const rules = await installRulesToAgent(agent, response, options);\n\n const totalWritten = skills.written + rules.written;\n const totalErrors = skills.errors + rules.errors;\n\n if (totalErrors > 0) {\n installSpinner.stop(\n `${agent.name}: ${totalWritten} installed, ${totalErrors} failed`\n );\n } else {\n installSpinner.stop(\n formatInstallSummary(agent.name, skills.written, rules.written)\n );\n }\n\n if (response.skills.length > 0 && installPath) {\n await updateMetadataAsync(\n installPath,\n response.skills.map((s) => ({\n name: s.name,\n source: response.source,\n version: response.version,\n serverUrl,\n }))\n );\n }\n\n return { written: totalWritten, errors: totalErrors };\n}\n\nexport async function installCommand(options: InstallOptions): Promise<void> {\n const config = await loadMergedConfigAsync();\n const resolved = resolveInstallConfig(options, config);\n\n validateInstallOptions(resolved);\n\n const sourceDesc = buildSourceDescription(resolved);\n intro(`Installing from ${sourceDesc}`);\n\n const installSpinner = spinner();\n installSpinner.start(\"Fetching from Braid...\");\n\n try {\n const fetchOptions = buildFetchOptions(resolved);\n const response = await fetchSkillsAsync(fetchOptions);\n\n const ruleCount = response.rules?.length ?? 0;\n const skillCount = response.skills.length;\n const foundParts: string[] = [];\n if (skillCount > 0) {\n foundParts.push(`${skillCount} skills`);\n }\n if (ruleCount > 0) {\n foundParts.push(`${ruleCount} rules`);\n }\n installSpinner.stop(`Found ${foundParts.join(\", \") || \"nothing\"}`);\n\n if (skillCount === 0 && ruleCount === 0) {\n log.warn(\n \"No skills or rules found. Check that your profile/project has enabled prompts.\"\n );\n process.exit(0);\n }\n\n if (options.list) {\n displaySkillsAndExit(response.skills);\n }\n\n let selectedAgents = await resolveAgents(options, installSpinner);\n if (!options.agents) {\n selectedAgents = await selectAgents(selectedAgents, options);\n }\n\n let totalWritten = 0;\n let totalErrors = 0;\n\n for (const agent of selectedAgents) {\n const result = await installToAgent(\n agent,\n response,\n resolved.serverUrl,\n options,\n installSpinner\n );\n totalWritten += result.written;\n totalErrors += result.errors;\n }\n\n if (totalErrors > 0) {\n outro(`Installed ${totalWritten} items with ${totalErrors} errors.`);\n } else {\n outro(\n `Successfully installed ${totalWritten} items to ${selectedAgents.length} agent(s).`\n );\n }\n\n log.info(\"Run 'braid list' to see installed skills.\");\n } catch (error) {\n installSpinner.stop(\"Install failed\");\n const message = error instanceof Error ? error.message : String(error);\n log.error(message);\n process.exit(1);\n }\n}\n","import { access, constants } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport { Effect, pipe } from \"effect\";\n\ntype AgentId =\n | \"amp\"\n | \"kimi-cli\"\n | \"antigravity\"\n | \"claude-code\"\n | \"moltbot\"\n | \"cline\"\n | \"codebuddy\"\n | \"codex\"\n | \"command-code\"\n | \"continue\"\n | \"crush\"\n | \"cursor\"\n | \"droid\"\n | \"gemini-cli\"\n | \"github-copilot\"\n | \"goose\"\n | \"junie\"\n | \"kilo\"\n | \"kiro-cli\"\n | \"kode\"\n | \"mcpjam\"\n | \"mux\"\n | \"opencode\"\n | \"openhands\"\n | \"pi\"\n | \"qoder\"\n | \"qwen-code\"\n | \"roo\"\n | \"trae\"\n | \"windsurf\"\n | \"zencoder\"\n | \"neovate\"\n | \"pochi\"\n | \"zed\";\n\ntype RuleFormat = \"mdc\" | \"markdown-dir\" | \"append-single\";\n\ninterface AgentConfig {\n id: AgentId;\n name: string;\n projectPath: string;\n globalPath: string;\n rulesProjectPath?: string;\n rulesGlobalPath?: string;\n ruleFormat?: RuleFormat;\n}\n\nconst home = homedir();\n\nconst AGENTS: AgentConfig[] = [\n {\n id: \"amp\",\n name: \"Amp, Kimi Code CLI\",\n projectPath: \".agents/skills\",\n globalPath: join(home, \".config\", \"agents\", \"skills\"),\n },\n {\n id: \"kimi-cli\",\n name: \"Kimi Code CLI\",\n projectPath: \".agents/skills\",\n globalPath: join(home, \".config\", \"agents\", \"skills\"),\n },\n {\n id: \"antigravity\",\n name: \"Antigravity\",\n projectPath: \".agent/skills\",\n globalPath: join(home, \".gemini\", \"antigravity\", \"global_skills\"),\n },\n {\n id: \"claude-code\",\n name: \"Claude Code\",\n projectPath: \".claude/skills\",\n globalPath: join(home, \".claude\", \"skills\"),\n rulesProjectPath: \".claude/rules\",\n rulesGlobalPath: join(home, \".claude\", \"rules\"),\n ruleFormat: \"markdown-dir\",\n },\n {\n id: \"moltbot\",\n name: \"Moltbot\",\n projectPath: \"skills\",\n globalPath: join(home, \".moltbot\", \"skills\"),\n },\n {\n id: \"cline\",\n name: \"Cline\",\n projectPath: \".cline/skills\",\n globalPath: join(home, \".cline\", \"skills\"),\n rulesProjectPath: \".clinerules\",\n ruleFormat: \"append-single\",\n },\n {\n id: \"codebuddy\",\n name: \"CodeBuddy\",\n projectPath: \".codebuddy/skills\",\n globalPath: join(home, \".codebuddy\", \"skills\"),\n },\n {\n id: \"codex\",\n name: \"Codex\",\n projectPath: \".codex/skills\",\n globalPath: join(home, \".codex\", \"skills\"),\n },\n {\n id: \"command-code\",\n name: \"Command Code\",\n projectPath: \".commandcode/skills\",\n globalPath: join(home, \".commandcode\", \"skills\"),\n },\n {\n id: \"continue\",\n name: \"Continue\",\n projectPath: \".continue/skills\",\n globalPath: join(home, \".continue\", \"skills\"),\n },\n {\n id: \"crush\",\n name: \"Crush\",\n projectPath: \".crush/skills\",\n globalPath: join(home, \".config\", \"crush\", \"skills\"),\n },\n {\n id: \"cursor\",\n name: \"Cursor\",\n projectPath: \".cursor/skills\",\n globalPath: join(home, \".cursor\", \"skills\"),\n rulesProjectPath: \".cursor/rules\",\n ruleFormat: \"mdc\",\n },\n {\n id: \"droid\",\n name: \"Droid\",\n projectPath: \".factory/skills\",\n globalPath: join(home, \".factory\", \"skills\"),\n },\n {\n id: \"gemini-cli\",\n name: \"Gemini CLI\",\n projectPath: \".gemini/skills\",\n globalPath: join(home, \".gemini\", \"skills\"),\n },\n {\n id: \"github-copilot\",\n name: \"GitHub Copilot\",\n projectPath: \".github/skills\",\n globalPath: join(home, \".copilot\", \"skills\"),\n rulesProjectPath: \".github/copilot-instructions.md\",\n ruleFormat: \"append-single\",\n },\n {\n id: \"goose\",\n name: \"Goose\",\n projectPath: \".goose/skills\",\n globalPath: join(home, \".config\", \"goose\", \"skills\"),\n },\n {\n id: \"junie\",\n name: \"Junie\",\n projectPath: \".junie/skills\",\n globalPath: join(home, \".junie\", \"skills\"),\n },\n {\n id: \"kilo\",\n name: \"Kilo Code\",\n projectPath: \".kilocode/skills\",\n globalPath: join(home, \".kilocode\", \"skills\"),\n },\n {\n id: \"kiro-cli\",\n name: \"Kiro CLI\",\n projectPath: \".kiro/skills\",\n globalPath: join(home, \".kiro\", \"skills\"),\n },\n {\n id: \"kode\",\n name: \"Kode\",\n projectPath: \".kode/skills\",\n globalPath: join(home, \".kode\", \"skills\"),\n },\n {\n id: \"mcpjam\",\n name: \"MCPJam\",\n projectPath: \".mcpjam/skills\",\n globalPath: join(home, \".mcpjam\", \"skills\"),\n },\n {\n id: \"mux\",\n name: \"Mux\",\n projectPath: \".mux/skills\",\n globalPath: join(home, \".mux\", \"skills\"),\n },\n {\n id: \"opencode\",\n name: \"OpenCode\",\n projectPath: \".opencode/skills\",\n globalPath: join(home, \".config\", \"opencode\", \"skills\"),\n },\n {\n id: \"openhands\",\n name: \"OpenHands\",\n projectPath: \".openhands/skills\",\n globalPath: join(home, \".openhands\", \"skills\"),\n },\n {\n id: \"pi\",\n name: \"Pi\",\n projectPath: \".pi/skills\",\n globalPath: join(home, \".pi\", \"agent\", \"skills\"),\n },\n {\n id: \"qoder\",\n name: \"Qoder\",\n projectPath: \".qoder/skills\",\n globalPath: join(home, \".qoder\", \"skills\"),\n },\n {\n id: \"qwen-code\",\n name: \"Qwen Code\",\n projectPath: \".qwen/skills\",\n globalPath: join(home, \".qwen\", \"skills\"),\n },\n {\n id: \"roo\",\n name: \"Roo Code\",\n projectPath: \".roo/skills\",\n globalPath: join(home, \".roo\", \"skills\"),\n rulesProjectPath: \".roo/rules\",\n rulesGlobalPath: join(home, \".roo\", \"rules\"),\n ruleFormat: \"markdown-dir\",\n },\n {\n id: \"trae\",\n name: \"Trae\",\n projectPath: \".trae/skills\",\n globalPath: join(home, \".trae\", \"skills\"),\n },\n {\n id: \"windsurf\",\n name: \"Windsurf\",\n projectPath: \".windsurf/skills\",\n globalPath: join(home, \".codeium\", \"windsurf\", \"skills\"),\n rulesProjectPath: \".windsurfrules\",\n ruleFormat: \"append-single\",\n },\n {\n id: \"zencoder\",\n name: \"Zencoder\",\n projectPath: \".zencoder/skills\",\n globalPath: join(home, \".zencoder\", \"skills\"),\n },\n {\n id: \"neovate\",\n name: \"Neovate\",\n projectPath: \".neovate/skills\",\n globalPath: join(home, \".neovate\", \"skills\"),\n },\n {\n id: \"pochi\",\n name: \"Pochi\",\n projectPath: \".pochi/skills\",\n globalPath: join(home, \".pochi\", \"skills\"),\n },\n {\n id: \"zed\",\n name: \"Zed\",\n projectPath: \"\",\n globalPath: \"\",\n rulesProjectPath: \".zed/rules\",\n rulesGlobalPath: join(home, \".config\", \"zed\", \"rules\"),\n ruleFormat: \"markdown-dir\",\n },\n];\n\nconst directoryExists = (path: string): Effect.Effect<boolean> =>\n pipe(\n Effect.tryPromise({\n try: () => access(path, constants.F_OK),\n catch: () => false,\n }),\n Effect.map(() => true),\n Effect.orElseSucceed(() => false)\n );\n\ninterface DetectedAgent extends AgentConfig {\n hasProjectConfig: boolean;\n hasGlobalConfig: boolean;\n}\n\ninterface InstalledAgent extends AgentConfig {\n hasProjectInstall: boolean;\n hasGlobalInstall: boolean;\n}\n\nconst METADATA_FILENAME = \".braidskills-metadata.json\";\n\nconst detectAgents = (projectRoot?: string): Effect.Effect<DetectedAgent[]> => {\n const cwd = projectRoot ?? process.cwd();\n\n return pipe(\n Effect.forEach(\n AGENTS,\n (agent) =>\n pipe(\n Effect.all({\n hasProjectConfig: agent.projectPath\n ? directoryExists(join(cwd, agent.projectPath))\n : Effect.succeed(false),\n hasGlobalConfig: agent.globalPath\n ? directoryExists(agent.globalPath)\n : Effect.succeed(false),\n hasRulesProjectConfig: agent.rulesProjectPath\n ? directoryExists(join(cwd, agent.rulesProjectPath))\n : Effect.succeed(false),\n hasRulesGlobalConfig: agent.rulesGlobalPath\n ? directoryExists(agent.rulesGlobalPath)\n : Effect.succeed(false),\n }),\n Effect.map(\n ({\n hasProjectConfig,\n hasGlobalConfig,\n hasRulesProjectConfig,\n hasRulesGlobalConfig,\n }): DetectedAgent => ({\n ...agent,\n hasProjectConfig: hasProjectConfig || hasRulesProjectConfig,\n hasGlobalConfig: hasGlobalConfig || hasRulesGlobalConfig,\n })\n )\n ),\n { concurrency: \"unbounded\" }\n ),\n Effect.map((agents) =>\n agents.filter((a) => a.hasProjectConfig || a.hasGlobalConfig)\n )\n );\n};\n\nconst detectInstalledAgents = (\n projectRoot?: string\n): Effect.Effect<InstalledAgent[]> => {\n const cwd = projectRoot ?? process.cwd();\n\n return pipe(\n Effect.forEach(\n AGENTS,\n (agent) =>\n pipe(\n Effect.all({\n hasProjectInstall: agent.projectPath\n ? directoryExists(join(cwd, agent.projectPath, METADATA_FILENAME))\n : Effect.succeed(false),\n hasGlobalInstall: agent.globalPath\n ? directoryExists(join(agent.globalPath, METADATA_FILENAME))\n : Effect.succeed(false),\n }),\n Effect.map(\n ({ hasProjectInstall, hasGlobalInstall }): InstalledAgent => ({\n ...agent,\n hasProjectInstall,\n hasGlobalInstall,\n })\n )\n ),\n { concurrency: \"unbounded\" }\n ),\n Effect.map((agents) =>\n agents.filter((a) => a.hasProjectInstall || a.hasGlobalInstall)\n )\n );\n};\n\nconst detectInstalledAgentsAsync = (\n projectRoot?: string\n): Promise<InstalledAgent[]> =>\n Effect.runPromise(detectInstalledAgents(projectRoot));\n\ninterface ResolvedAgentsResult {\n agents: AgentConfig[];\n source: \"config\" | \"installed\" | \"detected\" | \"none\";\n}\n\nconst resolveAgents = (options: {\n configAgents?: string[];\n projectRoot?: string;\n global?: boolean;\n}): Effect.Effect<ResolvedAgentsResult> => {\n const { configAgents, projectRoot, global: useGlobal } = options;\n\n if (configAgents && configAgents.length > 0) {\n const agents = configAgents\n .map((id) => getAgentById(id as AgentId))\n .filter((a): a is AgentConfig => a !== undefined);\n\n if (agents.length > 0) {\n return Effect.succeed<ResolvedAgentsResult>({\n agents,\n source: \"config\",\n });\n }\n }\n\n return pipe(\n Effect.all({\n installed: detectInstalledAgents(projectRoot),\n detected: detectAgents(projectRoot),\n }),\n Effect.map(({ installed, detected }): ResolvedAgentsResult => {\n const relevantInstalled = installed.filter((a) =>\n useGlobal ? a.hasGlobalInstall : a.hasProjectInstall\n );\n\n if (relevantInstalled.length > 0) {\n return {\n agents: relevantInstalled,\n source: \"installed\",\n };\n }\n\n const relevantDetected = detected.filter((a) =>\n useGlobal ? a.hasGlobalConfig : a.hasProjectConfig\n );\n\n if (relevantDetected.length > 0) {\n return {\n agents: relevantDetected,\n source: \"detected\",\n };\n }\n\n return { agents: [], source: \"none\" };\n })\n );\n};\n\nconst resolveAgentsAsync = (options: {\n configAgents?: string[];\n projectRoot?: string;\n global?: boolean;\n}): Promise<ResolvedAgentsResult> => Effect.runPromise(resolveAgents(options));\n\nconst getAgentById = (id: AgentId): AgentConfig | undefined =>\n AGENTS.find((a) => a.id === id);\n\nconst getAllAgentIds = (): AgentId[] => AGENTS.map((a) => a.id);\n\nconst detectAgentsAsync = (projectRoot?: string): Promise<DetectedAgent[]> =>\n Effect.runPromise(detectAgents(projectRoot));\n\nconst directoryExistsAsync = (path: string): Promise<boolean> =>\n Effect.runPromise(directoryExists(path));\n\nconst resolveInstallPath = (\n agent: AgentConfig,\n options: { global?: boolean; projectRoot?: string }\n): string | undefined => {\n if (options.global) {\n return agent.globalPath || undefined;\n }\n if (!agent.projectPath) {\n return undefined;\n }\n const cwd = options.projectRoot ?? process.cwd();\n return join(cwd, agent.projectPath);\n};\n\nconst resolveRulesInstallPath = (\n agent: AgentConfig,\n options: { global?: boolean; projectRoot?: string }\n): string | undefined => {\n if (options.global) {\n return agent.rulesGlobalPath;\n }\n if (!agent.rulesProjectPath) {\n return undefined;\n }\n const cwd = options.projectRoot ?? process.cwd();\n return join(cwd, agent.rulesProjectPath);\n};\n\nexport type {\n AgentConfig,\n AgentId,\n DetectedAgent,\n InstalledAgent,\n ResolvedAgentsResult,\n RuleFormat,\n};\nexport {\n AGENTS,\n detectAgents,\n detectAgentsAsync,\n detectInstalledAgents,\n detectInstalledAgentsAsync,\n directoryExists,\n directoryExistsAsync,\n getAgentById,\n getAllAgentIds,\n resolveAgents,\n resolveAgentsAsync,\n resolveInstallPath,\n resolveRulesInstallPath,\n};\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { Data, Effect, pipe } from \"effect\";\n\nconst METADATA_FILENAME = \".braidskills-metadata.json\";\n\ninterface InstalledSkill {\n name: string;\n source: {\n type: \"profile\" | \"projects\";\n name: string;\n orgProjects?: string[];\n personalProjects?: string[];\n };\n version: string;\n installedAt: string;\n serverUrl: string;\n}\n\ninterface SkillsMetadata {\n skills: InstalledSkill[];\n}\n\nclass MetadataReadError extends Data.TaggedError(\"MetadataReadError\")<{\n path: string;\n cause: unknown;\n}> {}\n\nclass MetadataWriteError extends Data.TaggedError(\"MetadataWriteError\")<{\n path: string;\n cause: unknown;\n}> {}\n\nconst getMetadataPath = (skillsDir: string): string =>\n join(skillsDir, METADATA_FILENAME);\n\nconst readMetadata = (\n skillsDir: string\n): Effect.Effect<SkillsMetadata, MetadataReadError> => {\n const metadataPath = getMetadataPath(skillsDir);\n\n return pipe(\n Effect.tryPromise({\n try: () => readFile(metadataPath, \"utf-8\"),\n catch: (e) => new MetadataReadError({ path: metadataPath, cause: e }),\n }),\n Effect.flatMap((content) =>\n Effect.try({\n try: () => JSON.parse(content) as SkillsMetadata,\n catch: () => ({ skills: [] }) as SkillsMetadata,\n })\n ),\n Effect.orElseSucceed(() => ({ skills: [] }) as SkillsMetadata)\n );\n};\n\nconst writeMetadata = (\n skillsDir: string,\n metadata: SkillsMetadata\n): Effect.Effect<void, MetadataWriteError> => {\n const metadataPath = getMetadataPath(skillsDir);\n\n return Effect.tryPromise({\n try: () =>\n writeFile(metadataPath, JSON.stringify(metadata, null, 2), \"utf-8\"),\n catch: (e) => new MetadataWriteError({ path: metadataPath, cause: e }),\n });\n};\n\nconst updateMetadata = (\n skillsDir: string,\n newSkills: Array<{\n name: string;\n source: InstalledSkill[\"source\"];\n version: string;\n serverUrl: string;\n }>\n): Effect.Effect<void, MetadataReadError | MetadataWriteError> =>\n pipe(\n readMetadata(skillsDir),\n Effect.map((existing) => {\n const now = new Date().toISOString();\n const updatedSkills = [...existing.skills];\n\n for (const skill of newSkills) {\n const existingIndex = updatedSkills.findIndex(\n (s) => s.name === skill.name\n );\n const newEntry: InstalledSkill = {\n name: skill.name,\n source: skill.source,\n version: skill.version,\n installedAt: now,\n serverUrl: skill.serverUrl,\n };\n\n if (existingIndex >= 0) {\n updatedSkills[existingIndex] = newEntry;\n } else {\n updatedSkills.push(newEntry);\n }\n }\n\n return { skills: updatedSkills };\n }),\n Effect.flatMap((metadata) => writeMetadata(skillsDir, metadata))\n );\n\nconst getOutdatedSkills = (\n skillsDir: string,\n currentVersion: string\n): Effect.Effect<InstalledSkill[], MetadataReadError> =>\n pipe(\n readMetadata(skillsDir),\n Effect.map((metadata) =>\n metadata.skills.filter((s) => s.version !== currentVersion)\n )\n );\n\nconst removeFromMetadata = (\n skillsDir: string,\n skillName: string\n): Effect.Effect<void, MetadataReadError | MetadataWriteError> =>\n pipe(\n readMetadata(skillsDir),\n Effect.map((metadata) => ({\n skills: metadata.skills.filter((s) => s.name !== skillName),\n })),\n Effect.flatMap((metadata) => writeMetadata(skillsDir, metadata))\n );\n\nconst readMetadataAsync = (skillsDir: string): Promise<SkillsMetadata> =>\n Effect.runPromise(readMetadata(skillsDir));\n\nconst writeMetadataAsync = (\n skillsDir: string,\n metadata: SkillsMetadata\n): Promise<void> => Effect.runPromise(writeMetadata(skillsDir, metadata));\n\nconst updateMetadataAsync = (\n skillsDir: string,\n newSkills: Array<{\n name: string;\n source: InstalledSkill[\"source\"];\n version: string;\n serverUrl: string;\n }>\n): Promise<void> => Effect.runPromise(updateMetadata(skillsDir, newSkills));\n\nconst getOutdatedSkillsAsync = (\n skillsDir: string,\n currentVersion: string\n): Promise<InstalledSkill[]> =>\n Effect.runPromise(getOutdatedSkills(skillsDir, currentVersion));\n\nconst removeFromMetadataAsync = (\n skillsDir: string,\n skillName: string\n): Promise<void> => Effect.runPromise(removeFromMetadata(skillsDir, skillName));\n\nexport type { InstalledSkill, SkillsMetadata };\nexport {\n getMetadataPath,\n getOutdatedSkills,\n getOutdatedSkillsAsync,\n METADATA_FILENAME,\n MetadataReadError,\n MetadataWriteError,\n readMetadata,\n readMetadataAsync,\n removeFromMetadata,\n removeFromMetadataAsync,\n updateMetadata,\n updateMetadataAsync,\n writeMetadata,\n writeMetadataAsync,\n};\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve, sep } from \"node:path\";\nimport { Data, Effect, pipe } from \"effect\";\nimport type { AgentConfig, RuleFormat } from \"./agents.ts\";\nimport type { ExportedRule } from \"./api.ts\";\n\nclass RuleWriteError extends Data.TaggedError(\"RuleWriteError\")<{\n path: string;\n operation: \"mkdir\" | \"write\" | \"read\";\n cause: unknown;\n}> {}\n\nconst createDirectory = (dir: string): Effect.Effect<void, RuleWriteError> =>\n Effect.tryPromise({\n try: () => mkdir(dir, { recursive: true }),\n catch: (e) =>\n new RuleWriteError({ path: dir, operation: \"mkdir\", cause: e }),\n });\n\nconst writeTextFile = (\n fullPath: string,\n content: string\n): Effect.Effect<void, RuleWriteError> =>\n Effect.tryPromise({\n try: () => writeFile(fullPath, content, \"utf-8\"),\n catch: (e) =>\n new RuleWriteError({ path: fullPath, operation: \"write\", cause: e }),\n });\n\nconst readTextFile = (\n fullPath: string\n): Effect.Effect<string, RuleWriteError> =>\n Effect.tryPromise({\n try: () => readFile(fullPath, \"utf-8\"),\n catch: (e) =>\n new RuleWriteError({ path: fullPath, operation: \"read\", cause: e }),\n });\n\nconst assertRulePathWithinBase = (\n basePath: string,\n ruleName: string\n): Effect.Effect<string, RuleWriteError> => {\n const resolvedBase = resolve(basePath);\n const resolvedFull = resolve(basePath, ruleName);\n if (\n resolvedFull !== resolvedBase &&\n !resolvedFull.startsWith(resolvedBase + sep)\n ) {\n return Effect.fail(\n new RuleWriteError({\n path: ruleName,\n operation: \"write\",\n cause: new Error(\n `Path traversal detected: \"${ruleName}\" resolves outside base directory`\n ),\n })\n );\n }\n return Effect.succeed(resolvedFull);\n};\n\nconst BRAID_SECTION_START = \"<!-- braid:rules:start -->\";\nconst BRAID_SECTION_END = \"<!-- braid:rules:end -->\";\nconst YAML_SPECIAL_CHARS = /[\\n\\r:#{}[\\],&*?|>!'\"%@`]/;\n\nfunction escapeYamlValue(value: string): string {\n if (\n YAML_SPECIAL_CHARS.test(value) ||\n value.startsWith(\" \") ||\n value.endsWith(\" \")\n ) {\n return `\"${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n }\n return value;\n}\n\nfunction buildMdcContent(rule: ExportedRule): string {\n const lines: string[] = [\"---\"];\n lines.push(`description: ${escapeYamlValue(rule.title)}`);\n lines.push(\"alwaysApply: true\");\n lines.push(\"---\");\n lines.push(\"\");\n lines.push(`# ${rule.title}`);\n lines.push(\"\");\n lines.push(rule.content);\n return lines.join(\"\\n\");\n}\n\nfunction buildAppendContent(rules: ExportedRule[]): string {\n const lines: string[] = [BRAID_SECTION_START, \"\"];\n\n for (const rule of rules) {\n lines.push(`## ${rule.title}`);\n lines.push(\"\");\n lines.push(rule.content);\n lines.push(\"\");\n }\n\n lines.push(BRAID_SECTION_END);\n return lines.join(\"\\n\");\n}\n\nconst writeMdcRules = (\n basePath: string,\n rules: ExportedRule[]\n): Effect.Effect<void, RuleWriteError> =>\n pipe(\n createDirectory(basePath),\n Effect.flatMap(() =>\n Effect.forEach(\n rules,\n (rule) =>\n pipe(\n assertRulePathWithinBase(basePath, `${rule.name}.mdc`),\n Effect.flatMap((filePath) =>\n writeTextFile(filePath, buildMdcContent(rule))\n )\n ),\n { concurrency: \"unbounded\" }\n )\n ),\n Effect.asVoid\n );\n\nconst writeMarkdownDirRules = (\n basePath: string,\n rules: ExportedRule[]\n): Effect.Effect<void, RuleWriteError> =>\n pipe(\n createDirectory(basePath),\n Effect.flatMap(() =>\n Effect.forEach(\n rules,\n (rule) =>\n pipe(\n assertRulePathWithinBase(basePath, `${rule.name}.md`),\n Effect.flatMap((filePath) =>\n writeTextFile(filePath, `# ${rule.title}\\n\\n${rule.content}`)\n )\n ),\n { concurrency: \"unbounded\" }\n )\n ),\n Effect.asVoid\n );\n\nconst writeAppendSingleRules = (\n filePath: string,\n rules: ExportedRule[]\n): Effect.Effect<void, RuleWriteError> =>\n pipe(\n createDirectory(dirname(filePath)),\n Effect.flatMap(() =>\n pipe(\n readTextFile(filePath),\n Effect.orElseSucceed(() => \"\")\n )\n ),\n Effect.flatMap((existing) => {\n const braidContent = buildAppendContent(rules);\n\n const startIdx = existing.indexOf(BRAID_SECTION_START);\n const endIdx = existing.indexOf(BRAID_SECTION_END);\n\n let newContent: string;\n if (startIdx !== -1 && endIdx !== -1) {\n newContent =\n existing.slice(0, startIdx) +\n braidContent +\n existing.slice(endIdx + BRAID_SECTION_END.length);\n } else {\n newContent = existing ? `${existing}\\n\\n${braidContent}` : braidContent;\n }\n\n return writeTextFile(filePath, newContent);\n })\n );\n\nconst writeRulesForFormat = (\n basePath: string,\n rules: ExportedRule[],\n format: RuleFormat\n): Effect.Effect<void, RuleWriteError> => {\n switch (format) {\n case \"mdc\":\n return writeMdcRules(basePath, rules);\n case \"markdown-dir\":\n return writeMarkdownDirRules(basePath, rules);\n case \"append-single\":\n return writeAppendSingleRules(basePath, rules);\n default:\n return Effect.void;\n }\n};\n\ninterface WriteRulesResult {\n written: number;\n errors: Array<{ agent: string; error: string }>;\n}\n\nconst writeRulesForAgent = (\n agent: AgentConfig,\n rules: ExportedRule[],\n rulesPath: string\n): Effect.Effect<WriteRulesResult, never> => {\n if (!agent.ruleFormat || rules.length === 0) {\n return Effect.succeed({ written: 0, errors: [] });\n }\n\n return pipe(\n writeRulesForFormat(rulesPath, rules, agent.ruleFormat),\n Effect.map(() => ({\n written: rules.length,\n errors: [] as Array<{ agent: string; error: string }>,\n })),\n Effect.catchAll((error) =>\n Effect.succeed({\n written: 0,\n errors: [\n {\n agent: agent.name,\n error:\n error.cause instanceof Error\n ? error.cause.message\n : String(error.cause),\n },\n ],\n })\n )\n );\n};\n\nconst writeRulesForAgentAsync = (\n agent: AgentConfig,\n rules: ExportedRule[],\n rulesPath: string\n): Promise<WriteRulesResult> =>\n Effect.runPromise(writeRulesForAgent(agent, rules, rulesPath));\n\nexport type { WriteRulesResult };\nexport { RuleWriteError, writeRulesForAgent, writeRulesForAgentAsync };\n","import { chmod, mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve, sep } from \"node:path\";\nimport { Data, Effect, pipe } from \"effect\";\nimport type { AgentId } from \"./agents.ts\";\nimport type { Skill, SkillFile } from \"./api.ts\";\n\nclass WriteError extends Data.TaggedError(\"WriteError\")<{\n path: string;\n operation: \"mkdir\" | \"write\" | \"chmod\";\n cause: unknown;\n}> {}\n\nconst createDirectory = (\n dir: string,\n fullPath: string\n): Effect.Effect<void, WriteError> =>\n Effect.tryPromise({\n try: () => mkdir(dir, { recursive: true }),\n catch: (e) =>\n new WriteError({ path: fullPath, operation: \"mkdir\", cause: e }),\n });\n\nconst writeTextFile = (\n fullPath: string,\n content: string\n): Effect.Effect<void, WriteError> =>\n Effect.tryPromise({\n try: () => writeFile(fullPath, content, \"utf-8\"),\n catch: (e) =>\n new WriteError({ path: fullPath, operation: \"write\", cause: e }),\n });\n\nconst writeBinaryFile = (\n fullPath: string,\n content: Buffer\n): Effect.Effect<void, WriteError> =>\n Effect.tryPromise({\n try: () => writeFile(fullPath, content),\n catch: (e) =>\n new WriteError({ path: fullPath, operation: \"write\", cause: e }),\n });\n\nconst makeExecutable = (fullPath: string): Effect.Effect<void, WriteError> =>\n Effect.tryPromise({\n try: () => chmod(fullPath, 0o755),\n catch: (e) =>\n new WriteError({ path: fullPath, operation: \"chmod\", cause: e }),\n });\n\nconst assertWithinBase = (\n basePath: string,\n untrustedPath: string\n): Effect.Effect<string, WriteError> => {\n const resolvedBase = resolve(basePath);\n const resolvedFull = resolve(basePath, untrustedPath);\n if (\n resolvedFull !== resolvedBase &&\n !resolvedFull.startsWith(resolvedBase + sep)\n ) {\n return Effect.fail(\n new WriteError({\n path: untrustedPath,\n operation: \"write\",\n cause: new Error(\n `Path traversal detected: \"${untrustedPath}\" resolves outside base directory`\n ),\n })\n );\n }\n return Effect.succeed(resolvedFull);\n};\n\nconst COMPATIBILITY_REGEX = /^compatibility:\\s*.+$/m;\n\nconst rewriteCompatibility = (content: string, agentId: AgentId): string => {\n return content.replace(COMPATIBILITY_REGEX, `compatibility: ${agentId}`);\n};\n\nconst decodeFileContent = (file: SkillFile, agentId?: AgentId): string => {\n let content: string;\n if (file.encoding === \"base64\") {\n content = Buffer.from(file.content, \"base64\").toString(\"utf-8\");\n } else {\n content = file.content;\n }\n\n if (agentId && file.path === \"SKILL.md\") {\n content = rewriteCompatibility(content, agentId);\n }\n\n return content;\n};\n\nconst decodeFileContentBinary = (file: SkillFile): Buffer => {\n if (file.encoding === \"base64\") {\n return Buffer.from(file.content, \"base64\");\n }\n return Buffer.from(file.content, \"utf-8\");\n};\n\nconst isBinaryFile = (path: string): boolean => {\n const binaryExtensions = [\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".ico\",\n \".bmp\",\n ];\n return binaryExtensions.some((ext) => path.toLowerCase().endsWith(ext));\n};\n\n/**\n * Determines if a file should be made executable based on its path and extension.\n *\n * A file is considered a script if ALL of the following conditions are met:\n * 1. The file path contains \"/scripts/\" (indicating it's in a scripts directory)\n * 2. The file has a recognized script extension (.sh, .bash, .py, .js, .mjs, .rb)\n *\n * **Important behavior notes:**\n * - Files in the scripts/ directory WITHOUT a recognized extension will NOT be executable\n * - Files with script extensions OUTSIDE the scripts/ directory will NOT be executable\n * - No content validation is performed - the decision is purely path and extension based\n * - This follows the Agent Skills standard where executable scripts are placed in scripts/\n *\n * **Security consideration:**\n * This is a defensive approach that requires both correct location AND extension to grant\n * execute permissions. While a user could theoretically place a non-script file with a\n * script extension in scripts/, the dual requirement (path + extension) provides a\n * reasonable safeguard for the expected use case of skill distribution.\n *\n * @param path - The file path relative to the skill root\n * @returns true if the file should receive executable permissions (chmod 0o755)\n *\n * @example\n * isScriptFile(\"scripts/deploy.sh\") // true - in scripts/, has .sh extension\n * isScriptFile(\"scripts/setup.py\") // true - in scripts/, has .py extension\n * isScriptFile(\"src/scripts/deploy.sh\") // true - in nested scripts/, has .sh extension\n * isScriptFile(\"scripts/readme.txt\") // false - in scripts/, but not a script extension\n * isScriptFile(\"src/index.js\") // false - has .js extension, but not in scripts/\n * isScriptFile(\"deploy.sh\") // false - has .sh extension, but not in scripts/\n */\nconst isScriptFile = (path: string): boolean => {\n const scriptExtensions = [\".sh\", \".bash\", \".py\", \".js\", \".mjs\", \".rb\"];\n const lowerPath = path.toLowerCase();\n const inScriptsDir =\n lowerPath.includes(\"/scripts/\") || lowerPath.startsWith(\"scripts/\");\n return (\n inScriptsDir && scriptExtensions.some((ext) => lowerPath.endsWith(ext))\n );\n};\n\nconst writeFileContent = (\n fullPath: string,\n file: SkillFile,\n agentId?: AgentId\n): Effect.Effect<void, WriteError> =>\n isBinaryFile(file.path)\n ? writeBinaryFile(fullPath, decodeFileContentBinary(file))\n : writeTextFile(fullPath, decodeFileContent(file, agentId));\n\n/**\n * Conditionally sets executable permissions on a file if it's identified as a script.\n *\n * This function uses {@link isScriptFile} to determine if the file should be executable.\n * Only files in the scripts/ directory with recognized script extensions will receive\n * executable permissions (chmod 0o755).\n *\n * @param fullPath - The absolute filesystem path where the file is written\n * @param filePath - The relative path within the skill (used for script detection)\n * @returns Effect that succeeds after setting permissions, or immediately if not a script\n */\nconst setExecutableIfScript = (\n fullPath: string,\n filePath: string\n): Effect.Effect<void, WriteError> =>\n isScriptFile(filePath) ? makeExecutable(fullPath) : Effect.void;\n\nconst writeSkillFile = (\n basePath: string,\n file: SkillFile,\n agentId?: AgentId\n): Effect.Effect<void, WriteError> =>\n pipe(\n assertWithinBase(basePath, file.path),\n Effect.flatMap((fullPath) => {\n const dir = dirname(fullPath);\n return pipe(\n createDirectory(dir, fullPath),\n Effect.flatMap(() => writeFileContent(fullPath, file, agentId)),\n Effect.flatMap(() => setExecutableIfScript(fullPath, file.path))\n );\n })\n );\n\nconst writeSkill = (\n basePath: string,\n skill: Skill,\n agentId?: AgentId\n): Effect.Effect<void, WriteError> =>\n pipe(\n assertWithinBase(basePath, skill.name),\n Effect.flatMap((skillDir) =>\n pipe(\n Effect.forEach(\n skill.files,\n (file) => writeSkillFile(skillDir, file, agentId),\n {\n concurrency: \"unbounded\",\n }\n ),\n Effect.map(() => undefined)\n )\n )\n );\n\ninterface WriteSkillsResult {\n written: string[];\n errors: Array<{ skill: string; error: string }>;\n}\n\n/**\n * Writes multiple skills to disk\n *\n * @param basePath - Base directory to write skills to (e.g., \".claude/skills\")\n * @param skills - Skills to write\n * @param agentId - Agent ID to set in compatibility field\n */\nconst writeSkills = (\n basePath: string,\n skills: Skill[],\n agentId?: AgentId\n): Effect.Effect<WriteSkillsResult, never> =>\n pipe(\n Effect.forEach(\n skills,\n (skill) =>\n pipe(\n writeSkill(basePath, skill, agentId),\n Effect.map(() => ({ success: true as const, skill: skill.name })),\n Effect.catchAll((error) =>\n Effect.succeed({\n success: false as const,\n skill: skill.name,\n error:\n error.cause instanceof Error\n ? error.cause.message\n : String(error.cause),\n })\n )\n ),\n { concurrency: \"unbounded\" }\n ),\n Effect.map((results) => ({\n written: results.filter((r) => r.success).map((r) => r.skill),\n errors: results\n .filter(\n (r): r is { success: false; skill: string; error: string } =>\n !r.success\n )\n .map((r) => ({ skill: r.skill, error: r.error })),\n }))\n );\n\nconst writeSkillAsync = (\n basePath: string,\n skill: Skill,\n agentId?: AgentId\n): Promise<void> => Effect.runPromise(writeSkill(basePath, skill, agentId));\n\nconst writeSkillsAsync = (\n basePath: string,\n skills: Skill[],\n agentId?: AgentId\n): Promise<WriteSkillsResult> =>\n Effect.runPromise(writeSkills(basePath, skills, agentId));\n\nexport type { WriteSkillsResult };\nexport {\n decodeFileContent,\n decodeFileContentBinary,\n isBinaryFile,\n isScriptFile,\n WriteError,\n writeSkill,\n writeSkillAsync,\n writeSkillFile,\n writeSkills,\n writeSkillsAsync,\n};\n","import process from \"node:process\";\nimport {\n cancel as clackCancel,\n confirm as clackConfirm,\n group as clackGroup,\n groupMultiselect as clackGroupMultiselect,\n intro as clackIntro,\n isCancel as clackIsCancel,\n log as clackLog,\n multiselect as clackMultiselect,\n note as clackNote,\n outro as clackOutro,\n password as clackPassword,\n select as clackSelect,\n selectKey as clackSelectKey,\n spinner as clackSpinner,\n text as clackText,\n} from \"@clack/prompts\";\n\nconst isTTY = Boolean(process.stdout.isTTY);\n\ninterface NoopSpinner {\n start: (message?: string) => void;\n stop: (message?: string) => void;\n message: (message?: string) => void;\n}\n\nfunction spinner(): NoopSpinner | ReturnType<typeof clackSpinner> {\n if (isTTY) {\n return clackSpinner();\n }\n\n return {\n start: (message?: string) => {\n if (message) {\n process.stdout.write(`${message}\\n`);\n }\n },\n stop: (message?: string) => {\n if (message) {\n process.stdout.write(`${message}\\n`);\n }\n },\n message: (message?: string) => {\n if (message) {\n process.stdout.write(`${message}\\n`);\n }\n },\n };\n}\n\nfunction intro(message: string): void {\n if (isTTY) {\n clackIntro(message);\n } else {\n process.stdout.write(`\\n${message}\\n`);\n }\n}\n\nfunction outro(message: string): void {\n if (isTTY) {\n clackOutro(message);\n } else {\n process.stdout.write(`${message}\\n\\n`);\n }\n}\n\nconst cancel = clackCancel;\nconst confirm = clackConfirm;\nconst group = clackGroup;\nconst groupMultiselect = clackGroupMultiselect;\nconst isCancel = clackIsCancel;\nconst log = clackLog;\nconst multiselect = clackMultiselect;\nconst note = clackNote;\nconst password = clackPassword;\nconst select = clackSelect;\nconst selectKey = clackSelectKey;\nconst text = clackText;\n\nexport {\n cancel,\n confirm,\n group,\n groupMultiselect,\n intro,\n isCancel,\n log,\n multiselect,\n note,\n outro,\n password,\n select,\n selectKey,\n spinner,\n text,\n};\n","import { log, spinner } from \"@clack/prompts\";\nimport type { DetectedAgent } from \"../lib/agents.ts\";\nimport {\n detectAgentsAsync,\n directoryExistsAsync,\n resolveInstallPath,\n} from \"../lib/agents.ts\";\nimport type { InstalledSkill } from \"../lib/metadata.ts\";\nimport { readMetadataAsync } from \"../lib/metadata.ts\";\n\ninterface ListOptions {\n global?: boolean;\n}\n\nfunction formatRelativeTime(isoDate: string): string {\n const date = new Date(isoDate);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60_000);\n const diffHours = Math.floor(diffMins / 60);\n const diffDays = Math.floor(diffHours / 24);\n\n if (diffMins < 1) {\n return \"just now\";\n }\n if (diffMins < 60) {\n return `${diffMins} minute${diffMins !== 1 ? \"s\" : \"\"} ago`;\n }\n if (diffHours < 24) {\n return `${diffHours} hour${diffHours !== 1 ? \"s\" : \"\"} ago`;\n }\n if (diffDays < 30) {\n return `${diffDays} day${diffDays !== 1 ? \"s\" : \"\"} ago`;\n }\n return date.toLocaleDateString();\n}\n\nfunction displayAgentSkills(\n agent: DetectedAgent,\n installPath: string,\n braidSkills: InstalledSkill[]\n): void {\n const nameWidth = 25;\n const sourceWidth = 20;\n const installedWidth = 15;\n\n log.info(\"\");\n log.info(`Agent: ${agent.name} (${installPath})`);\n log.info(\"─\".repeat(60));\n\n const header = [\n \"Skill\".padEnd(nameWidth),\n \"Source\".padEnd(sourceWidth),\n \"Installed\".padEnd(installedWidth),\n ].join(\" \");\n\n log.info(header);\n log.info(\"─\".repeat(60));\n\n for (const skill of braidSkills) {\n const sourceName = skill.source.name;\n\n const row = [\n skill.name.slice(0, nameWidth).padEnd(nameWidth),\n sourceName.slice(0, sourceWidth).padEnd(sourceWidth),\n formatRelativeTime(skill.installedAt).padEnd(installedWidth),\n ].join(\" \");\n\n log.info(row);\n }\n}\n\nexport async function listCommand(options: ListOptions): Promise<void> {\n const listSpinner = spinner();\n listSpinner.start(\"Scanning for installed skills...\");\n\n try {\n const detectedAgents = await detectAgentsAsync();\n\n if (detectedAgents.length === 0) {\n listSpinner.stop(\"No agents detected\");\n log.warn(\"No AI coding agents detected.\");\n return;\n }\n\n listSpinner.stop(`Found ${detectedAgents.length} agent(s)`);\n\n let totalSkills = 0;\n\n for (const agent of detectedAgents) {\n const installPath = resolveInstallPath(agent, {\n global: options.global === true,\n });\n if (!installPath) {\n continue;\n }\n const exists = await directoryExistsAsync(installPath);\n\n if (!exists) {\n continue;\n }\n\n const metadata = await readMetadataAsync(installPath);\n const braidSkills = metadata.skills;\n\n if (braidSkills.length === 0) {\n continue;\n }\n\n totalSkills += braidSkills.length;\n displayAgentSkills(agent, installPath, braidSkills);\n }\n\n if (totalSkills === 0) {\n log.warn(\"\\nNo skills installed via braid.\");\n log.info(\"Run 'braid install --profile <name>' to install skills.\");\n } else {\n log.info(\"\");\n log.info(`Total: ${totalSkills} skill(s) installed`);\n }\n } catch (error) {\n listSpinner.stop(\"List failed\");\n const message = error instanceof Error ? error.message : String(error);\n log.error(message);\n process.exit(1);\n }\n}\n","import { rm } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport process from \"node:process\";\nimport type { DetectedAgent } from \"../lib/agents.ts\";\nimport {\n detectAgentsAsync,\n directoryExistsAsync,\n resolveInstallPath,\n} from \"../lib/agents.ts\";\nimport { readMetadataAsync, removeFromMetadataAsync } from \"../lib/metadata.ts\";\nimport {\n cancel,\n confirm,\n isCancel,\n log,\n multiselect,\n outro,\n spinner,\n} from \"../lib/tui.ts\";\n\ninterface RemoveOptions {\n all?: boolean;\n global?: boolean;\n yes?: boolean;\n skill?: string;\n}\n\ninterface SkillToRemove {\n name: string;\n agentName: string;\n installPath: string;\n skillPath: string;\n}\n\nasync function collectInstalledSkills(\n detectedAgents: DetectedAgent[],\n options: RemoveOptions\n): Promise<SkillToRemove[]> {\n const skillsToRemove: SkillToRemove[] = [];\n\n for (const agent of detectedAgents) {\n const installPath = resolveInstallPath(agent, {\n global: options.global === true,\n });\n if (!installPath) {\n continue;\n }\n const exists = await directoryExistsAsync(installPath);\n\n if (!exists) {\n continue;\n }\n\n const metadata = await readMetadataAsync(installPath);\n\n for (const skill of metadata.skills) {\n skillsToRemove.push({\n name: skill.name,\n agentName: agent.name,\n installPath,\n skillPath: join(installPath, skill.name),\n });\n }\n }\n\n return skillsToRemove;\n}\n\nasync function selectSkillsToRemove(\n skillsToRemove: SkillToRemove[],\n options: RemoveOptions\n): Promise<SkillToRemove[]> {\n if (options.skill) {\n const selected = skillsToRemove.filter((s) => s.name === options.skill);\n if (selected.length === 0) {\n log.error(`Skill '${options.skill}' not found.`);\n log.info(\"Run 'braid list' to see installed skills.\");\n process.exit(1);\n }\n return selected;\n }\n\n if (options.all || options.yes) {\n return skillsToRemove;\n }\n\n const choices = skillsToRemove.map((skill) => ({\n value: skill,\n label: skill.name,\n hint: skill.agentName,\n }));\n\n const result = await multiselect({\n message: \"Select skills to remove:\",\n options: choices,\n required: true,\n });\n\n if (isCancel(result)) {\n cancel(\"Remove cancelled.\");\n process.exit(0);\n }\n\n return result;\n}\n\nasync function confirmRemoval(\n selectedCount: number,\n options: RemoveOptions\n): Promise<void> {\n if (options.yes || options.skill || options.all) {\n return;\n }\n\n const confirmed = await confirm({\n message: `Remove ${selectedCount} skill(s)?`,\n initialValue: false,\n });\n\n if (isCancel(confirmed) || !confirmed) {\n cancel(\"Remove cancelled.\");\n process.exit(0);\n }\n}\n\nasync function removeSkill(\n skill: SkillToRemove,\n removeSpinner: ReturnType<typeof spinner>\n): Promise<boolean> {\n removeSpinner.start(`Removing ${skill.name} from ${skill.agentName}...`);\n\n try {\n const resolvedSkillPath = resolve(skill.skillPath);\n const resolvedInstallPath = resolve(skill.installPath);\n if (!resolvedSkillPath.startsWith(`${resolvedInstallPath}/`)) {\n removeSpinner.stop(`Unsafe path for ${skill.name}`);\n log.warn(\" Skill path escapes install directory, skipping.\");\n return false;\n }\n await rm(resolvedSkillPath, { recursive: true, force: true });\n await removeFromMetadataAsync(skill.installPath, skill.name);\n removeSpinner.stop(`Removed ${skill.name} from ${skill.agentName}`);\n return true;\n } catch (error) {\n removeSpinner.stop(`Failed to remove ${skill.name}`);\n const message = error instanceof Error ? error.message : String(error);\n log.warn(` ${message}`);\n return false;\n }\n}\n\nexport async function removeCommand(options: RemoveOptions): Promise<void> {\n const removeSpinner = spinner();\n removeSpinner.start(\"Scanning for installed skills...\");\n\n try {\n const detectedAgents = await detectAgentsAsync();\n\n if (detectedAgents.length === 0) {\n removeSpinner.stop(\"No agents detected\");\n log.warn(\"No AI coding agents detected.\");\n return;\n }\n\n const skillsToRemove = await collectInstalledSkills(\n detectedAgents,\n options\n );\n\n removeSpinner.stop(`Found ${skillsToRemove.length} installed skill(s)`);\n\n if (skillsToRemove.length === 0) {\n log.warn(\"No skills installed via braid.\");\n return;\n }\n\n const selected = await selectSkillsToRemove(skillsToRemove, options);\n await confirmRemoval(selected.length, options);\n\n let removed = 0;\n let errors = 0;\n\n for (const skill of selected) {\n const success = await removeSkill(skill, removeSpinner);\n if (success) {\n removed++;\n } else {\n errors++;\n }\n }\n\n if (errors > 0) {\n outro(`Removed ${removed} skill(s) with ${errors} error(s).`);\n } else {\n outro(`Successfully removed ${removed} skill(s).`);\n }\n } catch (error) {\n removeSpinner.stop(\"Remove failed\");\n const message = error instanceof Error ? error.message : String(error);\n log.error(message);\n process.exit(1);\n }\n}\n","import {\n cancel,\n isCancel,\n log,\n multiselect,\n outro,\n spinner,\n} from \"@clack/prompts\";\nimport { Data, Effect, pipe } from \"effect\";\nimport type { AgentId, DetectedAgent } from \"../lib/agents.ts\";\nimport {\n detectAgentsAsync,\n directoryExistsAsync,\n resolveInstallPath,\n} from \"../lib/agents.ts\";\nimport type { FetchSkillsOptions } from \"../lib/api.ts\";\nimport { fetchSkillsAsync } from \"../lib/api.ts\";\nimport { readMetadataAsync, updateMetadataAsync } from \"../lib/metadata.ts\";\nimport { writeSkillsAsync } from \"../lib/skill-writer.ts\";\n\ninterface UpdateOptions {\n global?: boolean;\n server?: string;\n yes?: boolean;\n}\n\ninterface SourceToUpdate {\n type: \"profile\" | \"projects\";\n name: string;\n orgProjects: string[] | undefined;\n personalProjects: string[] | undefined;\n serverUrl: string;\n agents: Array<{ agentId: AgentId; agentName: string; installPath: string }>;\n}\n\nclass UpdateError extends Data.TaggedError(\"UpdateError\")<{\n message: string;\n source?: string;\n}> {}\n\nclass UserCancelledError extends Data.TaggedError(\"UserCancelledError\")<{\n message: string;\n}> {}\n\nasync function resolveValidInstallPath(\n agent: DetectedAgent,\n options: UpdateOptions\n): Promise<string | null> {\n const installPath = resolveInstallPath(agent, {\n global: options.global === true,\n });\n if (!installPath) {\n return null;\n }\n const exists = await directoryExistsAsync(installPath);\n return exists ? installPath : null;\n}\n\nconst collectSourcesFromAgent = (\n agent: DetectedAgent,\n options: UpdateOptions,\n sourcesToUpdate: Map<string, SourceToUpdate>\n): Effect.Effect<void, UpdateError> =>\n Effect.tryPromise({\n try: async () => {\n const installPath = await resolveValidInstallPath(agent, options);\n if (!installPath) {\n return;\n }\n\n const metadata = await readMetadataAsync(installPath);\n\n for (const skill of metadata.skills) {\n const key =\n skill.source.type === \"profile\"\n ? `profile:${skill.source.name}`\n : `projects:${skill.source.name}`;\n\n if (!sourcesToUpdate.has(key)) {\n sourcesToUpdate.set(key, {\n type: skill.source.type,\n name: skill.source.name,\n orgProjects: skill.source.orgProjects,\n personalProjects: skill.source.personalProjects,\n serverUrl: skill.serverUrl,\n agents: [],\n });\n }\n\n const source = sourcesToUpdate.get(key);\n if (\n source &&\n !source.agents.some((a) => a.installPath === installPath)\n ) {\n source.agents.push({\n agentId: agent.id,\n agentName: agent.name,\n installPath,\n });\n }\n }\n },\n catch: () => new UpdateError({ message: \"Failed to collect sources\" }),\n });\n\nconst collectSources = (\n detectedAgents: DetectedAgent[],\n options: UpdateOptions\n): Effect.Effect<Map<string, SourceToUpdate>, UpdateError> =>\n pipe(\n Effect.succeed(new Map<string, SourceToUpdate>()),\n Effect.tap((sourcesToUpdate) =>\n Effect.forEach(\n detectedAgents,\n (agent) => collectSourcesFromAgent(agent, options, sourcesToUpdate),\n { concurrency: 1 }\n )\n )\n );\n\nconst selectSources = (\n sourcesToUpdate: Map<string, SourceToUpdate>,\n options: UpdateOptions\n): Effect.Effect<Map<string, SourceToUpdate>, UserCancelledError> => {\n if (options.yes) {\n return Effect.succeed(sourcesToUpdate);\n }\n\n return Effect.tryPromise({\n try: async () => {\n const sources = Array.from(sourcesToUpdate.entries()).map(\n ([key, source]) => ({\n value: key,\n label: source.name,\n hint: `${source.agents.length} agent(s)`,\n })\n );\n\n const selected = await multiselect({\n message: \"Select sources to update:\",\n options: sources,\n initialValues: sources.map((s) => s.value),\n required: true,\n });\n\n if (isCancel(selected)) {\n throw new Error(\"cancelled\");\n }\n\n for (const key of sourcesToUpdate.keys()) {\n if (!selected.includes(key)) {\n sourcesToUpdate.delete(key);\n }\n }\n\n return sourcesToUpdate;\n },\n catch: () => new UserCancelledError({ message: \"Update cancelled.\" }),\n });\n};\n\nconst getSourceDesc = (source: SourceToUpdate): string => source.name;\n\nconst buildFetchOptionsForSource = (\n source: SourceToUpdate,\n options: UpdateOptions\n): FetchSkillsOptions | null => {\n const serverUrl = options.server ?? source.serverUrl;\n const fetchOptions: FetchSkillsOptions = { serverUrl };\n\n if (source.type === \"profile\") {\n fetchOptions.profile = source.name;\n } else {\n const orgProjects = source.orgProjects;\n const personalProjects = source.personalProjects;\n const hasOrgProjects = orgProjects !== undefined && orgProjects.length > 0;\n const hasPersonalProjects =\n personalProjects !== undefined && personalProjects.length > 0;\n\n if (!(hasOrgProjects || hasPersonalProjects)) {\n return null;\n }\n\n if (hasOrgProjects) {\n fetchOptions.orgProjects = orgProjects;\n }\n if (hasPersonalProjects) {\n fetchOptions.personalProjects = personalProjects;\n }\n }\n\n return fetchOptions;\n};\n\nconst updateAgentSkills = (\n agentId: AgentId,\n agentName: string,\n installPath: string,\n response: Awaited<ReturnType<typeof fetchSkillsAsync>>,\n serverUrl: string,\n updateSpinner: ReturnType<typeof spinner>\n): Effect.Effect<{ updated: number; errors: number }, UpdateError> =>\n Effect.tryPromise({\n try: async () => {\n updateSpinner.start(`Updating ${agentName}...`);\n\n const result = await writeSkillsAsync(\n installPath,\n response.skills,\n agentId\n );\n\n if (result.errors.length > 0) {\n updateSpinner.stop(\n `${agentName}: ${result.written.length} updated, ${result.errors.length} failed`\n );\n } else {\n updateSpinner.stop(\n `${agentName}: ${result.written.length} skills updated`\n );\n }\n\n await updateMetadataAsync(\n installPath,\n response.skills.map((s) => ({\n name: s.name,\n source: response.source,\n version: response.version,\n serverUrl,\n }))\n );\n\n return { updated: result.written.length, errors: result.errors.length };\n },\n catch: (e) =>\n new UpdateError({\n message: e instanceof Error ? e.message : String(e),\n source: agentName,\n }),\n });\n\nconst updateSource = (\n source: SourceToUpdate,\n options: UpdateOptions,\n updateSpinner: ReturnType<typeof spinner>\n): Effect.Effect<{ updated: number; errors: number }, UpdateError> => {\n const sourceDesc = getSourceDesc(source);\n const serverUrl = options.server ?? source.serverUrl;\n\n const fetchOptions = buildFetchOptionsForSource(source, options);\n if (fetchOptions === null) {\n return Effect.fail(\n new UpdateError({\n message:\n \"Skills installed with legacy metadata format. Please reinstall using 'braid install --profile <name>' or 'braid install --projects <names>'.\",\n source: sourceDesc,\n })\n );\n }\n\n return pipe(\n Effect.tryPromise({\n try: async () => {\n updateSpinner.start(`Fetching latest skills from ${sourceDesc}...`);\n const response = await fetchSkillsAsync(fetchOptions);\n updateSpinner.stop(\n `Fetched ${response.skills.length} skills from ${sourceDesc}`\n );\n return response;\n },\n catch: (e) =>\n new UpdateError({\n message: e instanceof Error ? e.message : String(e),\n source: sourceDesc,\n }),\n }),\n Effect.flatMap((response) =>\n pipe(\n Effect.forEach(\n source.agents,\n ({ agentId, agentName, installPath }) =>\n updateAgentSkills(\n agentId,\n agentName,\n installPath,\n response,\n serverUrl,\n updateSpinner\n ),\n { concurrency: 1 }\n ),\n Effect.map((results) => ({\n updated: results.reduce((sum, r) => sum + r.updated, 0),\n errors: results.reduce((sum, r) => sum + r.errors, 0),\n }))\n )\n )\n );\n};\n\nconst updateAllSources = (\n sources: Map<string, SourceToUpdate>,\n options: UpdateOptions,\n updateSpinner: ReturnType<typeof spinner>\n): Effect.Effect<{ totalUpdated: number; totalErrors: number }> =>\n pipe(\n Effect.forEach(\n Array.from(sources.values()),\n (source) =>\n pipe(\n updateSource(source, options, updateSpinner),\n Effect.catchAll((error) => {\n updateSpinner.stop(\n `Failed to update from ${getSourceDesc(source)}`\n );\n log.error(` ${error.message}`);\n return Effect.succeed({ updated: 0, errors: 1 });\n })\n ),\n { concurrency: 1 }\n ),\n Effect.map((results) => ({\n totalUpdated: results.reduce((sum, r) => sum + r.updated, 0),\n totalErrors: results.reduce((sum, r) => sum + r.errors, 0),\n }))\n );\n\nconst handleUpdateError = (\n error: UpdateError,\n updateSpinner: ReturnType<typeof spinner>\n): void => {\n updateSpinner.stop(\"Update failed\");\n if (error.message === \"No AI coding agents detected.\") {\n log.warn(error.message);\n return;\n }\n if (error.message === \"No skills installed via braid.\") {\n log.warn(error.message);\n log.info(\"Run 'braid install --profile <name>' to install skills first.\");\n return;\n }\n log.error(error.message);\n process.exit(1);\n};\n\nconst handleProgramExit = (\n result: Awaited<\n ReturnType<\n typeof Effect.runPromiseExit<\n { totalUpdated: number; totalErrors: number },\n UpdateError | UserCancelledError\n >\n >\n >,\n updateSpinner: ReturnType<typeof spinner>\n): void => {\n if (result._tag !== \"Failure\") {\n return;\n }\n\n const cause = result.cause;\n if (cause._tag !== \"Fail\") {\n return;\n }\n\n const error = cause.error;\n if (error._tag === \"UserCancelledError\") {\n cancel(error.message);\n process.exit(0);\n }\n if (error._tag === \"UpdateError\") {\n handleUpdateError(error, updateSpinner);\n }\n};\n\nexport async function updateCommand(options: UpdateOptions): Promise<void> {\n const updateSpinner = spinner();\n updateSpinner.start(\"Scanning for installed skills...\");\n\n const program = pipe(\n Effect.tryPromise({\n try: () => detectAgentsAsync(),\n catch: () => new UpdateError({ message: \"Failed to detect agents\" }),\n }),\n Effect.filterOrFail(\n (agents) => agents.length > 0,\n () => new UpdateError({ message: \"No AI coding agents detected.\" })\n ),\n Effect.flatMap((detectedAgents) => collectSources(detectedAgents, options)),\n Effect.tap((sources) => {\n updateSpinner.stop(`Found ${sources.size} source(s) to update`);\n }),\n Effect.filterOrFail(\n (sources) => sources.size > 0,\n () => new UpdateError({ message: \"No skills installed via braid.\" })\n ),\n Effect.flatMap((sources) => selectSources(sources, options)),\n Effect.flatMap((selectedSources) =>\n updateAllSources(selectedSources, options, updateSpinner)\n ),\n Effect.tap(({ totalUpdated, totalErrors }) => {\n if (totalErrors > 0) {\n outro(`Updated ${totalUpdated} skills with ${totalErrors} errors.`);\n } else {\n outro(`Successfully updated ${totalUpdated} skills.`);\n }\n })\n );\n\n const result = await Effect.runPromiseExit(program);\n handleProgramExit(result, updateSpinner);\n}\n"],"mappings":"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","names":["process","process","Data","Effect","pipe","path","process","clearApiKeyAsync","homedir","join","process","Effect","pipe","path","process","pipe","Effect","join","Effect","path","process","join","readFile","writeFile","join","Data","Effect","pipe","pipe","Effect","Effect","Effect","mkdir","readFile","writeFile","dirname","Data","Effect","pipe","mkdir","writeFile","dirname","resolve","sep","Data","Effect","pipe","createDirectory","writeTextFile","path","Effect","process","spinner","intro","outro","cancel","confirm","isCancel","log","log","isCancel","cancel","intro","spinner","outro","log","spinner","log","spinner","join","resolve","process","join","log","process","isCancel","cancel","confirm","resolve","spinner","outro","cancel","isCancel","log","multiselect","outro","spinner","Data","Effect","pipe","Data","Effect","pipe","multiselect","isCancel","log","cancel","spinner","program","outro","require"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@braid-cloud/cli",
3
- "version": "0.1.1",
4
- "description": "Install braid rules as agent skills to your local development environment",
3
+ "version": "0.1.3",
4
+ "description": "Install braid prompts as agent skills to your local development environment",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "braid": "./dist/index.js"