comfy-qa 1.26.0 → 2.0.1

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 CHANGED
@@ -7,7 +7,7 @@ E2E QA automation for user-facing frontend repos. AI-driven Playwright tests wit
7
7
  Tell your AI agent (Claude Code, Cursor, etc.):
8
8
 
9
9
  ```
10
- run npx cmqa setup
10
+ run npx comfy-qa setup
11
11
  ```
12
12
 
13
13
  The agent reads the emitted prompt and automatically:
@@ -20,21 +20,21 @@ The agent reads the emitted prompt and automatically:
20
20
  - Creates starter `tests/e2e/qa.spec.ts` covering your key routes
21
21
  - Updates `.gitignore`
22
22
 
23
- Re-running `npx cmqa setup` updates existing files without overwriting what's already correct.
23
+ Re-running `npx comfy-qa setup` updates existing files without overwriting what's already correct.
24
24
 
25
25
  ## QA a PR or issue
26
26
 
27
27
  ```bash
28
28
  # Paste a GitHub URL — auto-detects PR vs issue
29
- cmqa https://github.com/org/repo/pull/123
30
- cmqa https://github.com/org/repo/issues/456
29
+ comfy-qa https://github.com/org/repo/pull/123
30
+ comfy-qa https://github.com/org/repo/issues/456
31
31
 
32
32
  # Or use subcommands
33
- cmqa pr https://github.com/org/repo/pull/123
34
- cmqa issue org/repo#456
33
+ comfy-qa pr https://github.com/org/repo/pull/123
34
+ comfy-qa issue org/repo#456
35
35
 
36
36
  # Batch QA recent open issues
37
- cmqa full org/repo --limit 5
37
+ comfy-qa full org/repo --limit 5
38
38
  ```
39
39
 
40
40
  Each run produces in `.comfy-qa/<slug>/`:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "comfy-qa",
3
- "version": "1.26.0",
3
+ "version": "2.0.1",
4
4
  "description": "ComfyUI QA automation CLI",
