@afps-spec/schema 1.0.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 ADDED
@@ -0,0 +1,59 @@
1
+ # AFPS JSON Schemas
2
+
3
+ Machine-readable representation of the AFPS specification. The specification text ([spec.md](../spec.md)) is the normative source.
4
+
5
+ ## npm package
6
+
7
+ This directory is published as `@afps/schema` on npm. Implementations can import the Zod schemas and extend them:
8
+
9
+ ```typescript
10
+ import { flowManifestSchema } from "@afps/schema";
11
+
12
+ const myFlowSchema = flowManifestSchema.extend({
13
+ "x-custom-field": z.string().optional(),
14
+ });
15
+ ```
16
+
17
+ ## Versioned schemas
18
+
19
+ Schemas are organized by major version:
20
+
21
+ ```
22
+ schema/
23
+ ├── v1/ ← AFPS v1.x schemas
24
+ │ ├── flow.schema.json
25
+ │ ├── skill.schema.json
26
+ │ ├── tool.schema.json
27
+ │ └── provider.schema.json
28
+ ├── src/
29
+ │ ├── schemas.ts ← Zod source (generates v1/)
30
+ │ ├── generate.ts ← Generation script
31
+ │ └── index.ts ← npm entry point
32
+ └── package.json ← @afps/schema
33
+ ```
34
+
35
+ URLs follow the pattern `https://afps.appstrate.dev/schema/v1/<type>.schema.json`.
36
+
37
+ ## Regenerating
38
+
39
+ After modifying the Zod source in `src/schemas.ts`:
40
+
41
+ ```sh
42
+ cd schema && bun install && bun run generate
43
+ ```
44
+
45
+ ## Usage in manifests
46
+
47
+ Reference a schema using `$schema` for editor validation:
48
+
49
+ ```json
50
+ {
51
+ "$schema": "https://afps.appstrate.dev/schema/v1/flow.schema.json",
52
+ "schemaVersion": "1.0",
53
+ "name": "@scope/my-flow",
54
+ "version": "1.0.0",
55
+ "type": "flow"
56
+ }
57
+ ```
58
+
59
+ Implementations may extend these schemas with additional fields using the `x-` prefix convention (see spec §10).
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@afps-spec/schema",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "files": [
6
+ "src",
7
+ "v1"
8
+ ],
9
+ "exports": {
10
+ ".": "./src/index.ts",
11
+ "./v1/*": "./v1/*"
12
+ },
13
+ "scripts": {
14
+ "generate": "bun src/generate.ts"
15
+ },
16
+ "dependencies": {
17
+ "zod": "^4.3.6"
18
+ },
19
+ "devDependencies": {
20
+ "bun-types": "latest"
21
+ }
22
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Generate AFPS JSON Schema files from the Zod definitions.
3
+ *
4
+ * Change MAJOR to generate schemas for a different spec version.
5
+ *
6
+ * Usage: bun src/generate.ts (from schema/)
7
+ */
8
+
9
+ import { toJSONSchema } from "zod/v4/core";
10
+ import { resolve, dirname } from "node:path";
11
+ import { writeFile, mkdir } from "node:fs/promises";
12
+ import { createSchemas } from "./schemas.ts";
13
+
14
+ const MAJOR = 1;
15
+ const VERSION_TAG = `v${MAJOR}`;
16
+ const BASE_URL = "https://afps.appstrate.dev/schema";
17
+ const OUTPUT_DIR = resolve(dirname(import.meta.filename!), "..", VERSION_TAG);
18
+
19
+ const { flowManifestSchema, skillManifestSchema, toolManifestSchema, providerManifestSchema } =
20
+ createSchemas(MAJOR);
21
+
22
+ const entries = [
23
+ {
24
+ filename: "flow.schema.json",
25
+ title: "AFPS Flow Manifest",
26
+ description:
27
+ "Manifest schema for AFPS flow packages. " +
28
+ "A flow declares dependencies, input/output/config schemas, a timeout hint, and provider configuration.",
29
+ schema: flowManifestSchema,
30
+ },
31
+ {
32
+ filename: "skill.schema.json",
33
+ title: "AFPS Skill Manifest",
34
+ description:
35
+ "Manifest schema for AFPS skill packages. " +
36
+ "A skill is a reusable prompt with optional frontmatter metadata.",
37
+ schema: skillManifestSchema,
38
+ },
39
+ {
40
+ filename: "tool.schema.json",
41
+ title: "AFPS Tool Manifest",
42
+ description:
43
+ "Manifest schema for AFPS tool packages. " +
44
+ "A tool declares a single callable capability with its interface and implementation source.",
45
+ schema: toolManifestSchema,
46
+ },
47
+ {
48
+ filename: "provider.schema.json",
49
+ title: "AFPS Provider Manifest",
50
+ description:
51
+ "Manifest schema for AFPS provider packages. " +
52
+ "A provider declares auth mode, OAuth endpoints, credential schema, and setup guide.",
53
+ schema: providerManifestSchema,
54
+ },
55
+ ];
56
+
57
+ await mkdir(OUTPUT_DIR, { recursive: true });
58
+
59
+ for (const entry of entries) {
60
+ const jsonSchema = toJSONSchema(entry.schema, {
61
+ unrepresentable: "any",
62
+ target: "draft-2020-12",
63
+ }) as Record<string, unknown>;
64
+
65
+ delete jsonSchema.$schema;
66
+
67
+ const final = {
68
+ $schema: "https://json-schema.org/draft/2020-12/schema",
69
+ $id: `${BASE_URL}/${VERSION_TAG}/${entry.filename}`,
70
+ title: entry.title,
71
+ description: entry.description,
72
+ ...jsonSchema,
73
+ };
74
+
75
+ const filePath = resolve(OUTPUT_DIR, entry.filename);
76
+ await writeFile(filePath, JSON.stringify(final, null, 2) + "\n");
77
+ console.log(` ✓ ${VERSION_TAG}/${entry.filename}`);
78
+ }
79
+
80
+ console.log(`\nGenerated ${entries.length} schemas in ${OUTPUT_DIR}`);
package/src/index.ts ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @afps/schema — AFPS Zod schemas for manifest validation.
3
+ *
4
+ * Default exports are AFPS v1 schemas. Use createSchemas(majorVersion)
5
+ * to generate schemas for a specific version.
6
+ */
7
+
8
+ export {
9
+ createSchemas,
10
+ flowManifestSchema,
11
+ skillManifestSchema,
12
+ toolManifestSchema,
13
+ providerManifestSchema,
14
+ } from "./schemas.ts";
package/src/schemas.ts ADDED
@@ -0,0 +1,197 @@
1
+ /**
2
+ * AFPS — Zod schemas for the four package types.
3
+ *
4
+ * These schemas define ONLY the fields in the AFPS specification.
5
+ * No implementation-specific fields (x-* or otherwise) belong here.
6
+ *
7
+ * Schemas are parameterized by major version: the schemaVersion field
8
+ * is constrained to match (e.g., v1 schemas accept "1.0", "1.1", etc.)
9
+ *
10
+ * Source of truth: ../spec.md (§2–§7)
11
+ */
12
+
13
+ import { z } from "zod";
14
+
15
+ // ─────────────────────────────────────────────
16
+ // Shared patterns and primitives
17
+ // ─────────────────────────────────────────────
18
+
19
+ const SLUG_PATTERN = "[a-z0-9]([a-z0-9-]*[a-z0-9])?";
20
+ const SCOPED_NAME_REGEX = new RegExp(`^@${SLUG_PATTERN}\\/${SLUG_PATTERN}$`);
21
+
22
+ const scopedName = z.string().regex(SCOPED_NAME_REGEX);
23
+ const semverRange = z.string().min(1);
24
+
25
+ // ─────────────────────────────────────────────
26
+ // Schema system (§5)
27
+ // ─────────────────────────────────────────────
28
+
29
+ const fieldTypeEnum = z.enum(["string", "number", "boolean", "array", "object", "file"]);
30
+
31
+ const schemaProperty = z.looseObject({
32
+ type: fieldTypeEnum,
33
+ description: z.string().optional(),
34
+ default: z.unknown().optional(),
35
+ enum: z.array(z.unknown()).optional(),
36
+ format: z.string().optional(),
37
+ placeholder: z.string().optional(),
38
+ accept: z.string().optional(),
39
+ maxSize: z.number().positive().optional(),
40
+ multiple: z.boolean().optional(),
41
+ maxFiles: z.number().positive().optional(),
42
+ });
43
+
44
+ const schemaObject = z.looseObject({
45
+ type: z.literal("object"),
46
+ properties: z.record(z.string(), schemaProperty),
47
+ required: z.array(z.string()).optional(),
48
+ propertyOrder: z.array(z.string()).optional(),
49
+ });
50
+
51
+ const schemaWrapper = z.object({
52
+ schema: schemaObject,
53
+ });
54
+
55
+ // ─────────────────────────────────────────────
56
+ // Dependencies (§4)
57
+ // ─────────────────────────────────────────────
58
+
59
+ const dependenciesSchema = z
60
+ .looseObject({
61
+ skills: z.record(scopedName, semverRange).optional(),
62
+ tools: z.record(scopedName, semverRange).optional(),
63
+ providers: z.record(scopedName, semverRange).optional(),
64
+ })
65
+ .optional();
66
+
67
+ // ─────────────────────────────────────────────
68
+ // Provider configuration (§4.4)
69
+ // ─────────────────────────────────────────────
70
+
71
+ const providerConfiguration = z.looseObject({
72
+ scopes: z.array(z.string()).optional(),
73
+ connectionMode: z.enum(["user", "admin"]).optional(),
74
+ });
75
+
76
+ // ─────────────────────────────────────────────
77
+ // Tool interface (§3.4)
78
+ // ─────────────────────────────────────────────
79
+
80
+ const toolInterface = z.object({
81
+ name: z.string().min(1),
82
+ description: z.string().min(1),
83
+ inputSchema: z.looseObject({}),
84
+ });
85
+
86
+ // ─────────────────────────────────────────────
87
+ // Auth and provider internals (§3.5 + §7)
88
+ // ─────────────────────────────────────────────
89
+
90
+ const authModeEnum = z.enum(["oauth2", "oauth1", "api_key", "basic", "custom"]);
91
+
92
+ const providerDefinition = z.looseObject({
93
+ authMode: authModeEnum,
94
+ authorizationUrl: z.string().optional(),
95
+ tokenUrl: z.string().optional(),
96
+ refreshUrl: z.string().optional(),
97
+ defaultScopes: z.array(z.string()).optional(),
98
+ scopeSeparator: z.string().optional(),
99
+ pkceEnabled: z.boolean().optional(),
100
+ tokenAuthMethod: z.string().optional(),
101
+ authorizationParams: z.record(z.string(), z.unknown()).optional(),
102
+ tokenParams: z.record(z.string(), z.unknown()).optional(),
103
+ requestTokenUrl: z.string().optional(),
104
+ accessTokenUrl: z.string().optional(),
105
+ credentialSchema: z.record(z.string(), z.unknown()).optional(),
106
+ credentialFieldName: z.string().optional(),
107
+ credentialHeaderName: z.string().optional(),
108
+ credentialHeaderPrefix: z.string().optional(),
109
+ authorizedUris: z.array(z.string()).optional(),
110
+ allowAllUris: z.boolean().optional(),
111
+ availableScopes: z.array(z.unknown()).optional(),
112
+ });
113
+
114
+ const setupGuide = z
115
+ .object({
116
+ callbackUrlHint: z.string().optional(),
117
+ steps: z
118
+ .array(
119
+ z.looseObject({
120
+ label: z.string(),
121
+ url: z.string().optional(),
122
+ }),
123
+ )
124
+ .optional(),
125
+ })
126
+ .optional();
127
+
128
+ // ─────────────────────────────────────────────
129
+ // Schema factory — parameterized by major version
130
+ // ─────────────────────────────────────────────
131
+
132
+ export function createSchemas(majorVersion: number) {
133
+ const schemaVersionField = z
134
+ .string()
135
+ .regex(new RegExp(`^${majorVersion}\\.(0|[1-9]\\d*)$`));
136
+
137
+ const commonFields = {
138
+ name: scopedName,
139
+ version: z.string().min(1),
140
+ type: z.enum(["flow", "skill", "tool", "provider"]),
141
+ displayName: z.string().optional(),
142
+ description: z.string().optional(),
143
+ keywords: z.array(z.string()).optional(),
144
+ license: z.string().optional(),
145
+ repository: z.string().optional(),
146
+ schemaVersion: schemaVersionField.optional(),
147
+ dependencies: dependenciesSchema,
148
+ };
149
+
150
+ const flowManifestSchema = z.looseObject({
151
+ ...commonFields,
152
+ type: z.literal("flow"),
153
+ schemaVersion: schemaVersionField,
154
+ displayName: z.string().min(1),
155
+ author: z.string(),
156
+ providersConfiguration: z.record(scopedName, providerConfiguration).optional(),
157
+ input: schemaWrapper.optional(),
158
+ output: schemaWrapper.optional(),
159
+ config: schemaWrapper.optional(),
160
+ timeout: z.number().positive().optional(),
161
+ });
162
+
163
+ const skillManifestSchema = z.looseObject({
164
+ ...commonFields,
165
+ type: z.literal("skill"),
166
+ });
167
+
168
+ const toolManifestSchema = z.looseObject({
169
+ ...commonFields,
170
+ type: z.literal("tool"),
171
+ entrypoint: z.string().min(1),
172
+ tool: toolInterface,
173
+ });
174
+
175
+ const providerManifestSchema = z.looseObject({
176
+ ...commonFields,
177
+ type: z.literal("provider"),
178
+ iconUrl: z.string().optional(),
179
+ categories: z.array(z.string()).optional(),
180
+ docsUrl: z.string().optional(),
181
+ definition: providerDefinition,
182
+ setupGuide: setupGuide,
183
+ });
184
+
185
+ return { flowManifestSchema, skillManifestSchema, toolManifestSchema, providerManifestSchema };
186
+ }
187
+
188
+ // ─────────────────────────────────────────────
189
+ // Default exports — AFPS v1
190
+ // ─────────────────────────────────────────────
191
+
192
+ const v1 = createSchemas(1);
193
+
194
+ export const flowManifestSchema = v1.flowManifestSchema;
195
+ export const skillManifestSchema = v1.skillManifestSchema;
196
+ export const toolManifestSchema = v1.toolManifestSchema;
197
+ export const providerManifestSchema = v1.providerManifestSchema;
@@ -0,0 +1,392 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://afps.appstrate.dev/schema/v1/flow.schema.json",
4
+ "title": "AFPS Flow Manifest",
5
+ "description": "Manifest schema for AFPS flow packages. A flow declares dependencies, input/output/config schemas, a timeout hint, and provider configuration.",
6
+ "type": "object",
7
+ "properties": {
8
+ "name": {
9
+ "type": "string",
10
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
11
+ },
12
+ "version": {
13
+ "type": "string",
14
+ "minLength": 1
15
+ },
16
+ "type": {
17
+ "type": "string",
18
+ "const": "flow"
19
+ },
20
+ "displayName": {
21
+ "type": "string",
22
+ "minLength": 1
23
+ },
24
+ "description": {
25
+ "type": "string"
26
+ },
27
+ "keywords": {
28
+ "type": "array",
29
+ "items": {
30
+ "type": "string"
31
+ }
32
+ },
33
+ "license": {
34
+ "type": "string"
35
+ },
36
+ "repository": {
37
+ "type": "string"
38
+ },
39
+ "schemaVersion": {
40
+ "type": "string",
41
+ "pattern": "^1\\.(0|[1-9]\\d*)$"
42
+ },
43
+ "dependencies": {
44
+ "type": "object",
45
+ "properties": {
46
+ "skills": {
47
+ "type": "object",
48
+ "propertyNames": {
49
+ "type": "string",
50
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
51
+ },
52
+ "additionalProperties": {
53
+ "type": "string",
54
+ "minLength": 1
55
+ }
56
+ },
57
+ "tools": {
58
+ "type": "object",
59
+ "propertyNames": {
60
+ "type": "string",
61
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
62
+ },
63
+ "additionalProperties": {
64
+ "type": "string",
65
+ "minLength": 1
66
+ }
67
+ },
68
+ "providers": {
69
+ "type": "object",
70
+ "propertyNames": {
71
+ "type": "string",
72
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
73
+ },
74
+ "additionalProperties": {
75
+ "type": "string",
76
+ "minLength": 1
77
+ }
78
+ }
79
+ },
80
+ "additionalProperties": {}
81
+ },
82
+ "author": {
83
+ "type": "string"
84
+ },
85
+ "providersConfiguration": {
86
+ "type": "object",
87
+ "propertyNames": {
88
+ "type": "string",
89
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
90
+ },
91
+ "additionalProperties": {
92
+ "type": "object",
93
+ "properties": {
94
+ "scopes": {
95
+ "type": "array",
96
+ "items": {
97
+ "type": "string"
98
+ }
99
+ },
100
+ "connectionMode": {
101
+ "type": "string",
102
+ "enum": [
103
+ "user",
104
+ "admin"
105
+ ]
106
+ }
107
+ },
108
+ "additionalProperties": {}
109
+ }
110
+ },
111
+ "input": {
112
+ "type": "object",
113
+ "properties": {
114
+ "schema": {
115
+ "type": "object",
116
+ "properties": {
117
+ "type": {
118
+ "type": "string",
119
+ "const": "object"
120
+ },
121
+ "properties": {
122
+ "type": "object",
123
+ "propertyNames": {
124
+ "type": "string"
125
+ },
126
+ "additionalProperties": {
127
+ "type": "object",
128
+ "properties": {
129
+ "type": {
130
+ "type": "string",
131
+ "enum": [
132
+ "string",
133
+ "number",
134
+ "boolean",
135
+ "array",
136
+ "object",
137
+ "file"
138
+ ]
139
+ },
140
+ "description": {
141
+ "type": "string"
142
+ },
143
+ "default": {},
144
+ "enum": {
145
+ "type": "array",
146
+ "items": {}
147
+ },
148
+ "format": {
149
+ "type": "string"
150
+ },
151
+ "placeholder": {
152
+ "type": "string"
153
+ },
154
+ "accept": {
155
+ "type": "string"
156
+ },
157
+ "maxSize": {
158
+ "type": "number",
159
+ "exclusiveMinimum": 0
160
+ },
161
+ "multiple": {
162
+ "type": "boolean"
163
+ },
164
+ "maxFiles": {
165
+ "type": "number",
166
+ "exclusiveMinimum": 0
167
+ }
168
+ },
169
+ "required": [
170
+ "type"
171
+ ],
172
+ "additionalProperties": {}
173
+ }
174
+ },
175
+ "required": {
176
+ "type": "array",
177
+ "items": {
178
+ "type": "string"
179
+ }
180
+ },
181
+ "propertyOrder": {
182
+ "type": "array",
183
+ "items": {
184
+ "type": "string"
185
+ }
186
+ }
187
+ },
188
+ "required": [
189
+ "type",
190
+ "properties"
191
+ ],
192
+ "additionalProperties": {}
193
+ }
194
+ },
195
+ "required": [
196
+ "schema"
197
+ ],
198
+ "additionalProperties": false
199
+ },
200
+ "output": {
201
+ "type": "object",
202
+ "properties": {
203
+ "schema": {
204
+ "type": "object",
205
+ "properties": {
206
+ "type": {
207
+ "type": "string",
208
+ "const": "object"
209
+ },
210
+ "properties": {
211
+ "type": "object",
212
+ "propertyNames": {
213
+ "type": "string"
214
+ },
215
+ "additionalProperties": {
216
+ "type": "object",
217
+ "properties": {
218
+ "type": {
219
+ "type": "string",
220
+ "enum": [
221
+ "string",
222
+ "number",
223
+ "boolean",
224
+ "array",
225
+ "object",
226
+ "file"
227
+ ]
228
+ },
229
+ "description": {
230
+ "type": "string"
231
+ },
232
+ "default": {},
233
+ "enum": {
234
+ "type": "array",
235
+ "items": {}
236
+ },
237
+ "format": {
238
+ "type": "string"
239
+ },
240
+ "placeholder": {
241
+ "type": "string"
242
+ },
243
+ "accept": {
244
+ "type": "string"
245
+ },
246
+ "maxSize": {
247
+ "type": "number",
248
+ "exclusiveMinimum": 0
249
+ },
250
+ "multiple": {
251
+ "type": "boolean"
252
+ },
253
+ "maxFiles": {
254
+ "type": "number",
255
+ "exclusiveMinimum": 0
256
+ }
257
+ },
258
+ "required": [
259
+ "type"
260
+ ],
261
+ "additionalProperties": {}
262
+ }
263
+ },
264
+ "required": {
265
+ "type": "array",
266
+ "items": {
267
+ "type": "string"
268
+ }
269
+ },
270
+ "propertyOrder": {
271
+ "type": "array",
272
+ "items": {
273
+ "type": "string"
274
+ }
275
+ }
276
+ },
277
+ "required": [
278
+ "type",
279
+ "properties"
280
+ ],
281
+ "additionalProperties": {}
282
+ }
283
+ },
284
+ "required": [
285
+ "schema"
286
+ ],
287
+ "additionalProperties": false
288
+ },
289
+ "config": {
290
+ "type": "object",
291
+ "properties": {
292
+ "schema": {
293
+ "type": "object",
294
+ "properties": {
295
+ "type": {
296
+ "type": "string",
297
+ "const": "object"
298
+ },
299
+ "properties": {
300
+ "type": "object",
301
+ "propertyNames": {
302
+ "type": "string"
303
+ },
304
+ "additionalProperties": {
305
+ "type": "object",
306
+ "properties": {
307
+ "type": {
308
+ "type": "string",
309
+ "enum": [
310
+ "string",
311
+ "number",
312
+ "boolean",
313
+ "array",
314
+ "object",
315
+ "file"
316
+ ]
317
+ },
318
+ "description": {
319
+ "type": "string"
320
+ },
321
+ "default": {},
322
+ "enum": {
323
+ "type": "array",
324
+ "items": {}
325
+ },
326
+ "format": {
327
+ "type": "string"
328
+ },
329
+ "placeholder": {
330
+ "type": "string"
331
+ },
332
+ "accept": {
333
+ "type": "string"
334
+ },
335
+ "maxSize": {
336
+ "type": "number",
337
+ "exclusiveMinimum": 0
338
+ },
339
+ "multiple": {
340
+ "type": "boolean"
341
+ },
342
+ "maxFiles": {
343
+ "type": "number",
344
+ "exclusiveMinimum": 0
345
+ }
346
+ },
347
+ "required": [
348
+ "type"
349
+ ],
350
+ "additionalProperties": {}
351
+ }
352
+ },
353
+ "required": {
354
+ "type": "array",
355
+ "items": {
356
+ "type": "string"
357
+ }
358
+ },
359
+ "propertyOrder": {
360
+ "type": "array",
361
+ "items": {
362
+ "type": "string"
363
+ }
364
+ }
365
+ },
366
+ "required": [
367
+ "type",
368
+ "properties"
369
+ ],
370
+ "additionalProperties": {}
371
+ }
372
+ },
373
+ "required": [
374
+ "schema"
375
+ ],
376
+ "additionalProperties": false
377
+ },
378
+ "timeout": {
379
+ "type": "number",
380
+ "exclusiveMinimum": 0
381
+ }
382
+ },
383
+ "required": [
384
+ "name",
385
+ "version",
386
+ "type",
387
+ "displayName",
388
+ "schemaVersion",
389
+ "author"
390
+ ],
391
+ "additionalProperties": {}
392
+ }
@@ -0,0 +1,220 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://afps.appstrate.dev/schema/v1/provider.schema.json",
4
+ "title": "AFPS Provider Manifest",
5
+ "description": "Manifest schema for AFPS provider packages. A provider declares auth mode, OAuth endpoints, credential schema, and setup guide.",
6
+ "type": "object",
7
+ "properties": {
8
+ "name": {
9
+ "type": "string",
10
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
11
+ },
12
+ "version": {
13
+ "type": "string",
14
+ "minLength": 1
15
+ },
16
+ "type": {
17
+ "type": "string",
18
+ "const": "provider"
19
+ },
20
+ "displayName": {
21
+ "type": "string"
22
+ },
23
+ "description": {
24
+ "type": "string"
25
+ },
26
+ "keywords": {
27
+ "type": "array",
28
+ "items": {
29
+ "type": "string"
30
+ }
31
+ },
32
+ "license": {
33
+ "type": "string"
34
+ },
35
+ "repository": {
36
+ "type": "string"
37
+ },
38
+ "schemaVersion": {
39
+ "type": "string",
40
+ "pattern": "^1\\.(0|[1-9]\\d*)$"
41
+ },
42
+ "dependencies": {
43
+ "type": "object",
44
+ "properties": {
45
+ "skills": {
46
+ "type": "object",
47
+ "propertyNames": {
48
+ "type": "string",
49
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
50
+ },
51
+ "additionalProperties": {
52
+ "type": "string",
53
+ "minLength": 1
54
+ }
55
+ },
56
+ "tools": {
57
+ "type": "object",
58
+ "propertyNames": {
59
+ "type": "string",
60
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
61
+ },
62
+ "additionalProperties": {
63
+ "type": "string",
64
+ "minLength": 1
65
+ }
66
+ },
67
+ "providers": {
68
+ "type": "object",
69
+ "propertyNames": {
70
+ "type": "string",
71
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
72
+ },
73
+ "additionalProperties": {
74
+ "type": "string",
75
+ "minLength": 1
76
+ }
77
+ }
78
+ },
79
+ "additionalProperties": {}
80
+ },
81
+ "iconUrl": {
82
+ "type": "string"
83
+ },
84
+ "categories": {
85
+ "type": "array",
86
+ "items": {
87
+ "type": "string"
88
+ }
89
+ },
90
+ "docsUrl": {
91
+ "type": "string"
92
+ },
93
+ "definition": {
94
+ "type": "object",
95
+ "properties": {
96
+ "authMode": {
97
+ "type": "string",
98
+ "enum": [
99
+ "oauth2",
100
+ "oauth1",
101
+ "api_key",
102
+ "basic",
103
+ "custom"
104
+ ]
105
+ },
106
+ "authorizationUrl": {
107
+ "type": "string"
108
+ },
109
+ "tokenUrl": {
110
+ "type": "string"
111
+ },
112
+ "refreshUrl": {
113
+ "type": "string"
114
+ },
115
+ "defaultScopes": {
116
+ "type": "array",
117
+ "items": {
118
+ "type": "string"
119
+ }
120
+ },
121
+ "scopeSeparator": {
122
+ "type": "string"
123
+ },
124
+ "pkceEnabled": {
125
+ "type": "boolean"
126
+ },
127
+ "tokenAuthMethod": {
128
+ "type": "string"
129
+ },
130
+ "authorizationParams": {
131
+ "type": "object",
132
+ "propertyNames": {
133
+ "type": "string"
134
+ },
135
+ "additionalProperties": {}
136
+ },
137
+ "tokenParams": {
138
+ "type": "object",
139
+ "propertyNames": {
140
+ "type": "string"
141
+ },
142
+ "additionalProperties": {}
143
+ },
144
+ "requestTokenUrl": {
145
+ "type": "string"
146
+ },
147
+ "accessTokenUrl": {
148
+ "type": "string"
149
+ },
150
+ "credentialSchema": {
151
+ "type": "object",
152
+ "propertyNames": {
153
+ "type": "string"
154
+ },
155
+ "additionalProperties": {}
156
+ },
157
+ "credentialFieldName": {
158
+ "type": "string"
159
+ },
160
+ "credentialHeaderName": {
161
+ "type": "string"
162
+ },
163
+ "credentialHeaderPrefix": {
164
+ "type": "string"
165
+ },
166
+ "authorizedUris": {
167
+ "type": "array",
168
+ "items": {
169
+ "type": "string"
170
+ }
171
+ },
172
+ "allowAllUris": {
173
+ "type": "boolean"
174
+ },
175
+ "availableScopes": {
176
+ "type": "array",
177
+ "items": {}
178
+ }
179
+ },
180
+ "required": [
181
+ "authMode"
182
+ ],
183
+ "additionalProperties": {}
184
+ },
185
+ "setupGuide": {
186
+ "type": "object",
187
+ "properties": {
188
+ "callbackUrlHint": {
189
+ "type": "string"
190
+ },
191
+ "steps": {
192
+ "type": "array",
193
+ "items": {
194
+ "type": "object",
195
+ "properties": {
196
+ "label": {
197
+ "type": "string"
198
+ },
199
+ "url": {
200
+ "type": "string"
201
+ }
202
+ },
203
+ "required": [
204
+ "label"
205
+ ],
206
+ "additionalProperties": {}
207
+ }
208
+ }
209
+ },
210
+ "additionalProperties": false
211
+ }
212
+ },
213
+ "required": [
214
+ "name",
215
+ "version",
216
+ "type",
217
+ "definition"
218
+ ],
219
+ "additionalProperties": {}
220
+ }
@@ -0,0 +1,88 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://afps.appstrate.dev/schema/v1/skill.schema.json",
4
+ "title": "AFPS Skill Manifest",
5
+ "description": "Manifest schema for AFPS skill packages. A skill is a reusable prompt with optional frontmatter metadata.",
6
+ "type": "object",
7
+ "properties": {
8
+ "name": {
9
+ "type": "string",
10
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
11
+ },
12
+ "version": {
13
+ "type": "string",
14
+ "minLength": 1
15
+ },
16
+ "type": {
17
+ "type": "string",
18
+ "const": "skill"
19
+ },
20
+ "displayName": {
21
+ "type": "string"
22
+ },
23
+ "description": {
24
+ "type": "string"
25
+ },
26
+ "keywords": {
27
+ "type": "array",
28
+ "items": {
29
+ "type": "string"
30
+ }
31
+ },
32
+ "license": {
33
+ "type": "string"
34
+ },
35
+ "repository": {
36
+ "type": "string"
37
+ },
38
+ "schemaVersion": {
39
+ "type": "string",
40
+ "pattern": "^1\\.(0|[1-9]\\d*)$"
41
+ },
42
+ "dependencies": {
43
+ "type": "object",
44
+ "properties": {
45
+ "skills": {
46
+ "type": "object",
47
+ "propertyNames": {
48
+ "type": "string",
49
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
50
+ },
51
+ "additionalProperties": {
52
+ "type": "string",
53
+ "minLength": 1
54
+ }
55
+ },
56
+ "tools": {
57
+ "type": "object",
58
+ "propertyNames": {
59
+ "type": "string",
60
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
61
+ },
62
+ "additionalProperties": {
63
+ "type": "string",
64
+ "minLength": 1
65
+ }
66
+ },
67
+ "providers": {
68
+ "type": "object",
69
+ "propertyNames": {
70
+ "type": "string",
71
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
72
+ },
73
+ "additionalProperties": {
74
+ "type": "string",
75
+ "minLength": 1
76
+ }
77
+ }
78
+ },
79
+ "additionalProperties": {}
80
+ }
81
+ },
82
+ "required": [
83
+ "name",
84
+ "version",
85
+ "type"
86
+ ],
87
+ "additionalProperties": {}
88
+ }
@@ -0,0 +1,118 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://afps.appstrate.dev/schema/v1/tool.schema.json",
4
+ "title": "AFPS Tool Manifest",
5
+ "description": "Manifest schema for AFPS tool packages. A tool declares a single callable capability with its interface and implementation source.",
6
+ "type": "object",
7
+ "properties": {
8
+ "name": {
9
+ "type": "string",
10
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
11
+ },
12
+ "version": {
13
+ "type": "string",
14
+ "minLength": 1
15
+ },
16
+ "type": {
17
+ "type": "string",
18
+ "const": "tool"
19
+ },
20
+ "displayName": {
21
+ "type": "string"
22
+ },
23
+ "description": {
24
+ "type": "string"
25
+ },
26
+ "keywords": {
27
+ "type": "array",
28
+ "items": {
29
+ "type": "string"
30
+ }
31
+ },
32
+ "license": {
33
+ "type": "string"
34
+ },
35
+ "repository": {
36
+ "type": "string"
37
+ },
38
+ "schemaVersion": {
39
+ "type": "string",
40
+ "pattern": "^1\\.(0|[1-9]\\d*)$"
41
+ },
42
+ "dependencies": {
43
+ "type": "object",
44
+ "properties": {
45
+ "skills": {
46
+ "type": "object",
47
+ "propertyNames": {
48
+ "type": "string",
49
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
50
+ },
51
+ "additionalProperties": {
52
+ "type": "string",
53
+ "minLength": 1
54
+ }
55
+ },
56
+ "tools": {
57
+ "type": "object",
58
+ "propertyNames": {
59
+ "type": "string",
60
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
61
+ },
62
+ "additionalProperties": {
63
+ "type": "string",
64
+ "minLength": 1
65
+ }
66
+ },
67
+ "providers": {
68
+ "type": "object",
69
+ "propertyNames": {
70
+ "type": "string",
71
+ "pattern": "^@[a-z0-9]([a-z0-9-]*[a-z0-9])?\\/[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
72
+ },
73
+ "additionalProperties": {
74
+ "type": "string",
75
+ "minLength": 1
76
+ }
77
+ }
78
+ },
79
+ "additionalProperties": {}
80
+ },
81
+ "entrypoint": {
82
+ "type": "string",
83
+ "minLength": 1
84
+ },
85
+ "tool": {
86
+ "type": "object",
87
+ "properties": {
88
+ "name": {
89
+ "type": "string",
90
+ "minLength": 1
91
+ },
92
+ "description": {
93
+ "type": "string",
94
+ "minLength": 1
95
+ },
96
+ "inputSchema": {
97
+ "type": "object",
98
+ "properties": {},
99
+ "additionalProperties": {}
100
+ }
101
+ },
102
+ "required": [
103
+ "name",
104
+ "description",
105
+ "inputSchema"
106
+ ],
107
+ "additionalProperties": false
108
+ }
109
+ },
110
+ "required": [
111
+ "name",
112
+ "version",
113
+ "type",
114
+ "entrypoint",
115
+ "tool"
116
+ ],
117
+ "additionalProperties": {}
118
+ }