qaify-playwright-reporter 0.9.7 → 0.10.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.
@@ -3,15 +3,18 @@
3
3
  # Butuh di repo runner ini (Settings → Secrets and variables → Actions):
4
4
  # secret QA_FACTORY_TOKEN token reporter repo runner (Pengaturan → Token Reporter)
5
5
  # variable QA_FACTORY_URL URL API Qaify
6
- # secret CLAUDE_CODE_OAUTH_TOKEN opsional: perbaikan temuan & audit mode claude (langganan Claude Pro/Max, `claude setup-token`)
6
+ # secret CLAUDE_CODE_OAUTH_TOKEN opsional: agen yang memakai langganan Claude Pro/Max (`claude setup-token`);
7
+ # tidak perlu bila semua agen memakai API key (Qaify → Setelan → Agen AI)
7
8
  # variable QA_FACTORY_AUDIT_MODE opsional, `static` / `claude`; hanya dipakai bila Qaify tidak mengirim mode
8
- # variable QA_FACTORY_AI_MODEL opsional, default sonnet
9
+ # variable QA_FACTORY_AI_MODEL opsional, default sonnet (langganan tanpa model dari Qaify)
9
10
  # variable QA_FACTORY_MCP_VERSION opsional, versi @playwright/mcp (default latest)
10
11
  # GitHub App Qaify harus terpasang di repo ini dan di repo FE + BE. Nama file harus tetap qaify-audit.yml.
11
- # Mode audit dipilih di Qaify (setelan aplikasi, bisa diganti per audit); mode claude tanpa secret jatuh ke static.
12
+ # Mode audit dipilih di Qaify (setelan aplikasi, bisa diganti per audit). Mode AI memakai agen "Auditor" dari
13
+ # Setelan → Agen AI: Claude Code (langganan / API key Anthropic) atau Qaify Agent (API key OpenRouter, OpenAI,
14
+ # Gemini, …). API key diambil dari Qaify tepat sebelum audit (`qaify ai-env`) dan disamarkan di log.
15
+ # Mode AI tanpa langganan maupun API key jatuh ke static.
12
16
  # Mode static (tanpa AI): build, test, composer/npm audit, dan smoke test Playwright; cepat, tanpa kuota AI,
13
- # tetapi tanpa analisis logika bisnis / kontrak API dari kode. Temuannya tetap bisa diperbaiki Claude (qaify-fix.yml).
14
- # Mode claude: satu sesi Claude yang panjang; kuota langganan dipakai bersama pemakaian pribadi.
17
+ # tetapi tanpa analisis logika bisnis / kontrak API dari kode. Temuannya tetap bisa diperbaiki agen AI (qaify-fix.yml).
15
18
  name: Qaify audit
16
19
  run-name: audit ${{ inputs.audit_id }}
17
20
  on:
@@ -44,7 +47,7 @@ jobs:
44
47
  ports: ['5432:5432']
45
48
  options: --health-cmd="pg_isready -U postgres" --health-interval=10s --health-timeout=5s --health-retries=10
46
49
  # context runner tidak tersedia di env level job; WORK diisi lewat GITHUB_ENV di step pertama,
47
- # AUDIT_MODE di step "Tentukan mode audit" (mode baru diketahui dari konteks audit)
50
+ # AUDIT_MODE & AUDIT_ENGINE di step "Tentukan mode audit" (baru diketahui dari Qaify)
48
51
  steps:
49
52
  - name: Siapkan direktori kerja
50
53
  run: echo "WORK=$RUNNER_TEMP/qaify" >> "$GITHUB_ENV"
@@ -58,7 +61,7 @@ jobs:
58
61
  tools: composer
59
62
 
60
63
  - name: Pasang Qaify CLI
61
- run: npm install -g qaify-playwright-reporter@0.9 playwright-core@1
64
+ run: npm install -g qaify-playwright-reporter@0.10 playwright-core@1
62
65
 
63
66
  # token clone sekali pakai (read-only, hanya repo FE + BE) dicabut sebelum auditor berjalan
64
67
  - name: Ambil konteks & clone repo FE + BE
@@ -68,24 +71,42 @@ jobs:
68
71
  QA_FACTORY_TOKEN: ${{ secrets.QA_FACTORY_TOKEN }}
69
72
  run: qaify audit-context --audit "${{ inputs.audit_id }}" --dir "$WORK"
