@alfe.ai/integrations 0.0.16 → 0.0.18

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
@@ -28,10 +28,11 @@ interface RegistryEntry {
28
28
  } | string;
29
29
  /** Pricing details */
30
30
  pricing?: {
31
- type: "free" | "paid";
31
+ type: "free" | "paid" | "usage";
32
32
  price?: number;
33
33
  currency?: string;
34
34
  interval?: "month" | "year";
35
+ description?: string;
35
36
  };
36
37
  /** Feature list for marketplace display */
37
38
  features?: string[];
@@ -261,7 +262,9 @@ interface CommandDeclaration {
261
262
  }
262
263
  interface SkillInstall {
263
264
  /** Relative path within the integration repo to the skill directory */
264
- path: string;
265
+ path?: string;
266
+ /** ClawHub skill slug to install from the registry */
267
+ clawhub?: string;
265
268
  }
266
269
  interface PluginInstall {
267
270
  /** npm package name to install */
@@ -297,11 +300,13 @@ interface IntegrationPricingPlan {
297
300
  interval?: 'month' | 'year';
298
301
  }
299
302
  interface IntegrationPricing {
300
- type: 'free' | 'paid';
303
+ type: 'free' | 'paid' | 'usage';
301
304
  /** Single price (shorthand for integrations with one plan) */
302
305
  price?: number;
303
306
  currency?: string;
304
307
  interval?: 'month' | 'year';
308
+ /** Description of usage-based pricing (for type: 'usage') */
309
+ description?: string;
305
310
  /** Multiple plans/tiers (e.g., starter, growth, scale) */
306
311
  plans?: Record<string, IntegrationPricingPlan>;
307
312
  }
@@ -332,6 +337,12 @@ interface IntegrationManifest {
332
337
  * Example: ['openclaw'] means this integration only works with OpenClaw.
333
338
  */
334
339
  supported_agents?: AgentRuntime[];
340
+ /**
341
+ * Scopes where this integration can be installed.
342
+ * Default: ['agent'] (per-agent only).
343
+ * 'org' means it can be installed at the org level and cascades to all agents.
344
+ */
345
+ supported_scopes?: ('agent' | 'org')[];
335
346
  /** Marketplace metadata */
336
347
  publisherId?: string;
337
348
  icon?: string;
@@ -367,6 +378,8 @@ interface RuntimeApplier {
367
378
  removePlugin(pkg: string): Promise<void>;
368
379
  /** Copy a skill directory into this runtime's skills location */
369
380
  applySkill(name: string, srcPath: string): Promise<void>;
381
+ /** Install a skill from ClawHub registry */
382
+ applyClawHubSkill(slug: string): Promise<void>;
370
383
  /** Remove a skill directory from this runtime */
371
384
  removeSkill(name: string): Promise<void>;
372
385
  /** Deep-merge config into the runtime's agent configuration */
@@ -701,6 +714,7 @@ declare class OpenClawApplier implements RuntimeApplier {
701
714
  private isPluginInstalled;
702
715
  removePlugin(pkg: string): Promise<void>;
703
716
  applySkill(name: string, srcPath: string): Promise<void>;
717
+ applyClawHubSkill(slug: string): Promise<void>;
704
718
  removeSkill(name: string): Promise<void>;
705
719
  /**
706
720
  * Apply integration config to the OpenClaw runtime via `openclaw config set`.
package/dist/index.js CHANGED
@@ -549,10 +549,11 @@ var LockManager = class {
549
549
  integrationVersion: version
550
550
  });
551
551
  for (const skill of skills) {
552
- const name = skill.path.split("/").pop() ?? skill.path;
552
+ const name = skill.clawhub ?? skill.path?.split("/").pop() ?? "unknown";
553
+ const sourcePath = skill.path ? join(installPath, skill.path) : `clawhub:${skill.clawhub ?? ""}`;
553
554
  if (!state.skills.some((s) => s.name === name && s.sourceIntegration === integrationId)) state.skills.push({
554
555
  name,
555
- sourcePath: join(installPath, skill.path),
556
+ sourcePath,
556
557
  sourceIntegration: integrationId,
557
558
  integrationVersion: version
558
559
  });
@@ -1009,7 +1010,10 @@ var IntegrationManager = class {
1009
1010
  this.log.info(`Applying plugin ${plugin.package} to ${runtimeName}`);
1010
1011
  await applier.applyPlugin(plugin.package, installPath);
1011
1012
  }
1012
- for (const skill of skills) {
1013
+ for (const skill of skills) if (skill.clawhub) {
1014
+ this.log.info(`Installing ClawHub skill ${skill.clawhub} to ${runtimeName}`);
1015
+ await applier.applyClawHubSkill(skill.clawhub);
1016
+ } else if (skill.path) {
1013
1017
  const skillName = skill.path.split("/").pop() ?? skill.path;
1014
1018
  const srcPath = join(installPath, skill.path);
1015
1019
  this.log.info(`Applying skill ${skillName} to ${runtimeName}`);
@@ -1494,6 +1498,19 @@ var OpenClawApplier = class {
1494
1498
  cpSync(srcPath, join(this.skillsDir, name), { recursive: true });
1495
1499
  return Promise.resolve();
1496
1500
  }
1501
+ async applyClawHubSkill(slug) {
1502
+ log.info({ slug }, "Installing skill from ClawHub");
1503
+ try {
1504
+ await execFileAsync("clawhub", ["install", slug], { timeout: 6e4 });
1505
+ log.info({ slug }, "ClawHub skill installed");
1506
+ } catch (err) {
1507
+ const msg = err instanceof Error ? err.message : String(err);
1508
+ log.warn({
1509
+ slug,
1510
+ err: msg
1511
+ }, "ClawHub skill install failed — clawhub CLI may not be available");
1512
+ }
1513
+ }
1497
1514
  removeSkill(name) {
1498
1515
  const skillPath = join(this.skillsDir, name);
1499
1516
  if (existsSync(skillPath)) rmSync(skillPath, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/integrations",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "description": "Integration lifecycle management for Alfe — registry, resolution, installation, and state",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@auriclabs/logger": "^0.1.1",
16
- "@alfe.ai/integration-manifest": "^0.0.6"
16
+ "@alfe.ai/integration-manifest": "^0.0.8"
17
17
  },
18
18
  "files": [
19
19
  "dist"