@capagents/forgeqe 2.2.4 → 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.
@@ -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. 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>
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>&lt;owner&gt;/&lt;repo&gt;/releases/download/&lt;tag&gt;/&lt;file&gt;</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.4",
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",
@@ -1,3 +1,7 @@
1
+ from forgeqe_engine.systemcerts import use_system_certificates
2
+
1
3
  from .cli import main
2
4
 
5
+ use_system_certificates()
6
+
3
7
  raise SystemExit(main())
@@ -1,3 +1,7 @@
1
+ from forgeqe_engine.systemcerts import use_system_certificates
2
+
1
3
  from .cli import main
2
4
 
5
+ use_system_certificates()
6
+
3
7
  raise SystemExit(main())
@@ -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"
@@ -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
@@ -1,3 +1,7 @@
1
+ from forgeqe_engine.systemcerts import use_system_certificates
2
+
1
3
  from .cli import main
2
4
 
5
+ use_system_certificates()
6
+
3
7
  raise SystemExit(main())