70
73
 
71
- # pilihan Qaify → variable QA_FACTORY_AUDIT_MODE → claude bila secret ada; claude tanpa secret → static
74
+ # mesin + model + API key agen Auditor; key ke berkas di luar folder kerja, disamarkan di log
75
+ - name: Pilih agen AI
76
+ id: ai
77
+ if: steps.ctx.outputs.ok == 'true' && steps.ctx.outputs.mode != 'static'
78
+ continue-on-error: true
79
+ env:
80
+ QA_FACTORY_URL: ${{ vars.QA_FACTORY_URL }}
81
+ QA_FACTORY_TOKEN: ${{ secrets.QA_FACTORY_TOKEN }}
82
+ run: |
83
+ qaify ai-env --kind audit --id "${{ inputs.audit_id }}" \
84
+ --env-file "$RUNNER_TEMP/qaify-ai.env" --error-out "$WORK/.qaify/claude.json"
85
+
86
+ # pilihan Qaify → variable QA_FACTORY_AUDIT_MODE → claude bila secret ada; AI tanpa langganan / API key → static
72
87
  - name: Tentukan mode audit
73
88
  if: steps.ctx.outputs.ok == 'true'
74
89
  env:
75
90
  REQUESTED: ${{ steps.ctx.outputs.mode || vars.QA_FACTORY_AUDIT_MODE }}
76
91
  HAS_CLAUDE: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN != '' }}
92
+ HAS_KEY: ${{ steps.ai.outputs.has_key }}
93
+ ENGINE: ${{ steps.ai.outputs.engine || 'claude_code' }}
77
94
  run: |
78
95
  mode="${REQUESTED:-$([ "$HAS_CLAUDE" = true ] && echo claude || echo static)}"
79
96
  if [ "$mode" != static ] && [ "$mode" != claude ]; then
80
97
  echo "::warning::Mode audit tidak dikenal ($mode); memakai static."
81
98
  mode=static
82
99
  fi
83
- if [ "$mode" = claude ] && [ "$HAS_CLAUDE" != true ]; then
84
- echo "::warning::Mode claude diminta tetapi secret CLAUDE_CODE_OAUTH_TOKEN kosong; audit dijalankan tanpa AI."
100
+ if [ "$mode" = claude ] && [ "$ENGINE" = none ]; then
101
+ # hasil gagal + penyebabnya sudah ditulis step "Pilih agen AI"
102
+ mode=failed
103
+ elif [ "$mode" = claude ] && [ "$HAS_CLAUDE" != true ] && [ "$HAS_KEY" != true ]; then
104
+ echo "::warning::Mode AI diminta tetapi secret CLAUDE_CODE_OAUTH_TOKEN kosong dan agen Auditor tidak memakai API key; audit dijalankan tanpa AI."
85
105
  mode=static
86
106
  fi
87
- echo "qa-factory: mode audit $mode"
107
+ echo "qa-factory: mode audit $mode ($ENGINE)"
88
108
  echo "AUDIT_MODE=$mode" >> "$GITHUB_ENV"
109
+ echo "AUDIT_ENGINE=$ENGINE" >> "$GITHUB_ENV"
89
110
 
90
111
  # tanpa secret apa pun: kode aplikasi (composer/npm script) berjalan di step ini
91
112
  - name: Audit tanpa AI (Playwright)
@@ -97,25 +118,32 @@ jobs:
97
118
  - name: Siapkan instruksi & Playwright MCP
98
119
  if: steps.ctx.outputs.ok == 'true' && env.AUDIT_MODE == 'claude'
99
120
  run: |
100
- npm install -g @anthropic-ai/claude-code
121
+ if [ "$AUDIT_ENGINE" = claude_code ]; then npm install -g @anthropic-ai/claude-code; fi
101
122
  mkdir -p "$WORK/.qaify"
102
123
  qaify audit-schema --out "$WORK/.qaify/schema.json" --instructions "$WORK/.qaify/instructions.txt"
124
+ qaify audit-schema --prompt > "$WORK/.qaify/prompt.txt"
103
125
  # Google Chrome sudah ada di runner ubuntu-latest
104
126
  cat > "$WORK/.qaify/mcp.json" <<JSON
