@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,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Renderer
|
|
3
|
+
*
|
|
4
|
+
* Generates Claude Code workspace configuration files from a ResolvedManifest:
|
|
5
|
+
* CLAUDE.md — combined instructions
|
|
6
|
+
* .claude/settings.json — MCP servers + settings
|
|
7
|
+
* .claude/agents/<name>.md — subagents (plain markdown)
|
|
8
|
+
* .mcp.json — project-level MCP config
|
|
9
|
+
*/
|
|
10
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
/**
|
|
13
|
+
* Render a resolved manifest into Claude Code workspace configuration files.
|
|
14
|
+
*/
|
|
15
|
+
export async function renderClaude(manifest, outputDir) {
|
|
16
|
+
await Promise.all([
|
|
17
|
+
renderClaudeMd(manifest.instructions, manifest.repos, outputDir),
|
|
18
|
+
renderSettings(manifest.mcp, outputDir),
|
|
19
|
+
renderMcpJson(manifest.mcp, outputDir),
|
|
20
|
+
renderAgents(manifest.agents, outputDir),
|
|
21
|
+
renderPrompts(manifest.prompts, outputDir),
|
|
22
|
+
]);
|
|
23
|
+
}
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// CLAUDE.md
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
async function renderClaudeMd(instructions, repos, outputDir) {
|
|
28
|
+
const hasInstructions = instructions.length > 0;
|
|
29
|
+
const hasRepos = repos.length > 0;
|
|
30
|
+
if (!hasInstructions && !hasRepos)
|
|
31
|
+
return;
|
|
32
|
+
const sections = [];
|
|
33
|
+
// Global instructions first
|
|
34
|
+
const globals = instructions.filter((i) => i.scope === 'global');
|
|
35
|
+
for (const instr of globals) {
|
|
36
|
+
sections.push(instr.content);
|
|
37
|
+
}
|
|
38
|
+
// Scoped instructions with a scope header
|
|
39
|
+
const scoped = instructions.filter((i) => i.scope !== 'global');
|
|
40
|
+
for (const instr of scoped) {
|
|
41
|
+
sections.push(`<!-- scope: ${instr.scope} -->\n${instr.content}`);
|
|
42
|
+
}
|
|
43
|
+
// Repos section
|
|
44
|
+
if (hasRepos) {
|
|
45
|
+
sections.push(buildReposSection(repos));
|
|
46
|
+
}
|
|
47
|
+
await mkdir(outputDir, { recursive: true });
|
|
48
|
+
await writeFile(join(outputDir, 'CLAUDE.md'), sections.join('\n\n'), 'utf-8');
|
|
49
|
+
}
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// .claude/settings.json
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
async function renderSettings(servers, outputDir) {
|
|
54
|
+
if (servers.length === 0)
|
|
55
|
+
return;
|
|
56
|
+
const claudeDir = join(outputDir, '.claude');
|
|
57
|
+
await mkdir(claudeDir, { recursive: true });
|
|
58
|
+
const mcpServers = {};
|
|
59
|
+
for (const server of servers) {
|
|
60
|
+
const entry = { type: server.type };
|
|
61
|
+
if (server.type === 'stdio') {
|
|
62
|
+
if (server.command)
|
|
63
|
+
entry.command = server.command;
|
|
64
|
+
if (server.args && server.args.length > 0)
|
|
65
|
+
entry.args = server.args;
|
|
66
|
+
if (server.env && Object.keys(server.env).length > 0)
|
|
67
|
+
entry.env = server.env;
|
|
68
|
+
}
|
|
69
|
+
else if (server.type === 'http' || server.type === 'sse') {
|
|
70
|
+
if (server.url)
|
|
71
|
+
entry.url = server.url;
|
|
72
|
+
}
|
|
73
|
+
mcpServers[server.id] = entry;
|
|
74
|
+
}
|
|
75
|
+
const settings = { mcpServers };
|
|
76
|
+
await writeFile(join(claudeDir, 'settings.json'), JSON.stringify(settings, null, 2), 'utf-8');
|
|
77
|
+
}
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// .mcp.json (project-level)
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
async function renderMcpJson(servers, outputDir) {
|
|
82
|
+
if (servers.length === 0)
|
|
83
|
+
return;
|
|
84
|
+
const mcpServers = {};
|
|
85
|
+
for (const server of servers) {
|
|
86
|
+
const entry = { type: server.type };
|
|
87
|
+
if (server.type === 'stdio') {
|
|
88
|
+
if (server.command)
|
|
89
|
+
entry.command = server.command;
|
|
90
|
+
if (server.args && server.args.length > 0)
|
|
91
|
+
entry.args = server.args;
|
|
92
|
+
if (server.env && Object.keys(server.env).length > 0)
|
|
93
|
+
entry.env = server.env;
|
|
94
|
+
}
|
|
95
|
+
else if (server.type === 'http' || server.type === 'sse') {
|
|
96
|
+
if (server.url)
|
|
97
|
+
entry.url = server.url;
|
|
98
|
+
}
|
|
99
|
+
mcpServers[server.id] = entry;
|
|
100
|
+
}
|
|
101
|
+
await mkdir(outputDir, { recursive: true });
|
|
102
|
+
await writeFile(join(outputDir, '.mcp.json'), JSON.stringify({ mcpServers }, null, 2), 'utf-8');
|
|
103
|
+
}
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
// Agents
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
async function renderAgents(agents, outputDir) {
|
|
108
|
+
if (agents.length === 0)
|
|
109
|
+
return;
|
|
110
|
+
const agentDir = join(outputDir, '.claude', 'agents');
|
|
111
|
+
await mkdir(agentDir, { recursive: true });
|
|
112
|
+
for (const agent of agents) {
|
|
113
|
+
// Claude agents are plain markdown — no frontmatter required
|
|
114
|
+
await writeFile(join(agentDir, `${agent.name}.md`), agent.content, 'utf-8');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
// Prompts → .claude/skills/<name>/SKILL.md
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
async function renderPrompts(prompts, outputDir) {
|
|
121
|
+
// Filter out shared prompts — they are referenced by other prompts, not standalone
|
|
122
|
+
const standalone = prompts.filter((p) => !p.shared);
|
|
123
|
+
if (standalone.length === 0)
|
|
124
|
+
return;
|
|
125
|
+
for (const prompt of standalone) {
|
|
126
|
+
const skillDir = join(outputDir, '.claude', 'skills', prompt.name);
|
|
127
|
+
await mkdir(skillDir, { recursive: true });
|
|
128
|
+
// Build Claude SKILL.md with converted frontmatter
|
|
129
|
+
const content = buildClaudeSkillMd(prompt);
|
|
130
|
+
await writeFile(join(skillDir, 'SKILL.md'), content, 'utf-8');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Convert a ResolvedPrompt to Claude SKILL.md format.
|
|
135
|
+
* Transforms Copilot frontmatter fields to Claude equivalents.
|
|
136
|
+
*/
|
|
137
|
+
function buildClaudeSkillMd(prompt) {
|
|
138
|
+
const lines = ['---'];
|
|
139
|
+
lines.push(`name: ${prompt.name}`);
|
|
140
|
+
if (prompt.description) {
|
|
141
|
+
lines.push(`description: ${prompt.description}`);
|
|
142
|
+
}
|
|
143
|
+
if (prompt.disableAutoInvoke) {
|
|
144
|
+
lines.push('disable-model-invocation: true');
|
|
145
|
+
}
|
|
146
|
+
if (prompt.tools && prompt.tools.length > 0) {
|
|
147
|
+
lines.push('allowed-tools:');
|
|
148
|
+
for (const tool of prompt.tools) {
|
|
149
|
+
lines.push(` - ${tool}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (prompt.model) {
|
|
153
|
+
lines.push(`model: ${prompt.model}`);
|
|
154
|
+
}
|
|
155
|
+
lines.push('---');
|
|
156
|
+
lines.push('');
|
|
157
|
+
// Strip original frontmatter from content and append body
|
|
158
|
+
const body = prompt.content.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n*/, '').trim();
|
|
159
|
+
lines.push(body);
|
|
160
|
+
return lines.join('\n') + '\n';
|
|
161
|
+
}
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
// Repos section builder
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
function buildReposSection(repos) {
|
|
166
|
+
const lines = ['## Related Repositories', ''];
|
|
167
|
+
for (const repo of repos) {
|
|
168
|
+
const repoName = repo.name ?? repo.url.replace(/\.git$/, '').split('/').slice(-2).join('/');
|
|
169
|
+
const desc = repo.description ? ` — ${repo.description}` : '';
|
|
170
|
+
if (repo.large) {
|
|
171
|
+
const note = repo.note ? ` (${repo.note})` : '';
|
|
172
|
+
lines.push(`- ⚠️ [${repoName}](${repo.url}) — LARGE${desc}${note}`);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
lines.push(`- [${repoName}](${repo.url})${desc}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return lines.join('\n');
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/renderers/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copilot Renderer
|
|
3
|
+
*
|
|
4
|
+
* Generates GitHub Copilot workspace configuration files from a ResolvedManifest:
|
|
5
|
+
* .github/copilot-instructions.md — global instructions
|
|
6
|
+
* .github/instructions/*.instructions.md — scoped instructions (applyTo)
|
|
7
|
+
* .github/agents/*.agent.md — custom agents with frontmatter
|
|
8
|
+
* .github/skills/<name>/SKILL.md — local skills
|
|
9
|
+
* .vscode/mcp.json — MCP server definitions
|
|
10
|
+
*/
|
|
11
|
+
import type { ResolvedManifest } from '../types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Render a resolved manifest into Copilot workspace configuration files.
|
|
14
|
+
*/
|
|
15
|
+
export declare function renderCopilot(manifest: ResolvedManifest, outputDir: string): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=copilot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot.d.ts","sourceRoot":"","sources":["../../src/renderers/copilot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EACV,gBAAgB,EAOjB,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhG"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copilot Renderer
|
|
3
|
+
*
|
|
4
|
+
* Generates GitHub Copilot workspace configuration files from a ResolvedManifest:
|
|
5
|
+
* .github/copilot-instructions.md — global instructions
|
|
6
|
+
* .github/instructions/*.instructions.md — scoped instructions (applyTo)
|
|
7
|
+
* .github/agents/*.agent.md — custom agents with frontmatter
|
|
8
|
+
* .github/skills/<name>/SKILL.md — local skills
|
|
9
|
+
* .vscode/mcp.json — MCP server definitions
|
|
10
|
+
*/
|
|
11
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
12
|
+
import { join, basename, dirname, extname } from 'node:path';
|
|
13
|
+
/**
|
|
14
|
+
* Render a resolved manifest into Copilot workspace configuration files.
|
|
15
|
+
*/
|
|
16
|
+
export async function renderCopilot(manifest, outputDir) {
|
|
17
|
+
const githubDir = join(outputDir, '.github');
|
|
18
|
+
await mkdir(githubDir, { recursive: true });
|
|
19
|
+
await Promise.all([
|
|
20
|
+
renderInstructions(manifest.instructions, manifest.repos, githubDir),
|
|
21
|
+
renderAgents(manifest.agents, githubDir),
|
|
22
|
+
renderMcp(manifest.mcp, outputDir),
|
|
23
|
+
renderSkills(manifest.skills, githubDir),
|
|
24
|
+
renderPrompts(manifest.prompts, githubDir),
|
|
25
|
+
]);
|
|
26
|
+
}
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Instructions
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
async function renderInstructions(instructions, repos, githubDir) {
|
|
31
|
+
const globals = instructions.filter((i) => i.scope === 'global');
|
|
32
|
+
const scoped = instructions.filter((i) => i.scope !== 'global');
|
|
33
|
+
// Global instructions → .github/copilot-instructions.md
|
|
34
|
+
const hasGlobals = globals.length > 0;
|
|
35
|
+
const hasRepos = repos.length > 0;
|
|
36
|
+
if (hasGlobals || hasRepos) {
|
|
37
|
+
const sections = [];
|
|
38
|
+
if (hasGlobals) {
|
|
39
|
+
sections.push(globals.map((i) => i.content).join('\n\n'));
|
|
40
|
+
}
|
|
41
|
+
if (hasRepos) {
|
|
42
|
+
sections.push(buildReposSection(repos));
|
|
43
|
+
}
|
|
44
|
+
await writeFile(join(githubDir, 'copilot-instructions.md'), sections.join('\n\n'), 'utf-8');
|
|
45
|
+
}
|
|
46
|
+
// Scoped instructions → .github/instructions/<name>.instructions.md
|
|
47
|
+
if (scoped.length > 0) {
|
|
48
|
+
const instrDir = join(githubDir, 'instructions');
|
|
49
|
+
await mkdir(instrDir, { recursive: true });
|
|
50
|
+
for (const instr of scoped) {
|
|
51
|
+
const name = deriveInstructionName(instr.sourcePath);
|
|
52
|
+
const frontmatter = `---\napplyTo: '${instr.scope}'\n---\n`;
|
|
53
|
+
const content = frontmatter + instr.content;
|
|
54
|
+
await writeFile(join(instrDir, `${name}.instructions.md`), content, 'utf-8');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Derive instruction filename from source path.
|
|
60
|
+
* e.g. "kusto.md" → "kusto", "instructions/dotnet.md" → "dotnet"
|
|
61
|
+
*/
|
|
62
|
+
function deriveInstructionName(sourcePath) {
|
|
63
|
+
const base = basename(sourcePath, extname(sourcePath));
|
|
64
|
+
return base.replace(/\.instructions$/, '');
|
|
65
|
+
}
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// Agents
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
async function renderAgents(agents, githubDir) {
|
|
70
|
+
if (agents.length === 0)
|
|
71
|
+
return;
|
|
72
|
+
const agentDir = join(githubDir, 'agents');
|
|
73
|
+
await mkdir(agentDir, { recursive: true });
|
|
74
|
+
for (const agent of agents) {
|
|
75
|
+
const slug = slugify(agent.name);
|
|
76
|
+
const frontmatter = buildAgentFrontmatter(agent);
|
|
77
|
+
const content = `${frontmatter}${agent.content}`;
|
|
78
|
+
await writeFile(join(agentDir, `${slug}.agent.md`), content, 'utf-8');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function buildAgentFrontmatter(agent) {
|
|
82
|
+
const lines = ['---'];
|
|
83
|
+
lines.push(`name: ${agent.name}`);
|
|
84
|
+
if (agent.description) {
|
|
85
|
+
lines.push(`description: ${agent.description}`);
|
|
86
|
+
}
|
|
87
|
+
if (agent.model) {
|
|
88
|
+
lines.push(`model: ${agent.model}`);
|
|
89
|
+
}
|
|
90
|
+
if (agent.tools.length > 0) {
|
|
91
|
+
lines.push('tools:');
|
|
92
|
+
for (const tool of agent.tools) {
|
|
93
|
+
lines.push(` - ${tool}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
lines.push('---');
|
|
97
|
+
lines.push('');
|
|
98
|
+
return lines.join('\n');
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Convert "Live Site" → "live-site" for filename.
|
|
102
|
+
*/
|
|
103
|
+
function slugify(name) {
|
|
104
|
+
return name
|
|
105
|
+
.toLowerCase()
|
|
106
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
107
|
+
.replace(/^-|-$/g, '');
|
|
108
|
+
}
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
// MCP
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
async function renderMcp(servers, outputDir) {
|
|
113
|
+
if (servers.length === 0)
|
|
114
|
+
return;
|
|
115
|
+
const vscodeDir = join(outputDir, '.vscode');
|
|
116
|
+
await mkdir(vscodeDir, { recursive: true });
|
|
117
|
+
const mcpConfig = { servers: {} };
|
|
118
|
+
for (const server of servers) {
|
|
119
|
+
const entry = { type: server.type };
|
|
120
|
+
if (server.type === 'stdio') {
|
|
121
|
+
if (server.command)
|
|
122
|
+
entry.command = server.command;
|
|
123
|
+
if (server.args && server.args.length > 0)
|
|
124
|
+
entry.args = server.args;
|
|
125
|
+
if (server.env && Object.keys(server.env).length > 0)
|
|
126
|
+
entry.env = server.env;
|
|
127
|
+
}
|
|
128
|
+
else if (server.type === 'http' || server.type === 'sse') {
|
|
129
|
+
if (server.url)
|
|
130
|
+
entry.url = server.url;
|
|
131
|
+
}
|
|
132
|
+
mcpConfig.servers[server.id] = entry;
|
|
133
|
+
}
|
|
134
|
+
await writeFile(join(vscodeDir, 'mcp.json'), JSON.stringify(mcpConfig, null, 2), 'utf-8');
|
|
135
|
+
}
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
// Skills
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
async function renderSkills(skills, githubDir) {
|
|
140
|
+
const localSkills = skills.filter((s) => s.type === 'local' && s.content);
|
|
141
|
+
if (localSkills.length === 0)
|
|
142
|
+
return;
|
|
143
|
+
const skillsDir = join(githubDir, 'skills');
|
|
144
|
+
for (const skill of localSkills) {
|
|
145
|
+
const name = skill.name ?? 'unnamed-skill';
|
|
146
|
+
const dir = join(skillsDir, name);
|
|
147
|
+
await mkdir(dir, { recursive: true });
|
|
148
|
+
await writeFile(join(dir, 'SKILL.md'), skill.content, 'utf-8');
|
|
149
|
+
if (skill.extraFiles) {
|
|
150
|
+
for (const extra of skill.extraFiles) {
|
|
151
|
+
const extraPath = join(dir, extra.relativePath);
|
|
152
|
+
await mkdir(dirname(extraPath), { recursive: true });
|
|
153
|
+
await writeFile(extraPath, extra.content, 'utf-8');
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
// Prompts
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
async function renderPrompts(prompts, githubDir) {
|
|
162
|
+
if (prompts.length === 0)
|
|
163
|
+
return;
|
|
164
|
+
const promptsDir = join(githubDir, 'prompts');
|
|
165
|
+
await mkdir(promptsDir, { recursive: true });
|
|
166
|
+
for (const prompt of prompts) {
|
|
167
|
+
const filename = `${prompt.name}.prompt.md`;
|
|
168
|
+
// Write the original content as-is (Copilot format)
|
|
169
|
+
await writeFile(join(promptsDir, filename), prompt.content, 'utf-8');
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// ---------------------------------------------------------------------------
|
|
173
|
+
// Repos section builder (shared)
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
function buildReposSection(repos) {
|
|
176
|
+
const lines = ['## Related Repositories', ''];
|
|
177
|
+
for (const repo of repos) {
|
|
178
|
+
// Extract repo name from URL
|
|
179
|
+
const repoName = repo.name ?? repo.url.replace(/\.git$/, '').split('/').slice(-2).join('/');
|
|
180
|
+
const desc = repo.description ? ` — ${repo.description}` : '';
|
|
181
|
+
if (repo.large) {
|
|
182
|
+
const note = repo.note ? `: ${repo.note}` : '';
|
|
183
|
+
lines.push(`- ⚠️ [${repoName}](${repo.url}) — LARGE${desc}${note ? ` (${repo.note})` : ''}`);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
lines.push(`- [${repoName}](${repo.url})${desc}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return lines.join('\n');
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=copilot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot.js","sourceRoot":"","sources":["../../src/renderers/copilot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repo Clone — Clones manifest repos into the workspace directory.
|
|
3
|
+
*
|
|
4
|
+
* Handles different repo types with appropriate strategies:
|
|
5
|
+
* - Normal GitHub repos → `gh repo clone` (parallel, up to concurrency limit)
|
|
6
|
+
* - ADO repos → `git clone` (interactive prompt, sequential)
|
|
7
|
+
* - Large repos → prompt user (clone / provide existing path / defer to agent)
|
|
8
|
+
* - Sparse repos → `git clone --filter=blob:none --sparse` + sparse-checkout
|
|
9
|
+
* - Skip strategy → skip with message
|
|
10
|
+
*
|
|
11
|
+
* Normal repos are cloned in parallel (default 4 concurrent).
|
|
12
|
+
* Large/ADO repos that require user interaction are processed sequentially.
|
|
13
|
+
* Directory junctions are only created when a user provides an external path
|
|
14
|
+
* for a large/ADO repo — not for repos cloned directly into the workspace.
|
|
15
|
+
*/
|
|
16
|
+
import type { ResolvedRepo } from './types.js';
|
|
17
|
+
export interface CloneRepoOptions {
|
|
18
|
+
/** Resolved repos from the template manifest */
|
|
19
|
+
repos: ResolvedRepo[];
|
|
20
|
+
/** Workspace directory where repos will be cloned */
|
|
21
|
+
workspaceDir: string;
|
|
22
|
+
/** Clone mode:
|
|
23
|
+
* - 'auto': clone non-large, prompt for large
|
|
24
|
+
* - 'all': clone everything without prompting
|
|
25
|
+
* - 'none': skip all (dry-run / list only)
|
|
26
|
+
*/
|
|
27
|
+
mode: 'auto' | 'all' | 'none';
|
|
28
|
+
/** Maximum concurrent clone operations (default: 4) */
|
|
29
|
+
concurrency?: number;
|
|
30
|
+
/** Inject exec function for testing. Supports sync or async.
|
|
31
|
+
* Default: async exec via child_process.exec */
|
|
32
|
+
execFn?: (cmd: string) => void | Promise<void>;
|
|
33
|
+
/** Prompt function for interactive decisions (large/ADO repos).
|
|
34
|
+
* Returns user choice: 'clone', 'skip', or a filesystem path to an existing clone.
|
|
35
|
+
*/
|
|
36
|
+
promptFn?: (message: string, choices: string[]) => Promise<string>;
|
|
37
|
+
/** Inject link function for creating directory junctions/symlinks.
|
|
38
|
+
* Called with (target, linkPath). Only used for external-path junctions.
|
|
39
|
+
*/
|
|
40
|
+
linkFn?: (target: string, linkPath: string) => Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
export interface CloneRepoResult {
|
|
43
|
+
/** Repos that were successfully cloned or linked */
|
|
44
|
+
cloned: Array<{
|
|
45
|
+
repo: ResolvedRepo;
|
|
46
|
+
path: string;
|
|
47
|
+
linkPath?: string;
|
|
48
|
+
}>;
|
|
49
|
+
/** Repos that were skipped (already exist, cloneStrategy:skip, mode:none) */
|
|
50
|
+
skipped: Array<{
|
|
51
|
+
repo: ResolvedRepo;
|
|
52
|
+
reason: string;
|
|
53
|
+
}>;
|
|
54
|
+
/** Repos deferred to the agent (large repo with no promptFn, user chose skip, etc.) */
|
|
55
|
+
deferred: Array<{
|
|
56
|
+
repo: ResolvedRepo;
|
|
57
|
+
reason: string;
|
|
58
|
+
}>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Derive a directory name from a repo URL (or override with id/name).
|
|
62
|
+
*/
|
|
63
|
+
export declare function deriveRepoDir(url: string, id?: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Clone all manifest repos into the workspace directory.
|
|
66
|
+
*
|
|
67
|
+
* Phase 1: Categorize repos (skip, auto-clone, interactive).
|
|
68
|
+
* Phase 2: Clone auto-clone repos in parallel (batched by concurrency limit).
|
|
69
|
+
* Phase 3: Process interactive repos sequentially (user prompts).
|
|
70
|
+
*/
|
|
71
|
+
export declare function cloneManifestRepos(options: CloneRepoOptions): Promise<CloneRepoResult>;
|
|
72
|
+
//# sourceMappingURL=repo-clone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-clone.d.ts","sourceRoot":"","sources":["../src/repo-clone.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAQ/C,MAAM,WAAW,gBAAgB;IAC/B,gDAAgD;IAChD,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IAC9B,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;qDACiD;IACjD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnE;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvE,6EAA6E;IAC7E,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvD,uFAAuF;IACvF,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzD;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAI9D;AAoBD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CA4F5F"}
|