@glubean/cli 0.1.16 → 0.1.18
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/dist/commands/config_mcp.d.ts +17 -0
- package/dist/commands/config_mcp.d.ts.map +1 -0
- package/dist/commands/config_mcp.js +262 -0
- package/dist/commands/config_mcp.js.map +1 -0
- package/dist/commands/config_skill.d.ts +16 -0
- package/dist/commands/config_skill.d.ts.map +1 -0
- package/dist/commands/config_skill.js +102 -0
- package/dist/commands/config_skill.js.map +1 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +30 -0
- package/dist/main.js.map +1 -1
- package/package.json +3 -3
- package/templates/claude-skill-glubean-test.md +48 -343
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* glubean config mcp — configure MCP server for AI coding tools.
|
|
3
|
+
*
|
|
4
|
+
* Supported targets:
|
|
5
|
+
* - claude-code: uses `claude mcp add/remove` CLI
|
|
6
|
+
* - codex: appends [mcp_servers.glubean] to ~/.codex/config.toml
|
|
7
|
+
* - cursor: writes .cursor/mcp.json in project root
|
|
8
|
+
* - windsurf: writes ~/.codeium/windsurf/mcp_config.json
|
|
9
|
+
*/
|
|
10
|
+
type Target = "claude-code" | "codex" | "cursor" | "windsurf";
|
|
11
|
+
interface ConfigMcpOptions {
|
|
12
|
+
target?: Target;
|
|
13
|
+
remove?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function configMcpCommand(options: ConfigMcpOptions): Promise<void>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=config_mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config_mcp.d.ts","sourceRoot":"","sources":["../../src/commands/config_mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH,KAAK,MAAM,GAAG,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE9D,UAAU,gBAAgB;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAS/E"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* glubean config mcp — configure MCP server for AI coding tools.
|
|
3
|
+
*
|
|
4
|
+
* Supported targets:
|
|
5
|
+
* - claude-code: uses `claude mcp add/remove` CLI
|
|
6
|
+
* - codex: appends [mcp_servers.glubean] to ~/.codex/config.toml
|
|
7
|
+
* - cursor: writes .cursor/mcp.json in project root
|
|
8
|
+
* - windsurf: writes ~/.codeium/windsurf/mcp_config.json
|
|
9
|
+
*/
|
|
10
|
+
import { execSync } from "node:child_process";
|
|
11
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
12
|
+
import { resolve, join } from "node:path";
|
|
13
|
+
import { homedir } from "node:os";
|
|
14
|
+
const MCP_SERVER_NAME = "glubean";
|
|
15
|
+
const MCP_COMMAND = "npx";
|
|
16
|
+
const MCP_ARGS = ["-y", "@glubean/mcp"];
|
|
17
|
+
export async function configMcpCommand(options) {
|
|
18
|
+
const target = options.target ?? (await promptTarget());
|
|
19
|
+
const remove = options.remove ?? false;
|
|
20
|
+
if (remove) {
|
|
21
|
+
await removeTarget(target);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
await installTarget(target);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function promptTarget() {
|
|
28
|
+
const { select } = await import("@inquirer/prompts");
|
|
29
|
+
return await select({
|
|
30
|
+
message: "Which AI tool do you use?",
|
|
31
|
+
choices: [
|
|
32
|
+
{ name: "Claude Code", value: "claude-code" },
|
|
33
|
+
{ name: "Codex (OpenAI)", value: "codex" },
|
|
34
|
+
{ name: "Cursor", value: "cursor" },
|
|
35
|
+
{ name: "Windsurf", value: "windsurf" },
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
40
|
+
// Install
|
|
41
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
42
|
+
async function installTarget(target) {
|
|
43
|
+
switch (target) {
|
|
44
|
+
case "claude-code":
|
|
45
|
+
return installClaudeCode();
|
|
46
|
+
case "codex":
|
|
47
|
+
return installCodex();
|
|
48
|
+
case "cursor":
|
|
49
|
+
return installCursor();
|
|
50
|
+
case "windsurf":
|
|
51
|
+
return installWindsurf();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async function installClaudeCode() {
|
|
55
|
+
const claudeBin = findClaudeBin();
|
|
56
|
+
if (!claudeBin) {
|
|
57
|
+
console.error("✗ Claude Code CLI not found. Install it first: https://docs.anthropic.com/en/docs/claude-code");
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
// Remove existing (may be stale Deno version) then add fresh
|
|
61
|
+
try {
|
|
62
|
+
execSync(`${claudeBin} mcp remove ${MCP_SERVER_NAME} -s user`, { stdio: "pipe" });
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Ignore if not found
|
|
66
|
+
}
|
|
67
|
+
const cmd = `${claudeBin} mcp add ${MCP_SERVER_NAME} -s user -- ${MCP_COMMAND} ${MCP_ARGS.join(" ")}`;
|
|
68
|
+
try {
|
|
69
|
+
execSync(cmd, { stdio: "pipe" });
|
|
70
|
+
console.log(`✓ MCP server configured for Claude Code (user scope)`);
|
|
71
|
+
console.log(` Command: ${MCP_COMMAND} ${MCP_ARGS.join(" ")}`);
|
|
72
|
+
console.log(` To verify: claude mcp get ${MCP_SERVER_NAME}`);
|
|
73
|
+
console.log(`\n ⚠ Restart your Claude Code session to activate the MCP server.`);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
console.error(`✗ Failed to configure Claude Code MCP.`);
|
|
77
|
+
console.error(` Try manually: ${cmd}`);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function installCodex() {
|
|
82
|
+
const configPath = join(homedir(), ".codex", "config.toml");
|
|
83
|
+
let content = await readFileSafe(configPath);
|
|
84
|
+
// Remove existing glubean section if present
|
|
85
|
+
content = removeTomlSection(content, MCP_SERVER_NAME);
|
|
86
|
+
// Append new section
|
|
87
|
+
const section = buildTomlSection();
|
|
88
|
+
content = content.trimEnd() + (content.trim() ? "\n\n" : "") + section + "\n";
|
|
89
|
+
await mkdir(join(homedir(), ".codex"), { recursive: true });
|
|
90
|
+
await writeFile(configPath, content);
|
|
91
|
+
console.log(`✓ MCP server configured for Codex`);
|
|
92
|
+
console.log(` Written to: ${configPath}`);
|
|
93
|
+
console.log(`\n ⚠ Restart Codex to activate the MCP server.`);
|
|
94
|
+
}
|
|
95
|
+
async function installCursor() {
|
|
96
|
+
const configPath = resolve(process.cwd(), ".cursor", "mcp.json");
|
|
97
|
+
const config = await readJsonSafe(configPath);
|
|
98
|
+
if (!config.mcpServers) {
|
|
99
|
+
config.mcpServers = {};
|
|
100
|
+
}
|
|
101
|
+
config.mcpServers[MCP_SERVER_NAME] = {
|
|
102
|
+
command: MCP_COMMAND,
|
|
103
|
+
args: MCP_ARGS,
|
|
104
|
+
};
|
|
105
|
+
await mkdir(resolve(process.cwd(), ".cursor"), { recursive: true });
|
|
106
|
+
await writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
107
|
+
console.log(`✓ MCP server configured for Cursor`);
|
|
108
|
+
console.log(` Written to: ${configPath}`);
|
|
109
|
+
console.log(`\n ⚠ Restart Cursor to activate the MCP server.`);
|
|
110
|
+
}
|
|
111
|
+
async function installWindsurf() {
|
|
112
|
+
const configPath = join(homedir(), ".codeium", "windsurf", "mcp_config.json");
|
|
113
|
+
const config = await readJsonSafe(configPath);
|
|
114
|
+
if (!config.mcpServers) {
|
|
115
|
+
config.mcpServers = {};
|
|
116
|
+
}
|
|
117
|
+
config.mcpServers[MCP_SERVER_NAME] = {
|
|
118
|
+
command: MCP_COMMAND,
|
|
119
|
+
args: MCP_ARGS,
|
|
120
|
+
};
|
|
121
|
+
await mkdir(join(homedir(), ".codeium", "windsurf"), { recursive: true });
|
|
122
|
+
await writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
123
|
+
console.log(`✓ MCP server configured for Windsurf`);
|
|
124
|
+
console.log(` Written to: ${configPath}`);
|
|
125
|
+
console.log(`\n ⚠ Restart Windsurf to activate the MCP server.`);
|
|
126
|
+
}
|
|
127
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
128
|
+
// Remove
|
|
129
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
130
|
+
async function removeTarget(target) {
|
|
131
|
+
switch (target) {
|
|
132
|
+
case "claude-code":
|
|
133
|
+
return removeClaudeCode();
|
|
134
|
+
case "codex":
|
|
135
|
+
return removeCodex();
|
|
136
|
+
case "cursor":
|
|
137
|
+
return removeCursor();
|
|
138
|
+
case "windsurf":
|
|
139
|
+
return removeWindsurf();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async function removeClaudeCode() {
|
|
143
|
+
const claudeBin = findClaudeBin();
|
|
144
|
+
if (!claudeBin) {
|
|
145
|
+
console.log(`✓ Claude Code CLI not found — nothing to remove.`);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
execSync(`${claudeBin} mcp remove ${MCP_SERVER_NAME} -s user`, { stdio: "pipe" });
|
|
150
|
+
console.log(`✓ MCP server removed from Claude Code.`);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
console.log(`✓ MCP server was not configured in Claude Code.`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async function removeCodex() {
|
|
157
|
+
const configPath = join(homedir(), ".codex", "config.toml");
|
|
158
|
+
const content = await readFileSafe(configPath);
|
|
159
|
+
const cleaned = removeTomlSection(content, MCP_SERVER_NAME);
|
|
160
|
+
if (cleaned !== content) {
|
|
161
|
+
await writeFile(configPath, cleaned);
|
|
162
|
+
console.log(`✓ MCP server removed from Codex (${configPath}).`);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
console.log(`✓ MCP server was not configured in Codex.`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async function removeCursor() {
|
|
169
|
+
const configPath = resolve(process.cwd(), ".cursor", "mcp.json");
|
|
170
|
+
const config = await readJsonSafe(configPath);
|
|
171
|
+
if (config.mcpServers?.[MCP_SERVER_NAME]) {
|
|
172
|
+
delete config.mcpServers[MCP_SERVER_NAME];
|
|
173
|
+
await writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
174
|
+
console.log(`✓ MCP server removed from Cursor (${configPath}).`);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
console.log(`✓ MCP server was not configured in Cursor.`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
async function removeWindsurf() {
|
|
181
|
+
const configPath = join(homedir(), ".codeium", "windsurf", "mcp_config.json");
|
|
182
|
+
const config = await readJsonSafe(configPath);
|
|
183
|
+
if (config.mcpServers?.[MCP_SERVER_NAME]) {
|
|
184
|
+
delete config.mcpServers[MCP_SERVER_NAME];
|
|
185
|
+
await writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
186
|
+
console.log(`✓ MCP server removed from Windsurf (${configPath}).`);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
console.log(`✓ MCP server was not configured in Windsurf.`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
193
|
+
// Helpers
|
|
194
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
195
|
+
/**
|
|
196
|
+
* Find the claude CLI binary. Checks PATH first, then the well-known install location.
|
|
197
|
+
*/
|
|
198
|
+
function findClaudeBin() {
|
|
199
|
+
// Try PATH
|
|
200
|
+
try {
|
|
201
|
+
execSync("claude --version", { stdio: "pipe" });
|
|
202
|
+
return "claude";
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// Not in PATH
|
|
206
|
+
}
|
|
207
|
+
// Try well-known location
|
|
208
|
+
const wellKnown = join(homedir(), ".claude", "local", "claude");
|
|
209
|
+
try {
|
|
210
|
+
execSync(`${wellKnown} --version`, { stdio: "pipe" });
|
|
211
|
+
return wellKnown;
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async function readJsonSafe(path) {
|
|
218
|
+
try {
|
|
219
|
+
const content = await readFile(path, "utf-8");
|
|
220
|
+
return JSON.parse(content);
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return {};
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
async function readFileSafe(path) {
|
|
227
|
+
try {
|
|
228
|
+
return await readFile(path, "utf-8");
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
return "";
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Build TOML section for Codex config.
|
|
236
|
+
* Format: [mcp_servers.glubean]
|
|
237
|
+
*/
|
|
238
|
+
function buildTomlSection() {
|
|
239
|
+
const argsToml = MCP_ARGS.map((a) => `"${a}"`).join(", ");
|
|
240
|
+
return [
|
|
241
|
+
`[mcp_servers.${MCP_SERVER_NAME}]`,
|
|
242
|
+
`command = "${MCP_COMMAND}"`,
|
|
243
|
+
`args = [${argsToml}]`,
|
|
244
|
+
].join("\n");
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Remove an [mcp_servers.<name>] section from TOML content.
|
|
248
|
+
* Removes from the header line until the next section header or EOF.
|
|
249
|
+
*/
|
|
250
|
+
function removeTomlSection(content, name) {
|
|
251
|
+
const header = `[mcp_servers.${name}]`;
|
|
252
|
+
const idx = content.indexOf(header);
|
|
253
|
+
if (idx === -1)
|
|
254
|
+
return content;
|
|
255
|
+
// Find the next section header after this one
|
|
256
|
+
const afterHeader = idx + header.length;
|
|
257
|
+
const nextSection = content.indexOf("\n[", afterHeader);
|
|
258
|
+
const before = content.slice(0, idx).replace(/\n+$/, "");
|
|
259
|
+
const after = nextSection === -1 ? "" : content.slice(nextSection);
|
|
260
|
+
return (before + after).trim() + (before || after ? "\n" : "");
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=config_mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config_mcp.js","sourceRoot":"","sources":["../../src/commands/config_mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* glubean config skill — install Glubean test-writing skill for AI coding tools.
|
|
3
|
+
*
|
|
4
|
+
* Supported targets:
|
|
5
|
+
* - claude-code: writes ~/.claude/skills/glubean/SKILL.md
|
|
6
|
+
* - codex: writes ~/.codex/skills/glubean/SKILL.md
|
|
7
|
+
* - cursor: writes .cursor/skills/glubean/SKILL.md (project-level)
|
|
8
|
+
*/
|
|
9
|
+
type Target = "claude-code" | "codex" | "cursor";
|
|
10
|
+
interface ConfigSkillOptions {
|
|
11
|
+
target?: Target;
|
|
12
|
+
remove?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare function configSkillCommand(options: ConfigSkillOptions): Promise<void>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=config_skill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config_skill.d.ts","sourceRoot":"","sources":["../../src/commands/config_skill.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,KAAK,MAAM,GAAG,aAAa,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEjD,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CASnF"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* glubean config skill — install Glubean test-writing skill for AI coding tools.
|
|
3
|
+
*
|
|
4
|
+
* Supported targets:
|
|
5
|
+
* - claude-code: writes ~/.claude/skills/glubean/SKILL.md
|
|
6
|
+
* - codex: writes ~/.codex/skills/glubean/SKILL.md
|
|
7
|
+
* - cursor: writes .cursor/skills/glubean/SKILL.md (project-level)
|
|
8
|
+
*/
|
|
9
|
+
import { readFile, writeFile, mkdir, rm } from "node:fs/promises";
|
|
10
|
+
import { resolve, join, dirname } from "node:path";
|
|
11
|
+
import { homedir } from "node:os";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
const SKILL_NAME = "glubean";
|
|
14
|
+
export async function configSkillCommand(options) {
|
|
15
|
+
const target = options.target ?? (await promptTarget());
|
|
16
|
+
const remove = options.remove ?? false;
|
|
17
|
+
if (remove) {
|
|
18
|
+
await removeSkill(target);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
await installSkill(target);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function promptTarget() {
|
|
25
|
+
const { select } = await import("@inquirer/prompts");
|
|
26
|
+
return await select({
|
|
27
|
+
message: "Which AI tool do you use?",
|
|
28
|
+
choices: [
|
|
29
|
+
{ name: "Claude Code", value: "claude-code" },
|
|
30
|
+
{ name: "Codex (OpenAI)", value: "codex" },
|
|
31
|
+
{ name: "Cursor", value: "cursor" },
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
36
|
+
// Paths
|
|
37
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
38
|
+
function skillDir(target) {
|
|
39
|
+
switch (target) {
|
|
40
|
+
case "claude-code":
|
|
41
|
+
return join(homedir(), ".claude", "skills", SKILL_NAME);
|
|
42
|
+
case "codex":
|
|
43
|
+
return join(homedir(), ".codex", "skills", SKILL_NAME);
|
|
44
|
+
case "cursor":
|
|
45
|
+
return resolve(process.cwd(), ".cursor", "skills", SKILL_NAME);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function targetLabel(target) {
|
|
49
|
+
switch (target) {
|
|
50
|
+
case "claude-code":
|
|
51
|
+
return "Claude Code";
|
|
52
|
+
case "codex":
|
|
53
|
+
return "Codex";
|
|
54
|
+
case "cursor":
|
|
55
|
+
return "Cursor";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
59
|
+
// Install
|
|
60
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
61
|
+
async function installSkill(target) {
|
|
62
|
+
const templatePath = getTemplatePath();
|
|
63
|
+
const template = await readFile(templatePath, "utf-8");
|
|
64
|
+
const dir = skillDir(target);
|
|
65
|
+
const skillPath = join(dir, "SKILL.md");
|
|
66
|
+
await mkdir(dir, { recursive: true });
|
|
67
|
+
await writeFile(skillPath, template);
|
|
68
|
+
const label = targetLabel(target);
|
|
69
|
+
console.log(`✓ Glubean skill installed for ${label}`);
|
|
70
|
+
console.log(` Written to: ${skillPath}`);
|
|
71
|
+
if (target === "cursor") {
|
|
72
|
+
console.log(` Scope: project-level (committed to repo)`);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
console.log(` Scope: user-level (all projects)`);
|
|
76
|
+
}
|
|
77
|
+
console.log(`\n Usage: type /glubean in your AI tool to generate tests.`);
|
|
78
|
+
console.log(` ⚠ Restart your ${label} session to activate.`);
|
|
79
|
+
}
|
|
80
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
81
|
+
// Remove
|
|
82
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
83
|
+
async function removeSkill(target) {
|
|
84
|
+
const dir = skillDir(target);
|
|
85
|
+
const label = targetLabel(target);
|
|
86
|
+
try {
|
|
87
|
+
await rm(dir, { recursive: true });
|
|
88
|
+
console.log(`✓ Glubean skill removed from ${label} (${dir}).`);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
console.log(`✓ Glubean skill was not installed for ${label}.`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
95
|
+
// Helpers
|
|
96
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
97
|
+
function getTemplatePath() {
|
|
98
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
99
|
+
// dist/commands/config_skill.js → templates/claude-skill-glubean-test.md
|
|
100
|
+
return join(dirname(thisFile), "..", "..", "templates", "claude-skill-glubean-test.md");
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=config_skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config_skill.js","sourceRoot":"","sources":["../../src/commands/config_skill.ts"],"names":[],"mappings":"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"}
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoZH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/main.js
CHANGED
|
@@ -22,6 +22,8 @@ import { patchCommand } from "./commands/patch.js";
|
|
|
22
22
|
import { specSplitCommand } from "./commands/spec_split.js";
|
|
23
23
|
import { workerCommand } from "./commands/worker.js";
|
|
24
24
|
import { redactCommand } from "./commands/redact.js";
|
|
25
|
+
import { configMcpCommand } from "./commands/config_mcp.js";
|
|
26
|
+
import { configSkillCommand } from "./commands/config_skill.js";
|
|
25
27
|
import { abortUpdateCheck, checkForUpdates } from "./update_check.js";
|
|
26
28
|
const program = new Command();
|
|
27
29
|
program
|
|
@@ -319,6 +321,34 @@ program
|
|
|
319
321
|
});
|
|
320
322
|
});
|
|
321
323
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
324
|
+
// config command (with subcommands)
|
|
325
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
326
|
+
const configCmd = program
|
|
327
|
+
.command("config")
|
|
328
|
+
.description("Configuration tools");
|
|
329
|
+
configCmd
|
|
330
|
+
.command("mcp")
|
|
331
|
+
.description("Configure MCP server for AI coding tools (Claude Code, Cursor, Windsurf)")
|
|
332
|
+
.option("--target <tool>", "AI tool: claude-code, codex, cursor, or windsurf")
|
|
333
|
+
.option("--remove", "Remove MCP server configuration")
|
|
334
|
+
.action(async (options) => {
|
|
335
|
+
await configMcpCommand({
|
|
336
|
+
target: options.target,
|
|
337
|
+
remove: options.remove,
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
configCmd
|
|
341
|
+
.command("skill")
|
|
342
|
+
.description("Install Glubean test-writing skill for AI coding tools")
|
|
343
|
+
.option("--target <tool>", "AI tool: claude-code, codex, or cursor")
|
|
344
|
+
.option("--remove", "Remove skill")
|
|
345
|
+
.action(async (options) => {
|
|
346
|
+
await configSkillCommand({
|
|
347
|
+
target: options.target,
|
|
348
|
+
remove: options.remove,
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
322
352
|
// Helpers
|
|
323
353
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
324
354
|
/** Collect repeated options into an array (Commander.js pattern) */
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glubean/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"glubean": "./bin/gb.js"
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"yaml": "^2.7.0",
|
|
28
28
|
"tsx": "^4.19.0",
|
|
29
29
|
"@glubean/sdk": "0.1.16",
|
|
30
|
-
"@glubean/
|
|
30
|
+
"@glubean/scanner": "0.1.16",
|
|
31
31
|
"@glubean/redaction": "0.1.16",
|
|
32
|
-
"@glubean/
|
|
32
|
+
"@glubean/runner": "0.1.16"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/node": "^22.0.0",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description: Generate Glubean API tests
|
|
2
|
+
name: glubean
|
|
3
|
+
description: Generate, run, and fix Glubean API/browser tests. Uses cheatsheet docs for SDK patterns and CLI for execution.
|
|
4
|
+
context: fork
|
|
4
5
|
allowed-tools:
|
|
5
6
|
- Read
|
|
6
7
|
- Write
|
|
@@ -8,354 +9,70 @@ allowed-tools:
|
|
|
8
9
|
- Glob
|
|
9
10
|
- Grep
|
|
10
11
|
- Bash
|
|
11
|
-
- mcp__glubean__glubean_run_local_file
|
|
12
|
-
- mcp__glubean__glubean_discover_tests
|
|
13
|
-
- mcp__glubean__glubean_list_test_files
|
|
14
|
-
- mcp__glubean__glubean_diagnose_config
|
|
15
|
-
- mcp__glubean__glubean_get_last_run_summary
|
|
16
|
-
- mcp__glubean__glubean_get_local_events
|
|
17
12
|
---
|
|
18
13
|
|
|
19
14
|
# Glubean Test Generator
|
|
20
15
|
|
|
21
|
-
You are a Glubean test expert. Generate, run, and fix
|
|
16
|
+
You are a Glubean test expert. Generate, run, and fix tests using `@glubean/sdk`.
|
|
22
17
|
|
|
23
|
-
##
|
|
18
|
+
## Rules (always follow)
|
|
24
19
|
|
|
25
|
-
1. **
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Bash.
|
|
34
|
-
5. **Fix failures** — read the structured failure output, fix the test code, and rerun. Repeat until green.
|
|
35
|
-
|
|
36
|
-
If $ARGUMENTS is provided, treat it as the target: an endpoint path, a tag, a file to test, or a natural language
|
|
37
|
-
description.
|
|
38
|
-
|
|
39
|
-
## Project structure
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
tests/ # Permanent test files (*.test.ts)
|
|
43
|
-
explore/ # Exploratory tests (same format, for iteration)
|
|
44
|
-
data/ # Test data files (JSON, CSV, YAML)
|
|
45
|
-
context/ # OpenAPI specs and reference docs
|
|
46
|
-
.env # Public variables (BASE_URL)
|
|
47
|
-
.env.secrets # Credentials — gitignored
|
|
48
|
-
package.json # Runtime config, dependencies, glubean settings
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Import convention
|
|
52
|
-
|
|
53
|
-
Always use the npm package name:
|
|
54
|
-
|
|
55
|
-
```typescript
|
|
56
|
-
import { configure, fromCsv, fromDir, fromYaml, test } from "@glubean/sdk";
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## SDK API Reference
|
|
62
|
-
|
|
63
|
-
### test()
|
|
64
|
-
|
|
65
|
-
```typescript
|
|
66
|
-
// Quick mode — single function
|
|
67
|
-
export const myTest = test(
|
|
68
|
-
{ id: "kebab-case-id", name: "Human name", tags: ["api"] },
|
|
69
|
-
async (ctx) => { ... }
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
// Builder mode — multi-step
|
|
73
|
-
export const myFlow = test("flow-id")
|
|
74
|
-
.meta({ name: "Flow name", tags: ["api"] })
|
|
75
|
-
.setup(async (ctx) => { return { token: "..." }; })
|
|
76
|
-
.step("step-name", async (ctx, state) => { return { ...state, new: "data" }; })
|
|
77
|
-
.teardown(async (ctx, state) => { /* cleanup, always runs */ });
|
|
78
|
-
|
|
79
|
-
// Reusable steps with .use() — extract common sequences into plain functions
|
|
80
|
-
const withAuth = (b: TestBuilder<unknown>) => b
|
|
81
|
-
.step("login", async (ctx) => {
|
|
82
|
-
const { token } = await ctx.http.post("/login", { json: { ... } }).json<{ token: string }>();
|
|
83
|
-
return { token };
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
export const testA = test("test-a").use(withAuth).step("act", async (ctx, { token }) => { ... });
|
|
87
|
-
export const testB = test("test-b").use(withAuth).step("verify", async (ctx, { token }) => { ... });
|
|
88
|
-
|
|
89
|
-
// .group(id, fn) — same as .use() but tags steps for visual grouping in reports
|
|
90
|
-
export const checkout = test("checkout")
|
|
91
|
-
.group("auth", withAuth)
|
|
92
|
-
.step("pay", async (ctx, { token }) => { ... });
|
|
93
|
-
// Report: checkout → [auth] login → pay
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### TestContext (ctx)
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
ctx.http // HTTP client (auto-traces)
|
|
100
|
-
ctx.expect(value) // Soft assertion
|
|
101
|
-
ctx.assert(condition, message?) // Hard assertion
|
|
102
|
-
ctx.log(message, data?) // Structured log
|
|
103
|
-
ctx.vars.require("KEY") // Read env var (throws if missing)
|
|
104
|
-
ctx.secrets.require("KEY") // Read secret (auto-redacted)
|
|
105
|
-
ctx.metric("name", value, { unit? }) // Record metric
|
|
106
|
-
ctx.validate(data, zodSchema) // Schema validation
|
|
107
|
-
ctx.pollUntil({ timeoutMs }, fn) // Poll until truthy
|
|
108
|
-
ctx.skip(reason?) // Skip test
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### HTTP Client
|
|
112
|
-
|
|
113
|
-
```typescript
|
|
114
|
-
const res = await ctx.http.get(url, options?);
|
|
115
|
-
const data = await ctx.http.post(url, { json: { ... } }).json<T>();
|
|
116
|
-
// Also: .put(), .patch(), .delete()
|
|
117
|
-
// Response: .json<T>(), .text(), .blob()
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Options:
|
|
121
|
-
|
|
122
|
-
```typescript
|
|
123
|
-
{
|
|
124
|
-
json: { ... }, // JSON body
|
|
125
|
-
searchParams: { key: "value" }, // Query params
|
|
126
|
-
headers: { "X-Custom": "val" }, // Headers
|
|
127
|
-
timeout: 5000, // ms
|
|
128
|
-
retry: 3, // Retry count
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
Extend with defaults:
|
|
133
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
const authed = ctx.http.extend({
|
|
136
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
137
|
-
});
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### Assertions — ctx.expect()
|
|
141
|
-
|
|
142
|
-
```typescript
|
|
143
|
-
expect(x).toBe(y); // Strict equal
|
|
144
|
-
expect(x).toEqual(y); // Deep equal
|
|
145
|
-
expect(x).toBeTruthy();
|
|
146
|
-
expect(x).toBeDefined();
|
|
147
|
-
expect(n).toBeGreaterThan(5);
|
|
148
|
-
expect(s).toContain("sub");
|
|
149
|
-
expect(s).toMatch(/regex/);
|
|
150
|
-
expect(arr).toHaveLength(3);
|
|
151
|
-
expect(obj).toMatchObject({ key: "val" });
|
|
152
|
-
expect(obj).toHaveProperty("path.to.key");
|
|
153
|
-
expect(res).toHaveStatus(200); // HTTP response
|
|
154
|
-
expect(x).not.toBe(y); // Negate
|
|
155
|
-
expect(x).toBe(y).orFail(); // Hard fail (stop test)
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### configure() — shared HTTP client
|
|
20
|
+
1. **Secrets → `.env.secrets`**, public vars → `.env`. NEVER inline as `const`.
|
|
21
|
+
2. **Use `configure()`** for HTTP clients — never raw `fetch()`.
|
|
22
|
+
3. **Tags on every test** — `["smoke"]`, `["api"]`, `["e2e"]`, etc.
|
|
23
|
+
4. **Teardown** any test that creates resources.
|
|
24
|
+
5. **IDs**: kebab-case, unique across project.
|
|
25
|
+
6. **Type responses**: `.json<{ id: string }>()`, never `.json<any>()`.
|
|
26
|
+
7. **One export per behavior**: each `export const` is one test case.
|
|
27
|
+
8. **Imports**: `import { test, configure } from "@glubean/sdk"` — always the npm package name.
|
|
159
28
|
|
|
160
|
-
|
|
161
|
-
// config/api.ts or tests/configure.ts
|
|
162
|
-
import { configure } from "@glubean/sdk";
|
|
29
|
+
## Workflow
|
|
163
30
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
prefixUrl: "BASE_URL", // Env var name
|
|
169
|
-
headers: {
|
|
170
|
-
Authorization: "Bearer {{API_KEY}}", // {{var}} interpolation
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
});
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
### Data loading
|
|
177
|
-
|
|
178
|
-
```typescript
|
|
179
|
-
const rows = await fromDir<T>("./data/users/"); // One JSON file = one row
|
|
180
|
-
const cases = await fromDir.merge<T>("./data/search/"); // Merged for test.pick
|
|
181
|
-
const csv = await fromCsv<T>("./data/file.csv");
|
|
182
|
-
const yaml = await fromYaml<T>("./data/file.yaml");
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
**Data file formats:**
|
|
186
|
-
|
|
187
|
-
`fromDir` — each file is one row. File content is a flat object:
|
|
188
|
-
|
|
189
|
-
```json
|
|
190
|
-
// data/users/alice.json — becomes one row with _name="alice"
|
|
191
|
-
{ "username": "alice", "role": "admin", "expected": 200 }
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
`fromDir.merge` — each file contains named examples as top-level keys. Keys = pick names, values = scenario objects. All
|
|
195
|
-
files are shallow-merged into one map:
|
|
196
|
-
|
|
197
|
-
```json
|
|
198
|
-
// data/search/queries.json
|
|
199
|
-
{
|
|
200
|
-
"by-name": { "q": "phone", "expected": "phone" },
|
|
201
|
-
"by-category": { "q": "laptop", "expected": "laptop" }
|
|
202
|
-
}
|
|
203
|
-
// data/search/edge-cases.json
|
|
204
|
-
{
|
|
205
|
-
"empty-query": { "q": "", "expected": "" }
|
|
206
|
-
}
|
|
207
|
-
// → merged result: { "by-name": {...}, "by-category": {...}, "empty-query": {...} }
|
|
208
|
-
```
|
|
31
|
+
1. **Load cheatsheet** — check `.glubean/docs/index.md` exists and is fresh.
|
|
32
|
+
- Missing → run `npx glubean docs pull` via Bash, then continue.
|
|
33
|
+
- Stale (`.glubean/docs/.pulled_at` is older than 1 day) → run `npx glubean docs pull` to update.
|
|
34
|
+
- Read `.glubean/docs/index.md` to see all available patterns and SDK capabilities.
|
|
209
35
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
// test.each — array of objects
|
|
214
|
-
test.each([
|
|
215
|
-
{ id: 1, expected: 200 },
|
|
216
|
-
{ id: 999, expected: 404 },
|
|
217
|
-
])("get-user-$id", async (ctx, { id, expected }) => { ... });
|
|
218
|
-
|
|
219
|
-
// test.pick — object with named keys
|
|
220
|
-
test.pick({
|
|
221
|
-
"normal": { name: "Alice", age: 25 },
|
|
222
|
-
"edge-case": { name: "", age: -1 },
|
|
223
|
-
})("create-user-$_pick", async (ctx, data) => { ... });
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### test.each — data-driven
|
|
227
|
-
|
|
228
|
-
```typescript
|
|
229
|
-
// Quick mode — single function per row
|
|
230
|
-
const users = await fromDir<{ username: string }>("./data/users/");
|
|
231
|
-
export const tests = test.each(users)(
|
|
232
|
-
"user-lookup-$username", // $field interpolates
|
|
233
|
-
async (ctx, { username }) => { ... },
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
// Builder mode — multi-step per row (omit callback to get builder)
|
|
237
|
-
export const flows = test.each(users)("user-flow-$username")
|
|
238
|
-
.step("fetch", async (ctx, _state, row) => {
|
|
239
|
-
const res = await ctx.http.get(`/users/${row.username}`).json<{ id: string }>();
|
|
240
|
-
return { id: res.id };
|
|
241
|
-
})
|
|
242
|
-
.step("verify", async (ctx, state, row) => {
|
|
243
|
-
ctx.expect(state.id).toBeDefined();
|
|
244
|
-
});
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
### test.pick — named examples
|
|
248
|
-
|
|
249
|
-
```typescript
|
|
250
|
-
// Quick mode — single function
|
|
251
|
-
const cases = await fromDir.merge<{ q: string }>("./data/search/");
|
|
252
|
-
export const tests = test.pick(cases)(
|
|
253
|
-
"search-$_pick", // $_pick = case name
|
|
254
|
-
async (ctx, { q }) => { ... },
|
|
255
|
-
);
|
|
256
|
-
|
|
257
|
-
// Builder mode — multi-step per picked example (omit callback to get builder)
|
|
258
|
-
export const flows = test.pick(cases)("search-flow-$_pick")
|
|
259
|
-
.setup(async (ctx, row) => ({ query: row.q }))
|
|
260
|
-
.step("search", async (ctx, state, row) => {
|
|
261
|
-
const res = await ctx.http.get("/search", { searchParams: { q: state.query } }).json<{ total: number }>();
|
|
262
|
-
return { ...state, total: res.total };
|
|
263
|
-
})
|
|
264
|
-
.step("verify", async (ctx, state) => {
|
|
265
|
-
ctx.expect(state.total).toBeGreaterThan(0);
|
|
266
|
-
})
|
|
267
|
-
.teardown(async (ctx, state) => { /* cleanup */ });
|
|
268
|
-
```
|
|
36
|
+
2. **Read relevant patterns** — based on the user's request, read 1-3 pattern files from `.glubean/docs/patterns/`.
|
|
37
|
+
For example: `configure.md` + `crud.md` for a CRUD test, or `browser.md` for E2E.
|
|
38
|
+
Also read `.glubean/docs/sdk-reference.md` if you need the full API surface.
|
|
269
39
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
## Patterns
|
|
40
|
+
3. **Read the API spec** — check `context/*-endpoints/_index.md` (pre-split specs). If found, read the index
|
|
41
|
+
and only open the specific endpoint file you need. If no split specs, search `context/` for OpenAPI specs
|
|
42
|
+
(`.json`, `.yaml`). If a spec is larger than 50K, suggest `npx glubean spec split context/<file>`. If
|
|
43
|
+
no spec found, ask the user for endpoint details.
|
|
276
44
|
|
|
277
|
-
|
|
45
|
+
4. **Read existing tests** — check `tests/`, `explore/`, and `config/` for patterns, configure files, and
|
|
46
|
+
naming conventions already in use. Follow the project's existing style.
|
|
278
47
|
|
|
279
|
-
|
|
280
|
-
import { test } from "@glubean/sdk";
|
|
281
|
-
import { http } from "./configure.ts";
|
|
48
|
+
5. **Write tests** — generate test files following the patterns from the cheatsheet and the project's conventions.
|
|
282
49
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
);
|
|
290
|
-
```
|
|
50
|
+
6. **Run tests** — execute via Bash:
|
|
51
|
+
```bash
|
|
52
|
+
npx glubean run <file> # Run single file
|
|
53
|
+
npx glubean run --filter <tag> # Run by tag
|
|
54
|
+
npx glubean run --verbose # Show traces and assertions
|
|
55
|
+
```
|
|
291
56
|
|
|
292
|
-
|
|
57
|
+
7. **Fix failures** — read the output, fix the test code, and rerun. Repeat until green.
|
|
293
58
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
.meta({ tags: ["api"] })
|
|
297
|
-
.setup(async () => {
|
|
298
|
-
const item = await http.post("items", { json: { name: "test" } }).json<{ id: string }>();
|
|
299
|
-
return { id: item.id };
|
|
300
|
-
})
|
|
301
|
-
.step("read", async ({ expect }, state) => {
|
|
302
|
-
const item = await http.get(`items/${state.id}`).json<{ name: string }>();
|
|
303
|
-
expect(item.name).toBe("test");
|
|
304
|
-
return state;
|
|
305
|
-
})
|
|
306
|
-
.step("update", async ({ expect }, state) => {
|
|
307
|
-
const item = await http.put(`items/${state.id}`, { json: { name: "updated" } }).json<{ name: string }>();
|
|
308
|
-
expect(item.name).toBe("updated");
|
|
309
|
-
return state;
|
|
310
|
-
})
|
|
311
|
-
.teardown(async (_ctx, state) => {
|
|
312
|
-
if (state?.id) await http.delete(`items/${state.id}`);
|
|
313
|
-
});
|
|
314
|
-
```
|
|
59
|
+
If $ARGUMENTS is provided, treat it as the target: an endpoint path, a tag, a file to test, or a natural
|
|
60
|
+
language description.
|
|
315
61
|
|
|
316
|
-
|
|
62
|
+
## Project structure
|
|
317
63
|
|
|
318
|
-
```typescript
|
|
319
|
-
export const auth = test("auth-flow")
|
|
320
|
-
.meta({ tags: ["api", "auth"] })
|
|
321
|
-
.step("login", async ({ http, expect, secrets }) => {
|
|
322
|
-
const res = await http.post("https://api.example.com/auth/login", {
|
|
323
|
-
json: { username: secrets.require("USERNAME"), password: secrets.require("PASSWORD") },
|
|
324
|
-
}).json<{ token: string }>();
|
|
325
|
-
expect(res.token).toBeDefined();
|
|
326
|
-
return { token: res.token };
|
|
327
|
-
})
|
|
328
|
-
.step("access protected", async ({ http, expect }, state) => {
|
|
329
|
-
const authed = http.extend({ headers: { Authorization: `Bearer ${state.token}` } });
|
|
330
|
-
const profile = await authed.get("https://api.example.com/me").json<{ id: string }>();
|
|
331
|
-
expect(profile.id).toBeDefined();
|
|
332
|
-
});
|
|
333
64
|
```
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
},
|
|
344
|
-
);
|
|
65
|
+
config/ # Shared HTTP clients, browser fixtures, plugin configs
|
|
66
|
+
tests/ # Permanent test files (*.test.ts)
|
|
67
|
+
explore/ # Exploratory tests (same format, for iteration)
|
|
68
|
+
data/ # Test data files (JSON, CSV, YAML)
|
|
69
|
+
context/ # OpenAPI specs and reference docs
|
|
70
|
+
.env # Public variables (BASE_URL)
|
|
71
|
+
.env.secrets # Credentials — gitignored
|
|
72
|
+
.glubean/docs/ # SDK cheatsheet (auto-pulled, gitignored)
|
|
73
|
+
package.json # Runtime config, dependencies
|
|
345
74
|
```
|
|
346
75
|
|
|
347
|
-
---
|
|
348
|
-
|
|
349
|
-
## Rules
|
|
350
|
-
|
|
351
|
-
- **IDs**: kebab-case, unique across the project
|
|
352
|
-
- **Tags**: always set — `["smoke"]`, `["api"]`, `["e2e"]`, `["auth"]`
|
|
353
|
-
- **Secrets**: use `secrets.require("KEY")` or `{{KEY}}` in configure. Never hardcode.
|
|
354
|
-
- **Cleanup**: any test that creates data MUST have `.teardown()`
|
|
355
|
-
- **Data**: keep test data in `data/`, not inline in test files
|
|
356
|
-
- **Imports**: use `.ts` extensions for local files
|
|
357
|
-
- **One export per behavior**: each `export const` is one test case
|
|
358
|
-
|
|
359
76
|
## Coverage expectations
|
|
360
77
|
|
|
361
78
|
For each endpoint, consider:
|
|
@@ -365,16 +82,4 @@ For each endpoint, consider:
|
|
|
365
82
|
- Validation boundary (400/422) — invalid input
|
|
366
83
|
- Not-found boundary (404) — nonexistent resource
|
|
367
84
|
|
|
368
|
-
Cover all applicable boundaries unless the user asks for a narrower scope.
|
|
369
|
-
say so explicitly.
|
|
370
|
-
|
|
371
|
-
## Anti-patterns to avoid
|
|
372
|
-
|
|
373
|
-
- Hardcoded secrets or base URLs
|
|
374
|
-
- Using raw `fetch()` instead of `ctx.http` or configured client
|
|
375
|
-
- No tags on tests
|
|
376
|
-
- Creating resources without teardown cleanup
|
|
377
|
-
- Guessing endpoint paths — always check the spec first
|
|
378
|
-
- Using hardcoded URLs instead of `@glubean/sdk` package
|
|
379
|
-
- Using `any` or `unknown` for HTTP response types — always provide a type parameter: `.json<{ id: string }>()`, not
|
|
380
|
-
`.json<any>()`. The SDK is fully typed; if you know the shape from the spec, type it.
|
|
85
|
+
Cover all applicable boundaries unless the user asks for a narrower scope.
|