|
f7eb47b…
|
lmata
|
1 |
"use strict"; |
|
f7eb47b…
|
lmata
|
2 |
var __create = Object.create; |
|
f7eb47b…
|
lmata
|
3 |
var __defProp = Object.defineProperty; |
|
f7eb47b…
|
lmata
|
4 |
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; |
|
f7eb47b…
|
lmata
|
5 |
var __getOwnPropNames = Object.getOwnPropertyNames; |
|
f7eb47b…
|
lmata
|
6 |
var __getProtoOf = Object.getPrototypeOf; |
|
f7eb47b…
|
lmata
|
7 |
var __hasOwnProp = Object.prototype.hasOwnProperty; |
|
f7eb47b…
|
lmata
|
8 |
var __export = (target, all) => { |
|
f7eb47b…
|
lmata
|
9 |
for (var name in all) |
|
f7eb47b…
|
lmata
|
10 |
__defProp(target, name, { get: all[name], enumerable: true }); |
|
f7eb47b…
|
lmata
|
11 |
}; |
|
f7eb47b…
|
lmata
|
12 |
var __copyProps = (to, from, except, desc) => { |
|
f7eb47b…
|
lmata
|
13 |
if (from && typeof from === "object" || typeof from === "function") { |
|
f7eb47b…
|
lmata
|
14 |
for (let key of __getOwnPropNames(from)) |
|
f7eb47b…
|
lmata
|
15 |
if (!__hasOwnProp.call(to, key) && key !== except) |
|
f7eb47b…
|
lmata
|
16 |
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); |
|
f7eb47b…
|
lmata
|
17 |
} |
|
f7eb47b…
|
lmata
|
18 |
return to; |
|
f7eb47b…
|
lmata
|
19 |
}; |
|
f7eb47b…
|
lmata
|
20 |
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( |
|
f7eb47b…
|
lmata
|
21 |
// If the importer is in node compatibility mode or this is not an ESM |
|
f7eb47b…
|
lmata
|
22 |
// file that has been converted to a CommonJS file using a Babel- |
|
f7eb47b…
|
lmata
|
23 |
// compatible transform (i.e. "__esModule" has not been set), then set |
|
f7eb47b…
|
lmata
|
24 |
// "default" to the CommonJS "module.exports" for node compatibility. |
|
f7eb47b…
|
lmata
|
25 |
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, |
|
f7eb47b…
|
lmata
|
26 |
mod |
|
f7eb47b…
|
lmata
|
27 |
)); |
|
f7eb47b…
|
lmata
|
28 |
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); |
|
f7eb47b…
|
lmata
|
29 |
var generateAgents_exports = {}; |
|
f7eb47b…
|
lmata
|
30 |
__export(generateAgents_exports, { |
|
f7eb47b…
|
lmata
|
31 |
ClaudeGenerator: () => ClaudeGenerator, |
|
f7eb47b…
|
lmata
|
32 |
CopilotGenerator: () => CopilotGenerator, |
|
f7eb47b…
|
lmata
|
33 |
OpencodeGenerator: () => OpencodeGenerator, |
|
f7eb47b…
|
lmata
|
34 |
VSCodeGenerator: () => VSCodeGenerator |
|
f7eb47b…
|
lmata
|
35 |
}); |
|
f7eb47b…
|
lmata
|
36 |
module.exports = __toCommonJS(generateAgents_exports); |
|
f7eb47b…
|
lmata
|
37 |
var import_fs = __toESM(require("fs")); |
|
f7eb47b…
|
lmata
|
38 |
var import_path = __toESM(require("path")); |
|
f7eb47b…
|
lmata
|
39 |
var import_utilsBundle = require("playwright-core/lib/utilsBundle"); |
|
f7eb47b…
|
lmata
|
40 |
var import_utils = require("playwright-core/lib/utils"); |
|
f7eb47b…
|
lmata
|
41 |
var import_seed = require("../mcp/test/seed"); |
|
f7eb47b…
|
lmata
|
42 |
var import_agentParser = require("./agentParser"); |
|
f7eb47b…
|
lmata
|
43 |
async function loadAgentSpecs() { |
|
f7eb47b…
|
lmata
|
44 |
const files = await import_fs.default.promises.readdir(__dirname); |
|
f7eb47b…
|
lmata
|
45 |
return Promise.all(files.filter((file) => file.endsWith(".agent.md")).map((file) => (0, import_agentParser.parseAgentSpec)(import_path.default.join(__dirname, file)))); |
|
f7eb47b…
|
lmata
|
46 |
} |
|
f7eb47b…
|
lmata
|
47 |
class ClaudeGenerator { |
|
f7eb47b…
|
lmata
|
48 |
static async init(config, projectName, prompts) { |
|
f7eb47b…
|
lmata
|
49 |
await initRepo(config, projectName, { |
|
f7eb47b…
|
lmata
|
50 |
promptsFolder: prompts ? ".claude/prompts" : void 0 |
|
f7eb47b…
|
lmata
|
51 |
}); |
|
f7eb47b…
|
lmata
|
52 |
const agents = await loadAgentSpecs(); |
|
f7eb47b…
|
lmata
|
53 |
await import_fs.default.promises.mkdir(".claude/agents", { recursive: true }); |
|
f7eb47b…
|
lmata
|
54 |
for (const agent of agents) |
|
f7eb47b…
|
lmata
|
55 |
await writeFile(`.claude/agents/${agent.name}.md`, ClaudeGenerator.agentSpec(agent), "\u{1F916}", "agent definition"); |
|
f7eb47b…
|
lmata
|
56 |
await writeFile(".mcp.json", JSON.stringify({ |
|
f7eb47b…
|
lmata
|
57 |
mcpServers: { |
|
f7eb47b…
|
lmata
|
58 |
"playwright-test": { |
|
f7eb47b…
|
lmata
|
59 |
command: "npx", |
|
f7eb47b…
|
lmata
|
60 |
args: ["playwright", "run-test-mcp-server"] |
|
f7eb47b…
|
lmata
|
61 |
} |
|
f7eb47b…
|
lmata
|
62 |
} |
|
f7eb47b…
|
lmata
|
63 |
}, null, 2), "\u{1F527}", "mcp configuration"); |
|
f7eb47b…
|
lmata
|
64 |
initRepoDone(); |
|
f7eb47b…
|
lmata
|
65 |
} |
|
f7eb47b…
|
lmata
|
66 |
static agentSpec(agent) { |
|
f7eb47b…
|
lmata
|
67 |
const claudeToolMap = /* @__PURE__ */ new Map([ |
|
f7eb47b…
|
lmata
|
68 |
["search", ["Glob", "Grep", "Read", "LS"]], |
|
f7eb47b…
|
lmata
|
69 |
["edit", ["Edit", "MultiEdit", "Write"]] |
|
f7eb47b…
|
lmata
|
70 |
]); |
|
f7eb47b…
|
lmata
|
71 |
function asClaudeTool(tool) { |
|
f7eb47b…
|
lmata
|
72 |
const [first, second] = tool.split("/"); |
|
f7eb47b…
|
lmata
|
73 |
if (!second) |
|
f7eb47b…
|
lmata
|
74 |
return (claudeToolMap.get(first) || [first]).join(", "); |
|
f7eb47b…
|
lmata
|
75 |
return `mcp__${first}__${second}`; |
|
f7eb47b…
|
lmata
|
76 |
} |
|
f7eb47b…
|
lmata
|
77 |
const examples = agent.examples.length ? ` Examples: ${agent.examples.map((example) => `<example>${example}</example>`).join("")}` : ""; |
|
f7eb47b…
|
lmata
|
78 |
const lines = []; |
|
f7eb47b…
|
lmata
|
79 |
const header = { |
|
f7eb47b…
|
lmata
|
80 |
name: agent.name, |
|
f7eb47b…
|
lmata
|
81 |
description: agent.description + examples, |
|
f7eb47b…
|
lmata
|
82 |
tools: agent.tools.map((tool) => asClaudeTool(tool)).join(", "), |
|
f7eb47b…
|
lmata
|
83 |
model: agent.model, |
|
f7eb47b…
|
lmata
|
84 |
color: agent.color |
|
f7eb47b…
|
lmata
|
85 |
}; |
|
f7eb47b…
|
lmata
|
86 |
lines.push(`---`); |
|
f7eb47b…
|
lmata
|
87 |
lines.push(import_utilsBundle.yaml.stringify(header, { lineWidth: 1e5 }) + `---`); |
|
f7eb47b…
|
lmata
|
88 |
lines.push(""); |
|
f7eb47b…
|
lmata
|
89 |
lines.push(agent.instructions); |
|
f7eb47b…
|
lmata
|
90 |
return lines.join("\n"); |
|
f7eb47b…
|
lmata
|
91 |
} |
|
f7eb47b…
|
lmata
|
92 |
} |
|
f7eb47b…
|
lmata
|
93 |
class OpencodeGenerator { |
|
f7eb47b…
|
lmata
|
94 |
static async init(config, projectName, prompts) { |
|
f7eb47b…
|
lmata
|
95 |
await initRepo(config, projectName, { |
|
f7eb47b…
|
lmata
|
96 |
defaultAgentName: "Build", |
|
f7eb47b…
|
lmata
|
97 |
promptsFolder: prompts ? ".opencode/prompts" : void 0 |
|
f7eb47b…
|
lmata
|
98 |
}); |
|
f7eb47b…
|
lmata
|
99 |
const agents = await loadAgentSpecs(); |
|
f7eb47b…
|
lmata
|
100 |
for (const agent of agents) { |
|
f7eb47b…
|
lmata
|
101 |
const prompt = [agent.instructions]; |
|
f7eb47b…
|
lmata
|
102 |
prompt.push(""); |
|
f7eb47b…
|
lmata
|
103 |
prompt.push(...agent.examples.map((example) => `<example>${example}</example>`)); |
|
f7eb47b…
|
lmata
|
104 |
await writeFile(`.opencode/prompts/${agent.name}.md`, prompt.join("\n"), "\u{1F916}", "agent definition"); |
|
f7eb47b…
|
lmata
|
105 |
} |
|
f7eb47b…
|
lmata
|
106 |
await writeFile("opencode.json", OpencodeGenerator.configuration(agents), "\u{1F527}", "opencode configuration"); |
|
f7eb47b…
|
lmata
|
107 |
initRepoDone(); |
|
f7eb47b…
|
lmata
|
108 |
} |
|
f7eb47b…
|
lmata
|
109 |
static configuration(agents) { |
|
f7eb47b…
|
lmata
|
110 |
const opencodeToolMap = /* @__PURE__ */ new Map([ |
|
f7eb47b…
|
lmata
|
111 |
["search", ["ls", "glob", "grep", "read"]], |
|
f7eb47b…
|
lmata
|
112 |
["edit", ["edit", "write"]] |
|
f7eb47b…
|
lmata
|
113 |
]); |
|
f7eb47b…
|
lmata
|
114 |
const asOpencodeTool = (tools, tool) => { |
|
f7eb47b…
|
lmata
|
115 |
const [first, second] = tool.split("/"); |
|
f7eb47b…
|
lmata
|
116 |
if (!second) { |
|
f7eb47b…
|
lmata
|
117 |
for (const tool2 of opencodeToolMap.get(first) || [first]) |
|
f7eb47b…
|
lmata
|
118 |
tools[tool2] = true; |
|
f7eb47b…
|
lmata
|
119 |
} else { |
|
f7eb47b…
|
lmata
|
120 |
tools[`${first}*${second}`] = true; |
|
f7eb47b…
|
lmata
|
121 |
} |
|
f7eb47b…
|
lmata
|
122 |
}; |
|
f7eb47b…
|
lmata
|
123 |
const result = {}; |
|
f7eb47b…
|
lmata
|
124 |
result["$schema"] = "https://opencode.ai/config.json"; |
|
f7eb47b…
|
lmata
|
125 |
result["mcp"] = {}; |
|
f7eb47b…
|
lmata
|
126 |
result["tools"] = { |
|
f7eb47b…
|
lmata
|
127 |
"playwright*": false |
|
f7eb47b…
|
lmata
|
128 |
}; |
|
f7eb47b…
|
lmata
|
129 |
result["agent"] = {}; |
|
f7eb47b…
|
lmata
|
130 |
for (const agent of agents) { |
|
f7eb47b…
|
lmata
|
131 |
const tools = {}; |
|
f7eb47b…
|
lmata
|
132 |
result["agent"][agent.name] = { |
|
f7eb47b…
|
lmata
|
133 |
description: agent.description, |
|
f7eb47b…
|
lmata
|
134 |
mode: "subagent", |
|
f7eb47b…
|
lmata
|
135 |
prompt: `{file:.opencode/prompts/${agent.name}.md}`, |
|
f7eb47b…
|
lmata
|
136 |
tools |
|
f7eb47b…
|
lmata
|
137 |
}; |
|
f7eb47b…
|
lmata
|
138 |
for (const tool of agent.tools) |
|
f7eb47b…
|
lmata
|
139 |
asOpencodeTool(tools, tool); |
|
f7eb47b…
|
lmata
|
140 |
} |
|
f7eb47b…
|
lmata
|
141 |
result["mcp"]["playwright-test"] = { |
|
f7eb47b…
|
lmata
|
142 |
type: "local", |
|
f7eb47b…
|
lmata
|
143 |
command: ["npx", "playwright", "run-test-mcp-server"], |
|
f7eb47b…
|
lmata
|
144 |
enabled: true |
|
f7eb47b…
|
lmata
|
145 |
}; |
|
f7eb47b…
|
lmata
|
146 |
return JSON.stringify(result, null, 2); |
|
f7eb47b…
|
lmata
|
147 |
} |
|
f7eb47b…
|
lmata
|
148 |
} |
|
f7eb47b…
|
lmata
|
149 |
class CopilotGenerator { |
|
f7eb47b…
|
lmata
|
150 |
static async init(config, projectName, prompts) { |
|
f7eb47b…
|
lmata
|
151 |
await initRepo(config, projectName, { |
|
f7eb47b…
|
lmata
|
152 |
defaultAgentName: "agent", |
|
f7eb47b…
|
lmata
|
153 |
promptsFolder: prompts ? ".github/prompts" : void 0, |
|
f7eb47b…
|
lmata
|
154 |
promptSuffix: "prompt" |
|
f7eb47b…
|
lmata
|
155 |
}); |
|
f7eb47b…
|
lmata
|
156 |
const agents = await loadAgentSpecs(); |
|
f7eb47b…
|
lmata
|
157 |
await import_fs.default.promises.mkdir(".github/agents", { recursive: true }); |
|
f7eb47b…
|
lmata
|
158 |
for (const agent of agents) |
|
f7eb47b…
|
lmata
|
159 |
await writeFile(`.github/agents/${agent.name}.agent.md`, CopilotGenerator.agentSpec(agent), "\u{1F916}", "agent definition"); |
|
f7eb47b…
|
lmata
|
160 |
await deleteFile(`.github/chatmodes/ \u{1F3AD} planner.chatmode.md`, "legacy planner chatmode"); |
|
f7eb47b…
|
lmata
|
161 |
await deleteFile(`.github/chatmodes/\u{1F3AD} generator.chatmode.md`, "legacy generator chatmode"); |
|
f7eb47b…
|
lmata
|
162 |
await deleteFile(`.github/chatmodes/\u{1F3AD} healer.chatmode.md`, "legacy healer chatmode"); |
|
f7eb47b…
|
lmata
|
163 |
await deleteFile(`.github/agents/ \u{1F3AD} planner.agent.md`, "legacy planner agent"); |
|
f7eb47b…
|
lmata
|
164 |
await deleteFile(`.github/agents/\u{1F3AD} generator.agent.md`, "legacy generator agent"); |
|
f7eb47b…
|
lmata
|
165 |
await deleteFile(`.github/agents/\u{1F3AD} healer.agent.md`, "legacy healer agent"); |
|
f7eb47b…
|
lmata
|
166 |
await VSCodeGenerator.appendToMCPJson(); |
|
f7eb47b…
|
lmata
|
167 |
const mcpConfig = { mcpServers: CopilotGenerator.mcpServers }; |
|
f7eb47b…
|
lmata
|
168 |
if (!import_fs.default.existsSync(".github/copilot-setup-steps.yml")) { |
|
f7eb47b…
|
lmata
|
169 |
const yaml2 = import_fs.default.readFileSync(import_path.default.join(__dirname, "copilot-setup-steps.yml"), "utf-8"); |
|
f7eb47b…
|
lmata
|
170 |
await writeFile(".github/workflows/copilot-setup-steps.yml", yaml2, "\u{1F527}", "GitHub Copilot setup steps"); |
|
f7eb47b…
|
lmata
|
171 |
} |
|
f7eb47b…
|
lmata
|
172 |
console.log(""); |
|
f7eb47b…
|
lmata
|
173 |
console.log(""); |
|
f7eb47b…
|
lmata
|
174 |
console.log(" \u{1F527} TODO: GitHub > Settings > Copilot > Coding agent > MCP configuration"); |
|
f7eb47b…
|
lmata
|
175 |
console.log("------------------------------------------------------------------"); |
|
f7eb47b…
|
lmata
|
176 |
console.log(JSON.stringify(mcpConfig, null, 2)); |
|
f7eb47b…
|
lmata
|
177 |
console.log("------------------------------------------------------------------"); |
|
f7eb47b…
|
lmata
|
178 |
initRepoDone(); |
|
f7eb47b…
|
lmata
|
179 |
} |
|
f7eb47b…
|
lmata
|
180 |
static agentSpec(agent) { |
|
f7eb47b…
|
lmata
|
181 |
const examples = agent.examples.length ? ` Examples: ${agent.examples.map((example) => `<example>${example}</example>`).join("")}` : ""; |
|
f7eb47b…
|
lmata
|
182 |
const lines = []; |
|
f7eb47b…
|
lmata
|
183 |
const header = { |
|
f7eb47b…
|
lmata
|
184 |
"name": agent.name, |
|
f7eb47b…
|
lmata
|
185 |
"description": agent.description + examples, |
|
f7eb47b…
|
lmata
|
186 |
"tools": agent.tools, |
|
f7eb47b…
|
lmata
|
187 |
"model": "Claude Sonnet 4", |
|
f7eb47b…
|
lmata
|
188 |
"mcp-servers": CopilotGenerator.mcpServers |
|
f7eb47b…
|
lmata
|
189 |
}; |
|
f7eb47b…
|
lmata
|
190 |
lines.push(`---`); |
|
f7eb47b…
|
lmata
|
191 |
lines.push(import_utilsBundle.yaml.stringify(header, { lineWidth: 1e5 }) + `---`); |
|
f7eb47b…
|
lmata
|
192 |
lines.push(""); |
|
f7eb47b…
|
lmata
|
193 |
lines.push(agent.instructions); |
|
f7eb47b…
|
lmata
|
194 |
lines.push(""); |
|
f7eb47b…
|
lmata
|
195 |
return lines.join("\n"); |
|
f7eb47b…
|
lmata
|
196 |
} |
|
f7eb47b…
|
lmata
|
197 |
static { |
|
f7eb47b…
|
lmata
|
198 |
this.mcpServers = { |
|
f7eb47b…
|
lmata
|
199 |
"playwright-test": { |
|
f7eb47b…
|
lmata
|
200 |
"type": "stdio", |
|
f7eb47b…
|
lmata
|
201 |
"command": "npx", |
|
f7eb47b…
|
lmata
|
202 |
"args": [ |
|
f7eb47b…
|
lmata
|
203 |
"playwright", |
|
f7eb47b…
|
lmata
|
204 |
"run-test-mcp-server" |
|
f7eb47b…
|
lmata
|
205 |
], |
|
f7eb47b…
|
lmata
|
206 |
"tools": ["*"] |
|
f7eb47b…
|
lmata
|
207 |
} |
|
f7eb47b…
|
lmata
|
208 |
}; |
|
f7eb47b…
|
lmata
|
209 |
} |
|
f7eb47b…
|
lmata
|
210 |
} |
|
f7eb47b…
|
lmata
|
211 |
class VSCodeGenerator { |
|
f7eb47b…
|
lmata
|
212 |
static async init(config, projectName) { |
|
f7eb47b…
|
lmata
|
213 |
await initRepo(config, projectName, { |
|
f7eb47b…
|
lmata
|
214 |
promptsFolder: void 0 |
|
f7eb47b…
|
lmata
|
215 |
}); |
|
f7eb47b…
|
lmata
|
216 |
const agents = await loadAgentSpecs(); |
|
f7eb47b…
|
lmata
|
217 |
const nameMap = /* @__PURE__ */ new Map([ |
|
f7eb47b…
|
lmata
|
218 |
["playwright-test-planner", " \u{1F3AD} planner"], |
|
f7eb47b…
|
lmata
|
219 |
["playwright-test-generator", "\u{1F3AD} generator"], |
|
f7eb47b…
|
lmata
|
220 |
["playwright-test-healer", "\u{1F3AD} healer"] |
|
f7eb47b…
|
lmata
|
221 |
]); |
|
f7eb47b…
|
lmata
|
222 |
await import_fs.default.promises.mkdir(".github/chatmodes", { recursive: true }); |
|
f7eb47b…
|
lmata
|
223 |
for (const agent of agents) |
|
f7eb47b…
|
lmata
|
224 |
await writeFile(`.github/chatmodes/${nameMap.get(agent.name)}.chatmode.md`, VSCodeGenerator.agentSpec(agent), "\u{1F916}", "chatmode definition"); |
|
f7eb47b…
|
lmata
|
225 |
await VSCodeGenerator.appendToMCPJson(); |
|
f7eb47b…
|
lmata
|
226 |
initRepoDone(); |
|
f7eb47b…
|
lmata
|
227 |
} |
|
f7eb47b…
|
lmata
|
228 |
static async appendToMCPJson() { |
|
f7eb47b…
|
lmata
|
229 |
await import_fs.default.promises.mkdir(".vscode", { recursive: true }); |
|
f7eb47b…
|
lmata
|
230 |
const mcpJsonPath = ".vscode/mcp.json"; |
|
f7eb47b…
|
lmata
|
231 |
let mcpJson = { |
|
f7eb47b…
|
lmata
|
232 |
servers: {}, |
|
f7eb47b…
|
lmata
|
233 |
inputs: [] |
|
f7eb47b…
|
lmata
|
234 |
}; |
|
f7eb47b…
|
lmata
|
235 |
try { |
|
f7eb47b…
|
lmata
|
236 |
mcpJson = JSON.parse(import_fs.default.readFileSync(mcpJsonPath, "utf8")); |
|
f7eb47b…
|
lmata
|
237 |
} catch { |
|
f7eb47b…
|
lmata
|
238 |
} |
|
f7eb47b…
|
lmata
|
239 |
if (!mcpJson.servers) |
|
f7eb47b…
|
lmata
|
240 |
mcpJson.servers = {}; |
|
f7eb47b…
|
lmata
|
241 |
mcpJson.servers["playwright-test"] = { |
|
f7eb47b…
|
lmata
|
242 |
type: "stdio", |
|
f7eb47b…
|
lmata
|
243 |
command: "npx", |
|
f7eb47b…
|
lmata
|
244 |
args: ["playwright", "run-test-mcp-server"] |
|
f7eb47b…
|
lmata
|
245 |
}; |
|
f7eb47b…
|
lmata
|
246 |
await writeFile(mcpJsonPath, JSON.stringify(mcpJson, null, 2), "\u{1F527}", "mcp configuration"); |
|
f7eb47b…
|
lmata
|
247 |
} |
|
f7eb47b…
|
lmata
|
248 |
static agentSpec(agent) { |
|
f7eb47b…
|
lmata
|
249 |
const vscodeToolMap = /* @__PURE__ */ new Map([ |
|
f7eb47b…
|
lmata
|
250 |
["search", ["search/listDirectory", "search/fileSearch", "search/textSearch"]], |
|
f7eb47b…
|
lmata
|
251 |
["read", ["search/readFile"]], |
|
f7eb47b…
|
lmata
|
252 |
["edit", ["edit/editFiles"]], |
|
f7eb47b…
|
lmata
|
253 |
["write", ["edit/createFile", "edit/createDirectory"]] |
|
f7eb47b…
|
lmata
|
254 |
]); |
|
f7eb47b…
|
lmata
|
255 |
const vscodeToolsOrder = ["edit/createFile", "edit/createDirectory", "edit/editFiles", "search/fileSearch", "search/textSearch", "search/listDirectory", "search/readFile"]; |
|
f7eb47b…
|
lmata
|
256 |
const vscodeMcpName = "playwright-test"; |
|
f7eb47b…
|
lmata
|
257 |
function asVscodeTool(tool) { |
|
f7eb47b…
|
lmata
|
258 |
const [first, second] = tool.split("/"); |
|
f7eb47b…
|
lmata
|
259 |
if (second) |
|
f7eb47b…
|
lmata
|
260 |
return `${vscodeMcpName}/${second}`; |
|
f7eb47b…
|
lmata
|
261 |
return vscodeToolMap.get(first) || first; |
|
f7eb47b…
|
lmata
|
262 |
} |
|
f7eb47b…
|
lmata
|
263 |
const tools = agent.tools.map(asVscodeTool).flat().sort((a, b) => { |
|
f7eb47b…
|
lmata
|
264 |
const indexA = vscodeToolsOrder.indexOf(a); |
|
f7eb47b…
|
lmata
|
265 |
const indexB = vscodeToolsOrder.indexOf(b); |
|
f7eb47b…
|
lmata
|
266 |
if (indexA === -1 && indexB === -1) |
|
f7eb47b…
|
lmata
|
267 |
return a.localeCompare(b); |
|
f7eb47b…
|
lmata
|
268 |
if (indexA === -1) |
|
f7eb47b…
|
lmata
|
269 |
return 1; |
|
f7eb47b…
|
lmata
|
270 |
if (indexB === -1) |
|
f7eb47b…
|
lmata
|
271 |
return -1; |
|
f7eb47b…
|
lmata
|
272 |
return indexA - indexB; |
|
f7eb47b…
|
lmata
|
273 |
}).map((tool) => `'${tool}'`).join(", "); |
|
f7eb47b…
|
lmata
|
274 |
const lines = []; |
|
f7eb47b…
|
lmata
|
275 |
lines.push(`---`); |
|
f7eb47b…
|
lmata
|
276 |
lines.push(`description: ${agent.description}.`); |
|
f7eb47b…
|
lmata
|
277 |
lines.push(`tools: [${tools}]`); |
|
f7eb47b…
|
lmata
|
278 |
lines.push(`---`); |
|
f7eb47b…
|
lmata
|
279 |
lines.push(""); |
|
f7eb47b…
|
lmata
|
280 |
lines.push(agent.instructions); |
|
f7eb47b…
|
lmata
|
281 |
for (const example of agent.examples) |
|
f7eb47b…
|
lmata
|
282 |
lines.push(`<example>${example}</example>`); |
|
f7eb47b…
|
lmata
|
283 |
lines.push(""); |
|
f7eb47b…
|
lmata
|
284 |
return lines.join("\n"); |
|
f7eb47b…
|
lmata
|
285 |
} |
|
f7eb47b…
|
lmata
|
286 |
} |
|
f7eb47b…
|
lmata
|
287 |
async function writeFile(filePath, content, icon, description) { |
|
f7eb47b…
|
lmata
|
288 |
console.log(` ${icon} ${import_path.default.relative(process.cwd(), filePath)} ${import_utilsBundle.colors.dim("- " + description)}`); |
|
f7eb47b…
|
lmata
|
289 |
await (0, import_utils.mkdirIfNeeded)(filePath); |
|
f7eb47b…
|
lmata
|
290 |
await import_fs.default.promises.writeFile(filePath, content, "utf-8"); |
|
f7eb47b…
|
lmata
|
291 |
} |
|
f7eb47b…
|
lmata
|
292 |
async function deleteFile(filePath, description) { |
|
f7eb47b…
|
lmata
|
293 |
try { |
|
f7eb47b…
|
lmata
|
294 |
if (!import_fs.default.existsSync(filePath)) |
|
f7eb47b…
|
lmata
|
295 |
return; |
|
f7eb47b…
|
lmata
|
296 |
} catch { |
|
f7eb47b…
|
lmata
|
297 |
return; |
|
f7eb47b…
|
lmata
|
298 |
} |
|
f7eb47b…
|
lmata
|
299 |
console.log(` \u2702\uFE0F ${import_path.default.relative(process.cwd(), filePath)} ${import_utilsBundle.colors.dim("- " + description)}`); |
|
f7eb47b…
|
lmata
|
300 |
await import_fs.default.promises.unlink(filePath); |
|
f7eb47b…
|
lmata
|
301 |
} |
|
f7eb47b…
|
lmata
|
302 |
async function initRepo(config, projectName, options) { |
|
f7eb47b…
|
lmata
|
303 |
const project = (0, import_seed.seedProject)(config, projectName); |
|
f7eb47b…
|
lmata
|
304 |
console.log(` \u{1F3AD} Using project "${project.project.name}" as a primary project`); |
|
f7eb47b…
|
lmata
|
305 |
if (!import_fs.default.existsSync("specs")) { |
|
f7eb47b…
|
lmata
|
306 |
await import_fs.default.promises.mkdir("specs"); |
|
f7eb47b…
|
lmata
|
307 |
await writeFile(import_path.default.join("specs", "README.md"), `# Specs |
|
f7eb47b…
|
lmata
|
308 |
|
|
f7eb47b…
|
lmata
|
309 |
This is a directory for test plans. |
|
f7eb47b…
|
lmata
|
310 |
`, "\u{1F4DD}", "directory for test plans"); |
|
f7eb47b…
|
lmata
|
311 |
} |
|
f7eb47b…
|
lmata
|
312 |
let seedFile = await (0, import_seed.findSeedFile)(project); |
|
f7eb47b…
|
lmata
|
313 |
if (!seedFile) { |
|
f7eb47b…
|
lmata
|
314 |
seedFile = (0, import_seed.defaultSeedFile)(project); |
|
f7eb47b…
|
lmata
|
315 |
await writeFile(seedFile, import_seed.seedFileContent, "\u{1F331}", "default environment seed file"); |
|
f7eb47b…
|
lmata
|
316 |
} |
|
f7eb47b…
|
lmata
|
317 |
if (options.promptsFolder) { |
|
f7eb47b…
|
lmata
|
318 |
await import_fs.default.promises.mkdir(options.promptsFolder, { recursive: true }); |
|
f7eb47b…
|
lmata
|
319 |
for (const promptFile of await import_fs.default.promises.readdir(__dirname)) { |
|
f7eb47b…
|
lmata
|
320 |
if (!promptFile.endsWith(".prompt.md")) |
|
f7eb47b…
|
lmata
|
321 |
continue; |
|
f7eb47b…
|
lmata
|
322 |
const shortName = promptFile.replace(".prompt.md", ""); |
|
f7eb47b…
|
lmata
|
323 |
const fileName = options.promptSuffix ? `${shortName}.${options.promptSuffix}.md` : `${shortName}.md`; |
|
f7eb47b…
|
lmata
|
324 |
const content = await loadPrompt(promptFile, { |
|
f7eb47b…
|
lmata
|
325 |
defaultAgentName: "default", |
|
f7eb47b…
|
lmata
|
326 |
...options, |
|
f7eb47b…
|
lmata
|
327 |
seedFile: import_path.default.relative(process.cwd(), seedFile) |
|
f7eb47b…
|
lmata
|
328 |
}); |
|
f7eb47b…
|
lmata
|
329 |
await writeFile(import_path.default.join(options.promptsFolder, fileName), content, "\u{1F4DD}", "prompt template"); |
|
f7eb47b…
|
lmata
|
330 |
} |
|
f7eb47b…
|
lmata
|
331 |
} |
|
f7eb47b…
|
lmata
|
332 |
} |
|
f7eb47b…
|
lmata
|
333 |
function initRepoDone() { |
|
f7eb47b…
|
lmata
|
334 |
console.log(" \u2705 Done."); |
|
f7eb47b…
|
lmata
|
335 |
} |
|
f7eb47b…
|
lmata
|
336 |
async function loadPrompt(file, params) { |
|
f7eb47b…
|
lmata
|
337 |
const content = await import_fs.default.promises.readFile(import_path.default.join(__dirname, file), "utf-8"); |
|
f7eb47b…
|
lmata
|
338 |
return Object.entries(params).reduce((acc, [key, value]) => { |
|
f7eb47b…
|
lmata
|
339 |
return acc.replace(new RegExp(`\\\${${key}}`, "g"), value); |
|
f7eb47b…
|
lmata
|
340 |
}, content); |
|
f7eb47b…
|
lmata
|
341 |
} |
|
f7eb47b…
|
lmata
|
342 |
// Annotate the CommonJS export names for ESM import in node: |
|
f7eb47b…
|
lmata
|
343 |
0 && (module.exports = { |
|
f7eb47b…
|
lmata
|
344 |
ClaudeGenerator, |
|
f7eb47b…
|
lmata
|
345 |
CopilotGenerator, |
|
f7eb47b…
|
lmata
|
346 |
OpencodeGenerator, |
|
f7eb47b…
|
lmata
|
347 |
VSCodeGenerator |
|
f7eb47b…
|
lmata
|
348 |
}); |