105
127
  {"mcpServers":{"playwright":{"command":"npx","args":["-y","@playwright/mcp@${{ vars.QA_FACTORY_MCP_VERSION || 'latest' }}","--headless","--isolated","--browser","chrome","--output-dir","$WORK/evidence"]}}}
106
128
  JSON
107
129
 
108
- # hanya CLAUDE_CODE_OAUTH_TOKEN yang tersedia di step ini; QA_FACTORY_TOKEN tidak
109
- - name: Audit dengan Claude Code (Claude Pro/Max)
110
- if: steps.ctx.outputs.ok == 'true' && env.AUDIT_MODE == 'claude'
130
+ # hanya kredensial AI (secret langganan / API key Anthropic dari Qaify) di step ini; QA_FACTORY_TOKEN tidak
131
+ - name: Audit dengan Claude Code
132
+ if: steps.ctx.outputs.ok == 'true' && env.AUDIT_MODE == 'claude' && env.AUDIT_ENGINE == 'claude_code'
111
133
  continue-on-error: true
112
134
  timeout-minutes: 45
113
135
  working-directory: ${{ runner.temp }}/qaify
114
136
  env:
115
137
  CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
138
+ MODEL: ${{ steps.ai.outputs.model || vars.QA_FACTORY_AI_MODEL || 'sonnet' }}
116
139
  run: |
117
- claude -p "$(qaify audit-schema --prompt)" \
118
- --model "${{ vars.QA_FACTORY_AI_MODEL || 'sonnet' }}" \
140
+ # API key Anthropic dari Qaify menggantikan langganan
141
+ if [ -f "$RUNNER_TEMP/qaify-ai.env" ]; then
142
+ set -a; . "$RUNNER_TEMP/qaify-ai.env"; set +a
143
+ rm -f "$RUNNER_TEMP/qaify-ai.env"; unset CLAUDE_CODE_OAUTH_TOKEN
144
+ fi
145
+ claude -p "$(cat .qaify/prompt.txt)" \
146
+ --model "$MODEL" \
119
147
  --allowedTools "Bash,Read,Grep,Glob,Write,Edit,mcp__playwright" \
120
148
  --disallowedTools "WebFetch,WebSearch" \
121
149
  --strict-mcp-config --mcp-config .qaify/mcp.json \
@@ -124,6 +152,18 @@ jobs:
124
152
  --output-format json --json-schema "$(cat .qaify/schema.json)" \
125
153
  > .qaify/claude.json
126
154
 
155
+ # Qaify Agent: key hanya di memori proses agen (berkas env dihapus saat dibaca), tidak diwarisi bash / MCP
156
+ - name: Audit dengan Qaify Agent (API key)
157
+ if: steps.ctx.outputs.ok == 'true' && env.AUDIT_MODE == 'claude' && env.AUDIT_ENGINE == 'qaify_agent'
158
+ continue-on-error: true
159
+ timeout-minutes: 45
160
+ working-directory: ${{ runner.temp }}/qaify
161
+ run: |
162
+ qaify agent --env-file "$RUNNER_TEMP/qaify-ai.env" \
163
+ --prompt-file .qaify/prompt.txt --instructions-file .qaify/instructions.txt --schema-file .qaify/schema.json \
164
+ --tools read,list,grep,write,edit,bash --mcp-config .qaify/mcp.json --max-turns 150 \
165
+ --out .qaify/claude.json
166
+
127
167
  # selalu jalan (juga saat konteks/clone gagal): tanpa hasil auditor, audit ditandai gagal beserta penyebabnya
128
168
  - name: Kirim hasil audit
129
169
  if: always()
@@ -131,5 +171,6 @@ jobs:
131
171
  QA_FACTORY_URL: ${{ vars.QA_FACTORY_URL }}
132
172
  QA_FACTORY_TOKEN: ${{ secrets.QA_FACTORY_TOKEN }}
133
173
  run: |
174
+ rm -f "$RUNNER_TEMP/qaify-ai.env"
134
175
  qaify audit-submit --audit "${{ inputs.audit_id }}" \
135
176
  --results "$WORK/.qaify/claude.json" --evidence "$WORK/evidence" --context "$WORK/context.json"
