@agentrules/core 0.0.6 → 0.0.7
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 +95 -60
- package/dist/index.d.ts +137 -136
- package/dist/index.js +63 -84
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,28 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
Shared types and utilities for the AGENT_RULES ecosystem.
|
|
4
4
|
|
|
5
|
+
**This package is for developers building custom registries or alternative clients.** If you just want to install or publish presets, use the [CLI](../cli) instead.
|
|
6
|
+
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
10
|
npm install @agentrules/core
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
##
|
|
13
|
+
## What's Included
|
|
14
|
+
|
|
15
|
+
| Module | Description |
|
|
16
|
+
|--------|-------------|
|
|
17
|
+
| **Types & Schemas** | TypeScript types and Zod schemas for presets, bundles, configs |
|
|
18
|
+
| **Registry Builder** | Build registry artifacts from preset inputs |
|
|
19
|
+
| **Registry Client** | Fetch and resolve presets from registries |
|
|
20
|
+
| **Bundle Utilities** | Encode/decode bundles, verify checksums |
|
|
21
|
+
| **Platform Config** | Platform IDs and directory paths |
|
|
12
22
|
|
|
13
|
-
|
|
14
|
-
- **Validation** - Zod schemas for validating `agentrules.json` configs
|
|
15
|
-
- **Registry Builder** - Transform preset inputs into registry JSON artifacts
|
|
16
|
-
- **Bundle Utilities** - Checksum verification, encoding/decoding helpers
|
|
17
|
-
- **Diff Utilities** - Generate previews for file conflicts
|
|
23
|
+
This package contains **pure functions with no environment assumptions**. It doesn't touch the file system or make network requests directly — that's left to the consumer (like the CLI).
|
|
18
24
|
|
|
19
25
|
## Usage
|
|
20
26
|
|
|
21
|
-
###
|
|
27
|
+
### Validating Preset Config
|
|
22
28
|
|
|
23
29
|
```ts
|
|
24
|
-
import {
|
|
30
|
+
import { presetConfigSchema, validatePresetConfig } from "@agentrules/core";
|
|
31
|
+
|
|
32
|
+
// Using Zod schema directly
|
|
33
|
+
const result = presetConfigSchema.safeParse(jsonData);
|
|
34
|
+
if (!result.success) {
|
|
35
|
+
console.error(result.error.issues);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Or use the helper (throws on error)
|
|
39
|
+
const config = validatePresetConfig(jsonData, "my-preset");
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Building Registry Artifacts
|
|
25
43
|
|
|
26
|
-
|
|
44
|
+
```ts
|
|
45
|
+
import { buildPresetRegistry } from "@agentrules/core";
|
|
46
|
+
|
|
47
|
+
const result = await buildPresetRegistry({
|
|
27
48
|
presets: [
|
|
28
49
|
{
|
|
29
50
|
slug: "my-preset",
|
|
@@ -32,48 +53,36 @@ const result = await buildRegistryData({
|
|
|
32
53
|
title: "My Preset",
|
|
33
54
|
version: 1,
|
|
34
55
|
description: "A helpful preset",
|
|
56
|
+
tags: ["starter"],
|
|
35
57
|
license: "MIT",
|
|
36
58
|
platform: "opencode",
|
|
37
|
-
path: "
|
|
59
|
+
path: "files",
|
|
38
60
|
},
|
|
39
61
|
files: [
|
|
40
62
|
{ path: "AGENT_RULES.md", contents: "# Rules\n" },
|
|
41
|
-
{ path: "config.json", contents: '{"key": "value"}' },
|
|
42
63
|
],
|
|
43
64
|
},
|
|
44
65
|
],
|
|
45
66
|
});
|
|
46
67
|
|
|
47
|
-
// result.entries →
|
|
48
|
-
// result.index →
|
|
49
|
-
// result.bundles →
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Validating Preset Config
|
|
53
|
-
|
|
54
|
-
```ts
|
|
55
|
-
import { validatePresetConfig, presetConfigSchema } from "@agentrules/core";
|
|
56
|
-
|
|
57
|
-
// Quick validation (throws on error)
|
|
58
|
-
const config = validatePresetConfig(jsonData, "my-preset");
|
|
59
|
-
|
|
60
|
-
// Zod schema for custom handling
|
|
61
|
-
const result = presetConfigSchema.safeParse(jsonData);
|
|
62
|
-
if (!result.success) {
|
|
63
|
-
console.error(result.error.issues);
|
|
64
|
-
}
|
|
68
|
+
// result.entries → Preset[] for registry listing
|
|
69
|
+
// result.index → PresetIndex for lookups
|
|
70
|
+
// result.bundles → PresetBundle[] with encoded files
|
|
65
71
|
```
|
|
66
72
|
|
|
67
|
-
### Fetching from Registry
|
|
73
|
+
### Fetching from a Registry
|
|
68
74
|
|
|
69
75
|
```ts
|
|
70
76
|
import { resolvePreset, fetchBundle } from "@agentrules/core";
|
|
71
77
|
|
|
72
|
-
|
|
78
|
+
// Resolve a preset (gets metadata and bundle URL)
|
|
79
|
+
const { preset, bundleUrl } = await resolvePreset(
|
|
73
80
|
"https://agentrules.directory/",
|
|
74
|
-
"
|
|
81
|
+
"my-preset",
|
|
75
82
|
"opencode"
|
|
76
83
|
);
|
|
84
|
+
|
|
85
|
+
// Fetch the bundle
|
|
77
86
|
const bundle = await fetchBundle(bundleUrl);
|
|
78
87
|
```
|
|
79
88
|
|
|
@@ -87,45 +96,71 @@ import {
|
|
|
87
96
|
} from "@agentrules/core";
|
|
88
97
|
|
|
89
98
|
for (const file of bundle.files) {
|
|
99
|
+
// Decode base64 contents
|
|
90
100
|
const data = decodeBundledFile(file);
|
|
101
|
+
|
|
102
|
+
// Verify integrity
|
|
91
103
|
await verifyBundledFileChecksum(file, data);
|
|
92
104
|
|
|
105
|
+
// Check if it's text or binary
|
|
93
106
|
if (isLikelyText(data)) {
|
|
94
|
-
|
|
107
|
+
const text = new TextDecoder().decode(data);
|
|
95
108
|
}
|
|
96
109
|
}
|
|
97
110
|
```
|
|
98
111
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
"tags": ["starter", "typescript"],
|
|
112
|
-
"features": ["Feature 1", "Feature 2"],
|
|
113
|
-
"platform": "opencode",
|
|
114
|
-
"path": "files"
|
|
115
|
-
}
|
|
112
|
+
### Platform Configuration
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import { PLATFORMS, PLATFORM_IDS } from "@agentrules/core";
|
|
116
|
+
|
|
117
|
+
// All supported platform IDs
|
|
118
|
+
console.log(PLATFORM_IDS); // ["opencode", "claude", "cursor", "codex"]
|
|
119
|
+
|
|
120
|
+
// Get paths for a platform
|
|
121
|
+
const opencode = PLATFORMS.opencode;
|
|
122
|
+
console.log(opencode.projectDir); // ".opencode"
|
|
123
|
+
console.log(opencode.globalDir); // "~/.config/opencode"
|
|
116
124
|
```
|
|
117
125
|
|
|
118
|
-
|
|
126
|
+
## Types
|
|
119
127
|
|
|
120
|
-
|
|
121
|
-
- **Major version**: Set by the publisher in config (defaults to 1)
|
|
122
|
-
- **Minor version**: Auto-incremented by the registry on each publish
|
|
128
|
+
Key types exported:
|
|
123
129
|
|
|
124
|
-
|
|
130
|
+
```ts
|
|
131
|
+
import type {
|
|
132
|
+
// Preset configuration (agentrules.json)
|
|
133
|
+
PresetConfig,
|
|
134
|
+
|
|
135
|
+
// What clients send to publish
|
|
136
|
+
PresetPublishInput,
|
|
137
|
+
|
|
138
|
+
// What registries store and return
|
|
139
|
+
PresetBundle,
|
|
140
|
+
Preset,
|
|
141
|
+
PresetIndex,
|
|
142
|
+
|
|
143
|
+
// Bundle file structure
|
|
144
|
+
BundledFile,
|
|
145
|
+
|
|
146
|
+
// Platform types
|
|
147
|
+
PlatformId,
|
|
148
|
+
PlatformConfig,
|
|
149
|
+
} from "@agentrules/core";
|
|
150
|
+
```
|
|
125
151
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
152
|
+
## Schemas
|
|
153
|
+
|
|
154
|
+
Zod schemas for validation:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import {
|
|
158
|
+
presetConfigSchema,
|
|
159
|
+
presetBundleSchema,
|
|
160
|
+
presetPublishInputSchema,
|
|
161
|
+
platformIdSchema,
|
|
162
|
+
slugSchema,
|
|
163
|
+
titleSchema,
|
|
164
|
+
descriptionSchema,
|
|
165
|
+
} from "@agentrules/core";
|
|
131
166
|
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,112 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
|
-
//#region src/
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Single source of truth for platform IDs.
|
|
7
|
-
* Add new platforms here - types and config will follow.
|
|
8
|
-
*/
|
|
9
|
-
declare const PLATFORM_ID_TUPLE: readonly ["opencode", "codex", "claude", "cursor"];
|
|
10
|
-
/** Union type of supported platform IDs, derived from PLATFORM_ID_TUPLE */
|
|
11
|
-
type PlatformId = (typeof PLATFORM_ID_TUPLE)[number];
|
|
12
|
-
/** List of supported platform IDs as a readonly tuple */
|
|
13
|
-
declare const PLATFORM_IDS: readonly ["opencode", "codex", "claude", "cursor"];
|
|
14
|
-
type PlatformConfig = {
|
|
15
|
-
/** Directory name for project installs (e.g., ".opencode") */
|
|
16
|
-
projectDir: string;
|
|
17
|
-
/** Path for global installs (e.g., "~/.config/opencode") */
|
|
18
|
-
globalDir: string;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Platform-specific configuration.
|
|
22
|
-
* Single source of truth for all platform paths.
|
|
23
|
-
*/
|
|
24
|
-
declare const PLATFORMS: Record<PlatformId, PlatformConfig>;
|
|
25
|
-
/**
|
|
26
|
-
* Convention: preset files under this directory map to the platform config directory.
|
|
27
|
-
* e.g., `config/agent.md` → `.opencode/agent.md` (project) or `agent.md` (global)
|
|
28
|
-
*/
|
|
29
|
-
declare const CONFIG_DIR_NAME = "config";
|
|
30
|
-
declare function isSupportedPlatform(value: string): value is PlatformId;
|
|
31
|
-
declare function normalizePlatformInput(value: string): PlatformId;
|
|
32
|
-
//#endregion
|
|
33
|
-
//#region src/types/definitions.d.ts
|
|
34
|
-
type PresetConfig = {
|
|
35
|
-
$schema?: string;
|
|
36
|
-
name: string;
|
|
37
|
-
title: string;
|
|
38
|
-
version?: number;
|
|
39
|
-
description: string;
|
|
40
|
-
tags?: string[];
|
|
41
|
-
features?: string[];
|
|
42
|
-
license: string;
|
|
43
|
-
platform: PlatformId;
|
|
44
|
-
/** Path to config files. Defaults to platform's projectDir (e.g., ".claude") */
|
|
45
|
-
path?: string;
|
|
46
|
-
};
|
|
47
|
-
type BundledFile = {
|
|
48
|
-
path: string;
|
|
49
|
-
/** File size in bytes */
|
|
50
|
-
size: number;
|
|
51
|
-
checksum: string;
|
|
52
|
-
contents: string;
|
|
53
|
-
};
|
|
54
|
-
/**
|
|
55
|
-
* What clients send to publish a preset.
|
|
56
|
-
* Version is optional major version. Registry assigns full MAJOR.MINOR.
|
|
57
|
-
*/
|
|
58
|
-
type PublishInput = {
|
|
59
|
-
slug: string;
|
|
60
|
-
platform: PlatformId;
|
|
61
|
-
title: string;
|
|
62
|
-
description: string;
|
|
63
|
-
tags: string[];
|
|
64
|
-
license: string;
|
|
65
|
-
licenseContent?: string;
|
|
66
|
-
readmeContent?: string;
|
|
67
|
-
features?: string[];
|
|
68
|
-
installMessage?: string;
|
|
69
|
-
files: BundledFile[];
|
|
70
|
-
/** Major version. Defaults to 1 if not specified. */
|
|
71
|
-
version?: number;
|
|
72
|
-
};
|
|
73
|
-
/**
|
|
74
|
-
* What registries store and return.
|
|
75
|
-
* Includes version (required) - full MAJOR.MINOR format assigned by registry.
|
|
76
|
-
*/
|
|
77
|
-
type RegistryBundle = Omit<PublishInput, "version"> & {
|
|
78
|
-
/** Full version in MAJOR.MINOR format (e.g., "1.3", "2.1") */
|
|
79
|
-
version: string;
|
|
80
|
-
};
|
|
81
|
-
type RegistryEntry = {
|
|
82
|
-
name: string;
|
|
83
|
-
slug: string;
|
|
84
|
-
platform: PlatformId;
|
|
85
|
-
title: string;
|
|
86
|
-
version: string;
|
|
87
|
-
description: string;
|
|
88
|
-
tags: string[];
|
|
89
|
-
license: string;
|
|
90
|
-
features?: string[];
|
|
91
|
-
bundleUrl: string;
|
|
92
|
-
fileCount: number;
|
|
93
|
-
totalSize: number;
|
|
94
|
-
};
|
|
95
|
-
type RegistryIndex = Record<string, RegistryEntry>;
|
|
96
|
-
type RegistryFileInput = {
|
|
97
|
-
path: string;
|
|
98
|
-
contents: ArrayBuffer | ArrayBufferView | string;
|
|
99
|
-
};
|
|
100
|
-
type RegistryPresetInput = {
|
|
101
|
-
slug: string;
|
|
102
|
-
config: PresetConfig;
|
|
103
|
-
files: RegistryFileInput[];
|
|
104
|
-
/** Install message from INSTALL.txt file */
|
|
105
|
-
installMessage?: string;
|
|
106
|
-
readmeContent?: string;
|
|
107
|
-
licenseContent?: string;
|
|
108
|
-
}; //#endregion
|
|
109
|
-
//#region src/types/schema.d.ts
|
|
3
|
+
//#region src/preset/schema.d.ts
|
|
110
4
|
declare const platformIdSchema: z.ZodEnum<{
|
|
111
5
|
opencode: "opencode";
|
|
112
6
|
codex: "codex";
|
|
@@ -115,18 +9,10 @@ declare const platformIdSchema: z.ZodEnum<{
|
|
|
115
9
|
}>;
|
|
116
10
|
declare const titleSchema: z.ZodString;
|
|
117
11
|
declare const descriptionSchema: z.ZodString;
|
|
118
|
-
/** Validate a title string and return error message if invalid, undefined if valid */
|
|
119
|
-
declare function validateTitle(value: string): string | undefined;
|
|
120
|
-
/** Validate a description string and return error message if invalid, undefined if valid */
|
|
121
|
-
declare function validateDescription(value: string): string | undefined;
|
|
122
12
|
declare const slugSchema: z.ZodString;
|
|
123
|
-
/** Validate a slug string and return error message if invalid, undefined if valid */
|
|
124
|
-
declare function validateSlug(value: string): string | undefined;
|
|
125
13
|
declare const COMMON_LICENSES: readonly ["MIT", "Apache-2.0", "GPL-3.0-only", "BSD-3-Clause", "ISC", "Unlicense"];
|
|
126
14
|
type CommonLicense = (typeof COMMON_LICENSES)[number];
|
|
127
15
|
declare const licenseSchema: z.ZodString;
|
|
128
|
-
/** Validate a license string and return error message if invalid, undefined if valid */
|
|
129
|
-
declare function validateLicense(value: string): string | undefined;
|
|
130
16
|
declare const presetConfigSchema: z.ZodObject<{
|
|
131
17
|
$schema: z.ZodOptional<z.ZodString>;
|
|
132
18
|
name: z.ZodString;
|
|
@@ -154,7 +40,7 @@ declare const bundledFileSchema: z.ZodObject<{
|
|
|
154
40
|
* Schema for what clients send to publish a preset.
|
|
155
41
|
* Version is optional major version. Registry assigns full MAJOR.MINOR.
|
|
156
42
|
*/
|
|
157
|
-
declare const
|
|
43
|
+
declare const presetPublishInputSchema: z.ZodObject<{
|
|
158
44
|
slug: z.ZodString;
|
|
159
45
|
platform: z.ZodEnum<{
|
|
160
46
|
opencode: "opencode";
|
|
@@ -182,7 +68,7 @@ declare const publishInputSchema: z.ZodObject<{
|
|
|
182
68
|
* Schema for what registries store and return.
|
|
183
69
|
* Includes version (required) - full MAJOR.MINOR format assigned by registry.
|
|
184
70
|
*/
|
|
185
|
-
declare const
|
|
71
|
+
declare const presetBundleSchema: z.ZodObject<{
|
|
186
72
|
title: z.ZodString;
|
|
187
73
|
description: z.ZodString;
|
|
188
74
|
license: z.ZodString;
|
|
@@ -206,7 +92,7 @@ declare const registryBundleSchema: z.ZodObject<{
|
|
|
206
92
|
}, z.core.$strip>>;
|
|
207
93
|
version: z.ZodString;
|
|
208
94
|
}, z.core.$strip>;
|
|
209
|
-
declare const
|
|
95
|
+
declare const presetSchema: z.ZodObject<{
|
|
210
96
|
title: z.ZodString;
|
|
211
97
|
description: z.ZodString;
|
|
212
98
|
license: z.ZodString;
|
|
@@ -225,7 +111,7 @@ declare const registryEntrySchema: z.ZodObject<{
|
|
|
225
111
|
fileCount: z.ZodNumber;
|
|
226
112
|
totalSize: z.ZodNumber;
|
|
227
113
|
}, z.core.$strip>;
|
|
228
|
-
declare const
|
|
114
|
+
declare const presetIndexSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
229
115
|
title: z.ZodString;
|
|
230
116
|
description: z.ZodString;
|
|
231
117
|
license: z.ZodString;
|
|
@@ -245,6 +131,121 @@ declare const registryIndexSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
|
245
131
|
totalSize: z.ZodNumber;
|
|
246
132
|
}, z.core.$strip>>;
|
|
247
133
|
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region src/platform/types.d.ts
|
|
136
|
+
/**
|
|
137
|
+
* Single source of truth for platform IDs.
|
|
138
|
+
* Add new platforms here - types and config will follow.
|
|
139
|
+
*/
|
|
140
|
+
declare const PLATFORM_ID_TUPLE: readonly ["opencode", "codex", "claude", "cursor"];
|
|
141
|
+
/** Union type of supported platform IDs, derived from PLATFORM_ID_TUPLE */
|
|
142
|
+
type PlatformId = (typeof PLATFORM_ID_TUPLE)[number];
|
|
143
|
+
/** Configuration for a platform's directory paths */
|
|
144
|
+
type PlatformConfig = {
|
|
145
|
+
/** Directory name for project installs (e.g., ".opencode") */
|
|
146
|
+
projectDir: string;
|
|
147
|
+
/** Path for global installs (e.g., "~/.config/opencode") */
|
|
148
|
+
globalDir: string;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/platform/config.d.ts
|
|
153
|
+
/** List of supported platform IDs as a readonly tuple */
|
|
154
|
+
declare const PLATFORM_IDS: readonly ["opencode", "codex", "claude", "cursor"];
|
|
155
|
+
/**
|
|
156
|
+
* Platform-specific configuration.
|
|
157
|
+
* Single source of truth for all platform paths.
|
|
158
|
+
*/
|
|
159
|
+
declare const PLATFORMS: Record<PlatformId, PlatformConfig>;
|
|
160
|
+
/**
|
|
161
|
+
* Convention: preset files under this directory map to the platform config directory.
|
|
162
|
+
* e.g., `config/agent.md` → `.opencode/agent.md` (project) or `agent.md` (global)
|
|
163
|
+
*/
|
|
164
|
+
declare const CONFIG_DIR_NAME = "config";
|
|
165
|
+
|
|
166
|
+
//#endregion
|
|
167
|
+
//#region src/platform/utils.d.ts
|
|
168
|
+
declare function isSupportedPlatform(value: string): value is PlatformId;
|
|
169
|
+
declare function normalizePlatformInput(value: string): PlatformId;
|
|
170
|
+
|
|
171
|
+
//#endregion
|
|
172
|
+
//#region src/preset/types.d.ts
|
|
173
|
+
type PresetConfig = {
|
|
174
|
+
$schema?: string;
|
|
175
|
+
name: string;
|
|
176
|
+
title: string;
|
|
177
|
+
version?: number;
|
|
178
|
+
description: string;
|
|
179
|
+
tags?: string[];
|
|
180
|
+
features?: string[];
|
|
181
|
+
license: string;
|
|
182
|
+
platform: PlatformId;
|
|
183
|
+
/** Path to config files. Defaults to platform's projectDir (e.g., ".claude") */
|
|
184
|
+
path?: string;
|
|
185
|
+
};
|
|
186
|
+
type BundledFile = {
|
|
187
|
+
path: string;
|
|
188
|
+
/** File size in bytes */
|
|
189
|
+
size: number;
|
|
190
|
+
checksum: string;
|
|
191
|
+
contents: string;
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* What clients send to publish a preset.
|
|
195
|
+
* Version is optional major version. Registry assigns full MAJOR.MINOR.
|
|
196
|
+
*/
|
|
197
|
+
type PresetPublishInput = {
|
|
198
|
+
slug: string;
|
|
199
|
+
platform: PlatformId;
|
|
200
|
+
title: string;
|
|
201
|
+
description: string;
|
|
202
|
+
tags: string[];
|
|
203
|
+
license: string;
|
|
204
|
+
licenseContent?: string;
|
|
205
|
+
readmeContent?: string;
|
|
206
|
+
features?: string[];
|
|
207
|
+
installMessage?: string;
|
|
208
|
+
files: BundledFile[];
|
|
209
|
+
/** Major version. Defaults to 1 if not specified. */
|
|
210
|
+
version?: number;
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* What registries store and return.
|
|
214
|
+
* Includes version (required) - full MAJOR.MINOR format assigned by registry.
|
|
215
|
+
*/
|
|
216
|
+
type PresetBundle = Omit<PresetPublishInput, "version"> & {
|
|
217
|
+
/** Full version in MAJOR.MINOR format (e.g., "1.3", "2.1") */
|
|
218
|
+
version: string;
|
|
219
|
+
};
|
|
220
|
+
type Preset = {
|
|
221
|
+
name: string;
|
|
222
|
+
slug: string;
|
|
223
|
+
platform: PlatformId;
|
|
224
|
+
title: string;
|
|
225
|
+
version: string;
|
|
226
|
+
description: string;
|
|
227
|
+
tags: string[];
|
|
228
|
+
license: string;
|
|
229
|
+
features?: string[];
|
|
230
|
+
bundleUrl: string;
|
|
231
|
+
fileCount: number;
|
|
232
|
+
totalSize: number;
|
|
233
|
+
};
|
|
234
|
+
type PresetIndex = Record<string, Preset>;
|
|
235
|
+
type PresetFileInput = {
|
|
236
|
+
path: string;
|
|
237
|
+
contents: ArrayBuffer | ArrayBufferView | string;
|
|
238
|
+
};
|
|
239
|
+
type PresetInput = {
|
|
240
|
+
slug: string;
|
|
241
|
+
config: PresetConfig;
|
|
242
|
+
files: PresetFileInput[];
|
|
243
|
+
/** Install message from INSTALL.txt file */
|
|
244
|
+
installMessage?: string;
|
|
245
|
+
readmeContent?: string;
|
|
246
|
+
licenseContent?: string;
|
|
247
|
+
};
|
|
248
|
+
|
|
248
249
|
//#endregion
|
|
249
250
|
//#region src/builder/registry.d.ts
|
|
250
251
|
/**
|
|
@@ -253,23 +254,23 @@ declare const registryIndexSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
|
253
254
|
*/
|
|
254
255
|
declare const STATIC_BUNDLE_DIR = "r";
|
|
255
256
|
/**
|
|
256
|
-
* Options for building a
|
|
257
|
+
* Options for building a PresetPublishInput (for CLI publish command).
|
|
257
258
|
*/
|
|
258
|
-
type
|
|
259
|
-
preset:
|
|
259
|
+
type BuildPresetPublishInputOptions = {
|
|
260
|
+
preset: PresetInput;
|
|
260
261
|
/** Major version. Defaults to 1 if not specified. */
|
|
261
262
|
version?: number;
|
|
262
263
|
};
|
|
263
264
|
/**
|
|
264
|
-
* Builds a
|
|
265
|
+
* Builds a PresetPublishInput from preset input.
|
|
265
266
|
* Used by CLI to prepare data for publishing to a registry.
|
|
266
267
|
*/
|
|
267
|
-
declare function
|
|
268
|
+
declare function buildPresetPublishInput(options: BuildPresetPublishInputOptions): Promise<PresetPublishInput>;
|
|
268
269
|
/**
|
|
269
270
|
* Options for building a static registry.
|
|
270
271
|
*/
|
|
271
|
-
type
|
|
272
|
-
presets:
|
|
272
|
+
type BuildPresetRegistryOptions = {
|
|
273
|
+
presets: PresetInput[];
|
|
273
274
|
/**
|
|
274
275
|
* Optional base path or URL prefix for bundle locations.
|
|
275
276
|
* Format: {bundleBase}/{STATIC_BUNDLE_DIR}/{slug}/{platform}
|
|
@@ -277,17 +278,17 @@ type BuildRegistryDataOptions = {
|
|
|
277
278
|
*/
|
|
278
279
|
bundleBase?: string;
|
|
279
280
|
};
|
|
280
|
-
type
|
|
281
|
-
entries:
|
|
282
|
-
index:
|
|
283
|
-
bundles:
|
|
281
|
+
type BuildPresetRegistryResult = {
|
|
282
|
+
entries: Preset[];
|
|
283
|
+
index: PresetIndex;
|
|
284
|
+
bundles: PresetBundle[];
|
|
284
285
|
};
|
|
285
286
|
/**
|
|
286
287
|
* Builds a static registry with entries, index, and bundles.
|
|
287
288
|
* Used for building static registry files (e.g., community-presets).
|
|
288
289
|
* Each preset uses its version from config (default: major 1, minor 0).
|
|
289
290
|
*/
|
|
290
|
-
declare function
|
|
291
|
+
declare function buildPresetRegistry(options: BuildPresetRegistryOptions): Promise<BuildPresetRegistryResult>;
|
|
291
292
|
|
|
292
293
|
//#endregion
|
|
293
294
|
//#region src/builder/utils.d.ts
|
|
@@ -308,7 +309,7 @@ declare function toUtf8String(payload: ArrayBuffer | ArrayBufferView): string;
|
|
|
308
309
|
* Resolved preset with absolute bundle URL
|
|
309
310
|
*/
|
|
310
311
|
type ResolvedPreset = {
|
|
311
|
-
|
|
312
|
+
preset: Preset;
|
|
312
313
|
bundleUrl: string;
|
|
313
314
|
};
|
|
314
315
|
/**
|
|
@@ -324,7 +325,7 @@ declare function resolvePreset(baseUrl: string, slug: string, platform: Platform
|
|
|
324
325
|
/**
|
|
325
326
|
* Fetches a bundle from an absolute URL or resolves it relative to the registry.
|
|
326
327
|
*/
|
|
327
|
-
declare function fetchBundle(bundleUrl: string): Promise<
|
|
328
|
+
declare function fetchBundle(bundleUrl: string): Promise<PresetBundle>;
|
|
328
329
|
|
|
329
330
|
//#endregion
|
|
330
331
|
//#region src/constants.d.ts
|
|
@@ -345,8 +346,8 @@ declare const API_ENDPOINTS: {
|
|
|
345
346
|
readonly presets: {
|
|
346
347
|
/** Base path for preset operations */
|
|
347
348
|
readonly base: "api/presets";
|
|
348
|
-
/** Get preset
|
|
349
|
-
readonly
|
|
349
|
+
/** Get preset by slug, platform, and version (defaults to "latest") */
|
|
350
|
+
readonly get: (slug: string, platform: string, version?: string) => string;
|
|
350
351
|
/** Unpublish preset version */
|
|
351
352
|
readonly unpublish: (slug: string, platform: string, version: string) => string;
|
|
352
353
|
};
|
|
@@ -383,4 +384,4 @@ declare function normalizePathFragment(value?: string): string | undefined;
|
|
|
383
384
|
declare function maybeStripPrefix(pathInput: string, prefix?: string): string;
|
|
384
385
|
|
|
385
386
|
//#endregion
|
|
386
|
-
export { API_ENDPOINTS,
|
|
387
|
+
export { API_ENDPOINTS, BuildPresetPublishInputOptions, BuildPresetRegistryOptions, BuildPresetRegistryResult, BundledFile, COMMON_LICENSES, CONFIG_DIR_NAME, CommonLicense, DiffPreviewOptions, LATEST_VERSION, PLATFORMS, PLATFORM_IDS, PLATFORM_ID_TUPLE, PRESET_CONFIG_FILENAME, PRESET_SCHEMA_URL, PlatformConfig, PlatformId, Preset, PresetBundle, PresetConfig, PresetFileInput, PresetIndex, PresetInput, PresetPublishInput, ResolvedPreset, STATIC_BUNDLE_DIR, buildPresetPublishInput, buildPresetRegistry, bundledFileSchema, cleanInstallMessage, createDiffPreview, decodeBundledFile, decodeUtf8, descriptionSchema, encodeItemName, encodeUtf8, fetchBundle, isLikelyText, isSupportedPlatform, licenseSchema, maybeStripPrefix, normalizeBundlePath, normalizePathFragment, normalizePlatformInput, platformIdSchema, presetBundleSchema, presetConfigSchema, presetIndexSchema, presetPublishInputSchema, presetSchema, resolvePreset, slugSchema, titleSchema, toPosixPath, toUint8Array, toUtf8String, validatePresetConfig, verifyBundledFileChecksum };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
1
|
+
import { ZodError, z } from "zod";
|
|
2
2
|
import { createTwoFilesPatch } from "diff";
|
|
3
3
|
|
|
4
4
|
//#region src/constants.ts
|
|
@@ -19,7 +19,7 @@ const LATEST_VERSION = "latest";
|
|
|
19
19
|
const API_ENDPOINTS = {
|
|
20
20
|
presets: {
|
|
21
21
|
base: `${API_PATH}/presets`,
|
|
22
|
-
|
|
22
|
+
get: (slug, platform, version = LATEST_VERSION) => `${API_PATH}/presets/${encodeURIComponent(slug)}/${encodeURIComponent(platform)}/${encodeURIComponent(version)}`,
|
|
23
23
|
unpublish: (slug, platform, version) => `${API_PATH}/presets/${encodeURIComponent(slug)}/${encodeURIComponent(platform)}/${encodeURIComponent(version)}`
|
|
24
24
|
},
|
|
25
25
|
auth: {
|
|
@@ -30,7 +30,7 @@ const API_ENDPOINTS = {
|
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
//#endregion
|
|
33
|
-
//#region src/types
|
|
33
|
+
//#region src/platform/types.ts
|
|
34
34
|
/**
|
|
35
35
|
* Single source of truth for platform IDs.
|
|
36
36
|
* Add new platforms here - types and config will follow.
|
|
@@ -41,6 +41,9 @@ const PLATFORM_ID_TUPLE = [
|
|
|
41
41
|
"claude",
|
|
42
42
|
"cursor"
|
|
43
43
|
];
|
|
44
|
+
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/platform/config.ts
|
|
44
47
|
/** List of supported platform IDs as a readonly tuple */
|
|
45
48
|
const PLATFORM_IDS = PLATFORM_ID_TUPLE;
|
|
46
49
|
/**
|
|
@@ -70,6 +73,9 @@ const PLATFORMS = {
|
|
|
70
73
|
* e.g., `config/agent.md` → `.opencode/agent.md` (project) or `agent.md` (global)
|
|
71
74
|
*/
|
|
72
75
|
const CONFIG_DIR_NAME = "config";
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/platform/utils.ts
|
|
73
79
|
function isSupportedPlatform(value) {
|
|
74
80
|
return PLATFORM_ID_TUPLE.includes(value);
|
|
75
81
|
}
|
|
@@ -80,44 +86,42 @@ function normalizePlatformInput(value) {
|
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
//#endregion
|
|
83
|
-
//#region src/
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const titleSchema = z.string().trim().min(1).max(120);
|
|
87
|
-
const descriptionSchema = z.string().trim().min(1).max(500);
|
|
88
|
-
/** Validate a title string and return error message if invalid, undefined if valid */
|
|
89
|
-
function validateTitle(value) {
|
|
90
|
-
const trimmed = value.trim();
|
|
91
|
-
if (!trimmed) return "Title is required";
|
|
92
|
-
if (trimmed.length > 120) return "Title must be 120 characters or less";
|
|
93
|
-
return;
|
|
89
|
+
//#region src/utils/encoding.ts
|
|
90
|
+
function toPosixPath(pathValue) {
|
|
91
|
+
return pathValue.split("\\").join("/");
|
|
94
92
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (!trimmed) return "Description is required";
|
|
99
|
-
if (trimmed.length > 500) return "Description must be 500 characters or less";
|
|
100
|
-
return;
|
|
93
|
+
function encodeUtf8(value) {
|
|
94
|
+
if (typeof Buffer !== "undefined") return new Uint8Array(Buffer.from(value, "utf8"));
|
|
95
|
+
return new TextEncoder().encode(value);
|
|
101
96
|
}
|
|
97
|
+
function decodeUtf8(payload) {
|
|
98
|
+
const bytes = toUint8Array(payload);
|
|
99
|
+
if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("utf8");
|
|
100
|
+
return new TextDecoder("utf-8", { fatal: false }).decode(bytes);
|
|
101
|
+
}
|
|
102
|
+
function toUint8Array(payload) {
|
|
103
|
+
if (payload instanceof Uint8Array) return payload;
|
|
104
|
+
if (ArrayBuffer.isView(payload)) return new Uint8Array(payload.buffer, payload.byteOffset, payload.byteLength);
|
|
105
|
+
return new Uint8Array(payload);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/preset/schema.ts
|
|
110
|
+
const VERSION_REGEX = /^[1-9]\d*\.\d+$/;
|
|
111
|
+
const platformIdSchema = z.enum(PLATFORM_IDS);
|
|
112
|
+
const titleSchema = z.string().trim().min(1, "Title is required").max(80, "Title must be 80 characters or less");
|
|
113
|
+
const descriptionSchema = z.string().trim().min(1, "Description is required").max(500, "Description must be 500 characters or less");
|
|
102
114
|
const versionSchema = z.string().trim().regex(VERSION_REGEX, "Version must be in MAJOR.MINOR format (e.g., 1.3)");
|
|
103
115
|
const majorVersionSchema = z.number().int().positive("Major version must be a positive integer");
|
|
104
|
-
const tagSchema = z.string().trim().min(1).max(
|
|
105
|
-
const tagsSchema = z.array(tagSchema).max(10);
|
|
106
|
-
const featureSchema = z.string().trim().min(1).max(
|
|
107
|
-
const featuresSchema = z.array(featureSchema).max(
|
|
108
|
-
const installMessageSchema = z.string().trim().max(
|
|
116
|
+
const tagSchema = z.string().trim().min(1, "Tag cannot be empty").max(35, "Tag must be 35 characters or less");
|
|
117
|
+
const tagsSchema = z.array(tagSchema).min(1, "At least one tag is required").max(10, "Maximum 10 tags allowed");
|
|
118
|
+
const featureSchema = z.string().trim().min(1, "Feature cannot be empty").max(100, "Feature must be 100 characters or less");
|
|
119
|
+
const featuresSchema = z.array(featureSchema).max(5, "Maximum 5 features allowed");
|
|
120
|
+
const installMessageSchema = z.string().trim().max(2e3, "Install message must be 2000 characters or less");
|
|
109
121
|
const contentSchema = z.string();
|
|
110
122
|
const SLUG_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
111
123
|
const SLUG_ERROR = "Must be lowercase alphanumeric with hyphens (e.g., my-preset)";
|
|
112
|
-
const slugSchema = z.string().trim().min(1).max(64).regex(SLUG_REGEX, SLUG_ERROR);
|
|
113
|
-
/** Validate a slug string and return error message if invalid, undefined if valid */
|
|
114
|
-
function validateSlug(value) {
|
|
115
|
-
const trimmed = value.trim();
|
|
116
|
-
if (!trimmed) return "Name is required";
|
|
117
|
-
if (trimmed.length > 64) return "Name must be 64 characters or less";
|
|
118
|
-
if (!SLUG_REGEX.test(trimmed)) return SLUG_ERROR;
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
124
|
+
const slugSchema = z.string().trim().min(1, "Name is required").max(64, "Name must be 64 characters or less").regex(SLUG_REGEX, SLUG_ERROR);
|
|
121
125
|
const COMMON_LICENSES = [
|
|
122
126
|
"MIT",
|
|
123
127
|
"Apache-2.0",
|
|
@@ -126,14 +130,7 @@ const COMMON_LICENSES = [
|
|
|
126
130
|
"ISC",
|
|
127
131
|
"Unlicense"
|
|
128
132
|
];
|
|
129
|
-
const licenseSchema = z.string().trim().min(1).max(128);
|
|
130
|
-
/** Validate a license string and return error message if invalid, undefined if valid */
|
|
131
|
-
function validateLicense(value) {
|
|
132
|
-
const trimmed = value.trim();
|
|
133
|
-
if (!trimmed) return "License is required";
|
|
134
|
-
if (trimmed.length > 128) return "License must be 128 characters or less";
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
133
|
+
const licenseSchema = z.string().trim().min(1, "License is required").max(128, "License must be 128 characters or less");
|
|
137
134
|
const pathSchema = z.string().trim().min(1);
|
|
138
135
|
const presetConfigSchema = z.object({
|
|
139
136
|
$schema: z.string().optional(),
|
|
@@ -157,7 +154,7 @@ const bundledFileSchema = z.object({
|
|
|
157
154
|
* Schema for what clients send to publish a preset.
|
|
158
155
|
* Version is optional major version. Registry assigns full MAJOR.MINOR.
|
|
159
156
|
*/
|
|
160
|
-
const
|
|
157
|
+
const presetPublishInputSchema = z.object({
|
|
161
158
|
slug: z.string().trim().min(1),
|
|
162
159
|
platform: platformIdSchema,
|
|
163
160
|
title: titleSchema,
|
|
@@ -175,8 +172,8 @@ const publishInputSchema = z.object({
|
|
|
175
172
|
* Schema for what registries store and return.
|
|
176
173
|
* Includes version (required) - full MAJOR.MINOR format assigned by registry.
|
|
177
174
|
*/
|
|
178
|
-
const
|
|
179
|
-
const
|
|
175
|
+
const presetBundleSchema = presetPublishInputSchema.omit({ version: true }).extend({ version: versionSchema });
|
|
176
|
+
const presetSchema = presetBundleSchema.omit({
|
|
180
177
|
files: true,
|
|
181
178
|
readmeContent: true,
|
|
182
179
|
licenseContent: true,
|
|
@@ -187,27 +184,7 @@ const registryEntrySchema = registryBundleSchema.omit({
|
|
|
187
184
|
fileCount: z.number().int().nonnegative(),
|
|
188
185
|
totalSize: z.number().int().nonnegative()
|
|
189
186
|
});
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
//#endregion
|
|
193
|
-
//#region src/utils/encoding.ts
|
|
194
|
-
function toPosixPath(pathValue) {
|
|
195
|
-
return pathValue.split("\\").join("/");
|
|
196
|
-
}
|
|
197
|
-
function encodeUtf8(value) {
|
|
198
|
-
if (typeof Buffer !== "undefined") return new Uint8Array(Buffer.from(value, "utf8"));
|
|
199
|
-
return new TextEncoder().encode(value);
|
|
200
|
-
}
|
|
201
|
-
function decodeUtf8(payload) {
|
|
202
|
-
const bytes = toUint8Array(payload);
|
|
203
|
-
if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("utf8");
|
|
204
|
-
return new TextDecoder("utf-8", { fatal: false }).decode(bytes);
|
|
205
|
-
}
|
|
206
|
-
function toUint8Array(payload) {
|
|
207
|
-
if (payload instanceof Uint8Array) return payload;
|
|
208
|
-
if (ArrayBuffer.isView(payload)) return new Uint8Array(payload.buffer, payload.byteOffset, payload.byteLength);
|
|
209
|
-
return new Uint8Array(payload);
|
|
210
|
-
}
|
|
187
|
+
const presetIndexSchema = z.record(z.string(), presetSchema);
|
|
211
188
|
|
|
212
189
|
//#endregion
|
|
213
190
|
//#region src/builder/utils.ts
|
|
@@ -220,16 +197,18 @@ function encodeItemName(slug, platform) {
|
|
|
220
197
|
return `${slug}.${platform}`;
|
|
221
198
|
}
|
|
222
199
|
function validatePresetConfig(config, slug) {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
200
|
+
try {
|
|
201
|
+
return presetConfigSchema.parse(config);
|
|
202
|
+
} catch (e) {
|
|
203
|
+
if (e instanceof ZodError) {
|
|
204
|
+
const messages = e.issues.map((issue) => {
|
|
205
|
+
const path = issue.path.length > 0 ? `${issue.path.join(".")}: ` : "";
|
|
206
|
+
return `${path}${issue.message}`;
|
|
207
|
+
});
|
|
208
|
+
throw new Error(`Invalid preset config for ${slug}:\n - ${messages.join("\n - ")}`);
|
|
209
|
+
}
|
|
210
|
+
throw e;
|
|
211
|
+
}
|
|
233
212
|
}
|
|
234
213
|
|
|
235
214
|
//#endregion
|
|
@@ -249,10 +228,10 @@ async function sha256(data) {
|
|
|
249
228
|
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
250
229
|
}
|
|
251
230
|
/**
|
|
252
|
-
* Builds a
|
|
231
|
+
* Builds a PresetPublishInput from preset input.
|
|
253
232
|
* Used by CLI to prepare data for publishing to a registry.
|
|
254
233
|
*/
|
|
255
|
-
async function
|
|
234
|
+
async function buildPresetPublishInput(options) {
|
|
256
235
|
const { preset: presetInput, version } = options;
|
|
257
236
|
if (!NAME_PATTERN.test(presetInput.slug)) throw new Error(`Invalid slug "${presetInput.slug}". Slugs must be lowercase kebab-case.`);
|
|
258
237
|
const presetConfig = validatePresetConfig(presetInput.config, presetInput.slug);
|
|
@@ -285,7 +264,7 @@ async function buildPublishInput(options) {
|
|
|
285
264
|
* Used for building static registry files (e.g., community-presets).
|
|
286
265
|
* Each preset uses its version from config (default: major 1, minor 0).
|
|
287
266
|
*/
|
|
288
|
-
async function
|
|
267
|
+
async function buildPresetRegistry(options) {
|
|
289
268
|
const bundleBase = normalizeBundleBase(options.bundleBase);
|
|
290
269
|
const entries = [];
|
|
291
270
|
const bundles = [];
|
|
@@ -442,7 +421,7 @@ async function sha256Hex(payload) {
|
|
|
442
421
|
* @param version - Version to resolve (defaults to "latest")
|
|
443
422
|
*/
|
|
444
423
|
async function resolvePreset(baseUrl, slug, platform, version = LATEST_VERSION) {
|
|
445
|
-
const apiUrl = new URL(API_ENDPOINTS.presets.
|
|
424
|
+
const apiUrl = new URL(API_ENDPOINTS.presets.get(slug, platform, version), baseUrl);
|
|
446
425
|
const response = await fetch(apiUrl);
|
|
447
426
|
if (!response.ok) {
|
|
448
427
|
if (response.status === 404) {
|
|
@@ -452,10 +431,10 @@ async function resolvePreset(baseUrl, slug, platform, version = LATEST_VERSION)
|
|
|
452
431
|
throw new Error(`Failed to resolve preset (${response.status} ${response.statusText}).`);
|
|
453
432
|
}
|
|
454
433
|
try {
|
|
455
|
-
const
|
|
456
|
-
const resolvedBundleUrl = new URL(
|
|
434
|
+
const preset = await response.json();
|
|
435
|
+
const resolvedBundleUrl = new URL(preset.bundleUrl, baseUrl).toString();
|
|
457
436
|
return {
|
|
458
|
-
|
|
437
|
+
preset,
|
|
459
438
|
bundleUrl: resolvedBundleUrl
|
|
460
439
|
};
|
|
461
440
|
} catch (error) {
|
|
@@ -506,4 +485,4 @@ function maybeStripPrefix(pathInput, prefix) {
|
|
|
506
485
|
}
|
|
507
486
|
|
|
508
487
|
//#endregion
|
|
509
|
-
export { API_ENDPOINTS, COMMON_LICENSES, CONFIG_DIR_NAME, LATEST_VERSION, PLATFORMS, PLATFORM_IDS, PRESET_CONFIG_FILENAME, PRESET_SCHEMA_URL, STATIC_BUNDLE_DIR,
|
|
488
|
+
export { API_ENDPOINTS, COMMON_LICENSES, CONFIG_DIR_NAME, LATEST_VERSION, PLATFORMS, PLATFORM_IDS, PLATFORM_ID_TUPLE, PRESET_CONFIG_FILENAME, PRESET_SCHEMA_URL, STATIC_BUNDLE_DIR, buildPresetPublishInput, buildPresetRegistry, bundledFileSchema, cleanInstallMessage, createDiffPreview, decodeBundledFile, decodeUtf8, descriptionSchema, encodeItemName, encodeUtf8, fetchBundle, isLikelyText, isSupportedPlatform, licenseSchema, maybeStripPrefix, normalizeBundlePath, normalizePathFragment, normalizePlatformInput, platformIdSchema, presetBundleSchema, presetConfigSchema, presetIndexSchema, presetPublishInputSchema, presetSchema, resolvePreset, slugSchema, titleSchema, toPosixPath, toUint8Array, toUtf8String, validatePresetConfig, verifyBundledFileChecksum };
|