droid-patch 0.13.0 → 0.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -62,12 +62,11 @@ npx droid-patch --skip-login -o /path/to/dir my-droid
62
62
  | `--is-custom` | Patch `isCustom:!0` to `isCustom:!1` (enables context compression for custom models) |
63
63
  | `--skip-login` | Bypass login by injecting a fake `FACTORY_API_KEY` into the binary |
64
64
  | `--api-base <url>` | Replace API URL (standalone: binary patch, max 22 chars; with `--websearch`: proxy forward target, no limit) |
65
- | `--websearch` | External providers mode: Smithery, Google PSE, Serper, Brave, SearXNG, DuckDuckGo |
65
+ | `--websearch` | External providers mode: Smithery, Google PSE, Tavily, Serper, Brave, SearXNG, DuckDuckGo |
66
66
  | `--websearch-proxy` | Native provider mode: use model's built-in web_search (requires proxy plugin) |
67
67
  | `--standalone` | Standalone mode: mock non-LLM Factory APIs (use with `--websearch` or `--websearch-proxy`) |
68
68
  | `--reasoning-effort` | Enable reasoning effort UI selector for custom models (set to high) |
69
69
  | `--disable-telemetry` | Disable telemetry and Sentry error reporting |
70
- | `--spec-model-custom` | Enable custom models as spec model (show in UI selector + bypass validation) |
71
70
  | `--dry-run` | Verify patches without actually modifying the binary |
72
71
  | `-p, --path <path>` | Path to the droid binary (default: `~/.droid/bin/droid`) |
73
72
  | `-o, --output <dir>` | Output directory for patched binary (creates file without alias) |
@@ -248,7 +247,7 @@ Enables WebSearch via **external search providers** through a local proxy server
248
247
 
249
248
  **Features**:
250
249
 
251
- - **Multiple search providers** with automatic fallback (Smithery > Google PSE > Serper > Brave > SearXNG > DuckDuckGo)
250
+ - **Multiple search providers** with automatic fallback (Smithery > Google PSE > Tavily > Serper > Brave > SearXNG > DuckDuckGo)
252
251
  - **Per-instance proxy**: Each droid instance runs its own proxy on an auto-assigned port
253
252
  - **Auto-cleanup**: Proxy automatically stops when droid exits
254
253
  - **Forward target**: Use `--api-base` with `--websearch` to forward non-search requests to a custom backend
@@ -435,29 +434,6 @@ npx droid-patch --disable-telemetry droid-private
435
434
  npx droid-patch --is-custom --skip-login --disable-telemetry droid-private
436
435
  ```
437
436
 
438
- ### `--spec-model-custom`
439
-
440
- Enables custom models to be used as the spec model in spec mode.
441
-
442
- **Purpose**: By default, droid only allows official models (like Claude, GPT) as spec models. This patch allows custom models to appear in the spec model selector and bypasses the compatibility validation.
443
-
444
- **How it works**:
445
-
446
- - Shows all custom models in the spec model selector UI (bypasses the filter that hides them)
447
- - Bypasses the `compatibilityGroup` validation check (uses regex matching to handle minified function name changes across versions)
448
-
449
- **Compatibility**: Requires droid 0.45.0 or later (the compatibilityGroup feature was added in this version).
450
-
451
- **Usage**:
452
-
453
- ```bash
454
- # Enable custom models as spec model
455
- npx droid-patch --spec-model-custom droid-spec
456
-
457
- # Combine with other patches for full custom model support
458
- npx droid-patch --is-custom --reasoning-effort --spec-model-custom droid-custom-full
459
- ```
460
-
461
437
  ---
462
438
 
463
439
  ## WebSearch Configuration Guide
@@ -472,10 +448,11 @@ The proxy tries providers in this order and uses the first one that succeeds:
472
448
  | -------- | ------------ | --------- | --------------------- | ---------------- |
473
449
  | 1 | Smithery Exa | Excellent | Free (via Smithery) | Easy |
474
450
  | 2 | Google PSE | Very Good | 10,000/day | Medium |
475
- | 3 | Serper | Very Good | 2,500 free credits | Easy |
476
- | 4 | Brave Search | Good | 2,000/month | Easy |
477
- | 5 | SearXNG | Good | Unlimited (self-host) | Hard |
478
- | 6 | DuckDuckGo | Basic | Unlimited | None |
451
+ | 3 | Tavily | Very Good | Free credits (varies) | Easy |
452
+ | 4 | Serper | Very Good | 2,500 free credits | Easy |
453
+ | 5 | Brave Search | Good | 2,000/month | Easy |
454
+ | 6 | SearXNG | Good | Unlimited (self-host) | Hard |
455
+ | 7 | DuckDuckGo | Basic | Unlimited | None |
479
456
 
480
457
  ---
481
458
 
@@ -557,7 +534,29 @@ export GOOGLE_PSE_CX="017576662512468239146:omuauf_lfve" # Your Search engine I
557
534
 
558
535
  ---
559
536
 
560
- ## 3. Serper
537
+ ## 3. Tavily
538
+
539
+ [Tavily](https://tavily.com/) provides an easy-to-use web search API.
540
+
541
+ ### Setup Steps
542
+
543
+ 1. **Create an Account**
544
+ - Go to [tavily.com](https://tavily.com/)
545
+ - Sign up for an account
546
+
547
+ 2. **Get Your API Key**
548
+ - Navigate to your dashboard / API settings
549
+ - Copy your API key
550
+
551
+ 3. **Configure Environment Variable**
552
+ ```bash
553
+ # Add to ~/.zshrc or ~/.bashrc
554
+ export TAVILY_API_KEY="your_api_key_here"
555
+ ```
556
+
557
+ ---
558
+
559
+ ## 4. Serper
561
560
 
562
561
  [Serper](https://serper.dev) provides Google search results through an easy-to-use API.
563
562
 
@@ -585,7 +584,7 @@ export GOOGLE_PSE_CX="017576662512468239146:omuauf_lfve" # Your Search engine I
585
584
 
586
585
  ---
587
586
 
588
- ## 4. Brave Search
587
+ ## 5. Brave Search
589
588
 
590
589
  [Brave Search API](https://brave.com/search/api/) provides privacy-focused search results.
591
590
 
@@ -617,7 +616,7 @@ export GOOGLE_PSE_CX="017576662512468239146:omuauf_lfve" # Your Search engine I
617
616
 
618
617
  ---
619
618
 
620
- ## 5. SearXNG (Self-Hosted)
619
+ ## 6. SearXNG (Self-Hosted)
621
620
 
622
621
  [SearXNG](https://github.com/searxng/searxng) is a free, privacy-respecting metasearch engine you can self-host.
623
622
 
@@ -666,7 +665,7 @@ Find public instances at [searx.space](https://searx.space/)
666
665
 
667
666
  ---
668
667
 
669
- ## 6. DuckDuckGo (Default Fallback)
668
+ ## 7. DuckDuckGo (Default Fallback)
670
669
 
671
670
  DuckDuckGo is used automatically as the final fallback when no other providers are configured or available.
672
671
 
@@ -714,10 +713,13 @@ export GOOGLE_PSE_CX="your_search_engine_id"
714
713
  export GOOGLE_PSE_API_KEY="your_google_key"
715
714
  export GOOGLE_PSE_CX="your_search_engine_id"
716
715
 
717
- # Option 2: Serper (2,500 free credits)
716
+ # Option 2: Tavily (free credits vary)
717
+ export TAVILY_API_KEY="your_tavily_key"
718
+
719
+ # Option 3: Serper (2,500 free credits)
718
720
  export SERPER_API_KEY="your_serper_key"
719
721
 
720
- # Option 3: Brave (2,000/month free)
722
+ # Option 4: Brave (2,000/month free)
721
723
  export BRAVE_API_KEY="your_brave_key"
722
724
 
723
725
  # DuckDuckGo is always available as final fallback
package/README.zh-CN.md CHANGED
@@ -62,12 +62,11 @@ npx droid-patch --skip-login -o /path/to/dir my-droid
62
62
  | `--is-custom` | 将 `isCustom:!0` 修改为 `isCustom:!1`(为自定义模型启用上下文压缩) |
63
63
  | `--skip-login` | 通过注入假的 `FACTORY_API_KEY` 跳过登录验证 |
64
64
  | `--api-base <url>` | 替换 API URL(单独使用:二进制补丁,最多 22 字符;与 `--websearch` 配合:代理转发目标,无限制) |
65
- | `--websearch` | 外部搜索模式:使用 Smithery、Google PSE、Serper、Brave、SearXNG、DuckDuckGo |
65
+ | `--websearch` | 外部搜索模式:使用 Smithery、Google PSE、Tavily、Serper、Brave、SearXNG、DuckDuckGo |
66
66
  | `--websearch-proxy` | 原生搜索模式:使用模型内置的 web_search 能力(需要 proxy 插件) |
67
67
  | `--standalone` | 独立模式:mock 非 LLM 的 Factory API(与 `--websearch` 或 `--websearch-proxy` 配合使用) |
68
68
  | `--reasoning-effort` | 为自定义模型启用推理强度 UI 选择器(设置为 high) |
69
69
  | `--disable-telemetry` | 禁用遥测数据上传和 Sentry 错误报告 |
70
- | `--spec-model-custom` | 允许自定义模型作为 spec 模型(在 UI 选择器中显示 + 绕过验证) |
71
70
  | `--dry-run` | 验证修补但不实际修改二进制文件 |
72
71
  | `-p, --path <path>` | droid 二进制文件路径(默认:`~/.droid/bin/droid`) |
73
72
  | `-o, --output <dir>` | 修补后二进制文件的输出目录(直接创建文件,不创建别名) |
@@ -248,7 +247,7 @@ npx droid-patch --websearch --api-base "http://my-proxy.example.com:3000" droid-
248
247
 
249
248
  **特性**:
250
249
 
251
- - **多搜索提供商**:自动降级(Smithery > Google PSE > Serper > Brave > SearXNG > DuckDuckGo)
250
+ - **多搜索提供商**:自动降级(Smithery > Google PSE > Tavily > Serper > Brave > SearXNG > DuckDuckGo)
252
251
  - **每实例独立代理**:每个 droid 实例运行自己的代理,自动分配端口
253
252
  - **自动清理**:droid 退出时代理自动停止
254
253
  - **转发目标**:使用 `--api-base` 配合 `--websearch` 可将非搜索请求转发到自定义后端
@@ -429,29 +428,6 @@ npx droid-patch --disable-telemetry droid-private
429
428
  npx droid-patch --is-custom --skip-login --disable-telemetry droid-private
430
429
  ```
431
430
 