@@ -1,14 +1,17 @@
1
- # Qaify — perbaikan temuan audit oleh Claude (1 temuan = 1 PR ke repo FE/BE). Dibuat oleh `npx qaify init-runner`.
2
- # Dipicu Qaify lewat workflow_dispatch (otomatis setelah audit, atau tombol "Perbaiki dengan Claude"); satu per satu per aplikasi.
1
+ # Qaify — perbaikan temuan audit oleh agen AI (1 temuan = 1 PR ke repo FE/BE). Dibuat oleh `npx qaify init-runner`.
2
+ # Dipicu Qaify lewat workflow_dispatch (otomatis setelah audit, atau tombol "Perbaiki"); satu per satu per aplikasi.
3
3
  # Butuh di repo runner ini (sama dengan qaify-audit.yml):
4
4
  # secret QA_FACTORY_TOKEN token reporter repo runner
5
5
  # variable QA_FACTORY_URL URL API Qaify
6
- # secret CLAUDE_CODE_OAUTH_TOKEN langganan Claude Pro/Max Anda (`claude setup-token`); wajib untuk perbaikan
6
+ # secret CLAUDE_CODE_OAUTH_TOKEN langganan Claude Pro/Max Anda (`claude setup-token`); hanya untuk engineer yang
7
+ # memakai langganan (tidak perlu bila semua engineer memakai API key di Qaify)
7
8
  # GitHub App Qaify butuh izin Contents: Read and write dan Pull requests: Read and write di repo FE/BE.
8
- # Model (haiku / sonnet / opus atau versi tertentu) dipilih Qaify per temuan menurut kompleksitas atau pilihan Anda.
9
- # Advisory dependensi (composer.lock / package-lock.json) diperbaiki tanpa Claude: `qaify fix-deps` memperbarui
9
+ # Engineer (Nanda / Fajar / Pak Yoga) dipilih Qaify per temuan menurut kompleksitas atau pilihan Anda; mesin, model,
10
+ # dan API key-nya dari Setelan → Agen AI (Claude Code dengan langganan / API key Anthropic, atau Qaify Agent dengan
11
+ # API key OpenRouter, OpenAI, Gemini, …). API key diambil tepat sebelum perbaikan (`qaify ai-env`), disamarkan di log.
12
+ # Advisory dependensi (composer.lock / package-lock.json) diperbaiki tanpa AI: `qaify fix-deps` memperbarui
10
13
  # paketnya di lockfile (mode deps), tanpa memakai kuota.
11
- # Job "fix" menjalankan Claude tanpa token push; job "submit" (VM bersih) meng-clone ulang, menerapkan patch, lalu push.
14
+ # Job "fix" menjalankan agen tanpa token push; job "submit" (VM bersih) meng-clone ulang, menerapkan patch, lalu push.
12
15
  # Nama file harus tetap qaify-fix.yml.
13
16
  name: Qaify fix
14
17
  run-name: fix ${{ inputs.fix_id }}
@@ -55,10 +58,10 @@ jobs:
55
58
  extensions: mbstring, intl, bcmath, gd, zip, pdo_mysql, pdo_pgsql
56
59
  tools: composer
57
60
 
58
- - name: Pasang Qaify CLI & Claude Code
59
- run: npm install -g qaify-playwright-reporter@0.9 @anthropic-ai/claude-code
61
+ - name: Pasang Qaify CLI
62
+ run: npm install -g qaify-playwright-reporter@0.10
60
63
 
61
- # token clone sekali pakai (read-only, hanya repo target) dicabut sebelum Claude berjalan
64
+ # token clone sekali pakai (read-only, hanya repo target) dicabut sebelum agen berjalan
62
65
  - name: Ambil temuan & clone repo target
63
66
  id: ctx
64
67
  env:
@@ -75,16 +78,34 @@ jobs:
75
78
  timeout-minutes: 15
76
79
  run: qaify fix-deps --dir "$WORK"
77
80
 
78
- # hanya CLAUDE_CODE_OAUTH_TOKEN yang tersedia di step ini; tidak ada token Qaify maupun token push
79
- - name: Perbaiki dengan Claude Code (Claude Pro/Max)
81
+ # mesin + model + API key engineer; key ke berkas di luar folder kerja, disamarkan di log
82
+ - name: Pilih agen AI
83
+ id: ai
80
84
  if: steps.ctx.outputs.ok == 'true' && steps.ctx.outputs.mode != 'deps'
81
85
  continue-on-error: true
