@alfe.ai/integration-manifest 0.0.11 → 0.2.0
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/README.md +40 -0
- package/dist/index.d.ts +377 -200
- package/dist/index.js +113 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -61,6 +61,46 @@ hooks:
|
|
|
61
61
|
|
|
62
62
|
Only `id`, `name`, `version`, `description`, and `author` are required — everything else has sensible defaults.
|
|
63
63
|
|
|
64
|
+
## Custom Connections — `expected_credentials`
|
|
65
|
+
|
|
66
|
+
For manifests consumed by [Custom Connections](../../services/connect/DEVELOPING.md#custom-connections-pr-8a-of-channels-and-credential-driven-integrations) (`requires_connection: ["custom"]`), the manifest declares the credential fields it needs the tenant operator to fill in via an `expected_credentials` block:
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
requires_connection: ["custom"]
|
|
70
|
+
expected_credentials:
|
|
71
|
+
- key: api_key
|
|
72
|
+
type: secret
|
|
73
|
+
label: "API Key"
|
|
74
|
+
description: "From the upstream dashboard"
|
|
75
|
+
required: true
|
|
76
|
+
- key: base_url
|
|
77
|
+
type: url
|
|
78
|
+
label: "Base URL"
|
|
79
|
+
placeholder: "https://api.example.com"
|
|
80
|
+
required: false
|
|
81
|
+
- key: workspace_id
|
|
82
|
+
type: string
|
|
83
|
+
label: "Workspace ID"
|
|
84
|
+
pattern: "^[a-zA-Z0-9_-]+$"
|
|
85
|
+
required: true
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Supported field `type`s — same vocabulary as the dashboard form renderer:
|
|
89
|
+
|
|
90
|
+
| Type | Stored as | Notes |
|
|
91
|
+
|-----------|------------------------------------|-----------------------------------------|
|
|
92
|
+
| `secret` | KMS-encrypted (`encryptedAccessToken`) | Joined into a JSON bundle by services/connect at write time |
|
|
93
|
+
| `string` | `providerMetadata.{key}` | Plain string |
|
|
94
|
+
| `url` | `providerMetadata.{key}` | Plain string; URL validation client-side |
|
|
95
|
+
| `number` | `providerMetadata.{key}` | Stored as JS number |
|
|
96
|
+
| `boolean` | `providerMetadata.{key}` | Stored as JS boolean |
|
|
97
|
+
|
|
98
|
+
When adding a new credential field type:
|
|
99
|
+
|
|
100
|
+
1. Extend `CredentialFieldTypeSchema` in `src/schema.ts`.
|
|
101
|
+
2. Extend `CredentialFieldType` consumers — the dashboard form renderer in PR 8b and the storage projection in `services/connect/src/providers/custom.ts`'s `buildCredentialsResponse` (if the storage shape differs).
|
|
102
|
+
3. Document the new type here.
|
|
103
|
+
|
|
64
104
|
## Usage
|
|
65
105
|
|
|
66
106
|
```typescript
|
package/dist/index.d.ts
CHANGED
|
@@ -1,208 +1,54 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
|
-
//#region src/
|
|
3
|
+
//#region src/schema.d.ts
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Connect provider ids that a manifest's `requires_connection` field may
|
|
7
|
+
* reference. The source of truth lives in `services/connect/src/providers/`
|
|
8
|
+
* (one `ProviderDefinition` per id) — this list mirrors that registry so
|
|
9
|
+
* the manifest schema can validate references statically.
|
|
7
10
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
11
|
+
* **Keep in sync** with `services/connect/src/providers/index.ts`. Adding a
|
|
12
|
+
* new connect provider requires updating both: add the provider definition
|
|
13
|
+
* there, then add its id here so manifests can declare `requires_connection`
|
|
14
|
+
* against it. Drift in the other direction (id here without provider) is
|
|
15
|
+
* caught at runtime when the integrations service tries to resolve the
|
|
16
|
+
* provider and gets nothing back.
|
|
10
17
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
command: string;
|
|
46
|
-
/** Arguments for the command */
|
|
47
|
-
args?: string[];
|
|
48
|
-
/** Environment variables — supports {{config.KEY}} interpolation from config + secrets */
|
|
49
|
-
env?: Record<string, string>;
|
|
50
|
-
/** Working directory (optional) */
|
|
51
|
-
cwd?: string;
|
|
52
|
-
/** If true, applier skips auto-application — a lifecycle hook manages this MCP server instead */
|
|
53
|
-
hook_managed?: boolean;
|
|
54
|
-
}
|
|
55
|
-
interface CommandDeclaration {
|
|
56
|
-
/** Dot-namespaced command name (e.g. "support.diagnostic") */
|
|
57
|
-
name: string;
|
|
58
|
-
/** Relative path to handler file within integration directory */
|
|
59
|
-
handler: string;
|
|
60
|
-
/** Exported function name (default: "handle") */
|
|
61
|
-
method?: string;
|
|
62
|
-
/** Timeout in milliseconds (default: 30000) */
|
|
63
|
-
timeout_ms?: number;
|
|
64
|
-
/** Human-readable description */
|
|
65
|
-
description?: string;
|
|
66
|
-
}
|
|
67
|
-
interface SkillInstall {
|
|
68
|
-
/** Relative path within the integration repo to the skill directory */
|
|
69
|
-
path?: string;
|
|
70
|
-
/** ClawHub skill slug to install from the registry */
|
|
71
|
-
clawhub?: string;
|
|
72
|
-
}
|
|
73
|
-
interface PluginInstall {
|
|
74
|
-
/** npm package name to install */
|
|
75
|
-
package: string;
|
|
76
|
-
}
|
|
77
|
-
type AgentRuntime = 'openclaw' | 'nanoclaw' | (string & {});
|
|
78
|
-
interface RuntimeInstall {
|
|
79
|
-
plugins?: PluginInstall[];
|
|
80
|
-
skills?: SkillInstall[];
|
|
81
|
-
/** Deep-merged into the runtime's agent config on activation */
|
|
82
|
-
config?: Record<string, unknown>;
|
|
83
|
-
}
|
|
84
|
-
interface InstallTargets {
|
|
85
|
-
/** Universal skills — applied to all runtimes */
|
|
86
|
-
skills?: SkillInstall[];
|
|
87
|
-
/** Universal plugins — applied to all runtimes */
|
|
88
|
-
plugins?: PluginInstall[];
|
|
89
|
-
/** Per-runtime installs */
|
|
90
|
-
runtimes?: Record<AgentRuntime, RuntimeInstall>;
|
|
91
|
-
}
|
|
92
|
-
interface IntegrationHooks {
|
|
93
|
-
pre_install?: string;
|
|
94
|
-
post_install?: string;
|
|
95
|
-
post_activate?: string;
|
|
96
|
-
pre_uninstall?: string;
|
|
97
|
-
post_uninstall?: string;
|
|
98
|
-
health_check?: string;
|
|
99
|
-
}
|
|
100
|
-
interface IntegrationPricingPlan {
|
|
101
|
-
name: string;
|
|
102
|
-
price: number;
|
|
103
|
-
currency?: string;
|
|
104
|
-
interval?: 'month' | 'year';
|
|
105
|
-
}
|
|
106
|
-
interface IntegrationPricing {
|
|
107
|
-
type: 'free' | 'paid' | 'usage';
|
|
108
|
-
/** Single price (shorthand for integrations with one plan) */
|
|
109
|
-
price?: number;
|
|
110
|
-
currency?: string;
|
|
111
|
-
interval?: 'month' | 'year';
|
|
112
|
-
/** Description of usage-based pricing (for type: 'usage') */
|
|
113
|
-
description?: string;
|
|
114
|
-
/** Multiple plans/tiers (e.g., starter, growth, scale) */
|
|
115
|
-
plans?: Record<string, IntegrationPricingPlan>;
|
|
116
|
-
}
|
|
117
|
-
interface IntegrationAuthor {
|
|
118
|
-
name: string;
|
|
119
|
-
url?: string;
|
|
120
|
-
}
|
|
121
|
-
interface IntegrationManifest {
|
|
122
|
-
id: string;
|
|
123
|
-
name: string;
|
|
124
|
-
version: string;
|
|
125
|
-
description: string;
|
|
126
|
-
/** Simple author string (legacy) or structured author object */
|
|
127
|
-
author: string | IntegrationAuthor;
|
|
128
|
-
license: string;
|
|
129
|
-
depends_on: string[];
|
|
130
|
-
min_gateway_version: string;
|
|
131
|
-
installs: InstallTargets;
|
|
132
|
-
config_schema: ConfigSchemaField[];
|
|
133
|
-
capabilities: string[];
|
|
134
|
-
hooks: IntegrationHooks;
|
|
135
|
-
commands: CommandDeclaration[];
|
|
136
|
-
/** MCP servers to configure in the agent runtime */
|
|
137
|
-
mcp_servers: McpServerDeclaration[];
|
|
138
|
-
/** Git repository URL (HTTPS) — not present in YAML, injected by the publish API */
|
|
139
|
-
repository?: string;
|
|
140
|
-
/**
|
|
141
|
-
* Agent runtimes this integration supports.
|
|
142
|
-
* If omitted or empty, the integration is considered universal (all runtimes).
|
|
143
|
-
* Example: ['openclaw'] means this integration only works with OpenClaw.
|
|
144
|
-
*/
|
|
145
|
-
supported_agents?: AgentRuntime[];
|
|
146
|
-
/**
|
|
147
|
-
* Scopes where this integration can be installed.
|
|
148
|
-
* Default: ['agent'] (per-agent only).
|
|
149
|
-
* 'org' means it can be installed at the org level and cascades to all agents.
|
|
150
|
-
*/
|
|
151
|
-
supported_scopes?: ('agent' | 'org')[];
|
|
152
|
-
/** Marketplace metadata */
|
|
153
|
-
publisherId?: string;
|
|
154
|
-
icon?: string;
|
|
155
|
-
pricing?: IntegrationPricing;
|
|
156
|
-
preview_images?: string[];
|
|
157
|
-
/** Long-form features list for the detail view */
|
|
158
|
-
features?: string[];
|
|
159
|
-
}
|
|
160
|
-
interface PublishedVersion {
|
|
161
|
-
version: string;
|
|
162
|
-
commit_hash: string;
|
|
163
|
-
changelog?: string;
|
|
164
|
-
published_at: string;
|
|
165
|
-
}
|
|
166
|
-
interface PublishedIntegration {
|
|
167
|
-
manifest: IntegrationManifest;
|
|
168
|
-
versions: PublishedVersion[];
|
|
169
|
-
/** Resolved asset URLs baked at publish time */
|
|
170
|
-
resolved_assets: {
|
|
171
|
-
icon?: string;
|
|
172
|
-
preview_images?: string[];
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
type IntegrationStatus = 'installing' | 'installed' | 'configured' | 'active' | 'error';
|
|
176
|
-
interface IntegrationStateEntry {
|
|
177
|
-
status: IntegrationStatus;
|
|
178
|
-
version: string;
|
|
179
|
-
installedAt: string;
|
|
180
|
-
config: Record<string, unknown>;
|
|
181
|
-
error?: string;
|
|
182
|
-
/** Number of consecutive auto-reinstall attempts. Reset on success or explicit reinstall. */
|
|
183
|
-
reinstallAttempts?: number;
|
|
184
|
-
}
|
|
185
|
-
interface IntegrationsStateFile {
|
|
186
|
-
version: number;
|
|
187
|
-
integrations: Record<string, IntegrationStateEntry>;
|
|
188
|
-
}
|
|
189
|
-
interface HealthCheckResult {
|
|
190
|
-
id: string;
|
|
191
|
-
name?: string;
|
|
192
|
-
healthy: boolean;
|
|
193
|
-
status: IntegrationStatus;
|
|
194
|
-
version?: string;
|
|
195
|
-
message?: string;
|
|
196
|
-
stdout?: string;
|
|
197
|
-
stderr?: string;
|
|
198
|
-
}
|
|
199
|
-
interface HealthReport {
|
|
200
|
-
overall: boolean;
|
|
201
|
-
results: HealthCheckResult[];
|
|
202
|
-
checkedAt: string;
|
|
203
|
-
}
|
|
204
|
-
//#endregion
|
|
205
|
-
//#region src/schema.d.ts
|
|
18
|
+
declare const KNOWN_CONNECT_PROVIDER_IDS: readonly ["atlassian", "custom", "discord", "github", "google", "microsoft", "mobile", "myob", "notion", "slack", "xero"];
|
|
19
|
+
type KnownConnectProviderId = (typeof KNOWN_CONNECT_PROVIDER_IDS)[number];
|
|
20
|
+
/**
|
|
21
|
+
* `custom` is a special provider id: it doesn't correspond to a fixed
|
|
22
|
+
* external service. Instead, every Custom Connection carries its own
|
|
23
|
+
* manifest URL (a GitHub repo path) on its `providerMetadata`, and the
|
|
24
|
+
* integration framework resolves the manifest at install time.
|
|
25
|
+
*
|
|
26
|
+
* Custom manifests therefore declare `requires_connection: ['custom']`
|
|
27
|
+
* and ship an `expected_credentials` schema (below) describing the
|
|
28
|
+
* credential fields the user must fill out when creating the Connection.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Channel types are the inbound-message-route taxonomy used by
|
|
32
|
+
* `ChannelEntity` (added in PR 2 of the channels-and-credential-driven-
|
|
33
|
+
* integrations plan). A manifest under the submodule's `channels/<id>/`
|
|
34
|
+
* folder declares which channel type it maps to via `channel_type`, and
|
|
35
|
+
* `getDesiredState` activates the manifest when at least one Channel of
|
|
36
|
+
* that type exists in the agent's resolved view.
|
|
37
|
+
*
|
|
38
|
+
* The enum is locked — channel adapters and the dashboard's compatibility
|
|
39
|
+
* matrix both depend on this exact list.
|
|
40
|
+
*/
|
|
41
|
+
declare const LOCKED_CHANNEL_TYPES: readonly ["whatsapp", "sms", "voice", "google_chat", "slack", "discord", "teams"];
|
|
42
|
+
type ChannelType = (typeof LOCKED_CHANNEL_TYPES)[number];
|
|
43
|
+
declare const ChannelTypeSchema: z.ZodEnum<{
|
|
44
|
+
discord: "discord";
|
|
45
|
+
slack: "slack";
|
|
46
|
+
whatsapp: "whatsapp";
|
|
47
|
+
sms: "sms";
|
|
48
|
+
voice: "voice";
|
|
49
|
+
google_chat: "google_chat";
|
|
50
|
+
teams: "teams";
|
|
51
|
+
}>;
|
|
206
52
|
declare const ConfigFieldTypeSchema: z.ZodEnum<{
|
|
207
53
|
string: "string";
|
|
208
54
|
number: "number";
|
|
@@ -251,12 +97,49 @@ declare const ConfigSchemaFieldSchema: z.ZodObject<{
|
|
|
251
97
|
}, z.core.$strip>]>>;
|
|
252
98
|
depends_on_integration: z.ZodOptional<z.ZodString>;
|
|
253
99
|
}, z.core.$strip>;
|
|
100
|
+
/**
|
|
101
|
+
* A field a manifest's owner expects the user to fill in when creating
|
|
102
|
+
* a Custom Connection. Used ONLY by manifests authored against the
|
|
103
|
+
* `custom` connect provider — built-in OAuth-based integrations don't
|
|
104
|
+
* declare these (their credential shape comes from the OAuth flow).
|
|
105
|
+
*
|
|
106
|
+
* The dashboard renders an `<AddCustomConnectionModal>` form whose
|
|
107
|
+
* fields are derived from this array; the backend's
|
|
108
|
+
* `services/connect/api/connections/custom/post.ts` (PR 8b) validates
|
|
109
|
+
* the submitted credential map against this schema before encrypting
|
|
110
|
+
* and storing it on the Connection.
|
|
111
|
+
*/
|
|
112
|
+
declare const CredentialFieldTypeSchema: z.ZodEnum<{
|
|
113
|
+
string: "string";
|
|
114
|
+
number: "number";
|
|
115
|
+
boolean: "boolean";
|
|
116
|
+
secret: "secret";
|
|
117
|
+
url: "url";
|
|
118
|
+
}>;
|
|
119
|
+
declare const CredentialFieldSpecSchema: z.ZodObject<{
|
|
120
|
+
key: z.ZodString;
|
|
121
|
+
type: z.ZodEnum<{
|
|
122
|
+
string: "string";
|
|
123
|
+
number: "number";
|
|
124
|
+
boolean: "boolean";
|
|
125
|
+
secret: "secret";
|
|
126
|
+
url: "url";
|
|
127
|
+
}>;
|
|
128
|
+
label: z.ZodString;
|
|
129
|
+
description: z.ZodOptional<z.ZodString>;
|
|
130
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
131
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
132
|
+
pattern: z.ZodOptional<z.ZodString>;
|
|
133
|
+
}, z.core.$strip>;
|
|
134
|
+
type CredentialFieldSpec = z.infer<typeof CredentialFieldSpecSchema>;
|
|
135
|
+
type CredentialFieldType = z.infer<typeof CredentialFieldTypeSchema>;
|
|
254
136
|
declare const McpServerDeclarationSchema: z.ZodObject<{
|
|
255
137
|
id: z.ZodString;
|
|
256
138
|
command: z.ZodString;
|
|
257
139
|
args: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
258
140
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
259
141
|
cwd: z.ZodOptional<z.ZodString>;
|
|
142
|
+
requires_credentials: z.ZodOptional<z.ZodString>;
|
|
260
143
|
hook_managed: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
261
144
|
}, z.core.$strip>;
|
|
262
145
|
declare const CommandDeclarationSchema: z.ZodObject<{
|
|
@@ -397,8 +280,46 @@ declare const IntegrationManifestSchema: z.ZodObject<{
|
|
|
397
280
|
args: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
398
281
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
399
282
|
cwd: z.ZodOptional<z.ZodString>;
|
|
283
|
+
requires_credentials: z.ZodOptional<z.ZodString>;
|
|
400
284
|
hook_managed: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
401
285
|
}, z.core.$strip>>>>;
|
|
286
|
+
requires_connection: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
287
|
+
atlassian: "atlassian";
|
|
288
|
+
custom: "custom";
|
|
289
|
+
discord: "discord";
|
|
290
|
+
github: "github";
|
|
291
|
+
google: "google";
|
|
292
|
+
microsoft: "microsoft";
|
|
293
|
+
mobile: "mobile";
|
|
294
|
+
myob: "myob";
|
|
295
|
+
notion: "notion";
|
|
296
|
+
slack: "slack";
|
|
297
|
+
xero: "xero";
|
|
298
|
+
}>>>;
|
|
299
|
+
channel_type: z.ZodOptional<z.ZodEnum<{
|
|
300
|
+
discord: "discord";
|
|
301
|
+
slack: "slack";
|
|
302
|
+
whatsapp: "whatsapp";
|
|
303
|
+
sms: "sms";
|
|
304
|
+
voice: "voice";
|
|
305
|
+
google_chat: "google_chat";
|
|
306
|
+
teams: "teams";
|
|
307
|
+
}>>;
|
|
308
|
+
expected_credentials: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
309
|
+
key: z.ZodString;
|
|
310
|
+
type: z.ZodEnum<{
|
|
311
|
+
string: "string";
|
|
312
|
+
number: "number";
|
|
313
|
+
boolean: "boolean";
|
|
314
|
+
secret: "secret";
|
|
315
|
+
url: "url";
|
|
316
|
+
}>;
|
|
317
|
+
label: z.ZodString;
|
|
318
|
+
description: z.ZodOptional<z.ZodString>;
|
|
319
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
320
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
321
|
+
pattern: z.ZodOptional<z.ZodString>;
|
|
322
|
+
}, z.core.$strip>>>;
|
|
402
323
|
repository: z.ZodOptional<z.ZodURL>;
|
|
403
324
|
supported_agents: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
404
325
|
supported_scopes: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
@@ -442,7 +363,263 @@ declare const IntegrationManifestSchema: z.ZodObject<{
|
|
|
442
363
|
declare function buildConfigValidationSchema(configSchema: z.infer<typeof ConfigSchemaFieldSchema>[]): z.ZodObject<Record<string, z.ZodType>>;
|
|
443
364
|
type ManifestSchemaType = z.infer<typeof IntegrationManifestSchema>;
|
|
444
365
|
//#endregion
|
|
366
|
+
//#region src/types.d.ts
|
|
367
|
+
type ConfigFieldType = 'secret' | 'string' | 'number' | 'boolean' | 'enum' | 'select' | 'multi_select' | 'oauth_connect';
|
|
368
|
+
interface SelectOption {
|
|
369
|
+
value: string;
|
|
370
|
+
label: string;
|
|
371
|
+
}
|
|
372
|
+
interface ConfigSchemaField {
|
|
373
|
+
key: string;
|
|
374
|
+
type: ConfigFieldType;
|
|
375
|
+
label: string;
|
|
376
|
+
description?: string;
|
|
377
|
+
required: boolean;
|
|
378
|
+
default?: string | number | boolean;
|
|
379
|
+
/** Who can mutate this field at runtime. Default: 'admin' */
|
|
380
|
+
editable: 'admin' | 'agent';
|
|
381
|
+
/** Only used when type === 'enum' */
|
|
382
|
+
options?: string[];
|
|
383
|
+
/** Structured options for select/multi_select fields */
|
|
384
|
+
select_options?: SelectOption[];
|
|
385
|
+
/** OAuth provider identifier for oauth_connect fields */
|
|
386
|
+
oauth_provider?: string;
|
|
387
|
+
/** Force specific scope groups for OAuth (e.g. ["chat"]) — hides other scopes in the dashboard */
|
|
388
|
+
oauth_scopes?: string[];
|
|
389
|
+
/** Integration ID to patch on OAuth callback (when using a shared OAuth provider) */
|
|
390
|
+
oauth_integration_id?: string;
|
|
391
|
+
/** If true, this field is not shown in the dashboard UI (install wizard or configure modal) */
|
|
392
|
+
hidden?: boolean;
|
|
393
|
+
/** Only show this field if another field has a truthy value (string) or matches a specific value (object) */
|
|
394
|
+
depends_on_field?: string | {
|
|
395
|
+
key: string;
|
|
396
|
+
value: string | number | boolean;
|
|
397
|
+
};
|
|
398
|
+
/** Only show this field if a specific integration is installed */
|
|
399
|
+
depends_on_integration?: string;
|
|
400
|
+
}
|
|
401
|
+
interface McpServerDeclaration {
|
|
402
|
+
/** Unique identifier within this integration */
|
|
403
|
+
id: string;
|
|
404
|
+
/** Command to spawn (e.g., 'npx', 'node', 'xero-mcp-proxy') */
|
|
405
|
+
command: string;
|
|
406
|
+
/** Arguments for the command */
|
|
407
|
+
args?: string[];
|
|
408
|
+
/**
|
|
409
|
+
* Environment variables. Two interpolation syntaxes are supported:
|
|
410
|
+
*
|
|
411
|
+
* - `{{config.KEY}}` — resolved from the integration's user-supplied
|
|
412
|
+
* config + secrets via `resolveConfig()`. Existing behavior.
|
|
413
|
+
* - `{{credentials.<provider>.<field>}}` — resolved by the
|
|
414
|
+
* `mcp-applier` via `AgentApiClient.get<Provider>Credentials()`.
|
|
415
|
+
* `<provider>` is the OAuth provider key (`atlassian`, `github`,
|
|
416
|
+
* `xero`, `notion`, `myob`, …); `<field>` is a top-level key on the
|
|
417
|
+
* credentials response (`accessToken`, `clientId`, `cloudId`, …).
|
|
418
|
+
* Used in conjunction with `requires_credentials` to signal the
|
|
419
|
+
* precondition.
|
|
420
|
+
*/
|
|
421
|
+
env?: Record<string, string>;
|
|
422
|
+
/** Working directory (optional) */
|
|
423
|
+
cwd?: string;
|
|
424
|
+
/**
|
|
425
|
+
* OAuth provider whose credentials this server requires. When set and
|
|
426
|
+
* the credentials are missing or 404, the applier logs and skips
|
|
427
|
+
* registration silently — same graceful no-op the `post_activate.mjs`
|
|
428
|
+
* hooks do today. Pair with `{{credentials.<provider>.<field>}}` env
|
|
429
|
+
* references; the explicit field is preferred over inferring from the
|
|
430
|
+
* presence of the interpolation pattern for clarity.
|
|
431
|
+
*/
|
|
432
|
+
requires_credentials?: string;
|
|
433
|
+
/**
|
|
434
|
+
* @deprecated As of 2026-05-18 the `mcp-applier` handles every case
|
|
435
|
+
* end-to-end (config + credentials interpolation, requires_credentials
|
|
436
|
+
* skip-silently, manager.addServer with owner attribution). The
|
|
437
|
+
* legacy `OpenClawApplier.applyMcpServers` path has been deleted so
|
|
438
|
+
* the field is now accepted but completely ignored on parse. Drop
|
|
439
|
+
* from new manifests.
|
|
440
|
+
*/
|
|
441
|
+
hook_managed?: boolean;
|
|
442
|
+
}
|
|
443
|
+
interface CommandDeclaration {
|
|
444
|
+
/** Dot-namespaced command name (e.g. "support.diagnostic") */
|
|
445
|
+
name: string;
|
|
446
|
+
/** Relative path to handler file within integration directory */
|
|
447
|
+
handler: string;
|
|
448
|
+
/** Exported function name (default: "handle") */
|
|
449
|
+
method?: string;
|
|
450
|
+
/** Timeout in milliseconds (default: 30000) */
|
|
451
|
+
timeout_ms?: number;
|
|
452
|
+
/** Human-readable description */
|
|
453
|
+
description?: string;
|
|
454
|
+
}
|
|
455
|
+
interface SkillInstall {
|
|
456
|
+
/** Relative path within the integration repo to the skill directory */
|
|
457
|
+
path?: string;
|
|
458
|
+
/** ClawHub skill slug to install from the registry */
|
|
459
|
+
clawhub?: string;
|
|
460
|
+
}
|
|
461
|
+
interface PluginInstall {
|
|
462
|
+
/** npm package name to install */
|
|
463
|
+
package: string;
|
|
464
|
+
}
|
|
465
|
+
type AgentRuntime = 'openclaw' | 'nanoclaw' | (string & {});
|
|
466
|
+
interface RuntimeInstall {
|
|
467
|
+
plugins?: PluginInstall[];
|
|
468
|
+
skills?: SkillInstall[];
|
|
469
|
+
/** Deep-merged into the runtime's agent config on activation */
|
|
470
|
+
config?: Record<string, unknown>;
|
|
471
|
+
}
|
|
472
|
+
interface InstallTargets {
|
|
473
|
+
/** Universal skills — applied to all runtimes */
|
|
474
|
+
skills?: SkillInstall[];
|
|
475
|
+
/** Universal plugins — applied to all runtimes */
|
|
476
|
+
plugins?: PluginInstall[];
|
|
477
|
+
/** Per-runtime installs */
|
|
478
|
+
runtimes?: Record<AgentRuntime, RuntimeInstall>;
|
|
479
|
+
}
|
|
480
|
+
interface IntegrationHooks {
|
|
481
|
+
pre_install?: string;
|
|
482
|
+
post_install?: string;
|
|
483
|
+
post_activate?: string;
|
|
484
|
+
pre_uninstall?: string;
|
|
485
|
+
post_uninstall?: string;
|
|
486
|
+
health_check?: string;
|
|
487
|
+
}
|
|
488
|
+
interface IntegrationPricingPlan {
|
|
489
|
+
name: string;
|
|
490
|
+
price: number;
|
|
491
|
+
currency?: string;
|
|
492
|
+
interval?: 'month' | 'year';
|
|
493
|
+
}
|
|
494
|
+
interface IntegrationPricing {
|
|
495
|
+
type: 'free' | 'paid' | 'usage';
|
|
496
|
+
/** Single price (shorthand for integrations with one plan) */
|
|
497
|
+
price?: number;
|
|
498
|
+
currency?: string;
|
|
499
|
+
interval?: 'month' | 'year';
|
|
500
|
+
/** Description of usage-based pricing (for type: 'usage') */
|
|
501
|
+
description?: string;
|
|
502
|
+
/** Multiple plans/tiers (e.g., starter, growth, scale) */
|
|
503
|
+
plans?: Record<string, IntegrationPricingPlan>;
|
|
504
|
+
}
|
|
505
|
+
interface IntegrationAuthor {
|
|
506
|
+
name: string;
|
|
507
|
+
url?: string;
|
|
508
|
+
}
|
|
509
|
+
interface IntegrationManifest {
|
|
510
|
+
id: string;
|
|
511
|
+
name: string;
|
|
512
|
+
version: string;
|
|
513
|
+
description: string;
|
|
514
|
+
/** Simple author string (legacy) or structured author object */
|
|
515
|
+
author: string | IntegrationAuthor;
|
|
516
|
+
license: string;
|
|
517
|
+
depends_on: string[];
|
|
518
|
+
min_gateway_version: string;
|
|
519
|
+
installs: InstallTargets;
|
|
520
|
+
config_schema: ConfigSchemaField[];
|
|
521
|
+
capabilities: string[];
|
|
522
|
+
hooks: IntegrationHooks;
|
|
523
|
+
commands: CommandDeclaration[];
|
|
524
|
+
/** MCP servers to configure in the agent runtime */
|
|
525
|
+
mcp_servers: McpServerDeclaration[];
|
|
526
|
+
/** Git repository URL (HTTPS) — not present in YAML, injected by the publish API */
|
|
527
|
+
repository?: string;
|
|
528
|
+
/**
|
|
529
|
+
* Agent runtimes this integration supports.
|
|
530
|
+
* If omitted or empty, the integration is considered universal (all runtimes).
|
|
531
|
+
* Example: ['openclaw'] means this integration only works with OpenClaw.
|
|
532
|
+
*/
|
|
533
|
+
supported_agents?: AgentRuntime[];
|
|
534
|
+
/**
|
|
535
|
+
* Scopes where this integration can be installed.
|
|
536
|
+
* Default: ['agent'] (per-agent only).
|
|
537
|
+
* 'org' means it can be installed at the org level and cascades to all agents.
|
|
538
|
+
*/
|
|
539
|
+
supported_scopes?: ('agent' | 'org')[];
|
|
540
|
+
/**
|
|
541
|
+
* Connect provider ids whose credentials this integration resolves at
|
|
542
|
+
* runtime. OR-semantics: any one in the list satisfies activation. See
|
|
543
|
+
* the `requires_connection` field in `schema.ts` for full semantics.
|
|
544
|
+
* Typed as `KnownConnectProviderId[]` so consumers get compile-time
|
|
545
|
+
* narrowing matching the schema's runtime validation.
|
|
546
|
+
*/
|
|
547
|
+
requires_connection?: KnownConnectProviderId[];
|
|
548
|
+
/**
|
|
549
|
+
* Channel type this integration adapts. Populated on integrations under
|
|
550
|
+
* the submodule's `channels/<id>/` folder that map to a single channel
|
|
551
|
+
* type. See `channel_type` in `schema.ts` for full semantics.
|
|
552
|
+
*/
|
|
553
|
+
channel_type?: ChannelType;
|
|
554
|
+
/**
|
|
555
|
+
* Credential fields the manifest expects a Custom Connection's owner
|
|
556
|
+
* to fill in at create time. Used ONLY by manifests authored against
|
|
557
|
+
* the `custom` connect provider. See `expected_credentials` in
|
|
558
|
+
* `schema.ts` for full semantics.
|
|
559
|
+
*/
|
|
560
|
+
expected_credentials?: CredentialFieldSpec[];
|
|
561
|
+
/** Marketplace metadata */
|
|
562
|
+
publisherId?: string;
|
|
563
|
+
icon?: string;
|
|
564
|
+
pricing?: IntegrationPricing;
|
|
565
|
+
preview_images?: string[];
|
|
566
|
+
/** Long-form features list for the detail view */
|
|
567
|
+
features?: string[];
|
|
568
|
+
}
|
|
569
|
+
interface PublishedVersion {
|
|
570
|
+
version: string;
|
|
571
|
+
commit_hash: string;
|
|
572
|
+
changelog?: string;
|
|
573
|
+
published_at: string;
|
|
574
|
+
}
|
|
575
|
+
interface PublishedIntegration {
|
|
576
|
+
manifest: IntegrationManifest;
|
|
577
|
+
versions: PublishedVersion[];
|
|
578
|
+
/** Resolved asset URLs baked at publish time */
|
|
579
|
+
resolved_assets: {
|
|
580
|
+
icon?: string;
|
|
581
|
+
preview_images?: string[];
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
type IntegrationStatus = 'installing' | 'installed' | 'configured' | 'active' | 'error';
|
|
585
|
+
interface IntegrationStateEntry {
|
|
586
|
+
status: IntegrationStatus;
|
|
587
|
+
version: string;
|
|
588
|
+
installedAt: string;
|
|
589
|
+
config: Record<string, unknown>;
|
|
590
|
+
error?: string;
|
|
591
|
+
/** Number of consecutive auto-reinstall attempts. Reset on success or explicit reinstall. */
|
|
592
|
+
reinstallAttempts?: number;
|
|
593
|
+
}
|
|
594
|
+
interface IntegrationsStateFile {
|
|
595
|
+
version: number;
|
|
596
|
+
integrations: Record<string, IntegrationStateEntry>;
|
|
597
|
+
}
|
|
598
|
+
interface HealthCheckResult {
|
|
599
|
+
id: string;
|
|
600
|
+
name?: string;
|
|
601
|
+
healthy: boolean;
|
|
602
|
+
status: IntegrationStatus;
|
|
603
|
+
version?: string;
|
|
604
|
+
message?: string;
|
|
605
|
+
stdout?: string;
|
|
606
|
+
stderr?: string;
|
|
607
|
+
}
|
|
608
|
+
interface HealthReport {
|
|
609
|
+
overall: boolean;
|
|
610
|
+
results: HealthCheckResult[];
|
|
611
|
+
checkedAt: string;
|
|
612
|
+
}
|
|
613
|
+
//#endregion
|
|
445
614
|
//#region src/parser.d.ts
|
|
615
|
+
/**
|
|
616
|
+
* Pluggable warn-sink for parse-time advisories. Defaults to the
|
|
617
|
+
* Node `console.warn` so the message lands in the right place
|
|
618
|
+
* regardless of which logger the caller uses; callers that want
|
|
619
|
+
* structured logs can override.
|
|
620
|
+
*/
|
|
621
|
+
type ParseWarner = (message: string, meta?: Record<string, unknown>) => void;
|
|
622
|
+
declare function setParseWarner(warner: ParseWarner): void;
|
|
446
623
|
declare class ManifestParseError extends Error {
|
|
447
624
|
readonly issues?: {
|
|
448
625
|
path: string;
|
|
@@ -569,4 +746,4 @@ declare function migrateConfig(currentConfig: Record<string, unknown>, diff: Con
|
|
|
569
746
|
warnings: string[];
|
|
570
747
|
};
|
|
571
748
|
//#endregion
|
|
572
|
-
export { type AgentRuntime, type CommandContext, type CommandDeclaration, CommandDeclarationSchema, type CommandHandlerFn, type CommandResult, type ConfigFieldType, ConfigFieldTypeSchema, type ConfigSchemaDiff, type ConfigSchemaField, ConfigSchemaFieldSchema, type HealthCheckResult, type HealthReport, type InstallTargets, InstallTargetsSchema, type IntegrationHooks, IntegrationHooksSchema, type IntegrationManifest, IntegrationManifestSchema, type IntegrationPricing, type IntegrationPricingPlan, type IntegrationStateEntry, type IntegrationStatus, type IntegrationsStateFile, type InterpolationContext, ManifestParseError, type ManifestSchemaType, type McpServerDeclaration, McpServerDeclarationSchema, type PluginInstall, PluginInstallSchema, type PublishedIntegration, type PublishedVersion, type RuntimeInstall, RuntimeInstallSchema, type SelectOption, SelectOptionSchema, type SkillInstall, SkillInstallSchema, buildConfigValidationSchema, diffConfigSchemas, extractTemplateReferences, interpolateConfig, isRelativePath, migrateConfig, parseManifestFile, parseManifestString, resolveAssetUrl };
|
|
749
|
+
export { type AgentRuntime, type ChannelType, ChannelTypeSchema, type CommandContext, type CommandDeclaration, CommandDeclarationSchema, type CommandHandlerFn, type CommandResult, type ConfigFieldType, ConfigFieldTypeSchema, type ConfigSchemaDiff, type ConfigSchemaField, ConfigSchemaFieldSchema, type CredentialFieldSpec, CredentialFieldSpecSchema, type CredentialFieldType, CredentialFieldTypeSchema, type HealthCheckResult, type HealthReport, type InstallTargets, InstallTargetsSchema, type IntegrationHooks, IntegrationHooksSchema, type IntegrationManifest, IntegrationManifestSchema, type IntegrationPricing, type IntegrationPricingPlan, type IntegrationStateEntry, type IntegrationStatus, type IntegrationsStateFile, type InterpolationContext, KNOWN_CONNECT_PROVIDER_IDS, type KnownConnectProviderId, LOCKED_CHANNEL_TYPES, ManifestParseError, type ManifestSchemaType, type McpServerDeclaration, McpServerDeclarationSchema, type ParseWarner, type PluginInstall, PluginInstallSchema, type PublishedIntegration, type PublishedVersion, type RuntimeInstall, RuntimeInstallSchema, type SelectOption, SelectOptionSchema, type SkillInstall, SkillInstallSchema, buildConfigValidationSchema, diffConfigSchemas, extractTemplateReferences, interpolateConfig, isRelativePath, migrateConfig, parseManifestFile, parseManifestString, resolveAssetUrl, setParseWarner };
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,63 @@ import { parse } from "yaml";
|
|
|
9
9
|
* Used by the parser and by the lifecycle manager to ensure manifest
|
|
10
10
|
* correctness before installation.
|
|
11
11
|
*/
|
|
12
|
+
/**
|
|
13
|
+
* Connect provider ids that a manifest's `requires_connection` field may
|
|
14
|
+
* reference. The source of truth lives in `services/connect/src/providers/`
|
|
15
|
+
* (one `ProviderDefinition` per id) — this list mirrors that registry so
|
|
16
|
+
* the manifest schema can validate references statically.
|
|
17
|
+
*
|
|
18
|
+
* **Keep in sync** with `services/connect/src/providers/index.ts`. Adding a
|
|
19
|
+
* new connect provider requires updating both: add the provider definition
|
|
20
|
+
* there, then add its id here so manifests can declare `requires_connection`
|
|
21
|
+
* against it. Drift in the other direction (id here without provider) is
|
|
22
|
+
* caught at runtime when the integrations service tries to resolve the
|
|
23
|
+
* provider and gets nothing back.
|
|
24
|
+
*/
|
|
25
|
+
const KNOWN_CONNECT_PROVIDER_IDS = [
|
|
26
|
+
"atlassian",
|
|
27
|
+
"custom",
|
|
28
|
+
"discord",
|
|
29
|
+
"github",
|
|
30
|
+
"google",
|
|
31
|
+
"microsoft",
|
|
32
|
+
"mobile",
|
|
33
|
+
"myob",
|
|
34
|
+
"notion",
|
|
35
|
+
"slack",
|
|
36
|
+
"xero"
|
|
37
|
+
];
|
|
38
|
+
/**
|
|
39
|
+
* `custom` is a special provider id: it doesn't correspond to a fixed
|
|
40
|
+
* external service. Instead, every Custom Connection carries its own
|
|
41
|
+
* manifest URL (a GitHub repo path) on its `providerMetadata`, and the
|
|
42
|
+
* integration framework resolves the manifest at install time.
|
|
43
|
+
*
|
|
44
|
+
* Custom manifests therefore declare `requires_connection: ['custom']`
|
|
45
|
+
* and ship an `expected_credentials` schema (below) describing the
|
|
46
|
+
* credential fields the user must fill out when creating the Connection.
|
|
47
|
+
*/
|
|
48
|
+
/**
|
|
49
|
+
* Channel types are the inbound-message-route taxonomy used by
|
|
50
|
+
* `ChannelEntity` (added in PR 2 of the channels-and-credential-driven-
|
|
51
|
+
* integrations plan). A manifest under the submodule's `channels/<id>/`
|
|
52
|
+
* folder declares which channel type it maps to via `channel_type`, and
|
|
53
|
+
* `getDesiredState` activates the manifest when at least one Channel of
|
|
54
|
+
* that type exists in the agent's resolved view.
|
|
55
|
+
*
|
|
56
|
+
* The enum is locked — channel adapters and the dashboard's compatibility
|
|
57
|
+
* matrix both depend on this exact list.
|
|
58
|
+
*/
|
|
59
|
+
const LOCKED_CHANNEL_TYPES = [
|
|
60
|
+
"whatsapp",
|
|
61
|
+
"sms",
|
|
62
|
+
"voice",
|
|
63
|
+
"google_chat",
|
|
64
|
+
"slack",
|
|
65
|
+
"discord",
|
|
66
|
+
"teams"
|
|
67
|
+
];
|
|
68
|
+
const ChannelTypeSchema = z.enum(LOCKED_CHANNEL_TYPES);
|
|
12
69
|
const ConfigFieldTypeSchema = z.enum([
|
|
13
70
|
"secret",
|
|
14
71
|
"string",
|
|
@@ -59,12 +116,41 @@ const ConfigSchemaFieldSchema = z.object({
|
|
|
59
116
|
if (field.type === "oauth_connect") return field.oauth_provider !== void 0 && field.oauth_provider.length > 0;
|
|
60
117
|
return true;
|
|
61
118
|
}, { message: "oauth_connect fields must specify an oauth_provider" });
|
|
119
|
+
/**
|
|
120
|
+
* A field a manifest's owner expects the user to fill in when creating
|
|
121
|
+
* a Custom Connection. Used ONLY by manifests authored against the
|
|
122
|
+
* `custom` connect provider — built-in OAuth-based integrations don't
|
|
123
|
+
* declare these (their credential shape comes from the OAuth flow).
|
|
124
|
+
*
|
|
125
|
+
* The dashboard renders an `<AddCustomConnectionModal>` form whose
|
|
126
|
+
* fields are derived from this array; the backend's
|
|
127
|
+
* `services/connect/api/connections/custom/post.ts` (PR 8b) validates
|
|
128
|
+
* the submitted credential map against this schema before encrypting
|
|
129
|
+
* and storing it on the Connection.
|
|
130
|
+
*/
|
|
131
|
+
const CredentialFieldTypeSchema = z.enum([
|
|
132
|
+
"string",
|
|
133
|
+
"secret",
|
|
134
|
+
"url",
|
|
135
|
+
"number",
|
|
136
|
+
"boolean"
|
|
137
|
+
]);
|
|
138
|
+
const CredentialFieldSpecSchema = z.object({
|
|
139
|
+
key: z.string().min(1, "Credential field key must not be empty").regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/, "Credential field key must be a valid identifier (letters, digits, underscores; not starting with a digit)"),
|
|
140
|
+
type: CredentialFieldTypeSchema,
|
|
141
|
+
label: z.string().min(1, "Credential field label must not be empty"),
|
|
142
|
+
description: z.string().optional(),
|
|
143
|
+
required: z.boolean().default(true),
|
|
144
|
+
placeholder: z.string().optional(),
|
|
145
|
+
pattern: z.string().max(256).optional()
|
|
146
|
+
});
|
|
62
147
|
const McpServerDeclarationSchema = z.object({
|
|
63
148
|
id: z.string().min(1, "MCP server id must not be empty").regex(/^[a-z0-9][a-z0-9-]*$/, "MCP server id must be lowercase alphanumeric with hyphens"),
|
|
64
149
|
command: z.string().min(1, "MCP server command must not be empty"),
|
|
65
150
|
args: z.array(z.string()).optional().default([]),
|
|
66
151
|
env: z.record(z.string(), z.string()).optional(),
|
|
67
152
|
cwd: z.string().optional(),
|
|
153
|
+
requires_credentials: z.string().min(1).optional(),
|
|
68
154
|
hook_managed: z.boolean().optional().default(false)
|
|
69
155
|
});
|
|
70
156
|
const CommandDeclarationSchema = z.object({
|
|
@@ -148,6 +234,9 @@ const IntegrationManifestSchema = z.object({
|
|
|
148
234
|
hooks: IntegrationHooksSchema.optional().default({}),
|
|
149
235
|
commands: z.array(CommandDeclarationSchema).optional().default([]),
|
|
150
236
|
mcp_servers: z.array(McpServerDeclarationSchema).optional().default([]),
|
|
237
|
+
requires_connection: z.array(z.enum(KNOWN_CONNECT_PROVIDER_IDS)).optional(),
|
|
238
|
+
channel_type: ChannelTypeSchema.optional(),
|
|
239
|
+
expected_credentials: z.array(CredentialFieldSpecSchema).optional(),
|
|
151
240
|
repository: z.url().optional(),
|
|
152
241
|
supported_agents: z.array(RuntimeKeySchema).optional(),
|
|
153
242
|
supported_scopes: z.array(z.enum([
|
|
@@ -217,6 +306,13 @@ function buildConfigValidationSchema(configSchema) {
|
|
|
217
306
|
* and validates against the Zod schema. Returns a fully typed
|
|
218
307
|
* IntegrationManifest or throws a descriptive error.
|
|
219
308
|
*/
|
|
309
|
+
let parseWarner = (msg, meta) => {
|
|
310
|
+
if (meta && Object.keys(meta).length > 0) console.warn(`[integration-manifest] ${msg}`, meta);
|
|
311
|
+
else console.warn(`[integration-manifest] ${msg}`);
|
|
312
|
+
};
|
|
313
|
+
function setParseWarner(warner) {
|
|
314
|
+
parseWarner = warner;
|
|
315
|
+
}
|
|
220
316
|
var ManifestParseError = class extends Error {
|
|
221
317
|
constructor(message, issues) {
|
|
222
318
|
super(message);
|
|
@@ -248,7 +344,22 @@ function parseManifestString(yaml, overrides) {
|
|
|
248
344
|
}));
|
|
249
345
|
throw new ManifestParseError(`Invalid integration manifest:\n${issues.map((i) => ` ${i.path ? `${i.path}: ` : ""}${i.message}`).join("\n")}`, issues);
|
|
250
346
|
}
|
|
251
|
-
|
|
347
|
+
const manifest = result.data;
|
|
348
|
+
warnDeprecatedFields(manifest);
|
|
349
|
+
return manifest;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Emit one-time-per-parse advisories for fields that pass schema
|
|
353
|
+
* validation but are deprecated. The flag is accepted-but-ignored,
|
|
354
|
+
* not rejected — the warn is the only signal manifest authors get
|
|
355
|
+
* since the `@deprecated` JSDoc only surfaces in TS callers' IDEs.
|
|
356
|
+
*/
|
|
357
|
+
function warnDeprecatedFields(manifest) {
|
|
358
|
+
const hookManagedServers = manifest.mcp_servers.filter((s) => s.hook_managed === true).map((s) => s.id);
|
|
359
|
+
if (hookManagedServers.length > 0) parseWarner(`manifest "${manifest.id}" declares mcp_servers with deprecated hook_managed:true — drop the field, the mcp-applier handles every case end-to-end now`, {
|
|
360
|
+
integration: manifest.id,
|
|
361
|
+
servers: hookManagedServers
|
|
362
|
+
});
|
|
252
363
|
}
|
|
253
364
|
/**
|
|
254
365
|
* Read and parse an alfe-integration.yaml file from disk.
|
|
@@ -398,4 +509,4 @@ function migrateConfig(currentConfig, diff) {
|
|
|
398
509
|
};
|
|
399
510
|
}
|
|
400
511
|
//#endregion
|
|
401
|
-
export { CommandDeclarationSchema, ConfigFieldTypeSchema, ConfigSchemaFieldSchema, InstallTargetsSchema, IntegrationHooksSchema, IntegrationManifestSchema, ManifestParseError, McpServerDeclarationSchema, PluginInstallSchema, RuntimeInstallSchema, SelectOptionSchema, SkillInstallSchema, buildConfigValidationSchema, diffConfigSchemas, extractTemplateReferences, interpolateConfig, isRelativePath, migrateConfig, parseManifestFile, parseManifestString, resolveAssetUrl };
|
|
512
|
+
export { ChannelTypeSchema, CommandDeclarationSchema, ConfigFieldTypeSchema, ConfigSchemaFieldSchema, CredentialFieldSpecSchema, CredentialFieldTypeSchema, InstallTargetsSchema, IntegrationHooksSchema, IntegrationManifestSchema, KNOWN_CONNECT_PROVIDER_IDS, LOCKED_CHANNEL_TYPES, ManifestParseError, McpServerDeclarationSchema, PluginInstallSchema, RuntimeInstallSchema, SelectOptionSchema, SkillInstallSchema, buildConfigValidationSchema, diffConfigSchemas, extractTemplateReferences, interpolateConfig, isRelativePath, migrateConfig, parseManifestFile, parseManifestString, resolveAssetUrl, setParseWarner };
|