@capagents/forgeqe 0.0.0-stage → 1.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/HOW_TO_USE.md +1639 -0
- package/README.md +338 -2
- package/bin/forgeqe.d.ts +3 -0
- package/bin/forgeqe.js +188 -0
- package/docs/ARCHITECTURE.md +408 -0
- package/docs/security-data-flow.html +1870 -0
- package/docs/user-guide.html +2094 -0
- package/evals/domain/access-role-change.yaml +37 -0
- package/evals/domain/banking-payment-transfer.yaml +41 -0
- package/evals/domain/gdpr-account-erasure.yaml +30 -0
- package/evals/domain/insurance-claim-fnol.yaml +30 -0
- package/evals/domain/insurance-policy-renewal.yaml +37 -0
- package/evals/domain/lending-loan-application.yaml +36 -0
- package/forgeqe-architecture.html +718 -0
- package/forgeqe.example.yaml +203 -0
- package/knowledge/README.md +18 -0
- package/knowledge/business-rules.md +10 -0
- package/knowledge/compliance.md +16 -0
- package/knowledge/environments.md +5 -0
- package/knowledge/glossary.md +5 -0
- package/knowledge/product.md +16 -0
- package/knowledge/roles.md +9 -0
- package/knowledge/test-data.md +7 -0
- package/llms.example.json +51 -0
- package/package.json +63 -4
- package/prompts/README.md +34 -0
- package/prompts/api-scenarios.md +21 -0
- package/prompts/api-tests.md +39 -0
- package/prompts/brain.md +166 -0
- package/prompts/browser-capture.md +7 -0
- package/prompts/browser-case-report.md +7 -0
- package/prompts/browser-checks.md +14 -0
- package/prompts/browser-efficiency.md +7 -0
- package/prompts/browser-error-recovery.md +15 -0
- package/prompts/browser-extra.md +5 -0
- package/prompts/browser-goal-verification.md +13 -0
- package/prompts/browser-skill-select.md +6 -0
- package/prompts/domain-rule.md +13 -0
- package/prompts/eval-judge.md +19 -0
- package/prompts/explore-charters.md +27 -0
- package/prompts/find-tests.md +28 -0
- package/prompts/heal.md +40 -0
- package/prompts/pr-review.md +29 -0
- package/prompts/skill-rule.md +6 -0
- package/prompts/test-agent.md +34 -0
- package/prompts/test-reviewer.md +30 -0
- package/prompts/test-rules.md +28 -0
- package/py/forgeqe_engine/__init__.py +3 -0
- package/py/forgeqe_engine/__main__.py +3 -0
- package/py/forgeqe_engine/brand.py +453 -0
- package/py/forgeqe_engine/brand_assets.py +6 -0
- package/py/forgeqe_engine/browser.py +196 -0
- package/py/forgeqe_engine/capture.py +538 -0
- package/py/forgeqe_engine/checks.py +98 -0
- package/py/forgeqe_engine/cli.py +188 -0
- package/py/forgeqe_engine/diagnostics.py +609 -0
- package/py/forgeqe_engine/llm.py +195 -0
- package/py/forgeqe_engine/logins.py +251 -0
- package/py/forgeqe_engine/loops.py +224 -0
- package/py/forgeqe_engine/memory.py +1004 -0
- package/py/forgeqe_engine/network.py +244 -0
- package/py/forgeqe_engine/prompts.py +20 -0
- package/py/forgeqe_engine/replay.py +240 -0
- package/py/forgeqe_engine/report.py +173 -0
- package/py/forgeqe_engine/service.py +1335 -0
- package/py/forgeqe_engine/settings.py +93 -0
- package/py/forgeqe_engine/skills.py +88 -0
- package/py/forgeqe_engine/summary.py +239 -0
- package/py/forgeqe_engine/urls.py +81 -0
- package/py/forgeqe_engine/workflow_yaml.py +689 -0
- package/skills/dotnet-nunit-playwright/SKILL.md +34 -0
- package/skills/dynamics-365/SKILL.md +21 -0
- package/skills/playwright-typescript/SKILL.md +35 -0
- package/skills/writing-skills/SKILL.md +30 -0
- package/src/api/plan.ts +246 -0
- package/src/api/run.ts +204 -0
- package/src/api/scenario.ts +502 -0
- package/src/api/schema.ts +170 -0
- package/src/api/spec.ts +624 -0
- package/src/api/store.ts +232 -0
- package/src/api/traffic.ts +281 -0
- package/src/api/types.ts +163 -0
- package/src/api/write.ts +272 -0
- package/src/auth/signin.ts +494 -0
- package/src/auth/store.ts +170 -0
- package/src/brain/index.ts +189 -0
- package/src/brain/prompt.ts +19 -0
- package/src/capabilities/docs.ts +101 -0
- package/src/capabilities/guide.ts +455 -0
- package/src/capabilities/registry.ts +343 -0
- package/src/capabilities/render.ts +106 -0
- package/src/capabilities/status.ts +137 -0
- package/src/card.ts +11 -0
- package/src/cases/ado.ts +325 -0
- package/src/cases/api.ts +117 -0
- package/src/cases/bugs.ts +223 -0
- package/src/cases/confluence.ts +111 -0
- package/src/cases/context.ts +223 -0
- package/src/cases/dashboards.ts +137 -0
- package/src/cases/failure.ts +97 -0
- package/src/cases/files.ts +295 -0
- package/src/cases/goal.ts +53 -0
- package/src/cases/http.ts +111 -0
- package/src/cases/index.ts +131 -0
- package/src/cases/jira.ts +122 -0
- package/src/cases/qtest.ts +108 -0
- package/src/cases/quality.ts +190 -0
- package/src/cases/rag.ts +100 -0
- package/src/cases/readiness.ts +284 -0
- package/src/cases/save.ts +149 -0
- package/src/cases/sprints.ts +148 -0
- package/src/cases/testrail.ts +176 -0
- package/src/cases/types.ts +107 -0
- package/src/cases/wiki.ts +105 -0
- package/src/cases/xray.ts +206 -0
- package/src/cases/zephyr.ts +153 -0
- package/src/childEnv.ts +86 -0
- package/src/cli/args.ts +114 -0
- package/src/cli/help.ts +167 -0
- package/src/cli/index.ts +1142 -0
- package/src/cli/terminal.ts +187 -0
- package/src/code/areas.ts +337 -0
- package/src/code/attention.ts +214 -0
- package/src/code/find.ts +540 -0
- package/src/code/handoff.ts +541 -0
- package/src/code/history.ts +170 -0
- package/src/code/impact.ts +231 -0
- package/src/code/index.ts +34 -0
- package/src/code/livebrowser.ts +67 -0
- package/src/code/loop.ts +603 -0
- package/src/code/notes.ts +75 -0
- package/src/code/profile.ts +226 -0
- package/src/code/prompt.ts +303 -0
- package/src/code/prreview.ts +649 -0
- package/src/code/prtests.ts +103 -0
- package/src/code/replay.ts +772 -0
- package/src/code/review.ts +202 -0
- package/src/code/runtime.ts +781 -0
- package/src/code/slices.ts +159 -0
- package/src/code/testrun.ts +187 -0
- package/src/code/traceability.ts +100 -0
- package/src/code/worktree.ts +153 -0
- package/src/commands.ts +101 -0
- package/src/config.ts +970 -0
- package/src/detail.ts +65 -0
- package/src/domain.ts +19 -0
- package/src/engine/bridge.ts +359 -0
- package/src/engine/mock.ts +102 -0
- package/src/engine/setup.ts +298 -0
- package/src/entra.ts +154 -0
- package/src/env.ts +24 -0
- package/src/evals/domain.ts +338 -0
- package/src/explore/charters.ts +151 -0
- package/src/explore/run.ts +280 -0
- package/src/explore/story.ts +106 -0
- package/src/guard.ts +51 -0
- package/src/heal/loop.ts +357 -0
- package/src/heal/prompt.ts +143 -0
- package/src/heal/report.ts +95 -0
- package/src/index.ts +12 -0
- package/src/init.ts +102 -0
- package/src/knowledge.ts +114 -0
- package/src/legacyEnv.ts +9 -0
- package/src/llm.ts +61 -0
- package/src/locale.ts +25 -0
- package/src/logins.ts +148 -0
- package/src/managed.ts +101 -0
- package/src/mcp/apitools.ts +335 -0
- package/src/mcp/captools.ts +25 -0
- package/src/mcp/casetools.ts +223 -0
- package/src/mcp/commands.ts +421 -0
- package/src/mcp/exploretools.ts +129 -0
- package/src/mcp/external.ts +172 -0
- package/src/mcp/git.ts +78 -0
- package/src/mcp/notifytools.ts +49 -0
- package/src/mcp/prtools.ts +261 -0
- package/src/mcp/qualitytools.ts +154 -0
- package/src/mcp/repotests.ts +286 -0
- package/src/mcp/server.ts +234 -0
- package/src/mcp/tools.ts +810 -0
- package/src/memory.ts +250 -0
- package/src/money.ts +39 -0
- package/src/monitor/alerts.ts +94 -0
- package/src/monitor/background.ts +68 -0
- package/src/monitor/run.ts +263 -0
- package/src/monitor/state.ts +105 -0
- package/src/notify/events.ts +144 -0
- package/src/notify/notice.ts +177 -0
- package/src/prices.ts +175 -0
- package/src/print.ts +54 -0
- package/src/privacy.ts +35 -0
- package/src/prompts.ts +165 -0
- package/src/quality/budgets.ts +249 -0
- package/src/quality/history.ts +149 -0
- package/src/quality/visual.ts +201 -0
- package/src/report/data.ts +475 -0
- package/src/report/html.ts +106 -0
- package/src/report/template.html +84 -0
- package/src/run.ts +243 -0
- package/src/sessionLog.ts +216 -0
- package/src/sessionLogins.ts +94 -0
- package/src/skills/registry.ts +217 -0
- package/src/skills/scaffold.ts +65 -0
- package/src/skills/select.ts +37 -0
- package/src/skills/view.ts +44 -0
- package/src/suite/report.ts +135 -0
- package/src/suite/run.ts +303 -0
- package/src/summary.ts +188 -0
- package/src/tools.ts +130 -0
- package/src/tui/App.tsx +983 -0
- package/src/tui/clipboard.ts +36 -0
- package/src/tui/components.tsx +263 -0
- package/src/tui/dialogs.ts +65 -0
- package/src/tui/main.tsx +20 -0
- package/src/tui/text.ts +28 -0
- package/src/tui/theme.ts +104 -0
- package/src/tui/transcript.tsx +344 -0
- package/src/types.ts +146 -0
- package/src/update.ts +311 -0
- package/src/usage.ts +158 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Engine process protocol, used by the Bun CLI:
|
|
3
|
+
|
|
4
|
+
stdin line 1 run request JSON
|
|
5
|
+
stdin later "stop" aborts the run
|
|
6
|
+
stdout one JSON event per line (log, memory, step, result, usage, done);
|
|
7
|
+
steps replayed from page memory carry "source": "memory"
|
|
8
|
+
stderr engine logs
|
|
9
|
+
|
|
10
|
+
python -m forgeqe_engine run
|
|
11
|
+
python -m forgeqe_engine login (stdin: {url, logins}, then "save")
|
|
12
|
+
python -m forgeqe_engine doctor
|
|
13
|
+
python -m forgeqe_engine token (stdin: an llms.json profile with auth: entra; prints {token, expires_on})
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import asyncio
|
|
18
|
+
import json
|
|
19
|
+
import logging
|
|
20
|
+
import os
|
|
21
|
+
import sys
|
|
22
|
+
import threading
|
|
23
|
+
from typing import Any, Dict, TextIO
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _event_stream() -> TextIO:
|
|
27
|
+
"""Keep a private handle on stdout for events and point fd 1 at stderr, so library prints cannot corrupt the protocol."""
|
|
28
|
+
out = os.fdopen(os.dup(1), "w", buffering=1, encoding="utf-8")
|
|
29
|
+
os.dup2(2, 1)
|
|
30
|
+
sys.stdout = sys.stderr
|
|
31
|
+
return out
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
NO_TELEMETRY = {
|
|
35
|
+
"ANONYMIZED_TELEMETRY": "false",
|
|
36
|
+
"BROWSER_USE_CLOUD_SYNC": "false",
|
|
37
|
+
"BROWSER_USE_CALCULATE_COST": "false",
|
|
38
|
+
"OTEL_SDK_DISABLED": "true",
|
|
39
|
+
"DO_NOT_TRACK": "1",
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
ENGINE_PREFIX = "FORGEQE_ENGINE_"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _engine_settings() -> None:
|
|
47
|
+
"""FORGEQE_ENGINE_<NAME> sets engine setting <NAME>, which the engine and its library read as BROWSER_USE_<NAME>."""
|
|
48
|
+
for key, value in list(os.environ.items()):
|
|
49
|
+
if key.startswith(ENGINE_PREFIX) and len(key) > len(ENGINE_PREFIX):
|
|
50
|
+
os.environ["BROWSER_USE_" + key[len(ENGINE_PREFIX):]] = value
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _configure_env() -> None:
|
|
54
|
+
_engine_settings()
|
|
55
|
+
os.environ.update(NO_TELEMETRY)
|
|
56
|
+
os.environ.setdefault("BROWSER_USE_LOGGING_LEVEL", "info")
|
|
57
|
+
logging.basicConfig(stream=sys.stderr, level=logging.INFO, format="%(levelname)s %(name)s: %(message)s")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _doctor(out: TextIO) -> int:
|
|
61
|
+
info: Dict[str, Any] = {"python": sys.version.split()[0]}
|
|
62
|
+
try:
|
|
63
|
+
from importlib.metadata import version
|
|
64
|
+
|
|
65
|
+
info["browser_use"] = version("browser-use")
|
|
66
|
+
except Exception as e:
|
|
67
|
+
info["browser_use_error"] = str(e)
|
|
68
|
+
out.write(json.dumps(info) + "\n")
|
|
69
|
+
return 1
|
|
70
|
+
try:
|
|
71
|
+
info["azure_identity"] = version("azure-identity")
|
|
72
|
+
except Exception:
|
|
73
|
+
pass
|
|
74
|
+
try:
|
|
75
|
+
from .service import local_browser_launch_kwargs
|
|
76
|
+
|
|
77
|
+
kw = local_browser_launch_kwargs(headless=True)
|
|
78
|
+
except Exception as e:
|
|
79
|
+
info["engine_error"] = f"{type(e).__name__}: {e}"
|
|
80
|
+
out.write(json.dumps(info) + "\n")
|
|
81
|
+
return 1
|
|
82
|
+
info["channel"] = kw.get("channel")
|
|
83
|
+
info["executable_path"] = kw.get("executable_path") or ""
|
|
84
|
+
out.write(json.dumps(info) + "\n")
|
|
85
|
+
return 0
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _run(out: TextIO) -> int:
|
|
89
|
+
from .service import RunRequest, run_with_events
|
|
90
|
+
|
|
91
|
+
line = sys.stdin.readline()
|
|
92
|
+
if not line.strip():
|
|
93
|
+
out.write(json.dumps({"type": "done", "result": {"success": False, "error": "No run request on stdin."}}) + "\n")
|
|
94
|
+
return 2
|
|
95
|
+
req = RunRequest.from_dict(json.loads(line))
|
|
96
|
+
lock = threading.Lock()
|
|
97
|
+
|
|
98
|
+
def emit(event: Dict[str, Any]) -> None:
|
|
99
|
+
with lock:
|
|
100
|
+
out.write(json.dumps(event, ensure_ascii=False, default=str) + "\n")
|
|
101
|
+
out.flush()
|
|
102
|
+
|
|
103
|
+
async def main() -> int:
|
|
104
|
+
loop = asyncio.get_running_loop()
|
|
105
|
+
cancel = asyncio.Event()
|
|
106
|
+
|
|
107
|
+
def watch_stdin() -> None:
|
|
108
|
+
for cmd in sys.stdin:
|
|
109
|
+
if cmd.strip().lower() == "stop":
|
|
110
|
+
loop.call_soon_threadsafe(cancel.set)
|
|
111
|
+
return
|
|
112
|
+
loop.call_soon_threadsafe(cancel.set)
|
|
113
|
+
|
|
114
|
+
threading.Thread(target=watch_stdin, daemon=True).start()
|
|
115
|
+
result = await run_with_events(req, emit, cancel)
|
|
116
|
+
return 0 if result.get("success") else 1
|
|
117
|
+
|
|
118
|
+
return asyncio.run(main())
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _login(out: TextIO) -> int:
|
|
122
|
+
"""stdin line 1: {url, logins: [login]}; then "save" saves the session, "stop" or EOF cancels."""
|
|
123
|
+
from .logins import interactive_login
|
|
124
|
+
|
|
125
|
+
line = sys.stdin.readline()
|
|
126
|
+
payload = json.loads(line) if line.strip() else {}
|
|
127
|
+
|
|
128
|
+
def emit(event: Dict[str, Any]) -> None:
|
|
129
|
+
out.write(json.dumps(event, ensure_ascii=False, default=str) + "\n")
|
|
130
|
+
out.flush()
|
|
131
|
+
|
|
132
|
+
async def main() -> int:
|
|
133
|
+
loop = asyncio.get_running_loop()
|
|
134
|
+
finished = asyncio.Event()
|
|
135
|
+
|
|
136
|
+
def watch_stdin() -> None:
|
|
137
|
+
for cmd in sys.stdin:
|
|
138
|
+
if cmd.strip().lower() == "save":
|
|
139
|
+
loop.call_soon_threadsafe(finished.set)
|
|
140
|
+
return
|
|
141
|
+
if cmd.strip().lower() == "stop":
|
|
142
|
+
break
|
|
143
|
+
payload["cancelled"] = True
|
|
144
|
+
loop.call_soon_threadsafe(finished.set)
|
|
145
|
+
|
|
146
|
+
threading.Thread(target=watch_stdin, daemon=True).start()
|
|
147
|
+
try:
|
|
148
|
+
result = await interactive_login(payload, emit, finished)
|
|
149
|
+
except Exception as e:
|
|
150
|
+
result = {"success": False, "error": str(e)}
|
|
151
|
+
emit({"type": "done", "result": result})
|
|
152
|
+
return 0 if result.get("success") else 1
|
|
153
|
+
|
|
154
|
+
return asyncio.run(main())
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _token(out: TextIO) -> int:
|
|
158
|
+
"""stdin: an llms.json profile with auth: entra. Prints {token, expires_on} for its scope, or {error}."""
|
|
159
|
+
from .llm import entra_credential, entra_scope
|
|
160
|
+
|
|
161
|
+
line = sys.stdin.readline()
|
|
162
|
+
cfg = json.loads(line) if line.strip() else {}
|
|
163
|
+
try:
|
|
164
|
+
t = entra_credential(cfg).get_token(entra_scope(cfg))
|
|
165
|
+
out.write(json.dumps({"token": t.token, "expires_on": t.expires_on}) + "\n")
|
|
166
|
+
return 0
|
|
167
|
+
except Exception as e:
|
|
168
|
+
# The credential chain's message names every source it tried and why each failed; keep its first lines.
|
|
169
|
+
msg = " ".join(str(e).split("\n")[:6]).strip()
|
|
170
|
+
out.write(json.dumps({"error": f"{type(e).__name__}: {msg}"[:1500]}) + "\n")
|
|
171
|
+
return 1
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def main(argv: list[str] | None = None) -> int:
|
|
175
|
+
args = list(sys.argv[1:] if argv is None else argv)
|
|
176
|
+
out = _event_stream()
|
|
177
|
+
_configure_env()
|
|
178
|
+
cmd = args[0] if args else "run"
|
|
179
|
+
if cmd == "doctor":
|
|
180
|
+
return _doctor(out)
|
|
181
|
+
if cmd == "run":
|
|
182
|
+
return _run(out)
|
|
183
|
+
if cmd == "login":
|
|
184
|
+
return _login(out)
|
|
185
|
+
if cmd == "token":
|
|
186
|
+
return _token(out)
|
|
187
|
+
out.write(json.dumps({"type": "done", "result": {"success": False, "error": f"Unknown command {cmd}"}}) + "\n")
|
|
188
|
+
return 2
|