432
- ### `--spec-model-custom`
433
-
434
- 允许自定义模型作为 spec 模式中的 spec 模型使用。
435
-
436
- **用途**:默认情况下,droid 只允许官方模型(如 Claude、GPT)作为 spec 模型。此补丁使自定义模型出现在 spec 模型选择器中,并绕过兼容性验证。
437
-
438
- **工作原理**:
439
-
440
- - 在 spec 模型选择器 UI 中显示所有自定义模型(绕过隐藏它们的过滤器)
441
- - 绕过 `compatibilityGroup` 验证检查(使用正则表达式匹配以处理不同版本间混淆后的函数名变化)
442
-
443
- **兼容性**:需要 droid 0.45.0 或更高版本(compatibilityGroup 功能在此版本中添加)。
444
-
445
- **使用方法**:
446
-
447
- ```bash
448
- # 允许自定义模型作为 spec 模型
449
- npx droid-patch --spec-model-custom droid-spec
450
-
451
- # 与其他补丁组合以获得完整的自定义模型支持
452
- npx droid-patch --is-custom --reasoning-effort --spec-model-custom droid-custom-full
453
- ```
454
-
455
431
  ---
456
432
 
457
433
  ## WebSearch 配置指南
@@ -466,10 +442,11 @@ npx droid-patch --is-custom --reasoning-effort --spec-model-custom droid-custom-
466
442
  | ------ | ------------ | ---- | --------------------- | -------- |
467
443
  | 1 | Smithery Exa | 优秀 | 免费(通过 Smithery) | 简单 |
468
444
  | 2 | Google PSE | 很好 | 10,000 次/天 | 中等 |
469
- | 3 | Serper | 很好 | 2,500 免费额度 | 简单 |
470
- | 4 | Brave Search | 好 | 2,000 次/月 | 简单 |
471
- | 5 | SearXNG | 好 | 无限(自托管) | 较难 |
472
- | 6 | DuckDuckGo | 基本 | 无限 | 无需配置 |
445
+ | 3 | Tavily | 很好 | 免费额度(不固定) | 简单 |
446
+ | 4 | Serper | 很好 | 2,500 免费额度 | 简单 |
447
+ | 5 | Brave Search | 好 | 2,000 次/月 | 简单 |
448
+ | 6 | SearXNG | | 无限(自托管) | 较难 |
449
+ | 7 | DuckDuckGo | 基本 | 无限 | 无需配置 |
473
450
 
474
451
  ---
475
452
 
@@ -551,7 +528,28 @@ export GOOGLE_PSE_CX="017576662512468239146:omuauf_lfve" # 你的搜索引擎 I
551
528
 
552
529
  ---
553
530
 
