@a5c-ai/extension-mux 5.0.1-staging.04ca6ab00d21
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 +58 -0
- package/dist/binTemplates.d.ts +7 -0
- package/dist/binTemplates.d.ts.map +1 -0
- package/dist/binTemplates.js +292 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +299 -0
- package/dist/compiler.d.ts +15 -0
- package/dist/compiler.d.ts.map +1 -0
- package/dist/compiler.js +118 -0
- package/dist/diff.d.ts +9 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +183 -0
- package/dist/emit.d.ts +3 -0
- package/dist/emit.d.ts.map +1 -0
- package/dist/emit.js +42 -0
- package/dist/hookRegistration.d.ts +8 -0
- package/dist/hookRegistration.d.ts.map +1 -0
- package/dist/hookRegistration.js +9 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/init.d.ts +17 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +200 -0
- package/dist/installInstructions.d.ts +3 -0
- package/dist/installInstructions.d.ts.map +1 -0
- package/dist/installInstructions.js +150 -0
- package/dist/installSharedGenerator.d.ts +3 -0
- package/dist/installSharedGenerator.d.ts.map +1 -0
- package/dist/installSharedGenerator.js +229 -0
- package/dist/manifestGenerators.d.ts +10 -0
- package/dist/manifestGenerators.d.ts.map +1 -0
- package/dist/manifestGenerators.js +11 -0
- package/dist/marketplaceGenerator.d.ts +3 -0
- package/dist/marketplaceGenerator.d.ts.map +1 -0
- package/dist/marketplaceGenerator.js +46 -0
- package/dist/proxiedHookTemplates.d.ts +10 -0
- package/dist/proxiedHookTemplates.d.ts.map +1 -0
- package/dist/proxiedHookTemplates.js +122 -0
- package/dist/resolve.d.ts +3 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +106 -0
- package/dist/schema.d.ts +231 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +340 -0
- package/dist/sdkConfig.d.ts +20 -0
- package/dist/sdkConfig.d.ts.map +1 -0
- package/dist/sdkConfig.js +41 -0
- package/dist/targets/adapters/base.d.ts +10 -0
- package/dist/targets/adapters/base.d.ts.map +1 -0
- package/dist/targets/adapters/base.js +16 -0
- package/dist/targets/adapters/claude-code.d.ts +9 -0
- package/dist/targets/adapters/claude-code.d.ts.map +1 -0
- package/dist/targets/adapters/claude-code.js +83 -0
- package/dist/targets/adapters/codex.d.ts +13 -0
- package/dist/targets/adapters/codex.d.ts.map +1 -0
- package/dist/targets/adapters/codex.js +103 -0
- package/dist/targets/adapters/cursor.d.ts +9 -0
- package/dist/targets/adapters/cursor.d.ts.map +1 -0
- package/dist/targets/adapters/cursor.js +57 -0
- package/dist/targets/adapters/gemini.d.ts +9 -0
- package/dist/targets/adapters/gemini.d.ts.map +1 -0
- package/dist/targets/adapters/gemini.js +86 -0
- package/dist/targets/adapters/github-copilot.d.ts +9 -0
- package/dist/targets/adapters/github-copilot.d.ts.map +1 -0
- package/dist/targets/adapters/github-copilot.js +61 -0
- package/dist/targets/adapters/hermes.d.ts +13 -0
- package/dist/targets/adapters/hermes.d.ts.map +1 -0
- package/dist/targets/adapters/hermes.js +96 -0
- package/dist/targets/adapters/hooks-utils.d.ts +12 -0
- package/dist/targets/adapters/hooks-utils.d.ts.map +1 -0
- package/dist/targets/adapters/hooks-utils.js +60 -0
- package/dist/targets/adapters/index.d.ts +27 -0
- package/dist/targets/adapters/index.d.ts.map +1 -0
- package/dist/targets/adapters/index.js +64 -0
- package/dist/targets/adapters/interface.d.ts +8 -0
- package/dist/targets/adapters/interface.d.ts.map +1 -0
- package/dist/targets/adapters/interface.js +2 -0
- package/dist/targets/adapters/oh-my-pi.d.ts +11 -0
- package/dist/targets/adapters/oh-my-pi.d.ts.map +1 -0
- package/dist/targets/adapters/oh-my-pi.js +88 -0
- package/dist/targets/adapters/openclaw.d.ts +14 -0
- package/dist/targets/adapters/openclaw.d.ts.map +1 -0
- package/dist/targets/adapters/openclaw.js +165 -0
- package/dist/targets/adapters/opencode.d.ts +10 -0
- package/dist/targets/adapters/opencode.d.ts.map +1 -0
- package/dist/targets/adapters/opencode.js +93 -0
- package/dist/targets/adapters/pi.d.ts +11 -0
- package/dist/targets/adapters/pi.d.ts.map +1 -0
- package/dist/targets/adapters/pi.js +90 -0
- package/dist/targets/index.d.ts +7 -0
- package/dist/targets/index.d.ts.map +1 -0
- package/dist/targets/index.js +77 -0
- package/dist/transform.d.ts +4 -0
- package/dist/transform.d.ts.map +1 -0
- package/dist/transform.js +243 -0
- package/dist/transformEmitters.d.ts +8 -0
- package/dist/transformEmitters.d.ts.map +1 -0
- package/dist/transformEmitters.js +340 -0
- package/dist/transformHelpers.d.ts +13 -0
- package/dist/transformHelpers.d.ts.map +1 -0
- package/dist/transformHelpers.js +239 -0
- package/dist/types.d.ts +204 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/utils.d.ts +42 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +187 -0
- package/dist/validate.d.ts +3 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +188 -0
- package/dist/verify.d.ts +6 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +294 -0
- package/package.json +68 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
export interface A5cPluginManifest {
|
|
2
|
+
name: string;
|
|
3
|
+
version: string;
|
|
4
|
+
description: string;
|
|
5
|
+
author: string | {
|
|
6
|
+
name: string;
|
|
7
|
+
email?: string;
|
|
8
|
+
};
|
|
9
|
+
license: string;
|
|
10
|
+
repository?: {
|
|
11
|
+
type: string;
|
|
12
|
+
url: string;
|
|
13
|
+
};
|
|
14
|
+
homepage?: string;
|
|
15
|
+
keywords?: string[];
|
|
16
|
+
hooks?: Record<string, string | boolean | null>;
|
|
17
|
+
commands?: string[] | string;
|
|
18
|
+
skills?: Array<{
|
|
19
|
+
name: string;
|
|
20
|
+
file: string;
|
|
21
|
+
}>;
|
|
22
|
+
agents?: string | string[];
|
|
23
|
+
contextFiles?: Record<string, string>;
|
|
24
|
+
targets?: Record<string, TargetOverride>;
|
|
25
|
+
extraFileSets?: Record<string, Record<string, string>>;
|
|
26
|
+
harnessInstallSurfaceExportSets?: Record<string, string[]>;
|
|
27
|
+
sdk?: {
|
|
28
|
+
package?: string;
|
|
29
|
+
cli?: string;
|
|
30
|
+
proxyPackage?: string;
|
|
31
|
+
proxyBinary?: string;
|
|
32
|
+
scope?: string;
|
|
33
|
+
envPrefix?: string;
|
|
34
|
+
stateDir?: string;
|
|
35
|
+
};
|
|
36
|
+
hookFilePattern?: string;
|
|
37
|
+
include?: string[];
|
|
38
|
+
postInstall?: string;
|
|
39
|
+
installSurface?: string;
|
|
40
|
+
installSurfaceExports?: string[];
|
|
41
|
+
hookConfig?: {
|
|
42
|
+
proxyAdapter?: boolean;
|
|
43
|
+
matchers?: Record<string, string>;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export interface TargetOverride {
|
|
47
|
+
npmPackageName?: string;
|
|
48
|
+
type?: 'typescript-build';
|
|
49
|
+
skills?: 'derive-from-commands' | Array<{
|
|
50
|
+
name: string;
|
|
51
|
+
file: string;
|
|
52
|
+
}>;
|
|
53
|
+
hooks?: Record<string, string | boolean | null>;
|
|
54
|
+
commands?: string[] | string;
|
|
55
|
+
extensionManifest?: {
|
|
56
|
+
contextFileName?: string;
|
|
57
|
+
settings?: unknown[];
|
|
58
|
+
};
|
|
59
|
+
extraFileSets?: string[];
|
|
60
|
+
extraFiles?: Record<string, string>;
|
|
61
|
+
templateVars?: Record<string, string>;
|
|
62
|
+
harnessInstallSurface?: string;
|
|
63
|
+
harnessInstallSurfaceExportSets?: string[];
|
|
64
|
+
harnessInstallSurfaceExports?: string[];
|
|
65
|
+
hookFilePattern?: string;
|
|
66
|
+
hookJsPattern?: string;
|
|
67
|
+
harnessManifest?: Record<string, unknown>;
|
|
68
|
+
[key: string]: unknown;
|
|
69
|
+
}
|
|
70
|
+
export interface Diagnostic {
|
|
71
|
+
level: 'info' | 'warning' | 'error';
|
|
72
|
+
category: 'validation' | 'compatibility' | 'compilation' | 'verification';
|
|
73
|
+
message: string;
|
|
74
|
+
component?: string;
|
|
75
|
+
target?: string;
|
|
76
|
+
source?: string;
|
|
77
|
+
suggestion?: string;
|
|
78
|
+
}
|
|
79
|
+
export type HookSupport = 'native' | 'emulated' | 'unsupported';
|
|
80
|
+
export type CommandSupport = 'native' | 'toml' | 'derived' | 'unsupported';
|
|
81
|
+
export type SkillSupport = 'native' | 'derived' | 'unsupported';
|
|
82
|
+
export type AgentSupport = 'native' | 'unsupported';
|
|
83
|
+
export type ContextSupport = 'native' | 'unsupported';
|
|
84
|
+
export interface ComponentSupport {
|
|
85
|
+
hooks: Record<string, HookSupport>;
|
|
86
|
+
commands: CommandSupport;
|
|
87
|
+
skills: SkillSupport;
|
|
88
|
+
agents: AgentSupport;
|
|
89
|
+
context: ContextSupport;
|
|
90
|
+
}
|
|
91
|
+
export interface CompilationResult {
|
|
92
|
+
target: string;
|
|
93
|
+
status: 'success' | 'warning' | 'error';
|
|
94
|
+
outputDir: string;
|
|
95
|
+
emittedFiles: string[];
|
|
96
|
+
componentSupport: ComponentSupport;
|
|
97
|
+
diagnostics: Diagnostic[];
|
|
98
|
+
verificationChecklist: string[];
|
|
99
|
+
}
|
|
100
|
+
export interface DiffFileDifference {
|
|
101
|
+
path: string;
|
|
102
|
+
line: number;
|
|
103
|
+
compiledLine: string | null;
|
|
104
|
+
existingLine: string | null;
|
|
105
|
+
}
|
|
106
|
+
export interface DiffResult {
|
|
107
|
+
target: string;
|
|
108
|
+
sourceDir: string;
|
|
109
|
+
existingDir: string;
|
|
110
|
+
compilationStatus: CompilationResult['status'];
|
|
111
|
+
diagnostics: Diagnostic[];
|
|
112
|
+
status: 'match' | 'different' | 'error';
|
|
113
|
+
identical: boolean;
|
|
114
|
+
differenceCount: number;
|
|
115
|
+
onlyInCompiled: string[];
|
|
116
|
+
onlyInExisting: string[];
|
|
117
|
+
differingFiles: DiffFileDifference[];
|
|
118
|
+
ignoredExistingFiles: string[];
|
|
119
|
+
}
|
|
120
|
+
export interface ValidateResult {
|
|
121
|
+
valid: boolean;
|
|
122
|
+
manifest: A5cPluginManifest | null;
|
|
123
|
+
diagnostics: Diagnostic[];
|
|
124
|
+
}
|
|
125
|
+
export interface ResolveResult {
|
|
126
|
+
effectiveManifest: A5cPluginManifest;
|
|
127
|
+
targetProfile: TargetProfile;
|
|
128
|
+
componentSupport: ComponentSupport;
|
|
129
|
+
diagnostics: Diagnostic[];
|
|
130
|
+
}
|
|
131
|
+
export interface TransformedFile {
|
|
132
|
+
path: string;
|
|
133
|
+
content: string;
|
|
134
|
+
binaryContent?: Buffer;
|
|
135
|
+
executable?: boolean;
|
|
136
|
+
}
|
|
137
|
+
export interface TransformResult {
|
|
138
|
+
files: TransformedFile[];
|
|
139
|
+
diagnostics: Diagnostic[];
|
|
140
|
+
}
|
|
141
|
+
export interface EmitResult {
|
|
142
|
+
emittedFiles: string[];
|
|
143
|
+
diagnostics: Diagnostic[];
|
|
144
|
+
}
|
|
145
|
+
export interface VerifyResult {
|
|
146
|
+
diagnostics: Diagnostic[];
|
|
147
|
+
verificationChecklist: string[];
|
|
148
|
+
}
|
|
149
|
+
export type HookRegistrationFormat = string;
|
|
150
|
+
export type AdapterFamily = 'shell-hook' | 'programmatic';
|
|
151
|
+
export type DistributionModel = 'marketplace' | 'npm-cli' | 'both';
|
|
152
|
+
export interface InstallLayoutMetadata {
|
|
153
|
+
harnessHomeRelative?: string | null;
|
|
154
|
+
pluginsDirRelative?: string | null;
|
|
155
|
+
marketplacePathRelative?: string | null;
|
|
156
|
+
}
|
|
157
|
+
export interface PackageMetadata {
|
|
158
|
+
moduleType?: 'commonjs' | 'module';
|
|
159
|
+
binScriptExt?: '.js' | '.cjs';
|
|
160
|
+
installLifecycle?: 'postinstall' | 'plugin-scripts' | 'none';
|
|
161
|
+
activationMessage?: 'restart' | 'codex-open-plugins';
|
|
162
|
+
extraPackageFiles?: string[];
|
|
163
|
+
extraScripts?: Record<string, string>;
|
|
164
|
+
peerDependencyPackage?: string;
|
|
165
|
+
emitCjsWrappers?: boolean;
|
|
166
|
+
}
|
|
167
|
+
export interface TargetComponentSupport {
|
|
168
|
+
agents: 'native' | 'unsupported';
|
|
169
|
+
context: 'native' | 'unsupported';
|
|
170
|
+
}
|
|
171
|
+
export interface TargetProfile {
|
|
172
|
+
name: string;
|
|
173
|
+
displayName: string;
|
|
174
|
+
adapterName: string;
|
|
175
|
+
pluginRootEnvVar: string | null;
|
|
176
|
+
supportedHooks: Map<string, string>;
|
|
177
|
+
commandFormat: 'markdown' | 'toml' | 'none';
|
|
178
|
+
skillHandling: 'native' | 'derived-from-commands' | 'none';
|
|
179
|
+
manifestFormat: 'plugin.json' | 'package.json' | 'multiple';
|
|
180
|
+
hookRegistrationFormat: HookRegistrationFormat | null;
|
|
181
|
+
hookRegistrationOutputPath: string | null;
|
|
182
|
+
hookRegistrationAliasPaths: string[];
|
|
183
|
+
harnessManifestPath: string | null;
|
|
184
|
+
requiredSurfaceFile: string | null;
|
|
185
|
+
scriptVariants: Array<'bash' | 'powershell' | 'javascript' | 'typescript'>;
|
|
186
|
+
npmPublishable: boolean;
|
|
187
|
+
npmPackageName?: string;
|
|
188
|
+
extraCapabilities?: string[];
|
|
189
|
+
adapterFamily: AdapterFamily;
|
|
190
|
+
distribution: DistributionModel;
|
|
191
|
+
pluginRootEnvVarForExtension?: string;
|
|
192
|
+
marketplacePath?: string;
|
|
193
|
+
installLayout?: InstallLayoutMetadata;
|
|
194
|
+
packageMetadata?: PackageMetadata;
|
|
195
|
+
componentSupport?: TargetComponentSupport;
|
|
196
|
+
}
|
|
197
|
+
export interface FrontmatterData {
|
|
198
|
+
[key: string]: unknown;
|
|
199
|
+
}
|
|
200
|
+
export interface ParsedFrontmatter {
|
|
201
|
+
data: FrontmatterData;
|
|
202
|
+
body: string;
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { A5cPluginManifest, ParsedFrontmatter } from './types.js';
|
|
2
|
+
export declare function getCommandPaths(sourceDir: string, manifest: A5cPluginManifest): string[];
|
|
3
|
+
/**
|
|
4
|
+
* Parse YAML frontmatter from a markdown file.
|
|
5
|
+
* Supports both --- and +++ delimiters.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseFrontmatter(markdown: string): ParsedFrontmatter;
|
|
8
|
+
/**
|
|
9
|
+
* Build a skill SKILL.md from a command markdown file.
|
|
10
|
+
* This mirrors the logic from scripts/plugin-command-sync-lib.cjs.
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildSkillFromCommand(name: string, commandMarkdown: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Render a skill SKILL.md file with frontmatter and body.
|
|
15
|
+
*/
|
|
16
|
+
export declare function renderSkillMarkdown(name: string, description: string, body: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Convert Markdown command to TOML format (for Gemini).
|
|
19
|
+
* Extracts description from frontmatter and body as prompt.
|
|
20
|
+
*/
|
|
21
|
+
export declare function markdownToToml(commandMarkdown: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Generate TOML from a simple object (flat key-value pairs).
|
|
24
|
+
*/
|
|
25
|
+
export declare function generateToml(obj: Record<string, string>): string;
|
|
26
|
+
/**
|
|
27
|
+
* Deep merge two objects, with null deletion semantics.
|
|
28
|
+
* - Scalars: target replaces base
|
|
29
|
+
* - Objects: deep merge recursively
|
|
30
|
+
* - Arrays: target replaces base entirely
|
|
31
|
+
* - null values: delete the key
|
|
32
|
+
*/
|
|
33
|
+
export declare function deepMerge<T extends Record<string, unknown>>(base: T, override: Partial<T>): T;
|
|
34
|
+
/**
|
|
35
|
+
* Slugify a string to kebab-case for breakpoint IDs.
|
|
36
|
+
*/
|
|
37
|
+
export declare function slugify(text: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Check if a value is a plain object.
|
|
40
|
+
*/
|
|
41
|
+
export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
42
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAmB,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAMxF,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,iBAAiB,GAC1B,MAAM,EAAE,CAmBV;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CA0DpE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,CAKnF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,MAAM,CAcR;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAM9D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAWhE;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,GACnB,CAAC,CA6CH;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM5C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAE9E"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
// Utility functions for UPF compilation
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
function toOutputPath(value) {
|
|
5
|
+
return value.replace(/\\/g, '/');
|
|
6
|
+
}
|
|
7
|
+
export function getCommandPaths(sourceDir, manifest) {
|
|
8
|
+
if (!manifest.commands)
|
|
9
|
+
return [];
|
|
10
|
+
const commandPaths = [];
|
|
11
|
+
if (typeof manifest.commands === 'string') {
|
|
12
|
+
const commandDir = path.join(sourceDir, manifest.commands);
|
|
13
|
+
if (fs.existsSync(commandDir)) {
|
|
14
|
+
const entries = fs.readdirSync(commandDir);
|
|
15
|
+
for (const entry of entries) {
|
|
16
|
+
if (entry.endsWith('.md')) {
|
|
17
|
+
commandPaths.push(toOutputPath(path.join(manifest.commands, entry)));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
commandPaths.push(...manifest.commands.map(toOutputPath));
|
|
24
|
+
}
|
|
25
|
+
return commandPaths;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse YAML frontmatter from a markdown file.
|
|
29
|
+
* Supports both --- and +++ delimiters.
|
|
30
|
+
*/
|
|
31
|
+
export function parseFrontmatter(markdown) {
|
|
32
|
+
const lines = markdown.split('\n');
|
|
33
|
+
if (lines.length === 0) {
|
|
34
|
+
return { data: {}, body: markdown };
|
|
35
|
+
}
|
|
36
|
+
const firstLine = lines[0].trim();
|
|
37
|
+
if (firstLine !== '---' && firstLine !== '+++') {
|
|
38
|
+
return { data: {}, body: markdown };
|
|
39
|
+
}
|
|
40
|
+
const delimiter = firstLine;
|
|
41
|
+
let endIndex = -1;
|
|
42
|
+
for (let i = 1; i < lines.length; i++) {
|
|
43
|
+
if (lines[i].trim() === delimiter) {
|
|
44
|
+
endIndex = i;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (endIndex === -1) {
|
|
49
|
+
return { data: {}, body: markdown };
|
|
50
|
+
}
|
|
51
|
+
const frontmatterLines = lines.slice(1, endIndex);
|
|
52
|
+
const bodyLines = lines.slice(endIndex + 1);
|
|
53
|
+
// Simple YAML parser for frontmatter (key: value format)
|
|
54
|
+
const data = {};
|
|
55
|
+
for (const line of frontmatterLines) {
|
|
56
|
+
const trimmed = line.trim();
|
|
57
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
58
|
+
continue;
|
|
59
|
+
const colonIndex = trimmed.indexOf(':');
|
|
60
|
+
if (colonIndex === -1)
|
|
61
|
+
continue;
|
|
62
|
+
const key = trimmed.substring(0, colonIndex).trim();
|
|
63
|
+
let value = trimmed.substring(colonIndex + 1).trim();
|
|
64
|
+
// Remove quotes
|
|
65
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
66
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
67
|
+
value = value.slice(1, -1);
|
|
68
|
+
}
|
|
69
|
+
// Parse booleans and numbers
|
|
70
|
+
if (value === 'true')
|
|
71
|
+
value = true;
|
|
72
|
+
else if (value === 'false')
|
|
73
|
+
value = false;
|
|
74
|
+
else if (/^-?\d+(\.\d+)?$/.test(value))
|
|
75
|
+
value = parseFloat(value);
|
|
76
|
+
data[key] = value;
|
|
77
|
+
}
|
|
78
|
+
const body = bodyLines.join('\n').trim();
|
|
79
|
+
return { data, body };
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Build a skill SKILL.md from a command markdown file.
|
|
83
|
+
* This mirrors the logic from scripts/plugin-command-sync-lib.cjs.
|
|
84
|
+
*/
|
|
85
|
+
export function buildSkillFromCommand(name, commandMarkdown) {
|
|
86
|
+
const parsed = parseFrontmatter(commandMarkdown);
|
|
87
|
+
const description = parsed.data.description || `${name} mode.`;
|
|
88
|
+
return renderSkillMarkdown(name, description, parsed.body);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Render a skill SKILL.md file with frontmatter and body.
|
|
92
|
+
*/
|
|
93
|
+
export function renderSkillMarkdown(name, description, body) {
|
|
94
|
+
const lines = [
|
|
95
|
+
'---',
|
|
96
|
+
`name: ${name}`,
|
|
97
|
+
`description: ${description}`,
|
|
98
|
+
'---',
|
|
99
|
+
'',
|
|
100
|
+
`# ${name}`,
|
|
101
|
+
'',
|
|
102
|
+
body.trim(),
|
|
103
|
+
'',
|
|
104
|
+
];
|
|
105
|
+
return lines.join('\n');
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Convert Markdown command to TOML format (for Gemini).
|
|
109
|
+
* Extracts description from frontmatter and body as prompt.
|
|
110
|
+
*/
|
|
111
|
+
export function markdownToToml(commandMarkdown) {
|
|
112
|
+
const parsed = parseFrontmatter(commandMarkdown);
|
|
113
|
+
const description = parsed.data.description || '';
|
|
114
|
+
const prompt = parsed.body.trim();
|
|
115
|
+
return generateToml({ description, prompt });
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Generate TOML from a simple object (flat key-value pairs).
|
|
119
|
+
*/
|
|
120
|
+
export function generateToml(obj) {
|
|
121
|
+
const lines = [];
|
|
122
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
123
|
+
if (value === '')
|
|
124
|
+
continue;
|
|
125
|
+
const escaped = value.replace(/\r/g, '').replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
|
|
126
|
+
lines.push(`${key} = "${escaped}"`);
|
|
127
|
+
}
|
|
128
|
+
return lines.join('\n\n') + '\n';
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Deep merge two objects, with null deletion semantics.
|
|
132
|
+
* - Scalars: target replaces base
|
|
133
|
+
* - Objects: deep merge recursively
|
|
134
|
+
* - Arrays: target replaces base entirely
|
|
135
|
+
* - null values: delete the key
|
|
136
|
+
*/
|
|
137
|
+
export function deepMerge(base, override) {
|
|
138
|
+
const result = { ...base };
|
|
139
|
+
for (const key of Object.keys(override)) {
|
|
140
|
+
const overrideValue = override[key];
|
|
141
|
+
// null deletes the key
|
|
142
|
+
if (overrideValue === null) {
|
|
143
|
+
delete result[key];
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
// If override value is undefined, skip
|
|
147
|
+
if (overrideValue === undefined) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
const baseValue = result[key];
|
|
151
|
+
// If base doesn't have this key, just set it
|
|
152
|
+
if (!(key in result)) {
|
|
153
|
+
result[key] = overrideValue;
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
// If both are objects (not arrays), recurse
|
|
157
|
+
if (typeof baseValue === 'object' &&
|
|
158
|
+
baseValue !== null &&
|
|
159
|
+
!Array.isArray(baseValue) &&
|
|
160
|
+
typeof overrideValue === 'object' &&
|
|
161
|
+
overrideValue !== null &&
|
|
162
|
+
!Array.isArray(overrideValue)) {
|
|
163
|
+
result[key] = deepMerge(baseValue, overrideValue);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// Scalars and arrays: override replaces
|
|
167
|
+
result[key] = overrideValue;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Slugify a string to kebab-case for breakpoint IDs.
|
|
174
|
+
*/
|
|
175
|
+
export function slugify(text) {
|
|
176
|
+
return text
|
|
177
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
178
|
+
.toLowerCase()
|
|
179
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
180
|
+
.replace(/^-+|-+$/g, '');
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Check if a value is a plain object.
|
|
184
|
+
*/
|
|
185
|
+
export function isPlainObject(value) {
|
|
186
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
187
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAqB,cAAc,EAAc,MAAM,YAAY,CAAC;AAoChF,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CA4K1D"}
|
package/dist/validate.js
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// Stage 1: VALIDATE - Validate UPF source directory
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { validate as validateSchema } from './schema.js';
|
|
5
|
+
function validateReferencedPath(sourceDir, relativePath, diagnostics, options) {
|
|
6
|
+
const fullPath = path.join(sourceDir, relativePath);
|
|
7
|
+
if (!fs.existsSync(fullPath)) {
|
|
8
|
+
diagnostics.push({
|
|
9
|
+
level: options.level ?? 'error',
|
|
10
|
+
category: 'validation',
|
|
11
|
+
message: `${options.messagePrefix}: ${relativePath}`,
|
|
12
|
+
component: options.component,
|
|
13
|
+
source: fullPath,
|
|
14
|
+
});
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (!fs.statSync(fullPath).isFile()) {
|
|
18
|
+
diagnostics.push({
|
|
19
|
+
level: options.level ?? 'error',
|
|
20
|
+
category: 'validation',
|
|
21
|
+
message: `${options.messagePrefix} is not a file: ${relativePath}`,
|
|
22
|
+
component: options.component,
|
|
23
|
+
source: fullPath,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function validate(sourceDir) {
|
|
28
|
+
const diagnostics = [];
|
|
29
|
+
// Check if sourceDir exists
|
|
30
|
+
if (!fs.existsSync(sourceDir)) {
|
|
31
|
+
diagnostics.push({
|
|
32
|
+
level: 'error',
|
|
33
|
+
category: 'validation',
|
|
34
|
+
message: `Source directory does not exist: ${sourceDir}`,
|
|
35
|
+
});
|
|
36
|
+
return { valid: false, manifest: null, diagnostics };
|
|
37
|
+
}
|
|
38
|
+
// Load plugin.json
|
|
39
|
+
const manifestPath = path.join(sourceDir, 'plugin.json');
|
|
40
|
+
if (!fs.existsSync(manifestPath)) {
|
|
41
|
+
diagnostics.push({
|
|
42
|
+
level: 'error',
|
|
43
|
+
category: 'validation',
|
|
44
|
+
message: 'Missing required file: plugin.json',
|
|
45
|
+
source: manifestPath,
|
|
46
|
+
});
|
|
47
|
+
return { valid: false, manifest: null, diagnostics };
|
|
48
|
+
}
|
|
49
|
+
let manifest;
|
|
50
|
+
try {
|
|
51
|
+
const content = fs.readFileSync(manifestPath, 'utf-8');
|
|
52
|
+
manifest = JSON.parse(content);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
diagnostics.push({
|
|
56
|
+
level: 'error',
|
|
57
|
+
category: 'validation',
|
|
58
|
+
message: `Failed to parse plugin.json: ${error.message}`,
|
|
59
|
+
source: manifestPath,
|
|
60
|
+
});
|
|
61
|
+
return { valid: false, manifest: null, diagnostics };
|
|
62
|
+
}
|
|
63
|
+
// Validate against schema
|
|
64
|
+
const schemaResult = validateSchema(manifest);
|
|
65
|
+
diagnostics.push(...schemaResult.diagnostics);
|
|
66
|
+
if (!schemaResult.valid) {
|
|
67
|
+
return { valid: false, manifest, diagnostics };
|
|
68
|
+
}
|
|
69
|
+
// Verify referenced files exist
|
|
70
|
+
if (manifest.hooks) {
|
|
71
|
+
for (const [hookName, handlerValue] of Object.entries(manifest.hooks)) {
|
|
72
|
+
if (handlerValue === null || handlerValue === true)
|
|
73
|
+
continue;
|
|
74
|
+
if (typeof handlerValue !== 'string')
|
|
75
|
+
continue;
|
|
76
|
+
const fullPath = path.join(sourceDir, handlerValue);
|
|
77
|
+
if (!fs.existsSync(fullPath)) {
|
|
78
|
+
diagnostics.push({
|
|
79
|
+
level: 'error',
|
|
80
|
+
category: 'validation',
|
|
81
|
+
message: `Hook handler file not found: ${handlerValue}`,
|
|
82
|
+
component: `hooks.${hookName}`,
|
|
83
|
+
source: fullPath,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Verify command files
|
|
89
|
+
if (manifest.commands) {
|
|
90
|
+
const commandPaths = typeof manifest.commands === 'string'
|
|
91
|
+
? [manifest.commands]
|
|
92
|
+
: manifest.commands;
|
|
93
|
+
for (const cmdPath of commandPaths) {
|
|
94
|
+
const fullPath = path.join(sourceDir, cmdPath);
|
|
95
|
+
if (!fs.existsSync(fullPath)) {
|
|
96
|
+
diagnostics.push({
|
|
97
|
+
level: 'error',
|
|
98
|
+
category: 'validation',
|
|
99
|
+
message: `Command file or directory not found: ${cmdPath}`,
|
|
100
|
+
source: fullPath,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Verify skill files
|
|
106
|
+
if (manifest.skills) {
|
|
107
|
+
for (const skill of manifest.skills) {
|
|
108
|
+
validateReferencedPath(sourceDir, skill.file, diagnostics, {
|
|
109
|
+
messagePrefix: 'Skill file not found',
|
|
110
|
+
component: `skills.${skill.name}`,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Verify agent files
|
|
115
|
+
if (manifest.agents) {
|
|
116
|
+
const agentPaths = typeof manifest.agents === 'string'
|
|
117
|
+
? [manifest.agents]
|
|
118
|
+
: manifest.agents;
|
|
119
|
+
for (const [index, agentPath] of agentPaths.entries()) {
|
|
120
|
+
validateReferencedPath(sourceDir, agentPath, diagnostics, {
|
|
121
|
+
messagePrefix: 'Agent file not found',
|
|
122
|
+
component: agentPaths.length === 1 ? 'agents' : `agents.${index}`,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Verify context files
|
|
127
|
+
if (manifest.contextFiles) {
|
|
128
|
+
for (const [target, contextPath] of Object.entries(manifest.contextFiles)) {
|
|
129
|
+
validateReferencedPath(sourceDir, contextPath, diagnostics, {
|
|
130
|
+
messagePrefix: `Context file not found for target ${target}`,
|
|
131
|
+
component: `contextFiles.${target}`,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Verify versions.json exists
|
|
136
|
+
const versionsPath = path.join(sourceDir, 'versions.json');
|
|
137
|
+
if (!fs.existsSync(versionsPath)) {
|
|
138
|
+
diagnostics.push({
|
|
139
|
+
level: 'error',
|
|
140
|
+
category: 'validation',
|
|
141
|
+
message: 'Missing required file: versions.json',
|
|
142
|
+
source: versionsPath,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
try {
|
|
147
|
+
const versionsContent = fs.readFileSync(versionsPath, 'utf-8');
|
|
148
|
+
const versions = JSON.parse(versionsContent);
|
|
149
|
+
if (!versions.sdkVersion) {
|
|
150
|
+
diagnostics.push({
|
|
151
|
+
level: 'error',
|
|
152
|
+
category: 'validation',
|
|
153
|
+
message: 'versions.json is missing required field: sdkVersion',
|
|
154
|
+
source: versionsPath,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
diagnostics.push({
|
|
160
|
+
level: 'error',
|
|
161
|
+
category: 'validation',
|
|
162
|
+
message: `Failed to parse versions.json: ${error.message}`,
|
|
163
|
+
source: versionsPath,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// Check for duplicate skill names
|
|
168
|
+
if (manifest.skills) {
|
|
169
|
+
const skillNames = new Set();
|
|
170
|
+
for (const skill of manifest.skills) {
|
|
171
|
+
if (skillNames.has(skill.name)) {
|
|
172
|
+
diagnostics.push({
|
|
173
|
+
level: 'error',
|
|
174
|
+
category: 'validation',
|
|
175
|
+
message: `Duplicate skill name: ${skill.name}`,
|
|
176
|
+
component: `skills.${skill.name}`,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
skillNames.add(skill.name);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const hasErrors = diagnostics.some((d) => d.level === 'error');
|
|
183
|
+
return {
|
|
184
|
+
valid: !hasErrors,
|
|
185
|
+
manifest,
|
|
186
|
+
diagnostics,
|
|
187
|
+
};
|
|
188
|
+
}
|
package/dist/verify.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,YAAY,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAwBD,wBAAgB,MAAM,CACpB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,GAAE,aAAkB,GAC1B,YAAY,CA2Vd"}
|