@agent-loom/loom 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 +144 -0
- package/dist/apply.d.ts +56 -0
- package/dist/apply.d.ts.map +1 -0
- package/dist/apply.js +97 -0
- package/dist/apply.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +503 -0
- package/dist/cli.js.map +1 -0
- package/dist/clone.d.ts +38 -0
- package/dist/clone.d.ts.map +1 -0
- package/dist/clone.js +68 -0
- package/dist/clone.js.map +1 -0
- package/dist/config.d.ts +14 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +55 -0
- package/dist/config.js.map +1 -0
- package/dist/manifest.d.ts +41 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +454 -0
- package/dist/manifest.js.map +1 -0
- package/dist/renderers/claude.d.ts +15 -0
- package/dist/renderers/claude.d.ts.map +1 -0
- package/dist/renderers/claude.js +180 -0
- package/dist/renderers/claude.js.map +1 -0
- package/dist/renderers/copilot.d.ts +16 -0
- package/dist/renderers/copilot.d.ts.map +1 -0
- package/dist/renderers/copilot.js +191 -0
- package/dist/renderers/copilot.js.map +1 -0
- package/dist/repo-clone.d.ts +72 -0
- package/dist/repo-clone.d.ts.map +1 -0
- package/dist/repo-clone.js +197 -0
- package/dist/repo-clone.js.map +1 -0
- package/dist/resolve-template.d.ts +32 -0
- package/dist/resolve-template.d.ts.map +1 -0
- package/dist/resolve-template.js +75 -0
- package/dist/resolve-template.js.map +1 -0
- package/dist/search-registry.d.ts +31 -0
- package/dist/search-registry.d.ts.map +1 -0
- package/dist/search-registry.js +96 -0
- package/dist/search-registry.js.map +1 -0
- package/dist/search.d.ts +20 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +51 -0
- package/dist/search.js.map +1 -0
- package/dist/skill-fetcher.d.ts +40 -0
- package/dist/skill-fetcher.d.ts.map +1 -0
- package/dist/skill-fetcher.js +99 -0
- package/dist/skill-fetcher.js.map +1 -0
- package/dist/types.d.ts +297 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +18 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +42 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +191 -0
- package/dist/validate.js.map +1 -0
- package/dist/workspaces.d.ts +17 -0
- package/dist/workspaces.d.ts.map +1 -0
- package/dist/workspaces.js +72 -0
- package/dist/workspaces.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Fetcher — Resolves registry skills to local content
|
|
3
|
+
*
|
|
4
|
+
* Downloads/fetches skill content from external registries (craft, skills.sh)
|
|
5
|
+
* and converts them to local skills that can be placed in the workspace.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Create a mock fetcher backed by a static map (for testing and offline use).
|
|
9
|
+
*/
|
|
10
|
+
export function createMockFetcher(skills) {
|
|
11
|
+
return async (_registry, ref) => {
|
|
12
|
+
const content = skills[ref];
|
|
13
|
+
if (content === undefined) {
|
|
14
|
+
throw new Error(`Skill "${ref}" not found in mock registry.`);
|
|
15
|
+
}
|
|
16
|
+
return content;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create a fetcher for craft skills.
|
|
21
|
+
*
|
|
22
|
+
* Tries to fetch SKILL.md from the craft-skills GitHub repo.
|
|
23
|
+
* Falls back to a stub SKILL.md if the fetch fails.
|
|
24
|
+
*
|
|
25
|
+
* Supports optional authentication via tokenFn for private repos.
|
|
26
|
+
*/
|
|
27
|
+
export function createCraftFetcher(options) {
|
|
28
|
+
const baseUrl = options?.baseUrl
|
|
29
|
+
?? process.env.CRAFT_SKILLS_BASE_URL
|
|
30
|
+
?? 'https://raw.githubusercontent.com/serverless-paas-balam/craft/main/skills-repo/skills';
|
|
31
|
+
const tokenFn = options?.tokenFn;
|
|
32
|
+
const fetchImpl = options?.fetchFn ?? globalThis.fetch;
|
|
33
|
+
return async (registry, ref) => {
|
|
34
|
+
if (registry !== 'craft') {
|
|
35
|
+
return createStubSkill(registry, ref);
|
|
36
|
+
}
|
|
37
|
+
const url = `${baseUrl}/${ref}/SKILL.md`;
|
|
38
|
+
const headers = {};
|
|
39
|
+
const token = tokenFn?.();
|
|
40
|
+
if (token) {
|
|
41
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const response = await fetchImpl(url, { headers });
|
|
45
|
+
if (!response.ok) {
|
|
46
|
+
console.warn(` ⚠ Could not fetch skill "${ref}" from ${url} (${response.status}). Using stub.`);
|
|
47
|
+
return createStubSkill(registry, ref);
|
|
48
|
+
}
|
|
49
|
+
return await response.text();
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
console.warn(` ⚠ Network error fetching skill "${ref}". Using stub.`);
|
|
53
|
+
return createStubSkill(registry, ref);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create a stub SKILL.md when a skill cannot be fetched.
|
|
59
|
+
*/
|
|
60
|
+
function createStubSkill(registry, ref) {
|
|
61
|
+
return `---
|
|
62
|
+
name: ${ref}
|
|
63
|
+
description: "Skill from ${registry}:${ref} — content could not be fetched. Replace this with the actual skill content."
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
# ${ref}
|
|
67
|
+
|
|
68
|
+
> This is a placeholder. The original skill content from \`${registry}:${ref}\` could not be fetched.
|
|
69
|
+
> Replace this file with the actual SKILL.md content.
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolve registry skills by fetching their content and converting
|
|
74
|
+
* them to local skills. If no fetcher is provided, registry skills
|
|
75
|
+
* are passed through unchanged.
|
|
76
|
+
*
|
|
77
|
+
* @param skills - Array of resolved skills (may include registry type)
|
|
78
|
+
* @param fetcher - Optional function to fetch skill content
|
|
79
|
+
* @returns Updated skills array with registry skills converted to local
|
|
80
|
+
*/
|
|
81
|
+
export async function resolveRegistrySkills(skills, fetcher) {
|
|
82
|
+
if (!fetcher)
|
|
83
|
+
return skills;
|
|
84
|
+
return Promise.all(skills.map(async (skill) => {
|
|
85
|
+
if (skill.type !== 'registry' || !skill.registry || !skill.ref) {
|
|
86
|
+
return skill;
|
|
87
|
+
}
|
|
88
|
+
const content = await fetcher(skill.registry, skill.ref);
|
|
89
|
+
return {
|
|
90
|
+
type: 'local',
|
|
91
|
+
name: skill.ref,
|
|
92
|
+
content,
|
|
93
|
+
sourcePath: `${skill.registry}:${skill.ref}`,
|
|
94
|
+
originalRegistry: skill.registry,
|
|
95
|
+
originalRef: skill.ref,
|
|
96
|
+
};
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=skill-fetcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-fetcher.js","sourceRoot":"","sources":["../src/skill-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAA8B;IAE9B,OAAO,KAAK,EAAE,SAAiB,EAAE,GAAW,EAAmB,EAAE;QAC/D,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,UAAU,GAAG,+BAA+B,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAIC;IAED,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO;WAC3B,OAAO,CAAC,GAAG,CAAC,qBAAqB;WACjC,uFAAuF,CAAC;IAC7F,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,CAAC;IACjC,MAAM,SAAS,GAAG,OAAO,EAAE,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC;IAEvD,OAAO,KAAK,EAAE,QAAgB,EAAE,GAAW,EAAmB,EAAE;QAC9D,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,OAAO,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACxC,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,OAAO,IAAI,GAAG,WAAW,CAAC;QACzC,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,OAAO,EAAE,EAAE,CAAC;QAC1B,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;QAC/C,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YACnD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,CAAC,IAAI,CAAC,8BAA8B,GAAG,UAAU,GAAG,KAAK,QAAQ,CAAC,MAAM,gBAAgB,CAAC,CAAC;gBACjG,OAAO,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YACxC,CAAC;YACD,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,qCAAqC,GAAG,gBAAgB,CAAC,CAAC;YACvE,OAAO,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACxC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,QAAgB,EAAE,GAAW;IACpD,OAAO;QACD,GAAG;2BACgB,QAAQ,IAAI,GAAG;;;IAGtC,GAAG;;6DAEsD,QAAQ,IAAI,GAAG;;CAE3E,CAAC;AACF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAuB,EACvB,OAAsB;IAEtB,IAAI,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC;IAE5B,OAAO,OAAO,CAAC,GAAG,CAChB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAA0B,EAAE;QACjD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YAC/D,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAEzD,OAAO;YACL,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,KAAK,CAAC,GAAG;YACf,OAAO;YACP,UAAU,EAAE,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,GAAG,EAAE;YAC5C,gBAAgB,EAAE,KAAK,CAAC,QAAQ;YAChC,WAAW,EAAE,KAAK,CAAC,GAAG;SACvB,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loom — Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Core types for manifest.yaml schema, config, workspaces, and registry.
|
|
5
|
+
*/
|
|
6
|
+
/** Top-level manifest.yaml structure */
|
|
7
|
+
export interface Manifest {
|
|
8
|
+
version: string;
|
|
9
|
+
template: TemplateMetadata;
|
|
10
|
+
extends?: string[];
|
|
11
|
+
targets: TargetType[];
|
|
12
|
+
contents: ManifestContents;
|
|
13
|
+
prerequisites?: ResourceRef[];
|
|
14
|
+
}
|
|
15
|
+
export type TargetType = 'copilot' | 'claude' | 'cursor';
|
|
16
|
+
export interface TemplateMetadata {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
description: string;
|
|
20
|
+
author: string;
|
|
21
|
+
tags: string[];
|
|
22
|
+
icon?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ManifestContents {
|
|
25
|
+
instructions?: InstructionEntry[];
|
|
26
|
+
skills?: SkillEntry[];
|
|
27
|
+
agents?: AgentEntry[];
|
|
28
|
+
mcp?: McpEntry[];
|
|
29
|
+
repos?: RepoEntry[];
|
|
30
|
+
prompts?: PromptEntry[];
|
|
31
|
+
}
|
|
32
|
+
/** References a file in the shared/ directory */
|
|
33
|
+
export interface SharedRef {
|
|
34
|
+
$ref: string;
|
|
35
|
+
}
|
|
36
|
+
export declare function isSharedRef(entry: unknown): entry is SharedRef;
|
|
37
|
+
/** References a local file within the template directory */
|
|
38
|
+
export interface LocalFileRef {
|
|
39
|
+
file: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function isLocalFileRef(entry: unknown): entry is LocalFileRef;
|
|
42
|
+
/** References an external skill registry */
|
|
43
|
+
export interface RegistrySkillRef {
|
|
44
|
+
registry: 'skills.sh' | 'craft';
|
|
45
|
+
ref: string;
|
|
46
|
+
}
|
|
47
|
+
export declare function isRegistrySkillRef(entry: unknown): entry is RegistrySkillRef;
|
|
48
|
+
export type InstructionEntry = (SharedRef | LocalFileRef) & {
|
|
49
|
+
scope: string;
|
|
50
|
+
};
|
|
51
|
+
export type SkillEntry = RegistrySkillRef | (LocalFileRef & {
|
|
52
|
+
name?: string;
|
|
53
|
+
});
|
|
54
|
+
export type AgentEntry = LocalFileRef & {
|
|
55
|
+
model?: string;
|
|
56
|
+
tools?: string[];
|
|
57
|
+
};
|
|
58
|
+
export type McpEntry = SharedRef | McpInlineDef;
|
|
59
|
+
export interface McpInlineDef {
|
|
60
|
+
id: string;
|
|
61
|
+
name?: string;
|
|
62
|
+
description?: string;
|
|
63
|
+
type: 'stdio' | 'http';
|
|
64
|
+
command?: string;
|
|
65
|
+
args?: string[];
|
|
66
|
+
url?: string;
|
|
67
|
+
authType?: string;
|
|
68
|
+
env?: Record<string, string>;
|
|
69
|
+
}
|
|
70
|
+
export declare function isMcpInlineDef(entry: unknown): entry is McpInlineDef;
|
|
71
|
+
export type PromptEntry = SharedRef | PromptLocalRef;
|
|
72
|
+
export interface PromptLocalRef {
|
|
73
|
+
file: string;
|
|
74
|
+
name?: string;
|
|
75
|
+
description?: string;
|
|
76
|
+
agent?: string;
|
|
77
|
+
model?: string;
|
|
78
|
+
tools?: string[];
|
|
79
|
+
shared?: boolean;
|
|
80
|
+
disableAutoInvoke?: boolean;
|
|
81
|
+
}
|
|
82
|
+
export type RepoEntry = SharedRef | RepoInlineDef;
|
|
83
|
+
export interface RepoInlineDef {
|
|
84
|
+
id?: string;
|
|
85
|
+
name?: string;
|
|
86
|
+
url: string;
|
|
87
|
+
description?: string;
|
|
88
|
+
sparse?: boolean;
|
|
89
|
+
paths?: string[];
|
|
90
|
+
large?: boolean;
|
|
91
|
+
cloneStrategy?: 'prompt' | 'sparse' | 'partial' | 'skip';
|
|
92
|
+
note?: string;
|
|
93
|
+
}
|
|
94
|
+
export type ResourceRef = SharedRef | PrerequisiteInlineDef;
|
|
95
|
+
export interface PrerequisiteInlineDef {
|
|
96
|
+
id: string;
|
|
97
|
+
name: string;
|
|
98
|
+
required: boolean;
|
|
99
|
+
description?: string;
|
|
100
|
+
check: PlatformCommands;
|
|
101
|
+
install: PlatformCommands;
|
|
102
|
+
}
|
|
103
|
+
export interface PlatformCommands {
|
|
104
|
+
windows?: string;
|
|
105
|
+
mac?: string;
|
|
106
|
+
linux?: string;
|
|
107
|
+
}
|
|
108
|
+
export interface ResolvedManifest {
|
|
109
|
+
version: string;
|
|
110
|
+
template: TemplateMetadata;
|
|
111
|
+
targets: TargetType[];
|
|
112
|
+
instructions: ResolvedInstruction[];
|
|
113
|
+
skills: ResolvedSkill[];
|
|
114
|
+
agents: ResolvedAgent[];
|
|
115
|
+
mcp: ResolvedMcp[];
|
|
116
|
+
repos: ResolvedRepo[];
|
|
117
|
+
prompts: ResolvedPrompt[];
|
|
118
|
+
prerequisites: ResolvedPrerequisite[];
|
|
119
|
+
}
|
|
120
|
+
export interface ResolvedInstruction {
|
|
121
|
+
scope: string;
|
|
122
|
+
content: string;
|
|
123
|
+
sourcePath: string;
|
|
124
|
+
}
|
|
125
|
+
export interface ResolvedSkill {
|
|
126
|
+
type: 'registry' | 'local';
|
|
127
|
+
registry?: string;
|
|
128
|
+
ref?: string;
|
|
129
|
+
name?: string;
|
|
130
|
+
content?: string;
|
|
131
|
+
sourcePath?: string;
|
|
132
|
+
/** Extra files alongside SKILL.md (e.g. references/) */
|
|
133
|
+
extraFiles?: SkillExtraFile[];
|
|
134
|
+
/** Original registry name (set when a registry skill is fetched and converted to local) */
|
|
135
|
+
originalRegistry?: string;
|
|
136
|
+
/** Original ref/ID (set when a registry skill is fetched and converted to local) */
|
|
137
|
+
originalRef?: string;
|
|
138
|
+
}
|
|
139
|
+
/** An extra file bundled with a local skill */
|
|
140
|
+
export interface SkillExtraFile {
|
|
141
|
+
/** Path relative to the skill directory (e.g. "references/functions-icm-loops.md") */
|
|
142
|
+
relativePath: string;
|
|
143
|
+
/** File content (UTF-8 text) */
|
|
144
|
+
content: string;
|
|
145
|
+
}
|
|
146
|
+
export interface ResolvedAgent {
|
|
147
|
+
name: string;
|
|
148
|
+
description: string;
|
|
149
|
+
model?: string;
|
|
150
|
+
tools: string[];
|
|
151
|
+
content: string;
|
|
152
|
+
sourcePath: string;
|
|
153
|
+
}
|
|
154
|
+
export interface ResolvedMcp {
|
|
155
|
+
id: string;
|
|
156
|
+
name?: string;
|
|
157
|
+
description?: string;
|
|
158
|
+
type: 'stdio' | 'http';
|
|
159
|
+
command?: string;
|
|
160
|
+
args?: string[];
|
|
161
|
+
url?: string;
|
|
162
|
+
authType?: string;
|
|
163
|
+
env?: Record<string, string>;
|
|
164
|
+
}
|
|
165
|
+
export interface ResolvedPrompt {
|
|
166
|
+
name: string;
|
|
167
|
+
description?: string;
|
|
168
|
+
content: string;
|
|
169
|
+
sourcePath: string;
|
|
170
|
+
agent?: string;
|
|
171
|
+
model?: string;
|
|
172
|
+
tools?: string[];
|
|
173
|
+
shared?: boolean;
|
|
174
|
+
disableAutoInvoke?: boolean;
|
|
175
|
+
}
|
|
176
|
+
export interface ResolvedRepo {
|
|
177
|
+
id?: string;
|
|
178
|
+
name?: string;
|
|
179
|
+
url: string;
|
|
180
|
+
description?: string;
|
|
181
|
+
sparse?: boolean;
|
|
182
|
+
paths?: string[];
|
|
183
|
+
large?: boolean;
|
|
184
|
+
repoType?: 'github' | 'ado';
|
|
185
|
+
cloneStrategy?: 'prompt' | 'sparse' | 'partial' | 'skip';
|
|
186
|
+
note?: string;
|
|
187
|
+
}
|
|
188
|
+
export interface ResolvedPrerequisite {
|
|
189
|
+
id: string;
|
|
190
|
+
name: string;
|
|
191
|
+
required: boolean;
|
|
192
|
+
description?: string;
|
|
193
|
+
check: PlatformCommands;
|
|
194
|
+
install: PlatformCommands;
|
|
195
|
+
}
|
|
196
|
+
export interface LoomConfig {
|
|
197
|
+
registries: RegistryConfig[];
|
|
198
|
+
defaultTarget?: TargetType;
|
|
199
|
+
}
|
|
200
|
+
export interface RegistryConfig {
|
|
201
|
+
name: string;
|
|
202
|
+
url: string;
|
|
203
|
+
type?: 'github';
|
|
204
|
+
}
|
|
205
|
+
export interface WorkspacesFile {
|
|
206
|
+
workspaces: WorkspaceEntry[];
|
|
207
|
+
}
|
|
208
|
+
export interface WorkspaceEntry {
|
|
209
|
+
path: string;
|
|
210
|
+
template: string;
|
|
211
|
+
registry: string;
|
|
212
|
+
appliedAt: string;
|
|
213
|
+
lastOpenedAt?: string;
|
|
214
|
+
tags: string[];
|
|
215
|
+
notes: string;
|
|
216
|
+
}
|
|
217
|
+
export interface RegistryIndex {
|
|
218
|
+
version: string;
|
|
219
|
+
registry: {
|
|
220
|
+
name: string;
|
|
221
|
+
description: string;
|
|
222
|
+
url: string;
|
|
223
|
+
};
|
|
224
|
+
templates: RegistryTemplateEntry[];
|
|
225
|
+
}
|
|
226
|
+
export interface RegistryTemplateEntry {
|
|
227
|
+
id: string;
|
|
228
|
+
name: string;
|
|
229
|
+
description: string;
|
|
230
|
+
path: string;
|
|
231
|
+
tags: string[];
|
|
232
|
+
version: string;
|
|
233
|
+
/** Nested agent entries (for team-based templates) */
|
|
234
|
+
agents?: AgentRegistryEntry[];
|
|
235
|
+
}
|
|
236
|
+
/** Agent entry within a team template in index.yaml */
|
|
237
|
+
export interface AgentRegistryEntry {
|
|
238
|
+
id: string;
|
|
239
|
+
name: string;
|
|
240
|
+
description: string;
|
|
241
|
+
tags: string[];
|
|
242
|
+
path: string;
|
|
243
|
+
}
|
|
244
|
+
/** Per-agent manifest.yaml (lives in templates/<team>/agents/<id>/manifest.yaml) */
|
|
245
|
+
export interface AgentManifest {
|
|
246
|
+
agent: AgentManifestMeta;
|
|
247
|
+
contents?: AgentManifestContents;
|
|
248
|
+
prerequisites?: ResourceRef[];
|
|
249
|
+
}
|
|
250
|
+
export interface AgentManifestMeta {
|
|
251
|
+
id: string;
|
|
252
|
+
name: string;
|
|
253
|
+
description: string;
|
|
254
|
+
model?: string;
|
|
255
|
+
tags?: string[];
|
|
256
|
+
tools?: string[];
|
|
257
|
+
}
|
|
258
|
+
/** Agent-specific content additions (merged with team manifest) */
|
|
259
|
+
export interface AgentManifestContents {
|
|
260
|
+
instructions?: InstructionEntry[];
|
|
261
|
+
mcp?: McpEntry[];
|
|
262
|
+
repos?: RepoEntry[];
|
|
263
|
+
skills?: SkillEntry[];
|
|
264
|
+
prompts?: PromptEntry[];
|
|
265
|
+
}
|
|
266
|
+
export interface SharedMcpFile {
|
|
267
|
+
id: string;
|
|
268
|
+
name: string;
|
|
269
|
+
description?: string;
|
|
270
|
+
type: 'stdio' | 'http';
|
|
271
|
+
command?: string;
|
|
272
|
+
args?: string[];
|
|
273
|
+
url?: string;
|
|
274
|
+
authType?: string;
|
|
275
|
+
env?: Record<string, string>;
|
|
276
|
+
}
|
|
277
|
+
export interface SharedRepoFile {
|
|
278
|
+
id: string;
|
|
279
|
+
name: string;
|
|
280
|
+
description?: string;
|
|
281
|
+
url: string;
|
|
282
|
+
sparse?: boolean;
|
|
283
|
+
paths?: string[];
|
|
284
|
+
large?: boolean;
|
|
285
|
+
repoType?: 'github' | 'ado';
|
|
286
|
+
cloneStrategy?: 'prompt' | 'sparse' | 'skip';
|
|
287
|
+
note?: string;
|
|
288
|
+
}
|
|
289
|
+
export interface SharedPrerequisiteFile {
|
|
290
|
+
id: string;
|
|
291
|
+
name: string;
|
|
292
|
+
required: boolean;
|
|
293
|
+
description?: string;
|
|
294
|
+
check: PlatformCommands;
|
|
295
|
+
install: PlatformCommands;
|
|
296
|
+
}
|
|
297
|
+
//# 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
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loom — Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Core types for manifest.yaml schema, config, workspaces, and registry.
|
|
5
|
+
*/
|
|
6
|
+
export function isSharedRef(entry) {
|
|
7
|
+
return typeof entry === 'object' && entry !== null && '$ref' in entry;
|
|
8
|
+
}
|
|
9
|
+
export function isLocalFileRef(entry) {
|
|
10
|
+
return typeof entry === 'object' && entry !== null && 'file' in entry;
|
|
11
|
+
}
|
|
12
|
+
export function isRegistrySkillRef(entry) {
|
|
13
|
+
return typeof entry === 'object' && entry !== null && 'registry' in entry;
|
|
14
|
+
}
|
|
15
|
+
export function isMcpInlineDef(entry) {
|
|
16
|
+
return typeof entry === 'object' && entry !== null && 'id' in entry && 'type' in entry;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA2CH,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;AACxE,CAAC;AAOD,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;AACxE,CAAC;AAQD,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,UAAU,IAAI,KAAK,CAAC;AAC5E,CAAC;AAmCD,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,MAAM,IAAI,KAAK,CAAC;AACzF,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest validation — schema, reference, and registry checks.
|
|
3
|
+
*/
|
|
4
|
+
export interface ValidateResult {
|
|
5
|
+
templateId: string;
|
|
6
|
+
errors: ValidationError[];
|
|
7
|
+
warnings: ValidationWarning[];
|
|
8
|
+
summary: {
|
|
9
|
+
instructions: number;
|
|
10
|
+
skills: number;
|
|
11
|
+
agents: number;
|
|
12
|
+
mcp: number;
|
|
13
|
+
repos: number;
|
|
14
|
+
prompts: number;
|
|
15
|
+
prerequisites: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export interface ValidationError {
|
|
19
|
+
level: 'schema' | 'reference' | 'registry';
|
|
20
|
+
field: string;
|
|
21
|
+
message: string;
|
|
22
|
+
path?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ValidationWarning {
|
|
25
|
+
field: string;
|
|
26
|
+
message: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Validate a single template directory.
|
|
30
|
+
*/
|
|
31
|
+
export declare function validateTemplate(templateDir: string, registryRoot: string): Promise<ValidateResult>;
|
|
32
|
+
export interface RegistryIndex {
|
|
33
|
+
templates: Array<{
|
|
34
|
+
id: string;
|
|
35
|
+
path: string;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Validate all templates in a registry (reads index.yaml).
|
|
40
|
+
*/
|
|
41
|
+
export declare function validateRegistry(registryRoot: string): Promise<ValidateResult[]>;
|
|
42
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,OAAO,EAAE;QACP,YAAY,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAC;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,CAAC,CA+GzB;AAMD,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,EAAE,CAAC,CAyC3B"}
|
package/dist/validate.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest validation — schema, reference, and registry checks.
|
|
3
|
+
*/
|
|
4
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
5
|
+
import { join, resolve } from 'node:path';
|
|
6
|
+
import yaml from 'js-yaml';
|
|
7
|
+
import { isSharedRef, isLocalFileRef } from './types.js';
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// Validate Template
|
|
10
|
+
// =============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Validate a single template directory.
|
|
13
|
+
*/
|
|
14
|
+
export async function validateTemplate(templateDir, registryRoot) {
|
|
15
|
+
const manifestPath = join(templateDir, 'manifest.yaml');
|
|
16
|
+
const errors = [];
|
|
17
|
+
const warnings = [];
|
|
18
|
+
// --- Level 1: Schema validation ---
|
|
19
|
+
let manifest = null;
|
|
20
|
+
try {
|
|
21
|
+
const content = await readFile(manifestPath, 'utf-8');
|
|
22
|
+
const raw = yaml.load(content);
|
|
23
|
+
if (!raw || typeof raw !== 'object') {
|
|
24
|
+
errors.push({ level: 'schema', field: 'manifest', message: 'manifest.yaml is not a valid YAML object' });
|
|
25
|
+
return buildResult('unknown', errors, warnings);
|
|
26
|
+
}
|
|
27
|
+
manifest = raw;
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
if (err.code === 'ENOENT') {
|
|
31
|
+
errors.push({ level: 'schema', field: 'manifest', message: 'manifest.yaml not found' });
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
errors.push({ level: 'schema', field: 'manifest', message: `Failed to parse manifest.yaml: ${err.message}` });
|
|
35
|
+
}
|
|
36
|
+
return buildResult('unknown', errors, warnings);
|
|
37
|
+
}
|
|
38
|
+
// Required fields
|
|
39
|
+
if (!manifest.version) {
|
|
40
|
+
errors.push({ level: 'schema', field: 'version', message: 'Missing required field: version' });
|
|
41
|
+
}
|
|
42
|
+
else if (!/^\d+\.\d+\.\d+/.test(manifest.version)) {
|
|
43
|
+
errors.push({ level: 'schema', field: 'version', message: `Invalid semver: ${manifest.version}` });
|
|
44
|
+
}
|
|
45
|
+
if (!manifest.template?.id) {
|
|
46
|
+
errors.push({ level: 'schema', field: 'template.id', message: 'Missing required field: template.id' });
|
|
47
|
+
}
|
|
48
|
+
if (!manifest.template?.name) {
|
|
49
|
+
errors.push({ level: 'schema', field: 'template.name', message: 'Missing required field: template.name' });
|
|
50
|
+
}
|
|
51
|
+
if (!manifest.targets || !Array.isArray(manifest.targets) || manifest.targets.length === 0) {
|
|
52
|
+
errors.push({ level: 'schema', field: 'targets', message: 'Missing or empty required field: targets' });
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
const validTargets = ['copilot', 'claude', 'cursor'];
|
|
56
|
+
for (const t of manifest.targets) {
|
|
57
|
+
if (!validTargets.includes(t)) {
|
|
58
|
+
errors.push({ level: 'schema', field: 'targets', message: `Invalid target: ${t}` });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const templateId = manifest.template?.id ?? 'unknown';
|
|
63
|
+
// --- Level 2: Reference validation ---
|
|
64
|
+
const contents = manifest.contents ?? {};
|
|
65
|
+
const instructions = contents.instructions ?? [];
|
|
66
|
+
const skills = contents.skills ?? [];
|
|
67
|
+
const agents = contents.agents ?? [];
|
|
68
|
+
const mcp = contents.mcp ?? [];
|
|
69
|
+
const repos = contents.repos ?? [];
|
|
70
|
+
const prompts = contents.prompts ?? [];
|
|
71
|
+
const prerequisites = manifest.prerequisites ?? [];
|
|
72
|
+
// Check $ref and file references
|
|
73
|
+
for (const entry of instructions) {
|
|
74
|
+
if (isSharedRef(entry)) {
|
|
75
|
+
await checkFileExists(resolve(registryRoot, entry.$ref), entry.$ref, 'instructions', errors);
|
|
76
|
+
}
|
|
77
|
+
else if (isLocalFileRef(entry)) {
|
|
78
|
+
await checkFileExists(resolve(templateDir, entry.file), entry.file, 'instructions', errors);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
for (const entry of agents) {
|
|
82
|
+
if (isLocalFileRef(entry)) {
|
|
83
|
+
await checkFileExists(resolve(templateDir, entry.file), entry.file, 'agents', errors);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
for (const entry of mcp) {
|
|
87
|
+
if (isSharedRef(entry)) {
|
|
88
|
+
await checkFileExists(resolve(registryRoot, entry.$ref), entry.$ref, 'mcp', errors);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (const entry of repos) {
|
|
92
|
+
if (isSharedRef(entry)) {
|
|
93
|
+
await checkFileExists(resolve(registryRoot, entry.$ref), entry.$ref, 'repos', errors);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
for (const entry of prompts) {
|
|
97
|
+
if (isSharedRef(entry)) {
|
|
98
|
+
await checkFileExists(resolve(registryRoot, entry.$ref), entry.$ref, 'prompts', errors);
|
|
99
|
+
}
|
|
100
|
+
else if (isLocalFileRef(entry)) {
|
|
101
|
+
await checkFileExists(resolve(templateDir, entry.file), entry.file, 'prompts', errors);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
for (const entry of prerequisites) {
|
|
105
|
+
if (isSharedRef(entry)) {
|
|
106
|
+
await checkFileExists(resolve(registryRoot, entry.$ref), entry.$ref, 'prerequisites', errors);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return buildResult(templateId, errors, warnings, {
|
|
110
|
+
instructions: instructions.length,
|
|
111
|
+
skills: skills.length,
|
|
112
|
+
agents: agents.length,
|
|
113
|
+
mcp: mcp.length,
|
|
114
|
+
repos: repos.length,
|
|
115
|
+
prompts: prompts.length,
|
|
116
|
+
prerequisites: prerequisites.length,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Validate all templates in a registry (reads index.yaml).
|
|
121
|
+
*/
|
|
122
|
+
export async function validateRegistry(registryRoot) {
|
|
123
|
+
const indexPath = join(registryRoot, 'index.yaml');
|
|
124
|
+
const content = await readFile(indexPath, 'utf-8');
|
|
125
|
+
const index = yaml.load(content);
|
|
126
|
+
if (!index?.templates || !Array.isArray(index.templates)) {
|
|
127
|
+
return [{
|
|
128
|
+
templateId: '__registry__',
|
|
129
|
+
errors: [{ level: 'registry', field: 'index.yaml', message: 'index.yaml has no templates array' }],
|
|
130
|
+
warnings: [],
|
|
131
|
+
summary: { instructions: 0, skills: 0, agents: 0, mcp: 0, repos: 0, prompts: 0, prerequisites: 0 },
|
|
132
|
+
}];
|
|
133
|
+
}
|
|
134
|
+
// Check for duplicate IDs
|
|
135
|
+
const ids = index.templates.map((t) => t.id);
|
|
136
|
+
const duplicates = ids.filter((id, i) => ids.indexOf(id) !== i);
|
|
137
|
+
const results = [];
|
|
138
|
+
if (duplicates.length > 0) {
|
|
139
|
+
results.push({
|
|
140
|
+
templateId: '__registry__',
|
|
141
|
+
errors: duplicates.map((id) => ({
|
|
142
|
+
level: 'registry',
|
|
143
|
+
field: 'index.yaml',
|
|
144
|
+
message: `Duplicate template ID: ${id}`,
|
|
145
|
+
})),
|
|
146
|
+
warnings: [],
|
|
147
|
+
summary: { instructions: 0, skills: 0, agents: 0, mcp: 0, repos: 0, prompts: 0, prerequisites: 0 },
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
// Validate each template
|
|
151
|
+
for (const entry of index.templates) {
|
|
152
|
+
const templateDir = join(registryRoot, entry.path);
|
|
153
|
+
const result = await validateTemplate(templateDir, registryRoot);
|
|
154
|
+
results.push(result);
|
|
155
|
+
}
|
|
156
|
+
return results;
|
|
157
|
+
}
|
|
158
|
+
// =============================================================================
|
|
159
|
+
// Helpers
|
|
160
|
+
// =============================================================================
|
|
161
|
+
async function checkFileExists(absolutePath, refPath, field, errors) {
|
|
162
|
+
try {
|
|
163
|
+
await stat(absolutePath);
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
errors.push({
|
|
167
|
+
level: 'reference',
|
|
168
|
+
field,
|
|
169
|
+
message: `Missing reference: ${refPath}`,
|
|
170
|
+
path: refPath,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function buildResult(templateId, errors, warnings, summary) {
|
|
175
|
+
return {
|
|
176
|
+
templateId,
|
|
177
|
+
errors,
|
|
178
|
+
warnings,
|
|
179
|
+
summary: {
|
|
180
|
+
instructions: 0,
|
|
181
|
+
skills: 0,
|
|
182
|
+
agents: 0,
|
|
183
|
+
mcp: 0,
|
|
184
|
+
repos: 0,
|
|
185
|
+
prompts: 0,
|
|
186
|
+
prerequisites: 0,
|
|
187
|
+
...summary,
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=validate.js.map
|