554
- ## 3. Serper
531
+ ## 3. Tavily
532
+
533
+ [Tavily](https://tavily.com/) 提供简单易用的 Web 搜索 API。
534
+
535
+ ### 设置步骤
536
+
537
+ 1. **创建账号**
538
+ - 访问 [tavily.com](https://tavily.com/)
539
+ - 注册账号
540
+
541
+ 2. **获取 API Key**
542
+ - 在控制台/API 设置中找到并复制 API key
543
+
544
+ 3. **配置环境变量**
545
+ ```bash
546
+ # 添加到 ~/.zshrc 或 ~/.bashrc
547
+ export TAVILY_API_KEY="your_api_key_here"
548
+ ```
549
+
550
+ ---
551
+
552
+ ## 4. Serper
555
553
 
556
554
  [Serper](https://serper.dev) 通过易用的 API 提供 Google 搜索结果。
557
555
 
@@ -579,7 +577,7 @@ export GOOGLE_PSE_CX="017576662512468239146:omuauf_lfve" # 你的搜索引擎 I
579
577
 
580
578
  ---
581
579
 
582
- ## 4. Brave Search
580
+ ## 5. Brave Search
583
581
 
584
582
  [Brave Search API](https://brave.com/search/api/) 提供注重隐私的搜索结果。
585
583
 
@@ -611,7 +609,7 @@ export GOOGLE_PSE_CX="017576662512468239146:omuauf_lfve" # 你的搜索引擎 I
611
609
 
612
610
  ---
613
611
 
614
- ## 5. SearXNG(自托管)
612
+ ## 6. SearXNG(自托管)
615
613
 
616
614
  [SearXNG](https://github.com/searxng/searxng) 是一个免费、注重隐私的元搜索引擎,可以自托管。
617
615
 
@@ -660,7 +658,7 @@ export SEARXNG_URL="https://searx.be"
660
658
 
661
659
  ---
662
660
 
663
- ## 6. DuckDuckGo(默认备用)
661
+ ## 7. DuckDuckGo(默认备用)
664
662
 
665
663
  当没有配置其他提供商或其他提供商不可用时,自动使用 DuckDuckGo 作为最终备用。
666
664
 
@@ -708,10 +706,13 @@ export GOOGLE_PSE_CX="your_search_engine_id"
708
706
  export GOOGLE_PSE_API_KEY="your_google_key"
709
707
  export GOOGLE_PSE_CX="your_search_engine_id"
710
708
 
711
- # 选项 2:Serper(2,500 免费额度)
709
+ # 选项 2:Tavily(免费额度不固定)
710
+ export TAVILY_API_KEY="your_tavily_key"
711
+
712
+ # 选项 3:Serper(2,500 免费额度)
712
713
  export SERPER_API_KEY="your_serper_key"
713
714
 
714
- # 选项 3:Brave(每月 2,000 次免费)
715
+ # 选项 4:Brave(每月 2,000 次免费)
715
716
  export BRAVE_API_KEY="your_brave_key"
716
717
 
717
718
  # DuckDuckGo 始终作为最终备用可用
@@ -350,7 +350,6 @@ function formatPatches(patches) {
350
350
  if (patches.reasoningEffort) applied.push("reasoningEffort");
351
351
  if (patches.noTelemetry) applied.push("noTelemetry");
352
352
  if (patches.standalone) applied.push("standalone");
353
- if (patches.specModelCustom) applied.push("specModelCustom");
354
353
  return applied.length > 0 ? applied.join(", ") : "(none)";
355
354
  }
356
355
 
@@ -1182,9 +1181,6 @@ async function removeAliasesByFilter(filter) {
1182
1181
  case "standalone":
1183
1182
  if (!patches.standalone) matches = false;
1184
1183
  break;
1185
- case "spec-model-custom":
1186
- if (!patches.specModelCustom) matches = false;
1187
- break;
1188
1184
  }
1189
1185
  if (!matches) break;
1190
1186
  }
@@ -1300,4 +1296,4 @@ async function clearAllAliases() {
1300
1296
 
1301
1297
  //#endregion
1302
1298
  export { removeAlias as a, restoreOriginal as c, listAllMetadata as d, loadAliasMetadata as f, listAliases as i, createMetadata as l, patchDroid as m, createAlias as n, removeAliasesByFilter as o, saveAliasMetadata as p, createAliasForWrapper as r, replaceOriginal as s, clearAllAliases as t, formatPatches as u };
1303
- //# sourceMappingURL=alias-hvk8y5gC.mjs.map
1299
+ //# sourceMappingURL=alias-12JqnRQZ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alias-12JqnRQZ.mjs","names":["IS_WINDOWS","results: PatchResult[]","matches: Array<{ charIndex: number; match: string; replacement: string }>","match","positions: number[]","matchedVariant: (typeof variants)[number] | undefined","metaList: AliasMetadata[]","applied: string[]","exportLine: string","binaryDest","aliases: AliasInfo[]","matchingAliases: string[]"],"sources":["../src/patcher.ts","../src/metadata.ts","../src/alias.ts"],"sourcesContent":["import { readFile, writeFile, copyFile, chmod, stat } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { execSync } from \"node:child_process\";\nimport { styleText } from \"node:util\";\nimport { platform } from \"node:os\";\n\nconst IS_WINDOWS = platform() === \"win32\";\n\nexport interface Patch {\n name: string;\n description: string;\n pattern: Buffer;\n replacement: Buffer;\n variants?: Array<{\n pattern: Buffer;\n replacement: Buffer;\n }>;\n // Regex-based matching: use $1, $2, etc. in regexReplacement for capture groups\n regexPattern?: RegExp;\n regexReplacement?: string;\n}\n\nexport interface PatchOptions {\n inputPath: string;\n outputPath?: string;\n patches: Patch[];\n dryRun?: boolean;\n backup?: boolean;\n verbose?: boolean;\n}\n\ninterface PatchResult {\n name: string;\n found: number;\n positions?: number[];\n success: boolean;\n alreadyPatched?: boolean;\n}\n\nexport interface PatchDroidResult {\n success: boolean;\n dryRun?: boolean;\n results: PatchResult[];\n outputPath?: string;\n noPatchNeeded?: boolean;\n patchedCount?: number;\n}\n\nexport async function patchDroid(options: PatchOptions): Promise<PatchDroidResult> {\n const {\n inputPath,\n outputPath,\n patches,\n dryRun = false,\n backup = true,\n verbose = false,\n } = options;\n\n const finalOutputPath = outputPath || `${inputPath}.patched`;\n\n if (!existsSync(inputPath)) {\n throw new Error(`Binary not found: ${inputPath}`);\n }\n\n const stats = await stat(inputPath);\n const fileSizeMB = (stats.size / (1024 * 1024)).toFixed(2);\n\n console.log(styleText(\"white\", `[*] Reading binary: ${styleText(\"cyan\", inputPath)}`));\n console.log(styleText(\"white\", `[*] File size: ${styleText(\"cyan\", fileSizeMB)} MB`));\n console.log();\n\n const data = await readFile(inputPath);\n const buffer = Buffer.from(data);\n\n // Use a working buffer that gets updated after each patch application\n // This ensures later patches search against the already-patched content\n const workingBuffer = Buffer.from(buffer);\n\n const results: PatchResult[] = [];\n\n for (const patch of patches) {\n console.log(styleText(\"white\", `[*] Checking patch: ${styleText(\"yellow\", patch.name)}`));\n console.log(styleText(\"gray\", ` ${patch.description}`));\n\n // Handle regex-based matching\n // For binary files, convert pattern/replacement to Buffer and use findAllPositions\n if (patch.regexPattern && patch.regexReplacement) {\n const content = workingBuffer.toString(\"utf-8\");\n const regex = new RegExp(patch.regexPattern.source, \"g\");\n const matches: Array<{ charIndex: number; match: string; replacement: string }> = [];\n\n let match;\n while ((match = regex.exec(content)) !== null) {\n const replacement = match[0].replace(\n new RegExp(patch.regexPattern.source),\n patch.regexReplacement,\n );\n matches.push({\n charIndex: match.index,\n match: match[0],\n replacement,\n });\n }\n\n if (matches.length === 0) {\n console.log(styleText(\"yellow\", ` ! Pattern not found - may already be patched`));\n // Check if already patched by looking for a sample replacement pattern\n const sampleReplacement = patch.regexReplacement.replace(/\\$\\d+/g, \"X\");\n const alreadyPatched = content.includes(sampleReplacement.slice(0, 20));\n results.push({\n name: patch.name,\n found: 0,\n success: alreadyPatched,\n alreadyPatched,\n });\n if (alreadyPatched) {\n console.log(styleText(\"blue\", ` ✓ Binary appears to be already patched`));\n }\n continue;\n }\n\n console.log(styleText(\"green\", ` ✓ Found ${matches.length} occurrences (regex)`));\n\n if (!dryRun) {\n // Apply regex replacement using Buffer.indexOf for accurate byte positions\n for (const { match, replacement } of matches) {\n const matchBuffer = Buffer.from(match, \"utf-8\");\n const replacementBuffer = Buffer.from(replacement, \"utf-8\");\n\n if (matchBuffer.length !== replacementBuffer.length) {\n console.log(\n styleText(\n \"yellow\",\n ` ! Warning: Length mismatch: ${matchBuffer.length} vs ${replacementBuffer.length}`,\n ),\n );\n }\n\n // Find the actual byte position in the buffer\n const bytePos = workingBuffer.indexOf(matchBuffer);\n if (bytePos !== -1) {\n replacementBuffer.copy(workingBuffer, bytePos, 0, replacementBuffer.length);\n }\n }\n }\n\n results.push({\n name: patch.name,\n found: matches.length,\n positions: matches.map((m) => m.charIndex),\n success: true,\n });\n continue;\n }\n\n const variants = [\n { pattern: patch.pattern, replacement: patch.replacement },\n ...(patch.variants || []),\n ];\n\n // Search in the working buffer (which may have earlier patches applied)\n let positions: number[] = [];\n let matchedVariant: (typeof variants)[number] | undefined;\n for (const variant of variants) {\n positions = findAllPositions(workingBuffer, variant.pattern);\n if (positions.length > 0) {\n matchedVariant = variant;\n break;\n }\n }\n\n if (positions.length === 0) {\n console.log(styleText(\"yellow\", ` ! Pattern not found - may already be patched`));\n results.push({\n name: patch.name,\n found: 0,\n success: false,\n alreadyPatched: variants.some((v) => workingBuffer.includes(v.replacement)),\n });\n\n let totalReplacementPositions = 0;\n for (const variant of variants) {\n totalReplacementPositions += findAllPositions(workingBuffer, variant.replacement).length;\n }\n if (totalReplacementPositions > 0) {\n console.log(\n styleText(\n \"blue\",\n ` ✓ Found ${totalReplacementPositions} occurrences of patched pattern`,\n ),\n );\n console.log(styleText(\"blue\", ` ✓ Binary appears to be already patched`));\n results[results.length - 1].alreadyPatched = true;\n results[results.length - 1].success = true;\n }\n continue;\n }\n\n if (!matchedVariant) {\n throw new Error(`Internal error: matchedVariant not set for patch ${patch.name}`);\n }\n\n console.log(styleText(\"green\", ` ✓ Found ${positions.length} occurrences`));\n\n if (verbose) {\n for (const pos of positions.slice(0, 5)) {\n const context = getContext(workingBuffer, pos, matchedVariant.pattern.length, 25);\n console.log(\n styleText(\"gray\", ` @ 0x${pos.toString(16).padStart(8, \"0\")}: ...${context}...`),\n );\n }\n if (positions.length > 5) {\n console.log(styleText(\"gray\", ` ... and ${positions.length - 5} more`));\n }\n }\n\n // Apply patch immediately to working buffer so later patches see updated content\n if (!dryRun) {\n for (const pos of positions) {\n matchedVariant.replacement.copy(workingBuffer, pos);\n }\n }\n\n results.push({\n name: patch.name,\n found: positions.length,\n positions,\n success: true,\n });\n }\n\n console.log();\n\n if (dryRun) {\n console.log(styleText(\"blue\", \"─\".repeat(60)));\n console.log(styleText([\"blue\", \"bold\"], \" DRY RUN RESULTS\"));\n console.log(styleText(\"blue\", \"─\".repeat(60)));\n console.log();\n\n for (const result of results) {\n if (result.alreadyPatched) {\n console.log(styleText(\"blue\", ` [✓] ${result.name}: Already patched`));\n } else if (result.found > 0) {\n console.log(\n styleText(\"green\", ` [✓] ${result.name}: ${result.found} occurrences will be patched`),\n );\n } else {\n console.log(styleText(\"yellow\", ` [!] ${result.name}: Pattern not found`));\n }\n }\n\n return {\n success: results.every((r) => r.success || r.alreadyPatched),\n dryRun: true,\n results,\n };\n }\n\n const patchesNeeded = results.filter((r) => r.found > 0 && !r.alreadyPatched);\n\n if (patchesNeeded.length === 0) {\n const allPatched = results.every((r) => r.alreadyPatched);\n if (allPatched) {\n console.log(styleText(\"blue\", \"[*] All patches already applied. Binary is up to date.\"));\n return {\n success: true,\n outputPath: inputPath,\n results,\n noPatchNeeded: true,\n };\n }\n console.log(styleText(\"yellow\", \"[!] No patches could be applied.\"));\n return { success: false, results };\n }\n\n if (backup) {\n const backupPath = `${inputPath}.backup`;\n if (!existsSync(backupPath)) {\n await copyFile(inputPath, backupPath);\n console.log(styleText(\"white\", `[*] Created backup: ${styleText(\"cyan\", backupPath)}`));\n } else {\n console.log(styleText(\"gray\", `[*] Backup already exists: ${backupPath}`));\n }\n }\n\n console.log(styleText(\"white\", \"[*] Applying patches...\"));\n // Patches have already been applied to workingBuffer during the check phase\n // Count total patches applied\n const totalPatched = results.reduce((sum, r) => sum + (r.positions?.length || 0), 0);\n\n console.log(styleText(\"green\", `[*] Applied ${totalPatched} patches`));\n\n // Handle Windows file locking - if file is locked, use a new filename\n let actualOutputPath = finalOutputPath;\n try {\n await writeFile(finalOutputPath, workingBuffer);\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err.code === \"EBUSY\" && IS_WINDOWS) {\n // File is locked, generate new filename with timestamp\n const timestamp = Date.now();\n const ext = finalOutputPath.endsWith(\".exe\") ? \".exe\" : \"\";\n const basePath = finalOutputPath\n .replace(/\\.exe$/, \"\")\n .replace(/\\.patched$/, \"\")\n .replace(/-\\d+$/, \"\");\n actualOutputPath = `${basePath}-${timestamp}${ext ? ext : \".patched\"}`;\n console.log(styleText(\"yellow\", `[!] Original file locked, saving to: ${actualOutputPath}`));\n await writeFile(actualOutputPath, workingBuffer);\n } else {\n throw error;\n }\n }\n console.log(\n styleText(\"white\", `[*] Patched binary saved: ${styleText(\"cyan\", actualOutputPath)}`),\n );\n\n await chmod(actualOutputPath, 0o755);\n console.log(styleText(\"gray\", \"[*] Set executable permission\"));\n\n console.log();\n console.log(styleText(\"white\", \"[*] Verifying patches...\"));\n const verifyBuffer = await readFile(actualOutputPath);\n\n let allVerified = true;\n for (const patch of patches) {\n // Handle regex-based patches\n if (patch.regexPattern && patch.regexReplacement) {\n const content = verifyBuffer.toString(\"utf-8\");\n const oldMatches = [...content.matchAll(new RegExp(patch.regexPattern.source, \"g\"))];\n // For verification, just check that the original pattern is no longer present\n if (oldMatches.length === 0) {\n console.log(styleText(\"green\", ` ✓ ${patch.name}: Verified (regex)`));\n } else {\n console.log(\n styleText(\"red\", ` ✗ ${patch.name}: ${oldMatches.length} occurrences not patched`),\n );\n allVerified = false;\n }\n continue;\n }\n\n const variants = [\n { pattern: patch.pattern, replacement: patch.replacement },\n ...(patch.variants || []),\n ];\n\n let oldCount = 0;\n let newCount = 0;\n for (const variant of variants) {\n if (variant.pattern.length > 0) {\n oldCount += findAllPositions(verifyBuffer, variant.pattern).length;\n }\n if (variant.replacement.length > 0) {\n newCount += findAllPositions(verifyBuffer, variant.replacement).length;\n }\n }\n\n if (oldCount === 0) {\n console.log(styleText(\"green\", ` ✓ ${patch.name}: Verified (${newCount} patched)`));\n } else {\n console.log(styleText(\"red\", ` ✗ ${patch.name}: ${oldCount} occurrences not patched`));\n allVerified = false;\n }\n }\n\n if (allVerified) {\n console.log();\n console.log(styleText(\"green\", \"[+] All patches verified successfully!\"));\n }\n\n if (process.platform === \"darwin\") {\n console.log();\n try {\n console.log(styleText(\"gray\", \"[*] Re-signing binary for macOS...\"));\n execSync(`codesign --force --deep --sign - \"${finalOutputPath}\"`, {\n stdio: \"pipe\",\n });\n console.log(styleText(\"green\", \"[*] Binary re-signed successfully\"));\n } catch {\n console.log(styleText(\"yellow\", \"[!] Could not re-sign binary\"));\n console.log(\n styleText(\n \"gray\",\n ` You may need to run: codesign --force --deep --sign - ${finalOutputPath}`,\n ),\n );\n }\n\n try {\n execSync(`xattr -cr \"${finalOutputPath}\"`, { stdio: \"pipe\" });\n } catch {\n // Ignore\n }\n }\n\n return {\n success: allVerified,\n outputPath: actualOutputPath,\n results,\n patchedCount: totalPatched,\n };\n}\n\nfunction findAllPositions(buffer: Buffer, pattern: Buffer): number[] {\n const positions: number[] = [];\n let pos = 0;\n\n while (true) {\n pos = buffer.indexOf(pattern, pos);\n if (pos === -1) break;\n positions.push(pos);\n pos += pattern.length;\n }\n\n return positions;\n}\n\nfunction getContext(\n buffer: Buffer,\n position: number,\n patternLength: number,\n contextSize: number,\n): string {\n const start = Math.max(0, position - contextSize);\n const end = Math.min(buffer.length, position + patternLength + contextSize);\n const slice = buffer.slice(start, end);\n\n let str = \"\";\n for (let i = 0; i < slice.length; i++) {\n const c = slice[i];\n if (c >= 32 && c < 127) {\n str += String.fromCharCode(c);\n } else {\n str += \".\";\n }\n }\n return str;\n}\n","/**\n * Alias Metadata Management\n *\n * Stores and retrieves metadata about created aliases, including\n * which patches were applied. This enables the `update` command\n * to re-apply the same patches when the original droid binary is updated.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readdir, readFile, unlink, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\n/**\n * Metadata structure for an alias\n */\nexport interface AliasMetadata {\n /** Alias name */\n name: string;\n /** ISO timestamp when created */\n createdAt: string;\n /** ISO timestamp when last updated */\n updatedAt: string;\n /** Path to the original droid binary used for patching */\n originalBinaryPath: string;\n /** Path where the alias symlink was created */\n aliasPath?: string;\n /** droid-patch version used to create this alias */\n droidPatchVersion?: string;\n /** droid binary version */\n droidVersion?: string;\n /** Patches that were applied */\n patches: {\n isCustom: boolean;\n skipLogin: boolean;\n /** API base URL for binary patching or websearch forward target */\n apiBase: string | null;\n /** Whether websearch is enabled (external providers mode) */\n websearch: boolean;\n /** Whether websearch-proxy is enabled (native provider mode) */\n websearchProxy?: boolean;\n /** @deprecated Old proxy field, kept for backward compatibility */\n proxy?: string | null;\n reasoningEffort: boolean;\n /** Whether telemetry/Sentry is disabled */\n noTelemetry?: boolean;\n /** Standalone mode: mock non-LLM Factory APIs */\n standalone?: boolean;\n };\n}\n\n// Directory for storing metadata files\nconst META_DIR = join(homedir(), \".droid-patch\", \"meta\");\n\n/**\n * Ensure metadata directory exists\n */\nasync function ensureMetaDir(): Promise<void> {\n if (!existsSync(META_DIR)) {\n await mkdir(META_DIR, { recursive: true });\n }\n}\n\n/**\n * Get the path to a metadata file for an alias\n */\nfunction getMetaPath(aliasName: string): string {\n return join(META_DIR, `${aliasName}.json`);\n}\n\n/**\n * Save alias metadata to disk\n */\nexport async function saveAliasMetadata(meta: AliasMetadata): Promise<void> {\n await ensureMetaDir();\n const metaPath = getMetaPath(meta.name);\n await writeFile(metaPath, JSON.stringify(meta, null, 2));\n}\n\n/**\n * Load alias metadata from disk\n * Returns null if metadata doesn't exist\n */\nexport async function loadAliasMetadata(aliasName: string): Promise<AliasMetadata | null> {\n const metaPath = getMetaPath(aliasName);\n if (!existsSync(metaPath)) {\n return null;\n }\n try {\n const content = await readFile(metaPath, \"utf-8\");\n return JSON.parse(content) as AliasMetadata;\n } catch {\n return null;\n }\n}\n\n/**\n * List all alias metadata\n */\nexport async function listAllMetadata(): Promise<AliasMetadata[]> {\n await ensureMetaDir();\n\n const files = await readdir(META_DIR);\n const metaList: AliasMetadata[] = [];\n\n for (const file of files) {\n if (!file.endsWith(\".json\")) continue;\n\n const aliasName = file.replace(/\\.json$/, \"\");\n const meta = await loadAliasMetadata(aliasName);\n if (meta) {\n metaList.push(meta);\n }\n }\n\n return metaList;\n}\n\n/**\n * Remove alias metadata\n */\nexport async function removeAliasMetadata(aliasName: string): Promise<boolean> {\n const metaPath = getMetaPath(aliasName);\n if (!existsSync(metaPath)) {\n return false;\n }\n try {\n await unlink(metaPath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Create a new metadata object with current timestamp\n */\nexport function createMetadata(\n name: string,\n originalBinaryPath: string,\n patches: AliasMetadata[\"patches\"],\n options?: {\n droidPatchVersion?: string;\n droidVersion?: string;\n aliasPath?: string;\n },\n): AliasMetadata {\n const now = new Date().toISOString();\n return {\n name,\n createdAt: now,\n updatedAt: now,\n originalBinaryPath,\n aliasPath: options?.aliasPath,\n droidPatchVersion: options?.droidPatchVersion,\n droidVersion: options?.droidVersion,\n patches,\n };\n}\n\n/**\n * Format patches for display\n */\nexport function formatPatches(patches: AliasMetadata[\"patches\"]): string {\n const applied: string[] = [];\n if (patches.isCustom) applied.push(\"isCustom\");\n if (patches.skipLogin) applied.push(\"skipLogin\");\n // Show apiBase only when not using websearch (binary patch mode)\n if (patches.apiBase && !patches.websearch && !patches.websearchProxy)\n applied.push(`apiBase(${patches.apiBase})`);\n // Show websearch with optional custom target (external providers mode)\n if (patches.websearch) {\n const target = patches.apiBase || \"api.factory.ai\";\n applied.push(`websearch(${target})`);\n }\n // Show websearchProxy (native provider mode)\n if (patches.websearchProxy) {\n applied.push(\"websearchProxy(native)\");\n }\n // Support old proxy field for backward compatibility\n if (patches.proxy && !patches.websearch && !patches.websearchProxy)\n applied.push(`websearch(${patches.proxy})`);\n if (patches.reasoningEffort) applied.push(\"reasoningEffort\");\n if (patches.noTelemetry) applied.push(\"noTelemetry\");\n if (patches.standalone) applied.push(\"standalone\");\n return applied.length > 0 ? applied.join(\", \") : \"(none)\";\n}\n","import {\n existsSync,\n mkdirSync,\n readdirSync,\n unlinkSync,\n lstatSync,\n readFileSync,\n appendFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { symlink, readlink, unlink, copyFile, chmod } from \"node:fs/promises\";\nimport { join, basename, dirname, delimiter } from \"node:path\";\nimport { homedir, platform } from \"node:os\";\nimport { execSync } from \"node:child_process\";\nimport { styleText } from \"node:util\";\nimport { removeAliasMetadata, loadAliasMetadata, formatPatches } from \"./metadata.ts\";\n\nconst IS_WINDOWS = platform() === \"win32\";\n\nconst DROID_PATCH_DIR = join(homedir(), \".droid-patch\");\nconst ALIASES_DIR = join(DROID_PATCH_DIR, \"aliases\");\nconst BINS_DIR = join(DROID_PATCH_DIR, \"bins\");\n\n// Unix common PATH directories\nconst UNIX_PATH_DIRS = [\n join(homedir(), \".local/bin\"),\n join(homedir(), \"bin\"),\n join(homedir(), \".bin\"),\n \"/opt/homebrew/bin\",\n \"/usr/local/bin\",\n join(homedir(), \".npm-global/bin\"),\n join(homedir(), \".npm/bin\"),\n join(homedir(), \".pnpm-global/bin\"),\n join(homedir(), \".yarn/bin\"),\n join(homedir(), \".config/yarn/global/node_modules/.bin\"),\n join(homedir(), \".cargo/bin\"),\n join(homedir(), \"go/bin\"),\n join(homedir(), \".deno/bin\"),\n join(homedir(), \".bun/bin\"),\n join(homedir(), \".local/share/mise/shims\"),\n join(homedir(), \".asdf/shims\"),\n join(homedir(), \".nvm/current/bin\"),\n join(homedir(), \".volta/bin\"),\n join(homedir(), \".fnm/current/bin\"),\n];\n\n// Windows common PATH directories\nconst WINDOWS_PATH_DIRS = [\n join(homedir(), \".droid-patch\", \"bin\"),\n join(homedir(), \"scoop\", \"shims\"),\n join(homedir(), \"AppData\", \"Local\", \"Programs\", \"bin\"),\n];\n\nconst COMMON_PATH_DIRS = IS_WINDOWS ? WINDOWS_PATH_DIRS : UNIX_PATH_DIRS;\n\nfunction ensureDirectories(): void {\n if (!existsSync(DROID_PATCH_DIR)) {\n mkdirSync(DROID_PATCH_DIR, { recursive: true });\n }\n if (!existsSync(ALIASES_DIR)) {\n mkdirSync(ALIASES_DIR, { recursive: true });\n }\n if (!existsSync(BINS_DIR)) {\n mkdirSync(BINS_DIR, { recursive: true });\n }\n}\n\nfunction checkPathInclusion(): boolean {\n const pathEnv = process.env.PATH || \"\";\n return pathEnv.split(delimiter).some((p) => p.toLowerCase() === ALIASES_DIR.toLowerCase());\n}\n\nexport function findWritablePathDir(): string | null {\n const pathEnv = process.env.PATH || \"\";\n const pathDirs = pathEnv.split(delimiter);\n\n for (const dir of COMMON_PATH_DIRS) {\n // Case-insensitive comparison for Windows\n const isInPath = pathDirs.some((p) => p.toLowerCase() === dir.toLowerCase());\n if (isInPath) {\n try {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n const testFile = join(dir, `.droid-patch-test-${Date.now()}`);\n writeFileSync(testFile, \"\");\n unlinkSync(testFile);\n return dir;\n } catch {\n continue;\n }\n }\n }\n\n return null;\n}\n\nfunction getShellConfigPath(): string {\n if (IS_WINDOWS) {\n // Windows doesn't use shell config files for PATH\n return \"\";\n }\n const shell = process.env.SHELL || \"/bin/bash\";\n const shellName = basename(shell);\n\n switch (shellName) {\n case \"zsh\":\n return join(homedir(), \".zshrc\");\n case \"bash\": {\n const bashProfile = join(homedir(), \".bash_profile\");\n if (existsSync(bashProfile)) return bashProfile;\n return join(homedir(), \".bashrc\");\n }\n case \"fish\":\n return join(homedir(), \".config/fish/config.fish\");\n default:\n return join(homedir(), \".profile\");\n }\n}\n\nfunction isPathConfigured(shellConfigPath: string): boolean {\n if (IS_WINDOWS || !shellConfigPath) {\n return false;\n }\n\n if (!existsSync(shellConfigPath)) {\n return false;\n }\n\n try {\n const content = readFileSync(shellConfigPath, \"utf-8\");\n return content.includes(\".droid-patch/aliases\") || content.includes(\"droid-patch/aliases\");\n } catch {\n return false;\n }\n}\n\n/**\n * Add directory to Windows user PATH using setx command\n * This modifies the user's PATH permanently (requires terminal restart)\n */\nfunction addToWindowsUserPath(dir: string): boolean {\n try {\n // Get current user PATH from registry\n let existingPath = \"\";\n try {\n const result = execSync('reg query \"HKCU\\\\Environment\" /v Path 2>nul', {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n const match = result.match(/Path\\s+REG_(?:EXPAND_)?SZ\\s+(.+)/);\n existingPath = match ? match[1].trim() : \"\";\n } catch {\n // PATH not set yet, that's fine\n }\n\n // Check if already in PATH (case-insensitive)\n const paths = existingPath.split(\";\").map((p) => p.toLowerCase().trim());\n if (paths.includes(dir.toLowerCase())) {\n return true; // Already in PATH\n }\n\n // Add to PATH\n const newPath = existingPath ? `${existingPath};${dir}` : dir;\n execSync(`setx PATH \"${newPath}\"`, { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Generate Windows .cmd launcher script\n */\nfunction generateWindowsLauncher(targetPath: string): string {\n return `@echo off\\r\\n\"${targetPath}\" %*\\r\\n`;\n}\n\nfunction addPathToShellConfig(shellConfigPath: string, verbose = false): boolean {\n const shell = process.env.SHELL || \"/bin/bash\";\n const shellName = basename(shell);\n\n let exportLine: string;\n if (shellName === \"fish\") {\n exportLine = `\\n# Added by droid-patch\\nfish_add_path \"${ALIASES_DIR}\"\\n`;\n } else {\n exportLine = `\\n# Added by droid-patch\\nexport PATH=\"${ALIASES_DIR}:$PATH\"\\n`;\n }\n\n try {\n appendFileSync(shellConfigPath, exportLine);\n if (verbose) {\n console.log(styleText(\"gray\", ` Added PATH export to: ${shellConfigPath}`));\n }\n return true;\n } catch (error) {\n console.log(\n styleText(\"yellow\", `[!] Could not write to ${shellConfigPath}: ${(error as Error).message}`),\n );\n return false;\n }\n}\n\nexport interface CreateAliasResult {\n aliasPath: string;\n binaryPath: string;\n immediate?: boolean;\n}\n\nexport async function createAlias(\n patchedBinaryPath: string,\n aliasName: string,\n verbose = false,\n): Promise<CreateAliasResult> {\n ensureDirectories();\n\n console.log(styleText(\"white\", `[*] Creating alias: ${styleText(\"cyan\", aliasName)}`));\n\n // Windows: use .cmd launcher instead of symlink\n if (IS_WINDOWS) {\n return createWindowsAlias(patchedBinaryPath, aliasName, verbose);\n }\n\n const writablePathDir = findWritablePathDir();\n\n if (writablePathDir) {\n const targetPath = join(writablePathDir, aliasName);\n const binaryDest = join(BINS_DIR, `${aliasName}-patched`);\n await copyFile(patchedBinaryPath, binaryDest);\n await chmod(binaryDest, 0o755);\n\n if (verbose) {\n console.log(styleText(\"gray\", ` Stored binary: ${binaryDest}`));\n }\n\n if (existsSync(targetPath)) {\n await unlink(targetPath);\n if (verbose) {\n console.log(styleText(\"gray\", ` Removed existing: ${targetPath}`));\n }\n }\n\n await symlink(binaryDest, targetPath);\n\n if (process.platform === \"darwin\") {\n try {\n console.log(styleText(\"gray\", \"[*] Re-signing binary for macOS...\"));\n execSync(`codesign --force --deep --sign - \"${binaryDest}\"`, {\n stdio: \"pipe\",\n });\n console.log(styleText(\"green\", \"[*] Binary re-signed successfully\"));\n } catch {\n console.log(styleText(\"yellow\", \"[!] Could not re-sign binary\"));\n }\n\n try {\n execSync(`xattr -cr \"${binaryDest}\"`, { stdio: \"pipe\" });\n } catch {\n // Ignore\n }\n }\n\n console.log(styleText(\"green\", `[*] Created: ${targetPath} -> ${binaryDest}`));\n console.log();\n console.log(styleText(\"green\", \"─\".repeat(60)));\n console.log(styleText([\"green\", \"bold\"], \" ALIAS READY - NO ACTION REQUIRED!\"));\n console.log(styleText(\"green\", \"─\".repeat(60)));\n console.log();\n console.log(\n styleText(\n \"white\",\n `The alias \"${styleText([\"cyan\", \"bold\"], aliasName)}\" is now available in ALL terminals.`,\n ),\n );\n console.log(styleText(\"gray\", `(Installed to: ${writablePathDir})`));\n\n return {\n aliasPath: targetPath,\n binaryPath: binaryDest,\n immediate: true,\n };\n }\n\n console.log(styleText(\"yellow\", \"[*] No writable PATH directory found, using fallback...\"));\n\n const binaryDest = join(BINS_DIR, `${aliasName}-patched`);\n await copyFile(patchedBinaryPath, binaryDest);\n await chmod(binaryDest, 0o755);\n\n if (verbose) {\n console.log(styleText(\"gray\", ` Copied binary to: ${binaryDest}`));\n }\n\n if (process.platform === \"darwin\") {\n try {\n console.log(styleText(\"gray\", \"[*] Re-signing binary for macOS...\"));\n execSync(`codesign --force --deep --sign - \"${binaryDest}\"`, {\n stdio: \"pipe\",\n });\n console.log(styleText(\"green\", \"[*] Binary re-signed successfully\"));\n } catch {\n console.log(\n styleText(\"yellow\", \"[!] Could not re-sign binary. You may need to do this manually:\"),\n );\n console.log(styleText(\"gray\", ` codesign --force --deep --sign - \"${binaryDest}\"`));\n }\n\n try {\n execSync(`xattr -cr \"${binaryDest}\"`, { stdio: \"pipe\" });\n } catch {\n // Ignore\n }\n }\n\n const symlinkPath = join(ALIASES_DIR, aliasName);\n\n if (existsSync(symlinkPath)) {\n await unlink(symlinkPath);\n if (verbose) {\n console.log(styleText(\"gray\", ` Removed existing symlink`));\n }\n }\n\n await symlink(binaryDest, symlinkPath);\n await chmod(symlinkPath, 0o755);\n\n console.log(styleText(\"green\", `[*] Created symlink: ${symlinkPath} -> ${binaryDest}`));\n\n const shellConfig = getShellConfigPath();\n\n if (!checkPathInclusion()) {\n if (!isPathConfigured(shellConfig)) {\n console.log(styleText(\"white\", `[*] Configuring PATH in ${shellConfig}...`));\n\n if (addPathToShellConfig(shellConfig, verbose)) {\n console.log(styleText(\"green\", `[*] PATH configured successfully!`));\n console.log();\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log(styleText([\"yellow\", \"bold\"], \" ACTION REQUIRED\"));\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log();\n console.log(styleText(\"white\", \"To use the alias in this terminal, run:\"));\n console.log();\n console.log(styleText(\"cyan\", ` source ${shellConfig}`));\n console.log();\n console.log(styleText(\"gray\", \"Or simply open a new terminal window.\"));\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n } else {\n const exportLine = `export PATH=\"${ALIASES_DIR}:$PATH\"`;\n console.log();\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log(styleText([\"yellow\", \"bold\"], \" Manual PATH Configuration Required\"));\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log();\n console.log(styleText(\"white\", \"Add this line to your shell config:\"));\n console.log(styleText(\"cyan\", ` ${exportLine}`));\n console.log();\n console.log(styleText(\"gray\", `Shell config file: ${shellConfig}`));\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n }\n } else {\n console.log(styleText(\"green\", `[*] PATH already configured in ${shellConfig}`));\n console.log();\n console.log(\n styleText(\n \"yellow\",\n `Note: Run \\`source ${shellConfig}\\` or open a new terminal to use the alias.`,\n ),\n );\n }\n } else {\n console.log(styleText(\"green\", `[*] PATH already includes aliases directory`));\n console.log();\n console.log(\n styleText(\n \"green\",\n `You can now use \"${styleText([\"cyan\", \"bold\"], aliasName)}\" command directly!`,\n ),\n );\n }\n\n return {\n aliasPath: symlinkPath,\n binaryPath: binaryDest,\n };\n}\n\n/**\n * Create alias on Windows using .cmd launcher and setx for PATH\n */\n/**\n * Try to copy file, handling Windows file locking\n * If target is locked, use a new filename with timestamp\n */\nasync function copyFileWithLockHandling(\n src: string,\n dest: string,\n verbose = false,\n): Promise<string> {\n try {\n await copyFile(src, dest);\n return dest;\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n // EBUSY = file is locked/in use (Windows)\n if (err.code === \"EBUSY\" && IS_WINDOWS) {\n // Generate new filename with timestamp\n const timestamp = Date.now();\n const ext = dest.endsWith(\".exe\") ? \".exe\" : \"\";\n const baseName = dest.replace(/\\.exe$/, \"\").replace(/-\\d+$/, \"\"); // Remove old timestamp if any\n const newDest = `${baseName}-${timestamp}${ext}`;\n\n if (verbose) {\n console.log(styleText(\"yellow\", ` [!] File locked, using new path: ${newDest}`));\n }\n\n await copyFile(src, newDest);\n return newDest;\n }\n throw error;\n }\n}\n\nasync function createWindowsAlias(\n patchedBinaryPath: string,\n aliasName: string,\n verbose = false,\n): Promise<CreateAliasResult> {\n const binDir = join(DROID_PATCH_DIR, \"bin\");\n if (!existsSync(binDir)) {\n mkdirSync(binDir, { recursive: true });\n }\n\n // Copy binary to bins directory, handling file locking\n const targetPath = join(BINS_DIR, `${aliasName}-patched.exe`);\n const binaryDest = await copyFileWithLockHandling(patchedBinaryPath, targetPath, verbose);\n\n if (verbose) {\n console.log(styleText(\"gray\", ` Stored binary: ${binaryDest}`));\n }\n\n // Create .cmd launcher in bin directory\n const cmdPath = join(binDir, `${aliasName}.cmd`);\n const cmdContent = generateWindowsLauncher(binaryDest);\n writeFileSync(cmdPath, cmdContent);\n\n if (verbose) {\n console.log(styleText(\"gray\", ` Created launcher: ${cmdPath}`));\n }\n\n // Try to add bin directory to user PATH\n const pathAdded = addToWindowsUserPath(binDir);\n\n console.log(styleText(\"green\", `[*] Created: ${cmdPath}`));\n console.log();\n\n if (pathAdded) {\n if (checkPathInclusion()) {\n console.log(styleText(\"green\", \"─\".repeat(60)));\n console.log(styleText([\"green\", \"bold\"], \" ALIAS READY!\"));\n console.log(styleText(\"green\", \"─\".repeat(60)));\n console.log();\n console.log(\n styleText(\n \"white\",\n `The alias \"${styleText([\"cyan\", \"bold\"], aliasName)}\" is now available.`,\n ),\n );\n console.log(styleText(\"gray\", `(Installed to: ${binDir})`));\n\n return {\n aliasPath: cmdPath,\n binaryPath: binaryDest,\n immediate: true,\n };\n }\n\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log(styleText([\"yellow\", \"bold\"], \" PATH Updated - Restart Terminal\"));\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log();\n console.log(styleText(\"white\", \"PATH has been updated. Please restart your terminal.\"));\n console.log(\n styleText(\n \"white\",\n `Then you can use \"${styleText([\"cyan\", \"bold\"], aliasName)}\" command directly.`,\n ),\n );\n console.log();\n console.log(styleText(\"gray\", `Installed to: ${binDir}`));\n } else {\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log(styleText([\"yellow\", \"bold\"], \" Manual PATH Configuration Required\"));\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log();\n console.log(styleText(\"white\", \"Add this directory to your PATH:\"));\n console.log(styleText(\"cyan\", ` ${binDir}`));\n console.log();\n console.log(styleText(\"gray\", \"Or run directly:\"));\n console.log(styleText(\"cyan\", ` \"${cmdPath}\"`));\n }\n\n return {\n aliasPath: cmdPath,\n binaryPath: binaryDest,\n immediate: false,\n };\n}\n\nexport async function removeAlias(aliasName: string): Promise<void> {\n console.log(styleText(\"white\", `[*] Removing alias: ${styleText(\"cyan\", aliasName)}`));\n\n let removed = false;\n\n // Windows: check for .cmd launcher\n if (IS_WINDOWS) {\n const binDir = join(DROID_PATCH_DIR, \"bin\");\n const cmdPath = join(binDir, `${aliasName}.cmd`);\n if (existsSync(cmdPath)) {\n await unlink(cmdPath);\n console.log(styleText(\"green\", ` Removed: ${cmdPath}`));\n removed = true;\n }\n\n // Remove Windows binary (.exe)\n const exePath = join(BINS_DIR, `${aliasName}-patched.exe`);\n if (existsSync(exePath)) {\n await unlink(exePath);\n console.log(styleText(\"green\", ` Removed binary: ${exePath}`));\n removed = true;\n }\n\n // Also check for wrapper .cmd in proxy directory\n const proxyDir = join(DROID_PATCH_DIR, \"proxy\");\n const proxyWrapperCmd = join(proxyDir, `${aliasName}.cmd`);\n if (existsSync(proxyWrapperCmd)) {\n await unlink(proxyWrapperCmd);\n console.log(styleText(\"green\", ` Removed wrapper: ${proxyWrapperCmd}`));\n removed = true;\n }\n }\n\n // Check common PATH directories for symlinks (Unix)\n if (!IS_WINDOWS) {\n for (const pathDir of COMMON_PATH_DIRS) {\n const pathSymlink = join(pathDir, aliasName);\n if (existsSync(pathSymlink)) {\n try {\n const stats = lstatSync(pathSymlink);\n if (stats.isSymbolicLink()) {\n const target = await readlink(pathSymlink);\n // Support regular aliases, old websearch wrappers, and new proxy wrappers\n if (\n target.includes(\".droid-patch/bins\") ||\n target.includes(\".droid-patch/websearch\") ||\n target.includes(\".droid-patch/proxy\") ||\n target.includes(\".droid-patch/statusline\")\n ) {\n await unlink(pathSymlink);\n console.log(styleText(\"green\", ` Removed: ${pathSymlink}`));\n removed = true;\n }\n }\n } catch {\n // Ignore\n }\n }\n }\n }\n\n // Check aliases directory\n const symlinkPath = join(ALIASES_DIR, aliasName);\n if (existsSync(symlinkPath)) {\n await unlink(symlinkPath);\n console.log(styleText(\"green\", ` Removed: ${symlinkPath}`));\n removed = true;\n }\n\n // Remove binary if exists (Unix style without .exe)\n const binaryPath = join(BINS_DIR, `${aliasName}-patched`);\n if (existsSync(binaryPath)) {\n await unlink(binaryPath);\n console.log(styleText(\"green\", ` Removed binary: ${binaryPath}`));\n removed = true;\n }\n\n // Remove new proxy wrapper and related files if exist\n const proxyDir = join(DROID_PATCH_DIR, \"proxy\");\n const proxyWrapperPath = join(proxyDir, aliasName);\n const proxyScriptPath = join(proxyDir, `${aliasName}-proxy.js`);\n\n if (existsSync(proxyWrapperPath)) {\n await unlink(proxyWrapperPath);\n console.log(styleText(\"green\", ` Removed wrapper: ${proxyWrapperPath}`));\n removed = true;\n }\n\n if (existsSync(proxyScriptPath)) {\n await unlink(proxyScriptPath);\n console.log(styleText(\"green\", ` Removed proxy script: ${proxyScriptPath}`));\n removed = true;\n }\n\n // Remove old websearch wrapper and related files if exist (backward compatibility)\n const websearchDir = join(DROID_PATCH_DIR, \"websearch\");\n const wrapperPath = join(websearchDir, aliasName);\n const oldProxyPath = join(websearchDir, `${aliasName}-proxy.js`);\n const preloadPath = join(websearchDir, `${aliasName}-preload.js`);\n\n if (existsSync(wrapperPath)) {\n await unlink(wrapperPath);\n console.log(styleText(\"green\", ` Removed legacy wrapper: ${wrapperPath}`));\n removed = true;\n }\n\n if (existsSync(oldProxyPath)) {\n await unlink(oldProxyPath);\n console.log(styleText(\"green\", ` Removed legacy proxy: ${oldProxyPath}`));\n removed = true;\n }\n\n if (existsSync(preloadPath)) {\n await unlink(preloadPath);\n console.log(styleText(\"green\", ` Removed legacy preload: ${preloadPath}`));\n removed = true;\n }\n\n // Remove statusline wrapper and monitor script if exist\n const statuslineDir = join(DROID_PATCH_DIR, \"statusline\");\n const statuslineWrapperPath = join(statuslineDir, aliasName);\n const statuslineMonitorPath = join(statuslineDir, `${aliasName}-statusline.js`);\n const statuslineSessionsPath = join(statuslineDir, `${aliasName}-sessions.js`);\n\n if (existsSync(statuslineWrapperPath)) {\n await unlink(statuslineWrapperPath);\n console.log(styleText(\"green\", ` Removed statusline wrapper: ${statuslineWrapperPath}`));\n removed = true;\n }\n\n if (existsSync(statuslineMonitorPath)) {\n await unlink(statuslineMonitorPath);\n console.log(styleText(\"green\", ` Removed statusline monitor: ${statuslineMonitorPath}`));\n removed = true;\n }\n\n if (existsSync(statuslineSessionsPath)) {\n await unlink(statuslineSessionsPath);\n console.log(styleText(\"green\", ` Removed sessions browser: ${statuslineSessionsPath}`));\n removed = true;\n }\n\n // Remove metadata\n const metaRemoved = await removeAliasMetadata(aliasName);\n if (metaRemoved) {\n console.log(styleText(\"green\", ` Removed metadata`));\n removed = true;\n }\n\n if (!removed) {\n console.log(styleText(\"yellow\", ` Alias \"${aliasName}\" not found`));\n } else {\n console.log(styleText(\"green\", `[*] Alias \"${aliasName}\" removed successfully`));\n }\n}\n\nexport async function listAliases(): Promise<void> {\n ensureDirectories();\n\n console.log(styleText(\"cyan\", \"═\".repeat(60)));\n console.log(styleText([\"cyan\", \"bold\"], \" Droid-Patch Aliases\"));\n console.log(styleText(\"cyan\", \"═\".repeat(60)));\n console.log();\n\n interface AliasInfo {\n name: string;\n target: string;\n location: string;\n immediate: boolean;\n }\n\n const aliases: AliasInfo[] = [];\n\n // Windows: check for .cmd launchers in bin directory\n if (IS_WINDOWS) {\n const binDir = join(DROID_PATCH_DIR, \"bin\");\n if (existsSync(binDir)) {\n try {\n const files = readdirSync(binDir);\n for (const file of files) {\n if (file.endsWith(\".cmd\")) {\n const aliasName = file.replace(/\\.cmd$/, \"\");\n const fullPath = join(binDir, file);\n // Read .cmd to find target\n try {\n const content = readFileSync(fullPath, \"utf-8\");\n const match = content.match(/\"([^\"]+)\"/);\n const target = match ? match[1] : fullPath;\n aliases.push({\n name: aliasName,\n target,\n location: binDir,\n immediate: checkPathInclusion(),\n });\n } catch {\n aliases.push({\n name: aliasName,\n target: fullPath,\n location: binDir,\n immediate: false,\n });\n }\n }\n }\n } catch {\n // Directory can't be read\n }\n }\n\n // Also check proxy directory for wrapper .cmd files\n const proxyDir = join(DROID_PATCH_DIR, \"proxy\");\n if (existsSync(proxyDir)) {\n try {\n const files = readdirSync(proxyDir);\n for (const file of files) {\n if (file.endsWith(\".cmd\")) {\n const aliasName = file.replace(/\\.cmd$/, \"\");\n if (!aliases.find((a) => a.name === aliasName)) {\n const fullPath = join(proxyDir, file);\n aliases.push({\n name: aliasName,\n target: fullPath,\n location: proxyDir,\n immediate: false,\n });\n }\n }\n }\n } catch {\n // Ignore\n }\n }\n } else {\n // Unix: check for symlinks\n for (const pathDir of COMMON_PATH_DIRS) {\n if (!existsSync(pathDir)) continue;\n\n try {\n const files = readdirSync(pathDir);\n for (const file of files) {\n const fullPath = join(pathDir, file);\n try {\n const stats = lstatSync(fullPath);\n if (stats.isSymbolicLink()) {\n const target = await readlink(fullPath);\n // Support regular aliases, old websearch wrappers, and new proxy wrappers\n if (\n target.includes(\".droid-patch/bins\") ||\n target.includes(\".droid-patch/websearch\") ||\n target.includes(\".droid-patch/proxy\") ||\n target.includes(\".droid-patch/statusline\")\n ) {\n aliases.push({\n name: file,\n target,\n location: pathDir,\n immediate: true,\n });\n }\n }\n } catch {\n // Ignore\n }\n }\n } catch {\n // Directory can't be read\n }\n }\n\n try {\n const files = readdirSync(ALIASES_DIR);\n\n for (const file of files) {\n const fullPath = join(ALIASES_DIR, file);\n try {\n const stats = lstatSync(fullPath);\n if (stats.isSymbolicLink()) {\n const target = await readlink(fullPath);\n if (!aliases.find((a) => a.name === file)) {\n aliases.push({\n name: file,\n target,\n location: ALIASES_DIR,\n immediate: false,\n });\n }\n }\n } catch {\n // Ignore\n }\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n }\n\n if (aliases.length === 0) {\n console.log(styleText(\"gray\", \" No aliases configured.\"));\n console.log();\n console.log(styleText(\"gray\", \" Create one with: npx droid-patch --is-custom <alias-name>\"));\n } else {\n console.log(styleText(\"white\", ` Found ${aliases.length} alias(es):`));\n console.log();\n for (const alias of aliases) {\n const status = alias.immediate\n ? styleText(\"green\", \"✓ immediate\")\n : styleText(\"yellow\", \"requires source\");\n console.log(styleText(\"green\", ` • ${styleText([\"cyan\", \"bold\"], alias.name)} [${status}]`));\n console.log(styleText(\"gray\", ` → ${alias.target}`));\n\n // Load and display metadata\n const meta = await loadAliasMetadata(alias.name);\n if (meta) {\n // Version info\n const patchVer = meta.droidPatchVersion\n ? `droid-patch@${meta.droidPatchVersion}`\n : \"unknown\";\n const droidVer = meta.droidVersion ? `droid@${meta.droidVersion}` : \"unknown\";\n console.log(styleText(\"gray\", ` Versions: ${patchVer}, ${droidVer}`));\n\n // Flags/patches\n const flags = formatPatches(meta.patches);\n console.log(styleText(\"gray\", ` Flags: ${flags}`));\n\n // Created time\n if (meta.createdAt) {\n const date = new Date(meta.createdAt).toLocaleString();\n console.log(styleText(\"gray\", ` Created: ${date}`));\n }\n } else {\n console.log(styleText(\"yellow\", ` (no metadata - created by older version)`));\n }\n console.log();\n }\n }\n\n console.log();\n console.log(styleText(\"gray\", ` Aliases directory: ${ALIASES_DIR}`));\n console.log(\n styleText(\n \"gray\",\n ` PATH configured: ${checkPathInclusion() ? styleText(\"green\", \"Yes\") : styleText(\"yellow\", \"No\")}`,\n ),\n );\n console.log();\n}\n\nexport interface ReplaceOriginalResult {\n originalPath: string;\n backupPath: string;\n}\n\nexport async function replaceOriginal(\n patchedBinaryPath: string,\n originalPath: string,\n verbose = false,\n): Promise<ReplaceOriginalResult> {\n ensureDirectories();\n\n console.log(\n styleText(\"white\", `[*] Replacing original binary: ${styleText(\"cyan\", originalPath)}`),\n );\n\n const latestBackupPath = join(BINS_DIR, \"droid-original-latest\");\n\n if (!existsSync(latestBackupPath)) {\n await copyFile(originalPath, latestBackupPath);\n console.log(styleText(\"green\", `[*] Created backup: ${latestBackupPath}`));\n } else {\n if (verbose) {\n console.log(styleText(\"gray\", ` Backup already exists: ${latestBackupPath}`));\n }\n }\n\n await copyFile(patchedBinaryPath, originalPath);\n await chmod(originalPath, 0o755);\n console.log(styleText(\"green\", `[*] Replaced: ${originalPath}`));\n\n if (process.platform === \"darwin\") {\n try {\n console.log(styleText(\"gray\", \"[*] Re-signing binary for macOS...\"));\n execSync(`codesign --force --deep --sign - \"${originalPath}\"`, {\n stdio: \"pipe\",\n });\n console.log(styleText(\"green\", \"[*] Binary re-signed successfully\"));\n } catch {\n console.log(styleText(\"yellow\", \"[!] Could not re-sign binary. You may need to run:\"));\n console.log(styleText(\"gray\", ` codesign --force --deep --sign - \"${originalPath}\"`));\n }\n\n try {\n execSync(`xattr -cr \"${originalPath}\"`, { stdio: \"pipe\" });\n } catch {\n // Ignore\n }\n }\n\n console.log();\n console.log(styleText(\"green\", \"─\".repeat(60)));\n console.log(styleText([\"green\", \"bold\"], \" REPLACEMENT COMPLETE\"));\n console.log(styleText(\"green\", \"─\".repeat(60)));\n console.log();\n console.log(styleText(\"white\", \"The patched binary is now active in all terminals.\"));\n console.log(styleText(\"white\", \"No need to restart or source anything!\"));\n console.log();\n console.log(styleText(\"gray\", `To restore the original, run:`));\n console.log(styleText(\"cyan\", ` npx droid-patch restore`));\n\n return {\n originalPath,\n backupPath: latestBackupPath,\n };\n}\n\n/**\n * Create alias for wrapper script\n * Unlike createAlias, this function creates symlink pointing to wrapper script\n * Used for features like websearch that require preprocessing\n */\nexport async function createAliasForWrapper(\n wrapperPath: string,\n aliasName: string,\n verbose = false,\n): Promise<CreateAliasResult> {\n ensureDirectories();\n\n console.log(styleText(\"white\", `[*] Creating alias: ${styleText(\"cyan\", aliasName)}`));\n\n // Windows: create .cmd launcher pointing to wrapper\n if (IS_WINDOWS) {\n return createWindowsWrapperAlias(wrapperPath, aliasName, verbose);\n }\n\n const writablePathDir = findWritablePathDir();\n\n if (writablePathDir) {\n const targetPath = join(writablePathDir, aliasName);\n\n if (verbose) {\n console.log(styleText(\"gray\", ` Wrapper: ${wrapperPath}`));\n }\n\n if (existsSync(targetPath)) {\n await unlink(targetPath);\n if (verbose) {\n console.log(styleText(\"gray\", ` Removed existing: ${targetPath}`));\n }\n }\n\n await symlink(wrapperPath, targetPath);\n\n console.log(styleText(\"green\", `[*] Created: ${targetPath} -> ${wrapperPath}`));\n console.log();\n console.log(styleText(\"green\", \"─\".repeat(60)));\n console.log(styleText([\"green\", \"bold\"], \" ALIAS READY - NO ACTION REQUIRED!\"));\n console.log(styleText(\"green\", \"─\".repeat(60)));\n console.log();\n console.log(\n styleText(\n \"white\",\n `The alias \"${styleText([\"cyan\", \"bold\"], aliasName)}\" is now available in ALL terminals.`,\n ),\n );\n console.log(styleText(\"gray\", `(Installed to: ${writablePathDir})`));\n\n return {\n aliasPath: targetPath,\n binaryPath: wrapperPath,\n immediate: true,\n };\n }\n\n // Fallback: use ~/.droid-patch/aliases\n console.log(styleText(\"yellow\", \"[*] No writable PATH directory found, using fallback...\"));\n\n const symlinkPath = join(ALIASES_DIR, aliasName);\n\n if (existsSync(symlinkPath)) {\n await unlink(symlinkPath);\n if (verbose) {\n console.log(styleText(\"gray\", ` Removed existing symlink`));\n }\n }\n\n await symlink(wrapperPath, symlinkPath);\n\n console.log(styleText(\"green\", `[*] Created symlink: ${symlinkPath} -> ${wrapperPath}`));\n\n const shellConfig = getShellConfigPath();\n\n if (!checkPathInclusion()) {\n if (!isPathConfigured(shellConfig)) {\n console.log(styleText(\"white\", `[*] Configuring PATH in ${shellConfig}...`));\n\n if (addPathToShellConfig(shellConfig, verbose)) {\n console.log(styleText(\"green\", `[*] PATH configured successfully!`));\n console.log();\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log(styleText([\"yellow\", \"bold\"], \" ACTION REQUIRED\"));\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log();\n console.log(styleText(\"white\", \"To use the alias in this terminal, run:\"));\n console.log();\n console.log(styleText(\"cyan\", ` source ${shellConfig}`));\n console.log();\n console.log(styleText(\"gray\", \"Or simply open a new terminal window.\"));\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n } else {\n const exportLine = `export PATH=\"${ALIASES_DIR}:$PATH\"`;\n console.log();\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log(styleText([\"yellow\", \"bold\"], \" Manual PATH Configuration Required\"));\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log();\n console.log(styleText(\"white\", \"Add this line to your shell config:\"));\n console.log(styleText(\"cyan\", ` ${exportLine}`));\n console.log();\n console.log(styleText(\"gray\", `Shell config file: ${shellConfig}`));\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n }\n } else {\n console.log(styleText(\"green\", `[*] PATH already configured in ${shellConfig}`));\n console.log();\n console.log(\n styleText(\n \"yellow\",\n `Note: Run \\`source ${shellConfig}\\` or open a new terminal to use the alias.`,\n ),\n );\n }\n } else {\n console.log(styleText(\"green\", `[*] PATH already includes aliases directory`));\n console.log();\n console.log(\n styleText(\n \"green\",\n `You can now use \"${styleText([\"cyan\", \"bold\"], aliasName)}\" command directly!`,\n ),\n );\n }\n\n return {\n aliasPath: symlinkPath,\n binaryPath: wrapperPath,\n };\n}\n\n/**\n * Create Windows alias for wrapper script (.cmd pointing to wrapper .cmd)\n */\nasync function createWindowsWrapperAlias(\n wrapperPath: string,\n aliasName: string,\n verbose = false,\n): Promise<CreateAliasResult> {\n const binDir = join(DROID_PATCH_DIR, \"bin\");\n if (!existsSync(binDir)) {\n mkdirSync(binDir, { recursive: true });\n }\n\n if (verbose) {\n console.log(styleText(\"gray\", ` Wrapper: ${wrapperPath}`));\n }\n\n // Create .cmd launcher in bin directory that calls the wrapper\n const cmdPath = join(binDir, `${aliasName}.cmd`);\n const cmdContent = generateWindowsLauncher(wrapperPath);\n writeFileSync(cmdPath, cmdContent);\n\n if (verbose) {\n console.log(styleText(\"gray\", ` Created launcher: ${cmdPath}`));\n }\n\n // Try to add bin directory to user PATH\n const pathAdded = addToWindowsUserPath(binDir);\n\n console.log(styleText(\"green\", `[*] Created: ${cmdPath}`));\n console.log();\n\n if (pathAdded) {\n if (checkPathInclusion()) {\n console.log(styleText(\"green\", \"─\".repeat(60)));\n console.log(styleText([\"green\", \"bold\"], \" ALIAS READY!\"));\n console.log(styleText(\"green\", \"─\".repeat(60)));\n console.log();\n console.log(\n styleText(\n \"white\",\n `The alias \"${styleText([\"cyan\", \"bold\"], aliasName)}\" is now available.`,\n ),\n );\n console.log(styleText(\"gray\", `(Installed to: ${binDir})`));\n\n return {\n aliasPath: cmdPath,\n binaryPath: wrapperPath,\n immediate: true,\n };\n }\n\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log(styleText([\"yellow\", \"bold\"], \" PATH Updated - Restart Terminal\"));\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log();\n console.log(styleText(\"white\", \"PATH has been updated. Please restart your terminal.\"));\n console.log(\n styleText(\n \"white\",\n `Then you can use \"${styleText([\"cyan\", \"bold\"], aliasName)}\" command directly.`,\n ),\n );\n console.log();\n console.log(styleText(\"gray\", `Installed to: ${binDir}`));\n } else {\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log(styleText([\"yellow\", \"bold\"], \" Manual PATH Configuration Required\"));\n console.log(styleText(\"yellow\", \"─\".repeat(60)));\n console.log();\n console.log(styleText(\"white\", \"Add this directory to your PATH:\"));\n console.log(styleText(\"cyan\", ` ${binDir}`));\n console.log();\n console.log(styleText(\"gray\", \"Or run directly:\"));\n console.log(styleText(\"cyan\", ` \"${cmdPath}\"`));\n }\n\n return {\n aliasPath: cmdPath,\n binaryPath: wrapperPath,\n immediate: false,\n };\n}\n\nexport async function restoreOriginal(originalPath: string): Promise<void> {\n ensureDirectories();\n\n const latestBackupPath = join(BINS_DIR, \"droid-original-latest\");\n\n console.log(styleText(\"cyan\", \"═\".repeat(60)));\n console.log(styleText([\"cyan\", \"bold\"], \" Restore Original Droid\"));\n console.log(styleText(\"cyan\", \"═\".repeat(60)));\n console.log();\n\n if (!existsSync(latestBackupPath)) {\n const localBackup = `${originalPath}.backup`;\n if (existsSync(localBackup)) {\n console.log(styleText(\"white\", `[*] Found local backup: ${localBackup}`));\n console.log(styleText(\"white\", `[*] Restoring to: ${originalPath}`));\n\n await copyFile(localBackup, originalPath);\n await chmod(originalPath, 0o755);\n\n if (process.platform === \"darwin\") {\n try {\n execSync(`codesign --force --deep --sign - \"${originalPath}\"`, {\n stdio: \"pipe\",\n });\n execSync(`xattr -cr \"${originalPath}\"`, { stdio: \"pipe\" });\n } catch {\n // Ignore\n }\n }\n\n console.log();\n console.log(styleText(\"green\", \"═\".repeat(60)));\n console.log(styleText([\"green\", \"bold\"], \" RESTORE COMPLETE\"));\n console.log(styleText(\"green\", \"═\".repeat(60)));\n console.log();\n console.log(styleText(\"green\", \"Original droid binary has been restored from local backup.\"));\n return;\n }\n\n console.log(styleText(\"red\", \"[!] No backup found.\"));\n console.log(styleText(\"gray\", ` Checked: ${latestBackupPath}`));\n console.log(styleText(\"gray\", ` Checked: ${localBackup}`));\n console.log();\n console.log(styleText(\"gray\", \"If you have a manual backup, restore it with:\"));\n console.log(styleText(\"cyan\", ` cp /path/to/backup ${originalPath}`));\n return;\n }\n\n console.log(styleText(\"white\", `[*] Restoring from: ${latestBackupPath}`));\n console.log(styleText(\"white\", `[*] Restoring to: ${originalPath}`));\n\n const targetDir = dirname(originalPath);\n if (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n }\n\n await copyFile(latestBackupPath, originalPath);\n await chmod(originalPath, 0o755);\n\n if (process.platform === \"darwin\") {\n try {\n execSync(`codesign --force --deep --sign - \"${originalPath}\"`, {\n stdio: \"pipe\",\n });\n execSync(`xattr -cr \"${originalPath}\"`, { stdio: \"pipe\" });\n } catch {\n // Ignore\n }\n }\n\n console.log();\n console.log(styleText(\"green\", \"═\".repeat(60)));\n console.log(styleText([\"green\", \"bold\"], \" RESTORE COMPLETE\"));\n console.log(styleText(\"green\", \"═\".repeat(60)));\n console.log();\n console.log(styleText(\"green\", \"Original droid binary has been restored.\"));\n console.log(styleText(\"green\", \"All terminals will now use the original version.\"));\n}\n\n/**\n * Filter options for removing aliases\n * Uses the same names as CLI options for consistency\n */\nexport type FilterFlag =\n | \"is-custom\"\n | \"skip-login\"\n | \"websearch\"\n | \"api-base\"\n | \"reasoning-effort\"\n | \"disable-telemetry\"\n | \"standalone\";\n\nexport interface RemoveFilterOptions {\n /** Remove aliases created by this droid-patch version */\n patchVersion?: string;\n /** Remove aliases for this droid version */\n droidVersion?: string;\n /** Remove aliases that have these flags enabled (all must match) */\n flags?: FilterFlag[];\n}\n\n/**\n * Remove aliases matching filter criteria\n */\nexport async function removeAliasesByFilter(filter: RemoveFilterOptions): Promise<void> {\n console.log(styleText(\"cyan\", \"═\".repeat(60)));\n console.log(styleText([\"cyan\", \"bold\"], \" Remove Aliases by Filter\"));\n console.log(styleText(\"cyan\", \"═\".repeat(60)));\n console.log();\n\n // Show filter criteria\n if (filter.patchVersion) {\n console.log(styleText(\"white\", ` Filter: droid-patch version = ${filter.patchVersion}`));\n }\n if (filter.droidVersion) {\n console.log(styleText(\"white\", ` Filter: droid version = ${filter.droidVersion}`));\n }\n if (filter.flags && filter.flags.length > 0) {\n console.log(styleText(\"white\", ` Filter: flags = ${filter.flags.join(\", \")}`));\n }\n console.log();\n\n // Collect all alias names\n const aliasNames = new Set<string>();\n\n // Check common PATH directories for symlinks\n for (const pathDir of COMMON_PATH_DIRS) {\n if (!existsSync(pathDir)) continue;\n\n try {\n const files = readdirSync(pathDir);\n for (const file of files) {\n const fullPath = join(pathDir, file);\n try {\n const stats = lstatSync(fullPath);\n if (stats.isSymbolicLink()) {\n const target = await readlink(fullPath);\n if (\n target.includes(\".droid-patch/bins\") ||\n target.includes(\".droid-patch/websearch\") ||\n target.includes(\".droid-patch/proxy\") ||\n target.includes(\".droid-patch/statusline\")\n ) {\n aliasNames.add(file);\n }\n }\n } catch {\n // Ignore\n }\n }\n } catch {\n // Directory can't be read\n }\n }\n\n // Check aliases directory\n if (existsSync(ALIASES_DIR)) {\n try {\n const files = readdirSync(ALIASES_DIR);\n for (const file of files) {\n const fullPath = join(ALIASES_DIR, file);\n try {\n const stats = lstatSync(fullPath);\n if (stats.isSymbolicLink()) {\n aliasNames.add(file);\n }\n } catch {\n // Ignore\n }\n }\n } catch {\n // Directory can't be read\n }\n }\n\n // Filter aliases by metadata\n const matchingAliases: string[] = [];\n\n for (const aliasName of aliasNames) {\n const meta = await loadAliasMetadata(aliasName);\n\n // If no metadata, skip (can't filter without metadata)\n if (!meta) {\n continue;\n }\n\n let matches = true;\n\n // Check droid-patch version\n if (filter.patchVersion && meta.droidPatchVersion !== filter.patchVersion) {\n matches = false;\n }\n\n // Check droid version\n if (filter.droidVersion && meta.droidVersion !== filter.droidVersion) {\n matches = false;\n }\n\n // Check flags (all specified flags must match)\n if (filter.flags && filter.flags.length > 0) {\n const patches = meta.patches;\n for (const flag of filter.flags) {\n switch (flag) {\n case \"is-custom\":\n if (!patches.isCustom) matches = false;\n break;\n case \"skip-login\":\n if (!patches.skipLogin) matches = false;\n break;\n case \"websearch\":\n if (!patches.websearch) matches = false;\n break;\n case \"reasoning-effort\":\n if (!patches.reasoningEffort) matches = false;\n break;\n case \"api-base\":\n if (!patches.apiBase) matches = false;\n break;\n case \"disable-telemetry\":\n if (!patches.noTelemetry) matches = false;\n break;\n case \"standalone\":\n if (!patches.standalone) matches = false;\n break;\n }\n if (!matches) break;\n }\n }\n\n if (matches) {\n matchingAliases.push(aliasName);\n }\n }\n\n if (matchingAliases.length === 0) {\n console.log(styleText(\"yellow\", \" No aliases match the filter criteria.\"));\n console.log();\n return;\n }\n\n console.log(styleText(\"white\", ` Found ${matchingAliases.length} matching alias(es):`));\n for (const name of matchingAliases) {\n console.log(styleText(\"gray\", ` • ${name}`));\n }\n console.log();\n\n // Remove each matching alias\n for (const aliasName of matchingAliases) {\n await removeAlias(aliasName);\n console.log();\n }\n\n console.log(styleText(\"green\", `[*] Removed ${matchingAliases.length} alias(es)`));\n}\n\n/**\n * Clear all droid-patch aliases and related files\n */\nexport async function clearAllAliases(): Promise<void> {\n console.log(styleText(\"cyan\", \"═\".repeat(60)));\n console.log(styleText([\"cyan\", \"bold\"], \" Clearing All Droid-Patch Data\"));\n console.log(styleText(\"cyan\", \"═\".repeat(60)));\n console.log();\n\n // Collect all alias names\n const aliasNames = new Set<string>();\n\n // Check common PATH directories for symlinks\n for (const pathDir of COMMON_PATH_DIRS) {\n if (!existsSync(pathDir)) continue;\n\n try {\n const files = readdirSync(pathDir);\n for (const file of files) {\n const fullPath = join(pathDir, file);\n try {\n const stats = lstatSync(fullPath);\n if (stats.isSymbolicLink()) {\n const target = await readlink(fullPath);\n if (\n target.includes(\".droid-patch/bins\") ||\n target.includes(\".droid-patch/websearch\") ||\n target.includes(\".droid-patch/proxy\") ||\n target.includes(\".droid-patch/statusline\")\n ) {\n aliasNames.add(file);\n }\n }\n } catch {\n // Ignore\n }\n }\n } catch {\n // Directory can't be read\n }\n }\n\n // Check aliases directory\n if (existsSync(ALIASES_DIR)) {\n try {\n const files = readdirSync(ALIASES_DIR);\n for (const file of files) {\n const fullPath = join(ALIASES_DIR, file);\n try {\n const stats = lstatSync(fullPath);\n if (stats.isSymbolicLink()) {\n aliasNames.add(file);\n }\n } catch {\n // Ignore\n }\n }\n } catch {\n // Directory can't be read\n }\n }\n\n if (aliasNames.size === 0) {\n console.log(styleText(\"yellow\", \" No aliases found.\"));\n } else {\n console.log(styleText(\"white\", ` Found ${aliasNames.size} alias(es) to remove:`));\n for (const name of aliasNames) {\n console.log(styleText(\"gray\", ` • ${name}`));\n }\n console.log();\n\n // Remove each alias\n for (const aliasName of aliasNames) {\n await removeAlias(aliasName);\n console.log();\n }\n }\n\n // Clean up directories (including legacy files)\n console.log(styleText(\"white\", \" Cleaning up directories...\"));\n const dirsToClean = [\n join(DROID_PATCH_DIR, \"bins\"),\n join(DROID_PATCH_DIR, \"aliases\"),\n join(DROID_PATCH_DIR, \"proxy\"),\n join(DROID_PATCH_DIR, \"websearch\"),\n join(DROID_PATCH_DIR, \"statusline\"),\n ];\n\n for (const dir of dirsToClean) {\n if (existsSync(dir)) {\n try {\n const files = readdirSync(dir);\n for (const file of files) {\n const fullPath = join(dir, file);\n try {\n await unlink(fullPath);\n console.log(styleText(\"green\", ` Removed: ${fullPath}`));\n } catch {\n // Ignore\n }\n }\n } catch {\n // Ignore\n }\n }\n }\n\n // Clean up legacy temp files from old versions\n const legacyTempFiles = [\"/tmp/droid-search-proxy.pid\", \"/tmp/droid-search-proxy.log\"];\n\n for (const tempFile of legacyTempFiles) {\n if (existsSync(tempFile)) {\n try {\n await unlink(tempFile);\n console.log(styleText(\"green\", ` Removed legacy: ${tempFile}`));\n } catch {\n // Ignore\n }\n }\n }\n\n // Clean up temp port files (pattern: /tmp/droid-websearch-*.port)\n try {\n const tmpFiles = readdirSync(\"/tmp\");\n for (const file of tmpFiles) {\n if (file.startsWith(\"droid-websearch-\") && file.endsWith(\".port\")) {\n const fullPath = join(\"/tmp\", file);\n try {\n await unlink(fullPath);\n console.log(styleText(\"green\", ` Removed temp: ${fullPath}`));\n } catch {\n // Ignore\n }\n }\n // Also clean old droid-search-proxy-*.port files\n if (file.startsWith(\"droid-search-proxy-\") && file.endsWith(\".port\")) {\n const fullPath = join(\"/tmp\", file);\n try {\n await unlink(fullPath);\n console.log(styleText(\"green\", ` Removed legacy temp: ${fullPath}`));\n } catch {\n // Ignore\n }\n }\n }\n } catch {\n // Ignore\n }\n\n // Clean up metadata file\n const metadataFile = join(DROID_PATCH_DIR, \"metadata.json\");\n if (existsSync(metadataFile)) {\n try {\n await unlink(metadataFile);\n console.log(styleText(\"green\", ` Removed: ${metadataFile}`));\n } catch {\n // Ignore\n }\n }\n\n console.log();\n console.log(styleText(\"green\", \"[*] All droid-patch data cleared successfully\"));\n}\n"],"mappings":"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"}