86
+ env:
87
+ QA_FACTORY_URL: ${{ vars.QA_FACTORY_URL }}
88
+ QA_FACTORY_TOKEN: ${{ secrets.QA_FACTORY_TOKEN }}
89
+ run: |
90
+ qaify ai-env --kind audit_fix --id "${{ inputs.fix_id }}" \
91
+ --env-file "$RUNNER_TEMP/qaify-ai.env" --error-out "$WORK/.qaify/claude.json"
92
+
93
+ # hanya kredensial AI (secret langganan / API key Anthropic dari Qaify); tidak ada token Qaify maupun token push
94
+ - name: Perbaiki dengan Claude Code
95
+ if: steps.ctx.outputs.ok == 'true' && steps.ctx.outputs.mode != 'deps' && (steps.ai.outputs.engine || 'claude_code') == 'claude_code'
96
+ continue-on-error: true
82
97
  timeout-minutes: 45
83
98
  working-directory: ${{ runner.temp }}/qaify/repo
84
99
  env:
85
100
  CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
86
- MODEL: ${{ steps.ctx.outputs.model }}
101
+ MODEL: ${{ steps.ai.outputs.model || steps.ctx.outputs.model }}
87
102
  run: |
103
+ npm install -g @anthropic-ai/claude-code
104
+ # API key Anthropic dari Qaify menggantikan langganan
105
+ if [ -f "$RUNNER_TEMP/qaify-ai.env" ]; then
106
+ set -a; . "$RUNNER_TEMP/qaify-ai.env"; set +a
107
+ rm -f "$RUNNER_TEMP/qaify-ai.env"; unset CLAUDE_CODE_OAUTH_TOKEN
108
+ fi
88
109
  claude -p "$(cat ../.qaify/prompt.txt)" \
89
110
  --model "$MODEL" \
90
111
  --allowedTools "Bash,Read,Grep,Glob,Write,Edit" \
@@ -94,9 +115,22 @@ jobs:
94
115
  --output-format json --json-schema "$(cat ../.qaify/schema.json)" \
95
116
  > ../.qaify/claude.json
96
117
 
118
+ # Qaify Agent: key hanya di memori proses agen (berkas env dihapus saat dibaca), tidak diwarisi bash
119
+ - name: Perbaiki dengan Qaify Agent (API key)
120
+ if: steps.ctx.outputs.ok == 'true' && steps.ctx.outputs.mode != 'deps' && steps.ai.outputs.engine == 'qaify_agent'
121
+ continue-on-error: true
122
+ timeout-minutes: 45
123
+ working-directory: ${{ runner.temp }}/qaify/repo
124
+ run: |
125
+ qaify agent --env-file "$RUNNER_TEMP/qaify-ai.env" \
126
+ --prompt-file ../.qaify/prompt.txt --instructions-file ../.qaify/instructions.txt --schema-file ../.qaify/schema.json \
127
+ --tools read,list,grep,write,edit,bash --max-turns 80 \
128
+ --out ../.qaify/claude.json
129
+
97
130
  - name: Kumpulkan perubahan
98
131
  if: always() && steps.ctx.outputs.ok == 'true'
99
132
  run: |
133
+ rm -f "$RUNNER_TEMP/qaify-ai.env"
100
134
  qaify fix-diff --dir "$WORK" --out "$WORK/out"
101
135
  cp "$WORK/.qaify/claude.json" "$WORK/out/claude.json" 2>/dev/null || true
102
136
 
@@ -108,7 +142,7 @@ jobs:
108
142
  retention-days: 3
109
143
  if-no-files-found: ignore
110
144
 
111
- # selalu jalan setelah konteks diambil: tanpa hasil Claude, perbaikan ditandai gagal beserta penyebab yang mungkin
145
+ # selalu jalan setelah konteks diambil: tanpa hasil agen, perbaikan ditandai gagal beserta penyebab yang mungkin
112
146
  submit:
113
147
  needs: fix
114
148
  if: always() && needs.fix.outputs.ok == 'true'
@@ -118,7 +152,7 @@ jobs:
118
152
  - uses: actions/setup-node@v4
119
153
  with: { node-version: 22 }
120
154
  - name: Pasang Qaify CLI
121
- run: npm install -g qaify-playwright-reporter@0.9
155
+ run: npm install -g qaify-playwright-reporter@0.10
122
156
  - uses: actions/download-artifact@v4
123
157
  continue-on-error: true
124
158
  with: