@orderful/droid 0.27.1 → 0.27.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/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @orderful/droid
2
2
 
3
+ ## 0.27.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#152](https://github.com/Orderful/droid/pull/152) [`8bd3a4f`](https://github.com/Orderful/droid/commit/8bd3a4f4c6ef1352ed683be584693124a202f35a) Thanks [@frytyler](https://github.com/frytyler)! - Fix config skill name migration actually persisting changes to disk
8
+
9
+ **Bug fixes:**
10
+ - **Per-platform change tracking**: Migration now uses a `platformChanged` flag to track changes independently for each platform, ensuring all platform configs are properly saved
11
+ - **Prevent config overwrites**: `runPackageMigrations` now reloads config before saving the version marker, preventing stale data from overwriting migration changes
12
+ - **Remove conflicting legacy code**: Deleted v0.18.0 migration fallback that was actively undoing the config renaming by deleting newly-migrated unprefixed entries
13
+
14
+ **Impact:**
15
+
16
+ The v0.27.2 config migration now successfully renames tool entries (e.g. `droid-codex` → `codex`) and persists changes to `~/.droid/config.yaml`. Tools will correctly show as installed in the TUI after upgrade.
17
+
18
+ This completes the fix for tools showing as "not installed" after upgrading to v0.27.x.
19
+
20
+ ## 0.27.2
21
+
22
+ ### Patch Changes
23
+
24
+ - [#150](https://github.com/Orderful/droid/pull/150) [`07bffaa`](https://github.com/Orderful/droid/commit/07bffaab1a55363e0b12d7cb2e035dcdae113c8d) Thanks [@frytyler](https://github.com/frytyler)! - Fix config migration not running for users on v0.27.1 and npm cache issues
25
+
26
+ **Bug fix:**
27
+ - Change migration version from v0.27.0 to v0.27.2 to ensure it runs for users already on v0.27.1
28
+ - Add npm cache clear before update to prevent stale package installations
29
+ - Fixes TUI continuing to show tools as not installed after upgrade
30
+
31
+ **Technical details:**
32
+ - Migration was added in v0.27.1 but marked as v0.27.0, causing it to be skipped for users upgrading from v0.27.0 to v0.27.1
33
+ - Update command now runs `npm cache clean --force` before installing to prevent cached packages from being served
34
+ - Migration will now run when users upgrade to v0.27.2
35
+
3
36
  ## 0.27.1
4
37
 
5
38
  ### Patch Changes
package/dist/bin/droid.js CHANGED
@@ -352,16 +352,6 @@ function getInstalledToolVersion(toolName) {
352
352
  if (installedTools[skillName]) {
353
353
  return installedTools[skillName].version;
354
354
  }
355
- if (skillName.startsWith("droid-")) {
356
- const oldSkillName = skillName.replace(/^droid-/, "");
357
- if (installedTools[oldSkillName]) {
358
- const version2 = installedTools[oldSkillName].version;
359
- delete installedTools[oldSkillName];
360
- setPlatformTools(config, installedTools);
361
- saveConfig(config);
362
- return version2;
363
- }
364
- }
365
355
  }
366
356
  return null;
367
357
  }
@@ -628,6 +618,7 @@ function createConfigSkillNameMigration(version2) {
628
618
  config.platform = platformKey;
629
619
  const trackedTools = getPlatformTools(config);
630
620
  const skillNames = Object.keys(trackedTools);
621
+ let platformChanged = false;
631
622
  for (const skillName of skillNames) {
632
623
  if (!skillName.startsWith("droid-") || skillName === "droid") {
633
624
  continue;
@@ -636,10 +627,11 @@ function createConfigSkillNameMigration(version2) {
636
627
  if (!trackedTools[unprefixedName]) {
637
628
  trackedTools[unprefixedName] = trackedTools[skillName];
638
629
  delete trackedTools[skillName];
630
+ platformChanged = true;
639
631
  configChanged = true;
640
632
  }
641
633
  }
642
- if (configChanged) {
634
+ if (platformChanged) {
643
635
  setPlatformTools(config, trackedTools);
644
636
  }
645
637
  }
@@ -652,7 +644,7 @@ function createConfigSkillNameMigration(version2) {
652
644
  }
653
645
  var PACKAGE_MIGRATIONS = [
654
646
  createPlatformSyncMigration("0.25.0"),
655
- createConfigSkillNameMigration("0.27.0")
647
+ createConfigSkillNameMigration("0.27.2")
656
648
  ];
657
649
  var TOOL_MIGRATIONS = {
658
650
  brain: [createConfigDirMigration("droid-brain", "0.2.3")],
@@ -740,9 +732,10 @@ function runPackageMigrations(packageVersion) {
740
732
  return afterFrom && beforeOrAtTo;
741
733
  });
742
734
  if (pendingMigrations.length === 0) {
743
- config.migrations = config.migrations || {};
744
- config.migrations.package = packageVersion;
745
- saveConfig(config);
735
+ const freshConfig = loadConfig();
736
+ freshConfig.migrations = freshConfig.migrations || {};
737
+ freshConfig.migrations.package = packageVersion;
738
+ saveConfig(freshConfig);
746
739
  return { success: true };
747
740
  }
748
741
  const configDir = getConfigDir();
@@ -765,9 +758,10 @@ function runPackageMigrations(packageVersion) {
765
758
  };
766
759
  }
767
760
  }
768
- config.migrations = config.migrations || {};
769
- config.migrations.package = packageVersion;
770
- saveConfig(config);
761
+ const updatedConfig = loadConfig();
762
+ updatedConfig.migrations = updatedConfig.migrations || {};
763
+ updatedConfig.migrations.package = packageVersion;
764
+ saveConfig(updatedConfig);
771
765
  return { success: true };
772
766
  }
773
767
 
@@ -1762,21 +1756,32 @@ import { execSync as execSync4 } from "child_process";
1762
1756
  async function updateCommand(tool, options) {
1763
1757
  if (tool) {
1764
1758
  console.log(chalk8.yellow("\n\u26A0 Per-tool updates not implemented yet"));
1765
- console.log(chalk8.gray("Tools are bundled with the CLI - run `droid update` to update all."));
1759
+ console.log(
1760
+ chalk8.gray(
1761
+ "Tools are bundled with the CLI - run `droid update` to update all."
1762
+ )
1763
+ );
1766
1764
  return;
1767
1765
  }
1768
1766
  if (options?.tools) {
1769
1767
  console.log(chalk8.yellow("\n\u26A0 Tool-only updates not implemented yet"));
1770
- console.log(chalk8.gray("Tools are bundled with the CLI - run `droid update` to update all."));
1768
+ console.log(
1769
+ chalk8.gray(
1770
+ "Tools are bundled with the CLI - run `droid update` to update all."
1771
+ )
1772
+ );
1771
1773
  return;
1772
1774
  }
1773
1775
  console.log(chalk8.bold("\n\u{1F916} Updating Droid...\n"));
1774
1776
  const currentVersion = getVersion();
1775
1777
  console.log(chalk8.gray(`Current version: ${currentVersion}`));
1776
1778
  try {
1777
- const latestVersion = execSync4("npm view @orderful/droid version 2>/dev/null", {
1778
- encoding: "utf-8"
1779
- }).trim();
1779
+ const latestVersion = execSync4(
1780
+ "npm view @orderful/droid version 2>/dev/null",
1781
+ {
1782
+ encoding: "utf-8"
1783
+ }
1784
+ ).trim();
1780
1785
  if (!latestVersion) {
1781
1786
  console.log(chalk8.yellow("\n\u26A0 Could not check for updates"));
1782
1787
  return;
@@ -1787,6 +1792,7 @@ async function updateCommand(tool, options) {
1787
1792
  }
1788
1793
  console.log(chalk8.gray(`Latest version: ${latestVersion}`));
1789
1794
  console.log(chalk8.gray("\nUpdating..."));
1795
+ execSync4("npm cache clean --force 2>/dev/null", { stdio: "pipe" });
1790
1796
  execSync4("npm install -g @orderful/droid@latest", { stdio: "inherit" });
1791
1797
  console.log(chalk8.green(`
1792
1798
  \u2713 Updated to v${latestVersion}`));
@@ -1 +1 @@
1
- {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAIA,UAAU,aAAa;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDzF"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAIA,UAAU,aAAa;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,aAAa,CACjC,IAAI,CAAC,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,IAAI,CAAC,CA6Df"}
package/dist/index.js CHANGED
@@ -591,6 +591,7 @@ function createConfigSkillNameMigration(version) {
591
591
  config.platform = platformKey;
592
592
  const trackedTools = getPlatformTools(config);
593
593
  const skillNames = Object.keys(trackedTools);
594
+ let platformChanged = false;
594
595
  for (const skillName of skillNames) {
595
596
  if (!skillName.startsWith("droid-") || skillName === "droid") {
596
597
  continue;
@@ -599,10 +600,11 @@ function createConfigSkillNameMigration(version) {
599
600
  if (!trackedTools[unprefixedName]) {
600
601
  trackedTools[unprefixedName] = trackedTools[skillName];
601
602
  delete trackedTools[skillName];
603
+ platformChanged = true;
602
604
  configChanged = true;
603
605
  }
604
606
  }
605
- if (configChanged) {
607
+ if (platformChanged) {
606
608
  setPlatformTools(config, trackedTools);
607
609
  }
608
610
  }
@@ -615,7 +617,7 @@ function createConfigSkillNameMigration(version) {
615
617
  }
616
618
  var PACKAGE_MIGRATIONS = [
617
619
  createPlatformSyncMigration("0.25.0"),
618
- createConfigSkillNameMigration("0.27.0")
620
+ createConfigSkillNameMigration("0.27.2")
619
621
  ];
620
622
  var TOOL_MIGRATIONS = {
621
623
  brain: [createConfigDirMigration("droid-brain", "0.2.3")],
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2B,KAAK,WAAW,EAA0B,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAgDxI;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAItC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,WAAW,CA2BxC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAKpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAanD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAchE;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAWD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAapE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,GAAG,IAAI,CAWrF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CAMtD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAQ5E"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,WAAW,EAEhB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACtB,MAAM,SAAS,CAAC;AAmDjB;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAItC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,WAAW,CA4BxC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAKpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAanD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAiBhE;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAWD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAapE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,cAAc,GACxB,IAAI,CAWN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CAMtD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAQ5E"}
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/lib/migrations.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,SAAS,EAIf,MAAM,SAAS,CAAC;AAiOjB;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,CAE/D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAc/D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,IAAI,CAmBN;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA2CtC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,GACvB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAStC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG;IAC5D,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAqDA"}
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/lib/migrations.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,SAAS,EAIf,MAAM,SAAS,CAAC;AAmOjB;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,CAE/D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAc/D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,IAAI,CAmBN;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA2CtC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,GACvB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAStC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG;IAC5D,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAyDA"}
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/lib/tools.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,KAAK,YAAY,EAIlB,MAAM,SAAS,CAAC;AAMjB;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAyBrE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,YAAY,EAAE,CAmBhD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAczD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiCvE;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAuBpE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,EAAE,CA2BtD"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/lib/tools.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,SAAS,CAAC;AAMjB;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAyBrE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,YAAY,EAAE,CAmBhD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAczD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBvE;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAuBpE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,EAAE,CA2BtD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orderful/droid",
3
- "version": "0.27.1",
3
+ "version": "0.27.3",
4
4
  "description": "AI workflow toolkit for sharing skills, commands, and agents across the team",
5
5
  "type": "module",
6
6
  "bin": {
@@ -7,18 +7,29 @@ interface UpdateOptions {
7
7
  cli?: boolean;
8
8
  }
9
9
 
10
- export async function updateCommand(tool?: string, options?: UpdateOptions): Promise<void> {
10
+ export async function updateCommand(
11
+ tool?: string,
12
+ options?: UpdateOptions,
13
+ ): Promise<void> {
11
14
  // If specific tool specified, update just that tool
12
15
  if (tool) {
13
16
  console.log(chalk.yellow('\n⚠ Per-tool updates not implemented yet'));
14
- console.log(chalk.gray('Tools are bundled with the CLI - run `droid update` to update all.'));
17
+ console.log(
18
+ chalk.gray(
19
+ 'Tools are bundled with the CLI - run `droid update` to update all.',
20
+ ),
21
+ );
15
22
  return;
16
23
  }
17
24
 
18
25
  // If --tools flag, update tools only
19
26
  if (options?.tools) {
20
27
  console.log(chalk.yellow('\n⚠ Tool-only updates not implemented yet'));
21
- console.log(chalk.gray('Tools are bundled with the CLI - run `droid update` to update all.'));
28
+ console.log(
29
+ chalk.gray(
30
+ 'Tools are bundled with the CLI - run `droid update` to update all.',
31
+ ),
32
+ );
22
33
  return;
23
34
  }
24
35
 
@@ -30,9 +41,12 @@ export async function updateCommand(tool?: string, options?: UpdateOptions): Pro
30
41
 
31
42
  try {
32
43
  // Check for latest version
33
- const latestVersion = execSync('npm view @orderful/droid version 2>/dev/null', {
34
- encoding: 'utf-8',
35
- }).trim();
44
+ const latestVersion = execSync(
45
+ 'npm view @orderful/droid version 2>/dev/null',
46
+ {
47
+ encoding: 'utf-8',
48
+ },
49
+ ).trim();
36
50
 
37
51
  if (!latestVersion) {
38
52
  console.log(chalk.yellow('\n⚠ Could not check for updates'));
@@ -47,6 +61,8 @@ export async function updateCommand(tool?: string, options?: UpdateOptions): Pro
47
61
  console.log(chalk.gray(`Latest version: ${latestVersion}`));
48
62
  console.log(chalk.gray('\nUpdating...'));
49
63
 
64
+ // Clear npm cache to ensure fresh install
65
+ execSync('npm cache clean --force 2>/dev/null', { stdio: 'pipe' });
50
66
  execSync('npm install -g @orderful/droid@latest', { stdio: 'inherit' });
51
67
 
52
68
  console.log(chalk.green(`\n✓ Updated to v${latestVersion}`));
package/src/lib/config.ts CHANGED
@@ -2,14 +2,21 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
2
  import { homedir } from 'os';
3
3
  import { join } from 'path';
4
4
  import YAML from 'yaml';
5
- import { Platform, BuiltInOutput, type DroidConfig, type LegacyDroidConfig, type SkillOverrides, type AutoUpdateConfig } from './types';
5
+ import {
6
+ Platform,
7
+ BuiltInOutput,
8
+ type DroidConfig,
9
+ type LegacyDroidConfig,
10
+ type SkillOverrides,
11
+ type AutoUpdateConfig,
12
+ } from './types';
6
13
 
7
14
  const CONFIG_DIR = join(homedir(), '.droid');
8
15
  const CONFIG_FILE = join(CONFIG_DIR, 'config.yaml');
9
16
 
10
17
  const DEFAULT_AUTO_UPDATE: AutoUpdateConfig = {
11
- app: false, // Opt-in: user must enable
12
- tools: true, // Opt-out: enabled by default (tools only update when app updates)
18
+ app: false, // Opt-in: user must enable
19
+ tools: true, // Opt-out: enabled by default (tools only update when app updates)
13
20
  };
14
21
 
15
22
  const DEFAULT_CONFIG: DroidConfig = {
@@ -25,14 +32,17 @@ const DEFAULT_CONFIG: DroidConfig = {
25
32
  * v1: ai_tool + skills flat
26
33
  * v2: platform + platforms map with per-platform tools
27
34
  */
28
- function migrateConfig(config: Partial<DroidConfig> & Partial<LegacyDroidConfig>): DroidConfig {
35
+ function migrateConfig(
36
+ config: Partial<DroidConfig> & Partial<LegacyDroidConfig>,
37
+ ): DroidConfig {
29
38
  // Check if this is a legacy config (has ai_tool, no platform)
30
39
  if ('ai_tool' in config && !('platform' in config)) {
31
40
  const legacyConfig = config as LegacyDroidConfig;
32
41
  return {
33
42
  platform: legacyConfig.ai_tool,
34
43
  user_mention: legacyConfig.user_mention ?? DEFAULT_CONFIG.user_mention,
35
- output_preference: legacyConfig.output_preference ?? DEFAULT_CONFIG.output_preference,
44
+ output_preference:
45
+ legacyConfig.output_preference ?? DEFAULT_CONFIG.output_preference,
36
46
  git_username: legacyConfig.git_username ?? DEFAULT_CONFIG.git_username,
37
47
  platforms: {
38
48
  [legacyConfig.ai_tool]: {
@@ -79,7 +89,8 @@ export function loadConfig(): DroidConfig {
79
89
 
80
90
  try {
81
91
  const content = readFileSync(CONFIG_FILE, 'utf-8');
82
- const rawConfig = YAML.parse(content) as Partial<DroidConfig> & Partial<LegacyDroidConfig>;
92
+ const rawConfig = YAML.parse(content) as Partial<DroidConfig> &
93
+ Partial<LegacyDroidConfig>;
83
94
 
84
95
  // Check if migration is needed
85
96
  // TODO: Remove after v0.14.0 (target: late Jan 2025)
@@ -133,7 +144,10 @@ export function getConfigValue(key: string): unknown {
133
144
  export function setConfigValue(key: string, value: unknown): void {
134
145
  const config = loadConfig();
135
146
  const keys = key.split('.');
136
- let current: Record<string, unknown> = config as unknown as Record<string, unknown>;
147
+ let current: Record<string, unknown> = config as unknown as Record<
148
+ string,
149
+ unknown
150
+ >;
137
151
 
138
152
  for (let i = 0; i < keys.length - 1; i++) {
139
153
  if (current[keys[i]] === undefined) {
@@ -198,7 +212,10 @@ export function loadSkillOverrides(skillName: string): SkillOverrides {
198
212
  /**
199
213
  * Save skill-specific overrides
200
214
  */
201
- export function saveSkillOverrides(skillName: string, overrides: SkillOverrides): void {
215
+ export function saveSkillOverrides(
216
+ skillName: string,
217
+ overrides: SkillOverrides,
218
+ ): void {
202
219
  const normalizedName = normalizeSkillNameForConfig(skillName);
203
220
  const overridesPath = getSkillOverridesPath(skillName);
204
221
  const skillDir = join(CONFIG_DIR, 'skills', normalizedName);
@@ -179,6 +179,7 @@ function createConfigSkillNameMigration(version: string): Migration {
179
179
  config.platform = platformKey;
180
180
  const trackedTools = getPlatformTools(config);
181
181
  const skillNames = Object.keys(trackedTools);
182
+ let platformChanged = false;
182
183
 
183
184
  for (const skillName of skillNames) {
184
185
  // Skip if already unprefixed or is the special 'droid' tool
@@ -192,11 +193,12 @@ function createConfigSkillNameMigration(version: string): Migration {
192
193
  if (!trackedTools[unprefixedName]) {
193
194
  trackedTools[unprefixedName] = trackedTools[skillName];
194
195
  delete trackedTools[skillName];
196
+ platformChanged = true;
195
197
  configChanged = true;
196
198
  }
197
199
  }
198
200
 
199
- if (configChanged) {
201
+ if (platformChanged) {
200
202
  setPlatformTools(config, trackedTools);
201
203
  }
202
204
  }
@@ -217,7 +219,7 @@ function createConfigSkillNameMigration(version: string): Migration {
217
219
  */
218
220
  const PACKAGE_MIGRATIONS: Migration[] = [
219
221
  createPlatformSyncMigration('0.25.0'),
220
- createConfigSkillNameMigration('0.27.0'),
222
+ createConfigSkillNameMigration('0.27.2'),
221
223
  ];
222
224
 
223
225
  /**
@@ -387,9 +389,11 @@ export function runPackageMigrations(packageVersion: string): {
387
389
 
388
390
  if (pendingMigrations.length === 0) {
389
391
  // No migrations to run, but still update the version marker
390
- config.migrations = config.migrations || {};
391
- config.migrations.package = packageVersion;
392
- saveConfig(config);
392
+ // Reload config in case it was modified elsewhere
393
+ const freshConfig = loadConfig();
394
+ freshConfig.migrations = freshConfig.migrations || {};
395
+ freshConfig.migrations.package = packageVersion;
396
+ saveConfig(freshConfig);
393
397
  return { success: true };
394
398
  }
395
399
 
@@ -418,8 +422,10 @@ export function runPackageMigrations(packageVersion: string): {
418
422
  }
419
423
 
420
424
  // All migrations succeeded, update version marker
421
- config.migrations = config.migrations || {};
422
- config.migrations.package = packageVersion;
423
- saveConfig(config);
425
+ // Reload config in case migrations modified it
426
+ const updatedConfig = loadConfig();
427
+ updatedConfig.migrations = updatedConfig.migrations || {};
428
+ updatedConfig.migrations.package = packageVersion;
429
+ saveConfig(updatedConfig);
424
430
  return { success: true };
425
431
  }
package/src/lib/tools.ts CHANGED
@@ -2,12 +2,11 @@ import { existsSync, readdirSync, readFileSync } from 'fs';
2
2
  import { join, dirname } from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  import YAML from 'yaml';
5
- import { loadConfig, saveConfig } from './config';
5
+ import { loadConfig } from './config';
6
6
  import {
7
7
  type ToolManifest,
8
8
  type ToolIncludes,
9
9
  getPlatformTools,
10
- setPlatformTools,
11
10
  } from './types';
12
11
  import { compareSemver } from './version';
13
12
 
@@ -113,20 +112,6 @@ export function getInstalledToolVersion(toolName: string): string | null {
113
112
  if (installedTools[skillName]) {
114
113
  return installedTools[skillName].version;
115
114
  }
116
-
117
- // Migration fallback (v0.18.0): Check for old skill name without droid- prefix
118
- // This allows tools to show as "update available" rather than "not installed"
119
- if (skillName.startsWith('droid-')) {
120
- const oldSkillName = skillName.replace(/^droid-/, '');
121
- if (installedTools[oldSkillName]) {
122
- const version = installedTools[oldSkillName].version;
123
- // Clean up stale config entry now that we've detected it
124
- delete installedTools[oldSkillName];
125
- setPlatformTools(config, installedTools);
126
- saveConfig(config);
127
- return version;
128
- }
129
- }
130
115
  }
131
116
 
132
117
  return null;