specterqa 0.3.0__tar.gz
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.
- specterqa-0.3.0/.github/ISSUE_TEMPLATE/bug_report.yml +83 -0
- specterqa-0.3.0/.github/ISSUE_TEMPLATE/feature_request.yml +51 -0
- specterqa-0.3.0/.github/pull_request_template.md +25 -0
- specterqa-0.3.0/.github/workflows/ci.yml +51 -0
- specterqa-0.3.0/.github/workflows/publish.yml +31 -0
- specterqa-0.3.0/.gitignore +57 -0
- specterqa-0.3.0/.mcpregistry_github_token +1 -0
- specterqa-0.3.0/.mcpregistry_registry_token +1 -0
- specterqa-0.3.0/.well-known/agent.json +106 -0
- specterqa-0.3.0/CHANGELOG.md +76 -0
- specterqa-0.3.0/CONTRIBUTING.md +94 -0
- specterqa-0.3.0/LICENSE +21 -0
- specterqa-0.3.0/PKG-INFO +442 -0
- specterqa-0.3.0/README.md +400 -0
- specterqa-0.3.0/SECURITY.md +70 -0
- specterqa-0.3.0/SECURITY_ADVISORY.md +129 -0
- specterqa-0.3.0/docs/ci-integration.md +255 -0
- specterqa-0.3.0/docs/configuration.md +293 -0
- specterqa-0.3.0/docs/cost-guide.md +223 -0
- specterqa-0.3.0/docs/for-agents.md +447 -0
- specterqa-0.3.0/examples/demo-app/app.py +45 -0
- specterqa-0.3.0/examples/demo-app/requirements.txt +1 -0
- specterqa-0.3.0/examples/demo-app/templates/dashboard.html +57 -0
- specterqa-0.3.0/examples/demo-app/templates/homepage.html +55 -0
- specterqa-0.3.0/examples/demo-app/templates/signup.html +55 -0
- specterqa-0.3.0/examples/journeys/demo-onboarding.yaml +35 -0
- specterqa-0.3.0/examples/journeys/forgeos-onboarding.yaml +61 -0
- specterqa-0.3.0/examples/personas/alex-developer.yaml +18 -0
- specterqa-0.3.0/examples/products/demo.yaml +12 -0
- specterqa-0.3.0/examples/products/forgeos.yaml +12 -0
- specterqa-0.3.0/pyproject.toml +84 -0
- specterqa-0.3.0/server.json +37 -0
- specterqa-0.3.0/src/specterqa/__init__.py +3 -0
- specterqa-0.3.0/src/specterqa/__main__.py +5 -0
- specterqa-0.3.0/src/specterqa/cli/__init__.py +1 -0
- specterqa-0.3.0/src/specterqa/cli/app.py +94 -0
- specterqa-0.3.0/src/specterqa/cli/config_cmd.py +242 -0
- specterqa-0.3.0/src/specterqa/cli/dashboard.py +145 -0
- specterqa-0.3.0/src/specterqa/cli/init_cmd.py +269 -0
- specterqa-0.3.0/src/specterqa/cli/install.py +129 -0
- specterqa-0.3.0/src/specterqa/cli/report.py +243 -0
- specterqa-0.3.0/src/specterqa/cli/run.py +776 -0
- specterqa-0.3.0/src/specterqa/cli/validate.py +554 -0
- specterqa-0.3.0/src/specterqa/config.py +134 -0
- specterqa-0.3.0/src/specterqa/credentials.py +89 -0
- specterqa-0.3.0/src/specterqa/engine/__init__.py +49 -0
- specterqa-0.3.0/src/specterqa/engine/action_executor.py +1622 -0
- specterqa-0.3.0/src/specterqa/engine/ai_step_runner.py +590 -0
- specterqa-0.3.0/src/specterqa/engine/api_runner.py +552 -0
- specterqa-0.3.0/src/specterqa/engine/browser_runner.py +790 -0
- specterqa-0.3.0/src/specterqa/engine/cost_tracker.py +408 -0
- specterqa-0.3.0/src/specterqa/engine/mock_server.py +480 -0
- specterqa-0.3.0/src/specterqa/engine/native_action_executor.py +181 -0
- specterqa-0.3.0/src/specterqa/engine/native_app_runner.py +1523 -0
- specterqa-0.3.0/src/specterqa/engine/orchestrator.py +1000 -0
- specterqa-0.3.0/src/specterqa/engine/persona_agent.py +638 -0
- specterqa-0.3.0/src/specterqa/engine/protocols.py +85 -0
- specterqa-0.3.0/src/specterqa/engine/report_generator.py +210 -0
- specterqa-0.3.0/src/specterqa/engine/sim_action_executor.py +270 -0
- specterqa-0.3.0/src/specterqa/engine/simulator_runner.py +792 -0
- specterqa-0.3.0/src/specterqa/mcp/__init__.py +12 -0
- specterqa-0.3.0/src/specterqa/mcp/__main__.py +5 -0
- specterqa-0.3.0/src/specterqa/mcp/server.py +884 -0
- specterqa-0.3.0/src/specterqa/models.py +27 -0
- specterqa-0.3.0/src/specterqa/viewer/__init__.py +1 -0
- specterqa-0.3.0/src/specterqa/viewer/server.py +476 -0
- specterqa-0.3.0/src/specterqa/viewer/static/style.css +908 -0
- specterqa-0.3.0/src/specterqa/viewer/templates/base.html +33 -0
- specterqa-0.3.0/src/specterqa/viewer/templates/detail.html +284 -0
- specterqa-0.3.0/src/specterqa/viewer/templates/index.html +117 -0
- specterqa-0.3.0/tests/__init__.py +0 -0
- specterqa-0.3.0/tests/conftest.py +79 -0
- specterqa-0.3.0/tests/test_cli_init.py +175 -0
- specterqa-0.3.0/tests/test_config.py +193 -0
- specterqa-0.3.0/tests/test_cost_tracker.py +310 -0
- specterqa-0.3.0/tests/test_credentials.py +228 -0
- specterqa-0.3.0/tests/test_mcp_server.py +1754 -0
- specterqa-0.3.0/tests/test_models.py +136 -0
- specterqa-0.3.0/tests/test_report_generator.py +279 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
name: Bug Report
|
|
2
|
+
description: Report a bug in SpecterQA
|
|
3
|
+
title: "[Bug]: "
|
|
4
|
+
labels: ["bug", "triage"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for reporting a bug! Please fill out the sections below so we can reproduce and fix the issue.
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: description
|
|
13
|
+
attributes:
|
|
14
|
+
label: Description
|
|
15
|
+
description: A clear and concise description of what the bug is.
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: steps
|
|
21
|
+
attributes:
|
|
22
|
+
label: Steps to reproduce
|
|
23
|
+
description: How can we reproduce this behavior?
|
|
24
|
+
placeholder: |
|
|
25
|
+
1. Create a persona YAML with ...
|
|
26
|
+
2. Run `specterqa run ...`
|
|
27
|
+
3. See error ...
|
|
28
|
+
validations:
|
|
29
|
+
required: true
|
|
30
|
+
|
|
31
|
+
- type: textarea
|
|
32
|
+
id: expected
|
|
33
|
+
attributes:
|
|
34
|
+
label: Expected behavior
|
|
35
|
+
description: What did you expect to happen?
|
|
36
|
+
validations:
|
|
37
|
+
required: true
|
|
38
|
+
|
|
39
|
+
- type: textarea
|
|
40
|
+
id: actual
|
|
41
|
+
attributes:
|
|
42
|
+
label: Actual behavior
|
|
43
|
+
description: What actually happened? Include error messages or screenshots if applicable.
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
46
|
+
|
|
47
|
+
- type: input
|
|
48
|
+
id: specterqa-version
|
|
49
|
+
attributes:
|
|
50
|
+
label: SpecterQA version
|
|
51
|
+
description: "Output of `specterqa --version` or `pip show specterqa`"
|
|
52
|
+
placeholder: "0.1.0"
|
|
53
|
+
validations:
|
|
54
|
+
required: true
|
|
55
|
+
|
|
56
|
+
- type: input
|
|
57
|
+
id: python-version
|
|
58
|
+
attributes:
|
|
59
|
+
label: Python version
|
|
60
|
+
description: "Output of `python --version`"
|
|
61
|
+
placeholder: "3.12.0"
|
|
62
|
+
validations:
|
|
63
|
+
required: true
|
|
64
|
+
|
|
65
|
+
- type: dropdown
|
|
66
|
+
id: os
|
|
67
|
+
attributes:
|
|
68
|
+
label: Operating system
|
|
69
|
+
options:
|
|
70
|
+
- Linux
|
|
71
|
+
- macOS
|
|
72
|
+
- Windows
|
|
73
|
+
- Other
|
|
74
|
+
validations:
|
|
75
|
+
required: true
|
|
76
|
+
|
|
77
|
+
- type: textarea
|
|
78
|
+
id: additional
|
|
79
|
+
attributes:
|
|
80
|
+
label: Additional context
|
|
81
|
+
description: Any other context, logs, or screenshots about the problem.
|
|
82
|
+
validations:
|
|
83
|
+
required: false
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Feature Request
|
|
2
|
+
description: Suggest a new feature or improvement for SpecterQA
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for suggesting an improvement! Please describe your idea below.
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: description
|
|
13
|
+
attributes:
|
|
14
|
+
label: Description
|
|
15
|
+
description: A clear and concise description of the feature you'd like.
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: use-case
|
|
21
|
+
attributes:
|
|
22
|
+
label: Use case
|
|
23
|
+
description: What problem does this solve? Who benefits from it?
|
|
24
|
+
placeholder: |
|
|
25
|
+
As a QA engineer, I want to ... so that ...
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
|
|
29
|
+
- type: textarea
|
|
30
|
+
id: proposed-solution
|
|
31
|
+
attributes:
|
|
32
|
+
label: Proposed solution
|
|
33
|
+
description: How do you envision this working? Include API ideas, CLI flags, YAML config examples, etc.
|
|
34
|
+
validations:
|
|
35
|
+
required: false
|
|
36
|
+
|
|
37
|
+
- type: textarea
|
|
38
|
+
id: alternatives
|
|
39
|
+
attributes:
|
|
40
|
+
label: Alternatives considered
|
|
41
|
+
description: Have you considered other approaches? What are the trade-offs?
|
|
42
|
+
validations:
|
|
43
|
+
required: false
|
|
44
|
+
|
|
45
|
+
- type: textarea
|
|
46
|
+
id: additional
|
|
47
|
+
attributes:
|
|
48
|
+
label: Additional context
|
|
49
|
+
description: Any other context, mockups, or references.
|
|
50
|
+
validations:
|
|
51
|
+
required: false
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- What does this PR do? Why is it needed? Link related issues with "Closes #123". -->
|
|
4
|
+
|
|
5
|
+
## Changes
|
|
6
|
+
|
|
7
|
+
<!-- Bullet list of the key changes in this PR. -->
|
|
8
|
+
|
|
9
|
+
-
|
|
10
|
+
|
|
11
|
+
## Test plan
|
|
12
|
+
|
|
13
|
+
<!-- How did you verify this works? Include commands, screenshots, or test output. -->
|
|
14
|
+
|
|
15
|
+
- [ ] Tests pass locally (`pytest tests/ -v`)
|
|
16
|
+
- [ ] Linting passes (`ruff check src/`)
|
|
17
|
+
- [ ] Formatting passes (`ruff format --check src/`)
|
|
18
|
+
|
|
19
|
+
## Checklist
|
|
20
|
+
|
|
21
|
+
- [ ] I have read the [contributing guide](../CONTRIBUTING.md)
|
|
22
|
+
- [ ] My code follows the project's style (ruff-enforced)
|
|
23
|
+
- [ ] I have added tests for new functionality
|
|
24
|
+
- [ ] I have updated documentation if needed
|
|
25
|
+
- [ ] All new and existing tests pass
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
lint:
|
|
15
|
+
name: Lint
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: "3.12"
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: pip install -e ".[dev,mcp]"
|
|
26
|
+
|
|
27
|
+
- name: Ruff check
|
|
28
|
+
run: ruff check src/
|
|
29
|
+
|
|
30
|
+
- name: Ruff format check
|
|
31
|
+
run: ruff format --check src/
|
|
32
|
+
|
|
33
|
+
test:
|
|
34
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
strategy:
|
|
37
|
+
fail-fast: false
|
|
38
|
+
matrix:
|
|
39
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v4
|
|
42
|
+
|
|
43
|
+
- uses: actions/setup-python@v5
|
|
44
|
+
with:
|
|
45
|
+
python-version: ${{ matrix.python-version }}
|
|
46
|
+
|
|
47
|
+
- name: Install dependencies
|
|
48
|
+
run: pip install -e ".[dev,mcp]"
|
|
49
|
+
|
|
50
|
+
- name: Run tests
|
|
51
|
+
run: pytest tests/ -v --tb=short
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
id-token: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
publish:
|
|
12
|
+
name: Build and publish to PyPI
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
environment:
|
|
15
|
+
name: pypi
|
|
16
|
+
url: https://pypi.org/p/specterqa
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: "3.12"
|
|
23
|
+
|
|
24
|
+
- name: Install build tools
|
|
25
|
+
run: pip install build
|
|
26
|
+
|
|
27
|
+
- name: Build package
|
|
28
|
+
run: python -m build
|
|
29
|
+
|
|
30
|
+
- name: Publish to PyPI
|
|
31
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
|
|
7
|
+
# Distribution / packaging
|
|
8
|
+
.Python
|
|
9
|
+
build/
|
|
10
|
+
develop-eggs/
|
|
11
|
+
dist/
|
|
12
|
+
downloads/
|
|
13
|
+
eggs/
|
|
14
|
+
.eggs/
|
|
15
|
+
lib/
|
|
16
|
+
lib64/
|
|
17
|
+
parts/
|
|
18
|
+
sdist/
|
|
19
|
+
var/
|
|
20
|
+
wheels/
|
|
21
|
+
*.egg-info/
|
|
22
|
+
*.egg
|
|
23
|
+
|
|
24
|
+
# Virtual environments
|
|
25
|
+
.venv/
|
|
26
|
+
env/
|
|
27
|
+
venv/
|
|
28
|
+
ENV/
|
|
29
|
+
|
|
30
|
+
# IDE
|
|
31
|
+
.vscode/
|
|
32
|
+
.idea/
|
|
33
|
+
*.swp
|
|
34
|
+
*.swo
|
|
35
|
+
*~
|
|
36
|
+
|
|
37
|
+
# Testing
|
|
38
|
+
.pytest_cache/
|
|
39
|
+
.coverage
|
|
40
|
+
htmlcov/
|
|
41
|
+
.mypy_cache/
|
|
42
|
+
.ruff_cache/
|
|
43
|
+
|
|
44
|
+
# Environment variables
|
|
45
|
+
.env
|
|
46
|
+
.env.local
|
|
47
|
+
.env.*.local
|
|
48
|
+
|
|
49
|
+
# GhostQA project config and evidence
|
|
50
|
+
.ghostqa/config.yaml
|
|
51
|
+
.ghostqa/evidence/
|
|
52
|
+
evidence/
|
|
53
|
+
**/evidence/**/*.png
|
|
54
|
+
|
|
55
|
+
# OS
|
|
56
|
+
.DS_Store
|
|
57
|
+
Thumbs.db
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ghu_W3yptWq9TzcU9hjKG9YQSuy4XA5OEt3tuVe9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"token":"eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJtY3AtcmVnaXN0cnkiLCJleHAiOjE3NzE4MzAwMDgsIm5iZiI6MTc3MTgyOTcwOCwiaWF0IjoxNzcxODI5NzA4LCJhdXRoX21ldGhvZCI6ImdpdGh1Yi1hdCIsImF1dGhfbWV0aG9kX3N1YiI6IlN5bmNUZWtMTEMiLCJwZXJtaXNzaW9ucyI6W3siYWN0aW9uIjoicHVibGlzaCIsInJlc291cmNlIjoiaW8uZ2l0aHViLlN5bmNUZWtMTEMvKiJ9XX0.t0WySIpPwOm0CcdJrNreFdLjZAV1y_aQ2VIA8Ujc_c2Hv7vYxUeI4DBRO-HQnQNi3kYBMYbC8L5ay_f4BXxgBQ","expires_at":1771830008}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "SpecterQA",
|
|
3
|
+
"description": "AI behavioral testing for web and native applications. AI personas navigate your app in real browser sessions and report UX issues, broken flows, and errors — no test scripts required.",
|
|
4
|
+
"version": "0.3.0",
|
|
5
|
+
"url": "https://github.com/SyncTek-LLC/specterqa",
|
|
6
|
+
"homepage": "https://github.com/SyncTek-LLC/specterqa",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"capabilities": [
|
|
9
|
+
"behavioral_testing",
|
|
10
|
+
"ux_analysis",
|
|
11
|
+
"vision_testing",
|
|
12
|
+
"cost_tracking",
|
|
13
|
+
"mcp"
|
|
14
|
+
],
|
|
15
|
+
"invocation": {
|
|
16
|
+
"cli": {
|
|
17
|
+
"command": "specterqa run -p <product>",
|
|
18
|
+
"install": "pip install specterqa",
|
|
19
|
+
"json_output_flag": "--output json",
|
|
20
|
+
"exit_codes": {
|
|
21
|
+
"0": "all_passed",
|
|
22
|
+
"1": "test_failure",
|
|
23
|
+
"2": "config_error",
|
|
24
|
+
"3": "infra_error"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"python": {
|
|
28
|
+
"import": "from specterqa.engine.orchestrator import SpecterQAOrchestrator",
|
|
29
|
+
"package": "specterqa",
|
|
30
|
+
"entry_class": "specterqa.engine.orchestrator.SpecterQAOrchestrator"
|
|
31
|
+
},
|
|
32
|
+
"mcp": {
|
|
33
|
+
"command": "specterqa-mcp",
|
|
34
|
+
"transport": "stdio",
|
|
35
|
+
"config_example": {
|
|
36
|
+
"specterqa": {
|
|
37
|
+
"command": "specterqa-mcp",
|
|
38
|
+
"args": []
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"cost_model": {
|
|
44
|
+
"type": "per_run",
|
|
45
|
+
"basis": "anthropic_api_usage",
|
|
46
|
+
"typical_range_usd": [0.30, 1.50],
|
|
47
|
+
"budget_enforcement": true,
|
|
48
|
+
"default_budget_usd": 5.00,
|
|
49
|
+
"notes": "specterqa_run MCP calls are synchronous and may take 45-300 seconds. Budget cap enforced per run."
|
|
50
|
+
},
|
|
51
|
+
"tools": [
|
|
52
|
+
{
|
|
53
|
+
"name": "specterqa_run",
|
|
54
|
+
"description": "Run behavioral tests on a product. AI personas navigate the app and report UX issues. Synchronous — may take 45-300s. Incurs Anthropic API costs (default budget: $5.00).",
|
|
55
|
+
"inputs": {
|
|
56
|
+
"product": "string (required) — product name matching .specterqa/products/<name>.yaml",
|
|
57
|
+
"journey": "string (optional) — journey ID; runs all journeys if omitted",
|
|
58
|
+
"level": "string (optional) — smoke | standard | thorough",
|
|
59
|
+
"budget": "float (optional) — cost cap in USD, default 5.00",
|
|
60
|
+
"directory": "string (optional) — project root directory, defaults to CWD"
|
|
61
|
+
},
|
|
62
|
+
"outputs": "JSON with passed, run_id, step_reports, findings, cost_usd, cost_summary"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "specterqa_list_products",
|
|
66
|
+
"description": "List configured test products and their available journeys.",
|
|
67
|
+
"inputs": {
|
|
68
|
+
"directory": "string (optional) — project root directory, defaults to CWD"
|
|
69
|
+
},
|
|
70
|
+
"outputs": "Array of product configs with product name, display name, and journey IDs"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "specterqa_get_results",
|
|
74
|
+
"description": "Retrieve full structured results from a previous run by run ID.",
|
|
75
|
+
"inputs": {
|
|
76
|
+
"run_id": "string (required) — run ID in format GQA-RUN-YYYYMMDD-HHMMSS-xxxx",
|
|
77
|
+
"directory": "string (optional) — project root directory, defaults to CWD"
|
|
78
|
+
},
|
|
79
|
+
"outputs": "Full run result JSON including step reports, findings, screenshots paths, and cost breakdown"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "specterqa_init",
|
|
83
|
+
"description": "Initialize a new SpecterQA project directory with sample product, persona, and journey configs.",
|
|
84
|
+
"inputs": {
|
|
85
|
+
"directory": "string (optional) — target directory for initialization, defaults to CWD"
|
|
86
|
+
},
|
|
87
|
+
"outputs": "List of created file paths"
|
|
88
|
+
}
|
|
89
|
+
],
|
|
90
|
+
"requirements": {
|
|
91
|
+
"python": ">=3.10",
|
|
92
|
+
"anthropic_api_key": true,
|
|
93
|
+
"playwright": ">=1.48.0",
|
|
94
|
+
"notes": "Run 'specterqa install' after pip install to download Playwright browsers"
|
|
95
|
+
},
|
|
96
|
+
"output_schema": {
|
|
97
|
+
"run_result": {
|
|
98
|
+
"passed": "boolean — top-level pass/fail",
|
|
99
|
+
"run_id": "string — unique run identifier",
|
|
100
|
+
"step_reports": "array — per-step pass/fail, duration, error",
|
|
101
|
+
"findings": "array — UX issues found, each with severity, category, description, step_id",
|
|
102
|
+
"cost_usd": "float — total API cost for this run",
|
|
103
|
+
"cost_summary": "object — detailed cost breakdown with budget status"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to SpecterQA are documented here.
|
|
4
|
+
|
|
5
|
+
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
|
+
Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## [0.3.0] — 2026-02-23
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **Rebrand: GhostQA -> SpecterQA.** Package renamed from `ghostqa` to `specterqa`. All imports, CLI commands, MCP tool names, environment variables, and project directory paths updated accordingly. Key changes:
|
|
15
|
+
- CLI: `ghostqa` -> `specterqa`, `ghostqa-mcp` -> `specterqa-mcp`
|
|
16
|
+
- Python imports: `from ghostqa` -> `from specterqa`
|
|
17
|
+
- Classes: `GhostQAConfig` -> `SpecterQAConfig`, `GhostQAOrchestrator` -> `SpecterQAOrchestrator`
|
|
18
|
+
- MCP tools: `ghostqa_run` -> `specterqa_run`, `ghostqa_list_products` -> `specterqa_list_products`, etc.
|
|
19
|
+
- Env vars: `GHOSTQA_ALLOWED_DIRS` -> `SPECTERQA_ALLOWED_DIRS`, `GHOSTQA_PROJECT_DIR` -> `SPECTERQA_PROJECT_DIR`, etc.
|
|
20
|
+
- Project directory: `.ghostqa/` -> `.specterqa/`
|
|
21
|
+
- Repository URL: `github.com/SyncTek-LLC/ghostqa` -> `github.com/SyncTek-LLC/specterqa`
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## [0.2.2] — 2026-02-23
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- Added MCP Registry verification metadata to README (`mcp-name` comment)
|
|
30
|
+
- Added `server.json` for Official MCP Registry submission
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## [0.2.1] — 2026-02-23
|
|
35
|
+
|
|
36
|
+
### Security
|
|
37
|
+
|
|
38
|
+
- **[CRITICAL] Command injection fix (GHSA-SPECTERQA-001):** Removed the `check_command` field from the product YAML schema. The field allowed arbitrary shell commands to be embedded in a YAML service definition and executed by the SpecterQA process. Precondition service checks are now limited to TCP connectivity and HTTP health endpoint checks, which are safe. No workaround exists for v0.2.0 and earlier other than removing `check_command` from all product YAMLs. See [SECURITY_ADVISORY.md](SECURITY_ADVISORY.md) for full details.
|
|
39
|
+
- **MCP directory traversal fix (SPECTERQA_ALLOWED_DIRS):** The MCP server's `specterqa_run` tool now enforces an allowlist for the `directory` parameter when the `SPECTERQA_ALLOWED_DIRS` environment variable is set. Any path not under an allowed prefix is rejected with a structured error response. When the variable is unset, all paths remain accessible (permissive default for local development). Users running the MCP server in shared or multi-user environments should set this variable. See the [README Security section](README.md#security) and [docs/for-agents.md](docs/for-agents.md) for configuration guidance.
|
|
40
|
+
- **Credential scrubbing in run artifacts:** Run result JSON files and log output now automatically scrub known credential patterns (API keys, bearer tokens, passwords, connection strings) before writing to disk. Evidence directories are safer to share and commit as CI artifacts.
|
|
41
|
+
- **API key template removed from sample config:** The `specterqa init` sample configuration previously included a placeholder `anthropic_api_key: sk-ant-...` in `.specterqa/config.yaml`. This has been replaced with an environment variable reference (`${ANTHROPIC_API_KEY}`) to prevent accidental key commits.
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- **`--plain` mode for CI and screen readers:** `specterqa run --plain` disables Rich formatting, colors, and progress spinners and emits plain text to stdout. Useful in CI environments where Rich markup becomes noise, and for accessibility tools that consume terminal output.
|
|
46
|
+
- **`--fail-on-severity` threshold flag:** `specterqa run --fail-on-severity high` causes the run to exit with a non-zero status if any finding at or above the specified severity level is recorded, even if all steps technically passed. Accepted values: `low`, `medium`, `high`, `critical`, `block`. Default behavior (exit 0 on step pass) is unchanged.
|
|
47
|
+
- **`specterqa validate` command:** Validates product, persona, and journey YAML files against the SpecterQA schema without running a test. Reports schema errors, missing required fields, and deprecated fields (including `check_command`, which now produces a schema error). Useful in CI as a pre-flight check.
|
|
48
|
+
- **`.well-known/agent.json` — A2A Agent Card:** SpecterQA now ships an Agent Card at `.well-known/agent.json` following the [Agent-to-Agent (A2A) protocol](https://google.github.io/A2A/). This allows A2A-compatible agent hosts to discover SpecterQA's capabilities, available tools, input/output schemas, and cost model without prior out-of-band configuration.
|
|
49
|
+
- **108 new MCP server tests (248 total):** The MCP server test suite has been expanded from 140 to 248 tests, covering the `SPECTERQA_ALLOWED_DIRS` allowlist enforcement, credential scrubbing behavior, `specterqa validate` tool, the `--plain` and `--fail-on-severity` CLI flags, and edge cases in the `specterqa_run` tool response schema.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- The `services.*.check_command` field in product YAMLs is now a schema error. Existing configs containing this field will be rejected by `specterqa validate` and produce a startup error on `specterqa run`. Remove the field and use `health_endpoint` or TCP port checks instead.
|
|
54
|
+
- The `specterqa init` sample product YAML no longer includes a `check_command` example.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## [0.2.0] — 2026-02-22
|
|
59
|
+
|
|
60
|
+
Initial public release.
|
|
61
|
+
|
|
62
|
+
- Persona-based behavioral testing via YAML-configured personas and journeys
|
|
63
|
+
- Claude vision model integration (Haiku for simple actions, Sonnet for complex reasoning)
|
|
64
|
+
- Playwright-based browser automation with headless support
|
|
65
|
+
- macOS native app testing via Accessibility API (pyobjc optional extra)
|
|
66
|
+
- iOS Simulator testing via simctl (pyobjc optional extra)
|
|
67
|
+
- Budget enforcement with per-run, per-day, and per-month caps
|
|
68
|
+
- JUnit XML output for CI integration
|
|
69
|
+
- JSON structured output (`--output json`) for programmatic consumption
|
|
70
|
+
- Evidence collection: screenshots, findings, cost breakdown, run-result.json per run
|
|
71
|
+
- Stuck detection with model escalation (Haiku → Sonnet → abort)
|
|
72
|
+
- Template variables in journey steps (`{{persona.credentials.email}}`)
|
|
73
|
+
- MCP server (`specterqa-mcp`) exposing `specterqa_run`, `specterqa_list_products`, `specterqa_get_results`, `specterqa_init`
|
|
74
|
+
- Tiered model routing with optional local Ollama fallback for zero-cost simple actions
|
|
75
|
+
- Federated protocol: swap in custom `AIDecider` or `ActionExecutor` implementations
|
|
76
|
+
- 140 unit tests across config, cost tracking, report generation, MCP server, and CLI
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Contributing to SpecterQA
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing to SpecterQA! This guide will help you get started.
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
1. **Clone the repository**
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git clone https://github.com/SyncTek-LLC/specterqa.git
|
|
11
|
+
cd specterqa
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
2. **Create a virtual environment**
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
python -m venv .venv
|
|
18
|
+
source .venv/bin/activate # Linux/macOS
|
|
19
|
+
# .venv\Scripts\activate # Windows
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
3. **Install in development mode**
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install -e ".[dev]"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
4. **Install Playwright browsers** (needed for integration tests)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
playwright install chromium
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Running Tests
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Run all unit tests
|
|
38
|
+
pytest tests/ -v
|
|
39
|
+
|
|
40
|
+
# Run with coverage
|
|
41
|
+
pytest tests/ -v --cov=src/specterqa --cov-report=term-missing
|
|
42
|
+
|
|
43
|
+
# Skip integration tests (which require a running app and API key)
|
|
44
|
+
pytest tests/ -v -m "not integration"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Code Quality
|
|
48
|
+
|
|
49
|
+
We use [Ruff](https://docs.astral.sh/ruff/) for linting and formatting.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Check for lint issues
|
|
53
|
+
ruff check src/
|
|
54
|
+
|
|
55
|
+
# Auto-fix lint issues
|
|
56
|
+
ruff check src/ --fix
|
|
57
|
+
|
|
58
|
+
# Check formatting
|
|
59
|
+
ruff format --check src/
|
|
60
|
+
|
|
61
|
+
# Auto-format
|
|
62
|
+
ruff format src/
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Type checking with mypy:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
mypy src/specterqa
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Submitting Changes
|
|
72
|
+
|
|
73
|
+
1. **Fork the repository** and create a branch from `main`.
|
|
74
|
+
2. **Make your changes.** Add tests for new functionality.
|
|
75
|
+
3. **Ensure all checks pass:**
|
|
76
|
+
```bash
|
|
77
|
+
ruff check src/
|
|
78
|
+
ruff format --check src/
|
|
79
|
+
pytest tests/ -v
|
|
80
|
+
```
|
|
81
|
+
4. **Open a pull request** against `main`. Fill out the PR template.
|
|
82
|
+
5. A maintainer will review your PR. Address any feedback, then it will be merged.
|
|
83
|
+
|
|
84
|
+
## Reporting Bugs
|
|
85
|
+
|
|
86
|
+
Use the [bug report template](https://github.com/SyncTek-LLC/specterqa/issues/new?template=bug_report.yml) on GitHub Issues.
|
|
87
|
+
|
|
88
|
+
## Requesting Features
|
|
89
|
+
|
|
90
|
+
Use the [feature request template](https://github.com/SyncTek-LLC/specterqa/issues/new?template=feature_request.yml) on GitHub Issues.
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
By contributing to SpecterQA, you agree that your contributions will be licensed under the [MIT License](LICENSE). All contributions are subject to this project's license terms.
|
specterqa-0.3.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SyncTek LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|