@alfe.ai/integrations 0.0.31 → 0.0.32

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/dist/index.d.ts CHANGED
@@ -796,6 +796,16 @@ declare class OpenClawApplier implements RuntimeApplier {
796
796
  * plugins under 2026.5+, which made force-mode skip its uninstall step.
797
797
  */
798
798
  private isPluginInstalled;
799
+ /**
800
+ * Remove an extensions/ install that has no matching record in
801
+ * plugins/installs.json. OpenClaw 2026.5+ tracks installs via the records
802
+ * file — a leftover dir from 2026.4 is invisible to `openclaw plugins
803
+ * uninstall` (it errors with "not managed by plugins config/install
804
+ * records") and its pre-migration manifest blocks the new effective-plugin-
805
+ * set loader from importing it. Resetting the dir makes the next install
806
+ * write through the npm path with a proper tracking record.
807
+ */
808
+ private cleanupUntrackedExtensionInstall;
799
809
  removePlugin(pkg: string): Promise<void>;
800
810
  applySkill(name: string, srcPath: string): Promise<void>;
801
811
  applyClawHubSkill(slug: string): Promise<void>;
package/dist/index.js CHANGED
@@ -1583,6 +1583,7 @@ var OpenClawApplier = class {
1583
1583
  }
1584
1584
  async applyPlugin(pkg, _installPath, opts) {
1585
1585
  await this.ensurePluginsAllow(pkg);
1586
+ this.cleanupUntrackedExtensionInstall(pkg);
1586
1587
  if (opts?.force && this.isPluginInstalled(pkg)) {
1587
1588
  log.info({ pkg }, "Force mode — uninstalling plugin before reinstall");
1588
1589
  try {
@@ -1674,6 +1675,51 @@ var OpenClawApplier = class {
1674
1675
  const prefix = pkg.replaceAll("/", "-") + "-";
1675
1676
  return readdirSync(extensionsDir).some((dir) => dir.startsWith(prefix) && /^[0-9a-f]+$/i.test(dir.slice(prefix.length)));
1676
1677
  }
1678
+ /**
1679
+ * Remove an extensions/ install that has no matching record in
1680
+ * plugins/installs.json. OpenClaw 2026.5+ tracks installs via the records
1681
+ * file — a leftover dir from 2026.4 is invisible to `openclaw plugins
1682
+ * uninstall` (it errors with "not managed by plugins config/install
1683
+ * records") and its pre-migration manifest blocks the new effective-plugin-
1684
+ * set loader from importing it. Resetting the dir makes the next install
1685
+ * write through the npm path with a proper tracking record.
1686
+ */
1687
+ cleanupUntrackedExtensionInstall(pkg) {
1688
+ const installsPath = join(this.home, "plugins", "installs.json");
1689
+ if (!existsSync(installsPath)) return;
1690
+ let tracked = false;
1691
+ try {
1692
+ const raw = readFileSync(installsPath, "utf8");
1693
+ const data = JSON.parse(raw);
1694
+ tracked = Object.prototype.hasOwnProperty.call(data.installRecords ?? {}, pkg);
1695
+ } catch {
1696
+ return;
1697
+ }
1698
+ if (tracked) return;
1699
+ const extensionsDir = join(this.home, "extensions");
1700
+ if (!existsSync(extensionsDir)) return;
1701
+ const prefix = pkg.replaceAll("/", "-") + "-";
1702
+ const stale = readdirSync(extensionsDir).filter((dir) => dir.startsWith(prefix) && /^[0-9a-f]+$/i.test(dir.slice(prefix.length)));
1703
+ for (const dir of stale) {
1704
+ const fullPath = join(extensionsDir, dir);
1705
+ try {
1706
+ rmSync(fullPath, {
1707
+ recursive: true,
1708
+ force: true
1709
+ });
1710
+ log.info({
1711
+ pkg,
1712
+ removed: fullPath
1713
+ }, "Removed untracked extensions/ install — will reinstall via npm path");
1714
+ } catch (err) {
1715
+ log.warn({
1716
+ pkg,
1717
+ removed: fullPath,
1718
+ err: err instanceof Error ? err.message : String(err)
1719
+ }, "Failed to remove untracked extensions/ install");
1720
+ }
1721
+ }
1722
+ }
1677
1723
  async removePlugin(pkg) {
1678
1724
  await execFileAsync("openclaw", [
1679
1725
  "plugins",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/integrations",
3
- "version": "0.0.31",
3
+ "version": "0.0.32",
4
4
  "description": "Integration lifecycle management for Alfe — registry, resolution, installation, and state",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",