@alfe.ai/integrations 0.0.22 → 0.0.23

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
@@ -535,6 +535,11 @@ declare class IntegrationManager {
535
535
  * List all installed integrations.
536
536
  */
537
537
  list(): IntegrationInfo[];
538
+ /**
539
+ * Check if an integration's install directory and manifest file exist on disk.
540
+ * Returns false if the state says installed but files are missing (corrupted install).
541
+ */
542
+ isInstallIntact(integrationId: string): boolean;
538
543
  /**
539
544
  * Get a specific integration by name.
540
545
  */
@@ -815,6 +820,8 @@ interface IIntegrationManager {
815
820
  reinstall(integrationId: string, version: string, config: unknown): Promise<{
816
821
  configApplied: boolean;
817
822
  }>;
823
+ /** Check if an integration's install directory and manifest are intact on disk */
824
+ isInstallIntact(integrationId: string): Promise<boolean>;
818
825
  }
819
826
  declare class IntegrationManagerAdapter implements IIntegrationManager {
820
827
  private readonly manager;
@@ -834,6 +841,7 @@ declare class IntegrationManagerAdapter implements IIntegrationManager {
834
841
  reinstall(integrationId: string, version: string, config: unknown): Promise<{
835
842
  configApplied: boolean;
836
843
  }>;
844
+ isInstallIntact(integrationId: string): Promise<boolean>;
837
845
  }
838
846
  //#endregion
839
847
  export { type HookEnvOptions, type HookResult, type IIntegrationManager, type InstalledInfo, Installer, InstallerError, type IntegrationConfigureParams, type IntegrationHealthParams, type IntegrationInfo, type IntegrationInstallParams, IntegrationManager, IntegrationManagerAdapter, type IntegrationManagerOptions, type IntegrationRemoveParams, LockManager, OpenClawApplier, type OpenClawApplierOptions, Registry, type RegistryEntry, type RegistryFetcher, type RegistryIndex, RegistryResolveError, type ResolvedIntegration, Resolver, type RuntimeApplier, type RuntimeDesiredState, type RuntimeLockFile, type RuntimePluginEntry, type RuntimeSkillEntry, StateManager, buildHookEnv, resolveInstallsForRuntime, runHook, runHookWithContext };
package/dist/index.js CHANGED
@@ -855,7 +855,21 @@ var IntegrationManager = class {
855
855
  const { name, version, config } = params;
856
856
  if (!name) return this.err("INVALID_PARAMS", "Integration name is required");
857
857
  const existing = this.state.get(name);
858
- if (existing && existing.status !== "error") return this.err("ALREADY_INSTALLED", `Integration "${name}" is already installed (status: ${existing.status})`);
858
+ if (existing) {
859
+ if (existing.status === "installed" || existing.status === "configured" || existing.status === "active") {
860
+ this.log.info(`Integration "${name}" already installed (status: ${existing.status}) — skipping`);
861
+ return {
862
+ ok: true,
863
+ payload: {
864
+ id: name,
865
+ version: existing.version,
866
+ status: existing.status,
867
+ alreadyInstalled: true
868
+ }
869
+ };
870
+ }
871
+ if (existing.status === "installing") return this.err("ALREADY_INSTALLING", `Integration "${name}" is currently being installed`);
872
+ }
859
873
  this.log.info(`Installing integration: ${name}${version ? `@${version}` : ""}`);
860
874
  this.state.set(name, {
861
875
  status: "installing",
@@ -993,7 +1007,11 @@ var IntegrationManager = class {
993
1007
  try {
994
1008
  const installPath = this.installer.getInstallPath(integrationId);
995
1009
  const manifestPath = join(installPath, "alfe-integration.yaml");
996
- if (!existsSync(manifestPath)) return this.err("MANIFEST_MISSING", `Manifest not found at ${manifestPath}`);
1010
+ if (!existsSync(manifestPath)) {
1011
+ const errorMsg = `Manifest not found at ${manifestPath}`;
1012
+ this.state.setStatus(integrationId, "error", errorMsg);
1013
+ return this.err("MANIFEST_MISSING", errorMsg);
1014
+ }
997
1015
  const manifest = parseManifestFile(manifestPath);
998
1016
  let configApplied = false;
999
1017
  const supportedAgents = manifest.supported_agents;
@@ -1272,6 +1290,13 @@ var IntegrationManager = class {
1272
1290
  }));
1273
1291
  }
1274
1292
  /**
1293
+ * Check if an integration's install directory and manifest file exist on disk.
1294
+ * Returns false if the state says installed but files are missing (corrupted install).
1295
+ */
1296
+ isInstallIntact(integrationId) {
1297
+ return existsSync(join(this.installer.getInstallPath(integrationId), "alfe-integration.yaml"));
1298
+ }
1299
+ /**
1275
1300
  * Get a specific integration by name.
1276
1301
  */
1277
1302
  get(name) {
@@ -1660,6 +1685,9 @@ var IntegrationManagerAdapter = class {
1660
1685
  if (!result.ok) throw new Error(result.error?.message ?? `Failed to reinstall ${integrationId}`);
1661
1686
  return { configApplied: result.payload?.configApplied ?? false };
1662
1687
  }
1688
+ isInstallIntact(integrationId) {
1689
+ return Promise.resolve(this.manager.isInstallIntact(integrationId));
1690
+ }
1663
1691
  };
1664
1692
  //#endregion
1665
1693
  export { Installer, InstallerError, IntegrationManager, IntegrationManagerAdapter, LockManager, OpenClawApplier, Registry, RegistryResolveError, Resolver, StateManager, buildHookEnv, resolveInstallsForRuntime, runHook, runHookWithContext };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/integrations",
3
- "version": "0.0.22",
3
+ "version": "0.0.23",
4
4
  "description": "Integration lifecycle management for Alfe — registry, resolution, installation, and state",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",