@alfe.ai/integrations 0.0.7 → 0.0.8

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
@@ -614,6 +614,12 @@ declare class OpenClawApplier implements RuntimeApplier {
614
614
  private configPath;
615
615
  constructor(options: OpenClawApplierOptions);
616
616
  applyPlugin(pkg: string): Promise<void>;
617
+ /**
618
+ * Ensure the plugin is in plugins.allow in openclaw.json.
619
+ * When we skip `openclaw plugins install` (because the plugin dir exists),
620
+ * the allowlist may not include the plugin — add it if missing.
621
+ */
622
+ private ensurePluginsAllow;
617
623
  /**
618
624
  * Check if a plugin is already installed in ~/.openclaw/extensions/.
619
625
  * OpenClaw names extension dirs as {pkg-name-with-dashes}-{hash}.
package/dist/index.js CHANGED
@@ -662,6 +662,21 @@ async function runHookWithContext(integrationPath, hookScript, options) {
662
662
  * plugins/skills to runtimes. deactivate() removes them.
663
663
  */
664
664
  /**
665
+ * Deep-walk an object and replace `{{config.KEY}}` patterns with values
666
+ * from the per-agent config. Used to compose manifest runtime config
667
+ * with per-agent secrets (e.g., gateway token).
668
+ */
669
+ function interpolateSelfConfig(obj, config) {
670
+ const result = {};
671
+ for (const [key, value] of Object.entries(obj)) if (typeof value === "string") result[key] = value.replace(/\{\{config\.([a-zA-Z0-9_]+)\}\}/g, (_match, configKey) => {
672
+ const val = config[configKey];
673
+ return typeof val === "string" || typeof val === "number" ? String(val) : _match;
674
+ });
675
+ else if (value && typeof value === "object" && !Array.isArray(value)) result[key] = interpolateSelfConfig(value, config);
676
+ else result[key] = value;
677
+ return result;
678
+ }
679
+ /**
665
680
  * Merge universal installs with runtime-specific installs from the manifest.
666
681
  */
667
682
  function resolveInstallsForRuntime(manifest, runtime) {
@@ -871,8 +886,10 @@ var IntegrationManager = class {
871
886
  await applier.applySkill(skillName, srcPath);
872
887
  }
873
888
  if (runtimeConfig && Object.keys(runtimeConfig).length > 0) {
889
+ const agentConfig = entry.config;
890
+ const interpolatedConfig = interpolateSelfConfig(runtimeConfig, agentConfig);
874
891
  this.log.info(`Applying config for ${integrationId} to ${runtimeName}`);
875
- await applier.applyConfig(integrationId, runtimeConfig);
892
+ await applier.applyConfig(integrationId, interpolatedConfig);
876
893
  }
877
894
  if (plugins.length > 0 || skills.length > 0) this.lockManager.addEntries(runtimeName, integrationId, manifest.version, plugins, skills, installPath);
878
895
  }
@@ -1193,7 +1210,10 @@ var OpenClawApplier = class {
1193
1210
  this.configPath = options.configPath ?? join(this.workspace, "config.json");
1194
1211
  }
1195
1212
  async applyPlugin(pkg) {
1196
- if (this.isPluginInstalled(pkg)) return;
1213
+ if (this.isPluginInstalled(pkg)) {
1214
+ this.ensurePluginsAllow(pkg);
1215
+ return;
1216
+ }
1197
1217
  await execFileAsync("openclaw", [
1198
1218
  "plugins",
1199
1219
  "install",
@@ -1201,13 +1221,33 @@ var OpenClawApplier = class {
1201
1221
  ], { timeout: 6e4 });
1202
1222
  }
1203
1223
  /**
1224
+ * Ensure the plugin is in plugins.allow in openclaw.json.
1225
+ * When we skip `openclaw plugins install` (because the plugin dir exists),
1226
+ * the allowlist may not include the plugin — add it if missing.
1227
+ */
1228
+ ensurePluginsAllow(pkg) {
1229
+ const configPath = join(homedir(), ".openclaw", "openclaw.json");
1230
+ if (!existsSync(configPath)) return;
1231
+ try {
1232
+ const raw = readFileSync(configPath, "utf-8");
1233
+ const config = JSON.parse(raw);
1234
+ const plugins = config.plugins ?? {};
1235
+ const allow = plugins.allow ?? [];
1236
+ if (!allow.includes(pkg)) {
1237
+ plugins.allow = [...allow, pkg];
1238
+ config.plugins = plugins;
1239
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1240
+ }
1241
+ } catch {}
1242
+ }
1243
+ /**
1204
1244
  * Check if a plugin is already installed in ~/.openclaw/extensions/.
1205
1245
  * OpenClaw names extension dirs as {pkg-name-with-dashes}-{hash}.
1206
1246
  */
1207
1247
  isPluginInstalled(pkg) {
1208
1248
  const extensionsDir = join(homedir(), ".openclaw", "extensions");
1209
1249
  if (!existsSync(extensionsDir)) return false;
1210
- const prefix = pkg.replaceAll("/", "-").replaceAll("@", "");
1250
+ const prefix = pkg.replaceAll("/", "-");
1211
1251
  return readdirSync(extensionsDir).some((dir) => dir.startsWith(prefix));
1212
1252
  }
1213
1253
  async removePlugin(pkg) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/integrations",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Integration lifecycle management for Alfe — registry, resolution, installation, and state",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",