@capagents/forgeqe 2.2.3 → 2.2.5
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/HOW_TO_USE.md +34 -1
- package/THIRD_PARTY_NOTICES.md +2 -2
- package/bin/forgeqe.d.ts +6 -0
- package/bin/forgeqe.js +38 -6
- package/dist/forgeqe.js +836 -829
- package/docs/user-guide.html +34 -1
- package/package.json +11 -1
- package/py/forgeqe_desktop/__main__.py +4 -0
- package/py/forgeqe_engine/__main__.py +4 -0
- package/py/forgeqe_engine/browser.py +24 -1
- package/py/forgeqe_engine/cli.py +4 -0
- package/py/forgeqe_engine/copilot_gateway.py +3 -0
- package/py/forgeqe_engine/systemcerts.py +23 -0
- package/py/forgeqe_mobile/__main__.py +4 -0
package/docs/user-guide.html
CHANGED
|
@@ -470,7 +470,7 @@ forgeqe suite cases.yaml --parallel 3 # what pipelines call
|
|
|
470
470
|
pip install forgeqe-cli
|
|
471
471
|
forgeqe --help
|
|
472
472
|
</code></pre>
|
|
473
|
-
<p>That is the only install step on Windows, macOS and Linux.
|
|
473
|
+
<p>That is the only install step on Windows, macOS and Linux. npm installs Bun with ForgeQE (through your npm registry, so a company mirror works); with pip, or when npm skipped it, the first run downloads Bun into <code>~/.forgeqe/tools</code> (unless a Bun 1.3+ is already installed), and <code>forgeqe setup</code> downloads the agent runtime and uv, which fetches Python. Nothing is added to PATH or shell profiles; deleting <code>~/.forgeqe</code> removes it all.</p>
|
|
474
474
|
<p>Set up the ForgeQE engine once (the first live run does it automatically if you skip this):</p>
|
|
475
475
|
<pre><code class="language-bash">forgeqe setup
|
|
476
476
|
</code></pre>
|
|
@@ -488,6 +488,38 @@ bun install
|
|
|
488
488
|
bun src/index.ts --help
|
|
489
489
|
</code></pre>
|
|
490
490
|
</div></section>
|
|
491
|
+
<section class="doc sub" id="doc-how_to_use-company-networks"><h4>Company networks</h4><div class="prose"><p>On a company laptop, ForgeQE sets itself up for the network without anyone changing settings:</p>
|
|
492
|
+
<div class="tbl"><table>
|
|
493
|
+
<thead>
|
|
494
|
+
<tr><th>What the network does</th><th>What ForgeQE does</th></tr>
|
|
495
|
+
</thead>
|
|
496
|
+
<tbody>
|
|
497
|
+
<tr><td>Inspects HTTPS (Zscaler, Netskope, a firewall), with the company's own certificate</td><td>Uses the certificates this computer trusts: Windows' Trusted Root store, or the macOS System keychain. ForgeQE, the agent runtime, Playwright and Copilot's runtime get them through <code>NODE_EXTRA_CA_CERTS</code> (a copy in <code>~/.forgeqe/cache/system-ca.pem</code>, refreshed weekly); the Python engines check with the system through truststore; uv with <code>UV_SYSTEM_CERTS</code>. Certificates are still verified.</td></tr>
|
|
498
|
+
<tr><td>Sends traffic through a proxy set in Windows</td><td>Reads Windows' proxy setting (or the one proxy its automatic configuration script names) and passes it on as <code>HTTPS_PROXY</code>. ForgeQE's own servers on <code>127.0.0.1</code> always bypass it.</td></tr>
|
|
499
|
+
<tr><td>Blocks downloads from GitHub or the Playwright CDN</td><td>npm brings Bun through your registry; Microsoft Edge is used when Google Chrome is not installed, so no Chromium is downloaded; mirrors can stand in for the rest (below).</td></tr>
|
|
500
|
+
</tbody>
|
|
501
|
+
</table></div>
|
|
502
|
+
<p>To see where the network stops ForgeQE, run:</p>
|
|
503
|
+
<pre><code class="language-bash">forgeqe doctor
|
|
504
|
+
</code></pre>
|
|
505
|
+
<p>It shows the proxy and certificates in use, checks each address ForgeQE needs (GitHub downloads, Python packages, the npm registry, your models, Azure DevOps or Jira), and for anything blocked prints what to ask IT for, ready to forward.</p>
|
|
506
|
+
<p><strong>For IT: mirrors and settings.</strong> Set these as environment variables (for example by Group Policy):</p>
|
|
507
|
+
<div class="tbl"><table>
|
|
508
|
+
<thead>
|
|
509
|
+
<tr><th>Variable</th><th>What it does</th></tr>
|
|
510
|
+
</thead>
|
|
511
|
+
<tbody>
|
|
512
|
+
<tr><td><code>FORGEQE_GITHUB_MIRROR</code></td><td>A mirror of GitHub release downloads (<code>https://artifacts.example.com/github</code>, laid out as <code><owner>/<repo>/releases/download/<tag>/<file></code>): Bun, uv, the agent runtime, Python builds and Copilot's runtime come from it. Checksums are still checked.</td></tr>
|
|
513
|
+
<tr><td><code>UV_DEFAULT_INDEX</code> (or <code>PIP_INDEX_URL</code>)</td><td>A mirror of PyPI for the engine's Python packages.</td></tr>
|
|
514
|
+
<tr><td><code>PLAYWRIGHT_DOWNLOAD_HOST</code></td><td>A mirror for Chromium, needed only without Chrome or Edge.</td></tr>
|
|
515
|
+
<tr><td><code>HTTPS_PROXY</code>, <code>NO_PROXY</code></td><td>A proxy other than Windows' setting. A proxy that needs a sign-in takes <code>http://user:password@host:port</code>.</td></tr>
|
|
516
|
+
<tr><td><code>NODE_EXTRA_CA_CERTS</code></td><td>Your own certificate file instead of the system's roots.</td></tr>
|
|
517
|
+
<tr><td><code>FORGEQE_SYSTEM_CERTS=off</code></td><td>Leaves certificates to each tool's built-in list.</td></tr>
|
|
518
|
+
<tr><td><code>FORGEQE_HOME</code></td><td>Where ForgeQE keeps its tools (default <code>~/.forgeqe</code>), for machines where programs may run only from certain folders.</td></tr>
|
|
519
|
+
</tbody>
|
|
520
|
+
</table></div>
|
|
521
|
+
<p>What still needs IT: a proxy that signs in with your Windows account only (NTLM or Kerberos), and policies that block programs in the user folder (set <code>FORGEQE_HOME</code> to an allowed folder). On macOS, the company's certificate must be in the System keychain, where device management puts it.</p>
|
|
522
|
+
</div></section>
|
|
491
523
|
</section>
|
|
492
524
|
<section class="doc" id="doc-how_to_use-2-scaffold-config">
|
|
493
525
|
<h3>Scaffold config</h3>
|
|
@@ -577,6 +609,7 @@ bun src/index.ts init --global --profile azure-gpt4o
|
|
|
577
609
|
<tr><td><code>ForgeQE's agent and Scribe cannot run on a github_copilot profile yet</code></td><td>Pick another profile for them (<code>--profile</code>, or Tab in the shell), or set <code>code.model</code>.</td></tr>
|
|
578
610
|
<tr><td>The model is refused, or not found</td><td>The seat's plan or your organization's Copilot policies do not allow that model: pick one the sign-in listed, or ask a Copilot admin to enable it.</td></tr>
|
|
579
611
|
<tr><td><code>GitHub Copilot runs through the ForgeQE engine, which is not set up</code></td><td>Run <code>forgeqe setup</code>.</td></tr>
|
|
612
|
+
<tr><td><code>CERTIFICATE_VERIFY_FAILED</code> while downloading Copilot's runtime</td><td>Your network inspects HTTPS. Update ForgeQE and run <code>forgeqe setup</code>, then sign in again: it uses the certificates your computer trusts (see <a href="../HOW_TO_USE.md#company-networks">Company networks</a>). If it still fails, run <code>forgeqe doctor</code> and send its output to IT.</td></tr>
|
|
580
613
|
</tbody>
|
|
581
614
|
</table></div>
|
|
582
615
|
</div></section>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capagents/forgeqe",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.5",
|
|
4
4
|
"description": "ForgeQE: a browser agent CLI that runs goals and test cases in local Chrome or Chromium, or BrowserStack and TestMu AI/LambdaTest when configured, and turns passing runs into tests in your repo",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|
|
@@ -60,6 +60,16 @@
|
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@opentui/core": "^0.5.12"
|
|
62
62
|
},
|
|
63
|
+
"optionalDependencies": {
|
|
64
|
+
"@oven/bun-darwin-aarch64": "1.4.2",
|
|
65
|
+
"@oven/bun-darwin-x64-baseline": "1.4.2",
|
|
66
|
+
"@oven/bun-linux-aarch64": "1.4.2",
|
|
67
|
+
"@oven/bun-linux-aarch64-musl": "1.4.2",
|
|
68
|
+
"@oven/bun-linux-x64-baseline": "1.4.2",
|
|
69
|
+
"@oven/bun-linux-x64-musl-baseline": "1.4.2",
|
|
70
|
+
"@oven/bun-windows-aarch64": "1.4.2",
|
|
71
|
+
"@oven/bun-windows-x64-baseline": "1.4.2"
|
|
72
|
+
},
|
|
63
73
|
"devDependencies": {
|
|
64
74
|
"@opencode-ai/sdk": "1.18.33",
|
|
65
75
|
"@opentui/react": "^0.5.12",
|
|
@@ -7,9 +7,10 @@ import contextlib
|
|
|
7
7
|
import json
|
|
8
8
|
import logging
|
|
9
9
|
import os
|
|
10
|
+
import sys
|
|
10
11
|
import time
|
|
11
12
|
from pathlib import Path
|
|
12
|
-
from typing import Any, Dict, Optional
|
|
13
|
+
from typing import Any, Dict, List, Optional
|
|
13
14
|
from urllib.parse import quote, urlparse
|
|
14
15
|
|
|
15
16
|
logger = logging.getLogger("forgeqe_engine.service")
|
|
@@ -84,6 +85,24 @@ _UNSUPPORTED_BROWSER_USE_ARGS = (
|
|
|
84
85
|
_MAC_CHROME_EXECUTABLE = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
|
85
86
|
|
|
86
87
|
|
|
88
|
+
def find_edge_executable() -> Optional[str]:
|
|
89
|
+
"""
|
|
90
|
+
Microsoft Edge, which every Windows PC has: used when Google Chrome is not installed, so that no Chromium has to be
|
|
91
|
+
downloaded (company networks often block where it comes from).
|
|
92
|
+
"""
|
|
93
|
+
candidates: List[str] = []
|
|
94
|
+
if sys.platform == "win32":
|
|
95
|
+
for var in ("PROGRAMFILES(X86)", "PROGRAMFILES", "LOCALAPPDATA"):
|
|
96
|
+
base = os.environ.get(var)
|
|
97
|
+
if base:
|
|
98
|
+
candidates.append(os.path.join(base, "Microsoft", "Edge", "Application", "msedge.exe"))
|
|
99
|
+
elif sys.platform == "darwin":
|
|
100
|
+
candidates.append("/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge")
|
|
101
|
+
else:
|
|
102
|
+
candidates += ["/usr/bin/microsoft-edge", "/usr/bin/microsoft-edge-stable", "/opt/microsoft/msedge/msedge"]
|
|
103
|
+
return next((c for c in candidates if Path(c).is_file()), None)
|
|
104
|
+
|
|
105
|
+
|
|
87
106
|
def resolve_browser_channel() -> str:
|
|
88
107
|
"""Default is installed Google Chrome (`chrome`). Override with BROWSER_USE_CHANNEL (e.g. `chromium`)."""
|
|
89
108
|
raw = (os.getenv("BROWSER_USE_CHANNEL") or "chrome").strip().lower()
|
|
@@ -125,8 +144,12 @@ def local_browser_launch_kwargs(*, headless: bool) -> Dict[str, Any]:
|
|
|
125
144
|
"ignore_default_args": list(_UNSUPPORTED_BROWSER_USE_ARGS),
|
|
126
145
|
}
|
|
127
146
|
exe = resolve_chrome_executable_path(channel)
|
|
147
|
+
edge = None if exe or channel not in ("chrome", "msedge") else find_edge_executable()
|
|
128
148
|
if exe:
|
|
129
149
|
kw["executable_path"] = exe
|
|
150
|
+
elif edge:
|
|
151
|
+
kw["executable_path"] = edge
|
|
152
|
+
kw["channel"] = "msedge"
|
|
130
153
|
elif channel == "chrome":
|
|
131
154
|
# No Google Chrome here: let the library use its own Chromium instead of failing on the channel.
|
|
132
155
|
kw["channel"] = "chromium"
|
package/py/forgeqe_engine/cli.py
CHANGED
|
@@ -78,6 +78,10 @@ def _doctor(out: TextIO) -> int:
|
|
|
78
78
|
info["copilot_sdk"] = version("github-copilot-sdk")
|
|
79
79
|
except Exception:
|
|
80
80
|
pass
|
|
81
|
+
try:
|
|
82
|
+
info["truststore"] = version("truststore")
|
|
83
|
+
except Exception:
|
|
84
|
+
pass
|
|
81
85
|
try:
|
|
82
86
|
info["video"] = version("imageio")
|
|
83
87
|
except Exception:
|
|
@@ -26,6 +26,8 @@ import time
|
|
|
26
26
|
import uuid
|
|
27
27
|
from typing import Any, Dict, List, Optional, TextIO, Tuple
|
|
28
28
|
|
|
29
|
+
from .systemcerts import use_system_certificates
|
|
30
|
+
|
|
29
31
|
TOKEN_ENV = "COPILOT_GITHUB_TOKEN"
|
|
30
32
|
KEY_ENV = "FORGEQE_COPILOT_GATEWAY_KEY"
|
|
31
33
|
|
|
@@ -366,4 +368,5 @@ async def serve(out: TextIO, copilot: Any = None) -> int:
|
|
|
366
368
|
|
|
367
369
|
|
|
368
370
|
def main(out: TextIO) -> int:
|
|
371
|
+
use_system_certificates()
|
|
369
372
|
return asyncio.run(serve(out))
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
HTTPS certificates checked with the operating system's store (truststore), as pip and uv do. On a company network that
|
|
3
|
+
inspects HTTPS, the company's certificate authority is trusted by Windows or macOS but not by Python's own bundle
|
|
4
|
+
(certifi), and Python 3.13+ refuses such a CA whose Basic Constraints are not marked critical. With this, the engines'
|
|
5
|
+
calls to the model, the Copilot SDK's runtime download and any other HTTPS request work there.
|
|
6
|
+
|
|
7
|
+
Certificates are still verified, hostnames included; only who verifies them changes. FORGEQE_SYSTEM_CERTS=off leaves
|
|
8
|
+
Python's own checks in place (src/network.ts).
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def use_system_certificates() -> bool:
|
|
16
|
+
if os.environ.get("FORGEQE_SYSTEM_CERTS", "").strip().lower() in ("0", "off", "false", "no"):
|
|
17
|
+
return False
|
|
18
|
+
try:
|
|
19
|
+
import truststore
|
|
20
|
+
except ImportError:
|
|
21
|
+
return False
|
|
22
|
+
truststore.inject_into_ssl()
|
|
23
|
+
return True
|