5
5
  "repository": {
6
6
  "type": "git",
@@ -11,7 +11,6 @@
11
11
  "type": "module",
12
12
  "bin": {
13
13
  "comfy-qa": "./src/cli.ts",
14
- "cmqa": "./src/cli.ts",
15
14
  "qabot": "./bot/cli.ts"
16
15
  },
17
16
  "files": [
package/src/cli.ts CHANGED
@@ -10,17 +10,17 @@ const args = Bun.argv.slice(2);
10
10
  const cmd = args[0];
11
11
  const rest = args.slice(1);
12
12
 
13
- const HELP = `cmqa — E2E QA automation for frontend repos
13
+ const HELP = `comfy-qa — E2E QA automation for frontend repos
14
14
 
15
15
  USAGE
16
- cmqa setup Emit setup prompt for your agent
17
- cmqa <github-url> Auto-detect PR or issue from URL
18
- cmqa pr <github-url | owner/repo#N> Research & QA a pull request
19
- cmqa issue <github-url | owner/repo#N> Research & QA an issue / bug report
20
- cmqa full <owner/repo> Batch QA recent open issues
16
+ comfy-qa setup Emit setup prompt for your agent
17
+ comfy-qa <github-url> Auto-detect PR or issue from URL
18
+ comfy-qa pr <github-url | owner/repo#N> Research & QA a pull request
19
+ comfy-qa issue <github-url | owner/repo#N> Research & QA an issue / bug report
20
+ comfy-qa full <owner/repo> Batch QA recent open issues
21
21
 
22
22
  SETUP (one-shot)
23
- Tell your agent: "run npx cmqa setup"
23
+ Tell your agent: "run npx comfy-qa setup"
24
24
  The agent reads the emitted prompt and sets up a complete QA workflow
25
25
  for the current repo — Playwright config, E2E tests, skill files, etc.
26
26
 
@@ -33,12 +33,12 @@ OPTIONS
33
33
  -v, --version Show version
34
34
 
35
35
  EXAMPLES
36
- cmqa setup
37
- cmqa https://github.com/org/repo/pull/123
38
- cmqa https://github.com/org/repo/issues/456
39
- cmqa pr org/repo#123
40
- cmqa issue org/repo#456 --no-record
41
- cmqa full org/repo --limit 3
36
+ comfy-qa setup
37
+ comfy-qa https://github.com/org/repo/pull/123
38
+ comfy-qa https://github.com/org/repo/issues/456
39
+ comfy-qa pr org/repo#123
40
+ comfy-qa issue org/repo#456 --no-record
41
+ comfy-qa full org/repo --limit 3
42
42
  `;
43
43
 
44
44
  if (!cmd || cmd === "-h" || cmd === "--help") {
@@ -72,7 +72,7 @@ if (urlParsed) {
72
72
  await commandFull(rest);
73
73
  break;
74
74
  default:
75
- console.error(`Unknown command: ${cmd}\nRun 'cmqa --help' for usage.`);
75
+ console.error(`Unknown command: ${cmd}\nRun 'comfy-qa --help' for usage.`);
76
76
  process.exit(1);
77
77
  }
78
78
  }
@@ -10,7 +10,7 @@ export async function commandFull(args: string[]): Promise<void> {
10
10
  const comfyUrl = comfyUrlIdx >= 0 ? args[comfyUrlIdx + 1] : undefined;
11
11
 
12
12
  if (!repoRef) {
13
- console.error("Usage: cmqa full <owner/repo> [--limit N] [--no-record]");
13
+ console.error("Usage: comfy-qa full <owner/repo> [--limit N] [--no-record]");
14
14
  process.exit(1);
15
15
  }
16
16
 
@@ -7,15 +7,15 @@ export async function commandIssue(args: string[]): Promise<void> {
7
7
  const comfyUrlIdx = args.indexOf("--comfy-url");
8
8
  const comfyUrl = comfyUrlIdx >= 0 ? args[comfyUrlIdx + 1] : undefined;
9
9
 
10
- // Accept GitHub URL: cmqa issue https://github.com/org/repo/issues/456
10
+ // Accept GitHub URL: comfy-qa issue https://github.com/org/repo/issues/456
11
11
  if (ref) {
12
12
  const parsed = parseGitHubUrl(ref);
13
13
  if (parsed) ref = parsed.ref;
14
14
  }
15
15
 
16
16
  if (!ref) {
17
- console.error("Usage: cmqa issue <github-url | owner/repo#number>");
18
- console.error(" cmqa issue https://github.com/org/repo/issues/456");
17
+ console.error("Usage: comfy-qa issue <github-url | owner/repo#number>");
18
+ console.error(" comfy-qa issue https://github.com/org/repo/issues/456");
19
19
  process.exit(1);
20
20
  }
21
21
 
@@ -7,15 +7,15 @@ export async function commandPR(args: string[]): Promise<void> {
7
7
  const comfyUrlIdx = args.indexOf("--comfy-url");
8
8
  const comfyUrl = comfyUrlIdx >= 0 ? args[comfyUrlIdx + 1] : undefined;
9
9
 
10
- // Accept GitHub URL: cmqa pr https://github.com/org/repo/pull/123
10
+ // Accept GitHub URL: comfy-qa pr https://github.com/org/repo/pull/123
11
11
  if (ref) {
12
12
  const parsed = parseGitHubUrl(ref);
13
13
  if (parsed) ref = parsed.ref;
14
14
  }
15
15
 
16
16
  if (!ref) {
17
- console.error("Usage: cmqa pr <github-url | owner/repo#number>");
18
- console.error(" cmqa pr https://github.com/org/repo/pull/123");
17
+ console.error("Usage: comfy-qa pr <github-url | owner/repo#number>");
18
+ console.error(" comfy-qa pr https://github.com/org/repo/pull/123");
19
19
  process.exit(1);
20
20
  }
21
21
 
@@ -37,46 +37,56 @@ export function parseRef(ref: string): { owner: string; repo: string; number?: n
37
37
  }
38
38
 
39
39
  export async function fetchPR(owner: string, repo: string, number: number): Promise<PRInfo> {
40
- const json = await $`gh pr view ${number} --repo ${owner}/${repo} --json number,title,body,state,headRefName,baseRefName,author,labels,url,files,comments`.text();
41
- const raw = JSON.parse(json);
40
+ const [prJson, filesJson, commentsJson] = await Promise.all([
41
+ $`gh api repos/${owner}/${repo}/pulls/${number}`.text(),
42
+ $`gh api repos/${owner}/${repo}/pulls/${number}/files --paginate`.text(),
43
+ $`gh api repos/${owner}/${repo}/issues/${number}/comments --paginate`.text(),
44
+ ]);
45
+ const pr = JSON.parse(prJson);
46
+ const files = JSON.parse(filesJson);
47
+ const comments = JSON.parse(commentsJson);
42
48
  return {
43
- number: raw.number,
44
- title: raw.title,
45
- body: raw.body || "",
46
- state: raw.state,
47
- headRefName: raw.headRefName,
48
- baseRefName: raw.baseRefName,
49
- author: raw.author?.login || "unknown",
50
- labels: (raw.labels || []).map((l: any) => l.name),
51
- url: raw.url,
52
- files: (raw.files || []).map((f: any) => ({
53
- path: f.path,
49
+ number: pr.number,
50
+ title: pr.title,
51
+ body: pr.body || "",
52
+ state: pr.state,
53
+ headRefName: pr.head.ref,
54
+ baseRefName: pr.base.ref,
55
+ author: pr.user?.login || "unknown",
56
+ labels: (pr.labels || []).map((l: any) => l.name),
57
+ url: pr.html_url,
58
+ files: files.map((f: any) => ({
59
+ path: f.filename,
54
60
  additions: f.additions,
55
61
  deletions: f.deletions,
56
62
  })),
57
- comments: (raw.comments || []).map((c: any) => ({
58
- author: c.author?.login || "unknown",
63
+ comments: comments.map((c: any) => ({
64
+ author: c.user?.login || "unknown",
59
65
  body: c.body || "",
60
- createdAt: c.createdAt,
66
+ createdAt: c.created_at,
61
67
  })),
62
68
  };
63
69
  }
64
70
 
65
71
  export async function fetchIssue(owner: string, repo: string, number: number): Promise<IssueInfo> {
66
- const json = await $`gh issue view ${number} --repo ${owner}/${repo} --json number,title,body,state,author,labels,url,comments`.text();
67
- const raw = JSON.parse(json);
72
+ const [issueJson, commentsJson] = await Promise.all([
73
+ $`gh api repos/${owner}/${repo}/issues/${number}`.text(),
74
+ $`gh api repos/${owner}/${repo}/issues/${number}/comments --paginate`.text(),
75
+ ]);
76
+ const issue = JSON.parse(issueJson);
77
+ const comments = JSON.parse(commentsJson);
68
78
  return {
69
- number: raw.number,
70
- title: raw.title,
71
- body: raw.body || "",
72
- state: raw.state,
73
- author: raw.author?.login || "unknown",
74
- labels: (raw.labels || []).map((l: any) => l.name),
75
- url: raw.url,
76
- comments: (raw.comments || []).map((c: any) => ({
77
- author: c.author?.login || "unknown",
79
+ number: issue.number,
80
+ title: issue.title,
81
+ body: issue.body || "",
82
+ state: issue.state,
83
+ author: issue.user?.login || "unknown",
84
+ labels: (issue.labels || []).map((l: any) => l.name),
85
+ url: issue.html_url,
86
+ comments: comments.map((c: any) => ({
87
+ author: c.user?.login || "unknown",
78
88
  body: c.body || "",
79
- createdAt: c.createdAt,
89
+ createdAt: c.created_at,
80
90
  })),
81
91
  };
82
92
  }