@alfe.ai/integrations 0.0.26 → 0.0.27

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
@@ -193,6 +193,11 @@ declare class Installer {
193
193
  * Node module resolution from hook scripts (e.g.
194
194
  * ~/.alfe/integrations/console/hooks/post_install.js) walks up to
195
195
  * ~/.alfe/integrations/node_modules/ and finds these packages.
196
+ *
197
+ * Uses `"latest"` versions — npm install is always run when node_modules
198
+ * exists to pick up newer published versions (e.g. new API client methods).
199
+ * The in-memory `sharedPackagesReady` flag prevents redundant installs
200
+ * within a single daemon process lifetime.
196
201
  */
197
202
  private ensureSharedPackages;
198
203
  /**
@@ -389,7 +394,9 @@ interface RuntimeApplier {
389
394
  /** The runtime identifier (e.g. 'openclaw', 'nanoclaw') */
390
395
  readonly runtime: string;
391
396
  /** Install a plugin package into this runtime */
392
- applyPlugin(pkg: string, integrationInstallPath: string): Promise<void>;
397
+ applyPlugin(pkg: string, integrationInstallPath: string, opts?: {
398
+ force?: boolean;
399
+ }): Promise<void>;
393
400
  /** Remove a plugin package from this runtime */
394
401
  removePlugin(pkg: string): Promise<void>;
395
402
  /** Copy a skill directory into this runtime's skills location */
@@ -517,7 +524,9 @@ declare class IntegrationManager {
517
524
  * 4. Run health_check hook if present
518
525
  * 5. Mark as active in state
519
526
  */
520
- activate(integrationId: string): Promise<ManagerResponse>;
527
+ activate(integrationId: string, opts?: {
528
+ forcePlugins?: boolean;
529
+ }): Promise<ManagerResponse>;
521
530
  /**
522
531
  * Deactivate a running integration.
523
532
  *
@@ -728,7 +737,9 @@ declare class OpenClawApplier implements RuntimeApplier {
728
737
  private skillsDir;
729
738
  private trackingPath;
730
739
  constructor(options: OpenClawApplierOptions);
731
- applyPlugin(pkg: string): Promise<void>;
740
+ applyPlugin(pkg: string, _installPath?: string, opts?: {
741
+ force?: boolean;
742
+ }): Promise<void>;
732
743
  /**
733
744
  * Ensure the plugin is in plugins.allow in openclaw.json.
734
745
  * Uses `openclaw config set` to avoid clobbering OpenClaw's own file format.
package/dist/index.js CHANGED
@@ -276,24 +276,15 @@ var Installer = class {
276
276
  * Node module resolution from hook scripts (e.g.
277
277
  * ~/.alfe/integrations/console/hooks/post_install.js) walks up to
278
278
  * ~/.alfe/integrations/node_modules/ and finds these packages.
279
+ *
280
+ * Uses `"latest"` versions — npm install is always run when node_modules
281
+ * exists to pick up newer published versions (e.g. new API client methods).
282
+ * The in-memory `sharedPackagesReady` flag prevents redundant installs
283
+ * within a single daemon process lifetime.
279
284
  */
280
285
  async ensureSharedPackages() {
281
286
  if (this.sharedPackagesReady) return;
282
287
  const pkgJsonPath = join(this.basePath, "package.json");
283
- const nodeModulesExists = existsSync(join(this.basePath, "node_modules"));
284
- let needsInstall = false;
285
- if (existsSync(pkgJsonPath)) try {
286
- const deps = JSON.parse(readFileSync(pkgJsonPath, "utf-8")).dependencies ?? {};
287
- needsInstall = Object.keys(SHARED_PACKAGES).some((pkg) => !(pkg in deps));
288
- } catch {
289
- needsInstall = true;
290
- }
291
- else needsInstall = true;
292
- if (!needsInstall && !nodeModulesExists) needsInstall = true;
293
- if (!needsInstall) {
294
- this.sharedPackagesReady = true;
295
- return;
296
- }
297
288
  const pkgJson = {
298
289
  name: "alfe-integrations-root",
299
290
  private: true,
@@ -1016,7 +1007,7 @@ var IntegrationManager = class {
1016
1007
  * 4. Run health_check hook if present
1017
1008
  * 5. Mark as active in state
1018
1009
  */
1019
- async activate(integrationId) {
1010
+ async activate(integrationId, opts) {
1020
1011
  const entry = this.state.get(integrationId);
1021
1012
  if (!entry) return this.err("NOT_FOUND", `Integration "${integrationId}" is not installed`);
1022
1013
  if (entry.status === "active") return {
@@ -1052,7 +1043,7 @@ var IntegrationManager = class {
1052
1043
  const { plugins, skills, config: runtimeConfig } = resolveInstallsForRuntime(manifest, runtimeName);
1053
1044
  for (const plugin of plugins) {
1054
1045
  this.log.info(`Applying plugin ${plugin.package} to ${runtimeName}`);
1055
- await applier.applyPlugin(plugin.package, installPath);
1046
+ await applier.applyPlugin(plugin.package, installPath, { force: opts?.forcePlugins });
1056
1047
  }
1057
1048
  for (const skill of skills) if (skill.clawhub) {
1058
1049
  this.log.info(`Installing ClawHub skill ${skill.clawhub} to ${runtimeName}`);
@@ -1122,6 +1113,7 @@ var IntegrationManager = class {
1122
1113
  } catch (err) {
1123
1114
  const message = err instanceof Error ? err.message : String(err);
1124
1115
  this.log.error(`Failed to activate "${integrationId}": ${message}`);
1116
+ this.state.setStatus(integrationId, "error", message);
1125
1117
  return this.err("ACTIVATE_FAILED", message);
1126
1118
  }
1127
1119
  }
@@ -1290,7 +1282,7 @@ var IntegrationManager = class {
1290
1282
  if (!uninstallResult.ok) this.log.warn(`Uninstall returned error during reinstall: ${String(uninstallResult.error?.message)} — proceeding with install`);
1291
1283
  const installResult = await this.install(params);
1292
1284
  if (!installResult.ok) return installResult;
1293
- return await this.activate(name);
1285
+ return await this.activate(name, { forcePlugins: true });
1294
1286
  } catch (err) {
1295
1287
  const message = err instanceof Error ? err.message : String(err);
1296
1288
  this.log.error(`Failed to reinstall "${name}": ${message}`);
@@ -1494,8 +1486,19 @@ var OpenClawApplier = class {
1494
1486
  this.skillsDir = options.skillsDir ?? DEFAULT_SKILLS_DIR;
1495
1487
  this.trackingPath = options.configPath ?? join(this.workspace, "config.json");
1496
1488
  }
1497
- async applyPlugin(pkg) {
1489
+ async applyPlugin(pkg, _installPath, opts) {
1498
1490
  await this.ensurePluginsAllow(pkg);
1491
+ if (opts?.force && this.isPluginInstalled(pkg)) {
1492
+ log.info({ pkg }, "Force mode — uninstalling plugin before reinstall");
1493
+ try {
1494
+ await this.removePlugin(pkg);
1495
+ } catch (err) {
1496
+ log.warn({
1497
+ pkg,
1498
+ err: err instanceof Error ? err.message : String(err)
1499
+ }, "Failed to uninstall plugin during force reinstall — proceeding");
1500
+ }
1501
+ }
1499
1502
  if (!this.isPluginInstalled(pkg)) {
1500
1503
  try {
1501
1504
  const args = [
@@ -1555,8 +1558,7 @@ var OpenClawApplier = class {
1555
1558
  "config",
1556
1559
  "set",
1557
1560
  "plugins.allow",
1558
- JSON.stringify(updated),
1559
- "--strict-json"
1561
+ JSON.stringify(updated)
1560
1562
  ], { timeout: 1e4 });
1561
1563
  } catch (err) {
1562
1564
  log.warn({
@@ -1600,6 +1602,10 @@ var OpenClawApplier = class {
1600
1602
  log.info({ slug }, "ClawHub skill installed");
1601
1603
  } catch (err) {
1602
1604
  const msg = err instanceof Error ? err.message : String(err);
1605
+ if (msg.includes("already exists") || msg.includes("Skill already exists")) {
1606
+ log.info({ slug }, "ClawHub skill already installed (skipped)");
1607
+ return;
1608
+ }
1603
1609
  log.error({
1604
1610
  slug,
1605
1611
  err: msg
@@ -1646,8 +1652,7 @@ var OpenClawApplier = class {
1646
1652
  "config",
1647
1653
  "set",
1648
1654
  "--batch-json",
1649
- JSON.stringify(batch),
1650
- "--strict-json"
1655
+ JSON.stringify(batch)
1651
1656
  ], { timeout: 1e4 });
1652
1657
  } catch (err) {
1653
1658
  log.error({
@@ -1719,8 +1724,7 @@ var OpenClawApplier = class {
1719
1724
  "config",
1720
1725
  "set",
1721
1726
  "--batch-json",
1722
- JSON.stringify(batch),
1723
- "--strict-json"
1727
+ JSON.stringify(batch)
1724
1728
  ], { timeout: 1e4 });
1725
1729
  } catch (err) {
1726
1730
  log.error({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/integrations",
3
- "version": "0.0.26",
3
+ "version": "0.0.27",
4
4
  "description": "Integration lifecycle management for Alfe — registry, resolution, installation, and state",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",