@aion0/forge 0.10.87 → 0.10.88
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/RELEASE_NOTES.md +3 -9
- package/bin/forge-server.mjs +11 -0
- package/instrumentation.ts +2 -0
- package/lib/browser-bridge-standalone.ts +1 -0
- package/lib/chat/protocols/http.ts +16 -4
- package/lib/chat-standalone.ts +1 -0
- package/lib/connectors/test-runner.ts +8 -2
- package/lib/help-docs/10-troubleshooting.md +13 -0
- package/lib/memory-standalone.ts +2 -0
- package/lib/proxy-setup.ts +21 -0
- package/lib/telegram-standalone.ts +1 -0
- package/lib/terminal-standalone.ts +1 -0
- package/lib/workspace-standalone.ts +1 -0
- package/package.json +1 -1
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
# Forge v0.10.
|
|
1
|
+
# Forge v0.10.88
|
|
2
2
|
|
|
3
3
|
Released: 2026-06-17
|
|
4
4
|
|
|
5
|
-
## Changes since v0.10.
|
|
5
|
+
## Changes since v0.10.87
|
|
6
6
|
|
|
7
|
-
### Other
|
|
8
|
-
- feat(pipeline): log attached skills in task init line
|
|
9
|
-
- feat(skills): per-skill source badge in marketplace (#354)
|
|
10
|
-
- feat(skills): multi-source sync + install (enterprise + public) — #354
|
|
11
|
-
- feat(pipeline): workflow-level skills: field + template _skills auto-install
|
|
12
7
|
|
|
13
|
-
|
|
14
|
-
**Full Changelog**: https://github.com/aiwatching/forge/compare/v0.10.86...v0.10.87
|
|
8
|
+
**Full Changelog**: https://github.com/aiwatching/forge/compare/v0.10.87...v0.10.88
|
package/bin/forge-server.mjs
CHANGED
|
@@ -28,6 +28,17 @@ import { homedir } from 'node:os';
|
|
|
28
28
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
29
29
|
const ROOT = join(__dirname, '..');
|
|
30
30
|
|
|
31
|
+
// Pre-install EnvHttpProxyAgent before any dynamic import('undici') can
|
|
32
|
+
// clobber Node's NODE_USE_ENV_PROXY agent (see lib/proxy-setup.ts).
|
|
33
|
+
// No-op off-corp (no proxy env), so non-docker deployments are unchanged.
|
|
34
|
+
if (process.env.HTTPS_PROXY || process.env.HTTP_PROXY ||
|
|
35
|
+
process.env.https_proxy || process.env.http_proxy) {
|
|
36
|
+
try {
|
|
37
|
+
const { setGlobalDispatcher, EnvHttpProxyAgent } = await import('undici');
|
|
38
|
+
setGlobalDispatcher(new EnvHttpProxyAgent());
|
|
39
|
+
} catch { /* undici unavailable — leave Node's default dispatcher */ }
|
|
40
|
+
}
|
|
41
|
+
|
|
31
42
|
/** Build Next.js — install devDependencies first if missing */
|
|
32
43
|
function buildNext() {
|
|
33
44
|
// Check if devDependencies are installed (e.g. @tailwindcss/postcss)
|
package/instrumentation.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Next.js instrumentation — runs once when the server starts.
|
|
3
3
|
* Loads .env.local and prints login password.
|
|
4
4
|
*/
|
|
5
|
+
import './lib/proxy-setup'; // MUST be first — see proxy-setup.ts header.
|
|
6
|
+
|
|
5
7
|
export async function register() {
|
|
6
8
|
// Only run on server, not Edge
|
|
7
9
|
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
* Usage: npx tsx lib/browser-bridge-standalone.ts [--forge-port=8403]
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
|
+
import './proxy-setup'; // MUST be first — see proxy-setup.ts header.
|
|
42
43
|
import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';
|
|
43
44
|
import { WebSocket, WebSocketServer } from 'ws';
|
|
44
45
|
import { randomUUID, createHash } from 'node:crypto';
|
|
@@ -241,8 +241,14 @@ async function exchangeBearerToken(
|
|
|
241
241
|
const exchangeFetchInit = { method: auth.exchange_method || 'POST', headers, body };
|
|
242
242
|
let res: Response;
|
|
243
243
|
if (verifyTls === false) {
|
|
244
|
-
|
|
245
|
-
|
|
244
|
+
// Per-call dispatcher bypasses the global proxy agent — route via
|
|
245
|
+
// ProxyAgent when a proxy is set (corp), else plain Agent (direct).
|
|
246
|
+
const { fetch: undiciFetch, Agent, ProxyAgent } = await import('undici');
|
|
247
|
+
const proxyUrl = process.env.HTTPS_PROXY || process.env.https_proxy ||
|
|
248
|
+
process.env.HTTP_PROXY || process.env.http_proxy;
|
|
249
|
+
const dispatcher = proxyUrl
|
|
250
|
+
? new ProxyAgent({ uri: proxyUrl, requestTls: { rejectUnauthorized: false } })
|
|
251
|
+
: new Agent({ connect: { rejectUnauthorized: false } });
|
|
246
252
|
res = await undiciFetch(exchangeUrl, { ...exchangeFetchInit, dispatcher }) as unknown as Response;
|
|
247
253
|
} else {
|
|
248
254
|
res = await fetch(exchangeUrl, exchangeFetchInit);
|
|
@@ -488,8 +494,14 @@ export async function runHttp({ tool, settings, args, connectorAuth, noTruncatio
|
|
|
488
494
|
// fetch are version-matched; passing an external undici Agent
|
|
489
495
|
// into Node's bundled global fetch fails with UND_ERR_INVALID_ARG
|
|
490
496
|
// because Node 22 ships an older undici than the installed one.
|
|
491
|
-
|
|
492
|
-
|
|
497
|
+
// Per-call dispatcher bypasses the global proxy agent — route via
|
|
498
|
+
// ProxyAgent when a proxy is set (corp), else plain Agent (direct).
|
|
499
|
+
const { fetch: undiciFetch, Agent, ProxyAgent } = await import('undici');
|
|
500
|
+
const proxyUrl = process.env.HTTPS_PROXY || process.env.https_proxy ||
|
|
501
|
+
process.env.HTTP_PROXY || process.env.http_proxy;
|
|
502
|
+
const dispatcher = proxyUrl
|
|
503
|
+
? new ProxyAgent({ uri: proxyUrl, requestTls: { rejectUnauthorized: false } })
|
|
504
|
+
: new Agent({ connect: { rejectUnauthorized: false } });
|
|
493
505
|
res = await undiciFetch(url, { method, headers, body, signal: controller.signal, dispatcher }) as unknown as Response;
|
|
494
506
|
} else {
|
|
495
507
|
res = await fetch(url, { method, headers, body, signal: controller.signal });
|
package/lib/chat-standalone.ts
CHANGED
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
* keep their existing WS path; HTTP-only surfaces use SSE.
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
+
import './proxy-setup'; // MUST be first — see proxy-setup.ts header.
|
|
33
34
|
import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';
|
|
34
35
|
import {
|
|
35
36
|
createSession, getSession, listSessions, updateSession, deleteSession, listMessages,
|
|
@@ -134,8 +134,14 @@ async function runHttpProbe(
|
|
|
134
134
|
// NAC, ESXi …) need undici with rejectUnauthorized:false, same as http.ts.
|
|
135
135
|
const fetchInit = { method, headers, body, signal: ctrl.signal };
|
|
136
136
|
if (def.http?.verify_tls === false) {
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
// A per-call dispatcher bypasses the global proxy agent, so when a proxy
|
|
138
|
+
// is set (corp) route through ProxyAgent; else plain Agent (direct).
|
|
139
|
+
const { fetch: undiciFetch, Agent, ProxyAgent } = await import('undici');
|
|
140
|
+
const proxyUrl = process.env.HTTPS_PROXY || process.env.https_proxy ||
|
|
141
|
+
process.env.HTTP_PROXY || process.env.http_proxy;
|
|
142
|
+
const dispatcher = proxyUrl
|
|
143
|
+
? new ProxyAgent({ uri: proxyUrl, requestTls: { rejectUnauthorized: false } })
|
|
144
|
+
: new Agent({ connect: { rejectUnauthorized: false } });
|
|
139
145
|
res = await undiciFetch(url, { ...fetchInit, dispatcher } as any) as unknown as Response;
|
|
140
146
|
} else {
|
|
141
147
|
res = await fetch(url, fetchInit);
|
|
@@ -76,6 +76,19 @@ The WebSocket dropped (system suspend, network blip). Forge auto-reconnects afte
|
|
|
76
76
|
gh auth login
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
+
### Connector Test fails with `ENETUNREACH` behind a corp proxy
|
|
80
|
+
Symptom: a brand-new deployment behind a corporate proxy/ZTNA, configure a
|
|
81
|
+
connector (e.g. GitLab) → **Test** → `request failed: fetch failed: connect
|
|
82
|
+
ENETUNREACH <backend-ip>:443`.
|
|
83
|
+
|
|
84
|
+
Forge honours `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY` automatically — every
|
|
85
|
+
entry point pre-installs an `EnvHttpProxyAgent` before any code makes a request,
|
|
86
|
+
so a proxy set in the environment is used for all connector calls (including
|
|
87
|
+
`verify_tls: false` self-signed appliances like FortiNAC). Just make sure the
|
|
88
|
+
proxy env vars are exported for the Forge process (in Docker, via the
|
|
89
|
+
container's environment). Off-corp deployments with no proxy env are unaffected
|
|
90
|
+
— requests go direct as before.
|
|
91
|
+
|
|
79
92
|
### Skills not syncing
|
|
80
93
|
Click "Sync" in Skills tab. Check `skillsRepoUrl` in Settings points to valid registry.
|
|
81
94
|
|
package/lib/memory-standalone.ts
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-install an EnvHttpProxyAgent on undici's global dispatcher BEFORE
|
|
3
|
+
* anything dynamic-imports the npm undici (8.x).
|
|
4
|
+
*
|
|
5
|
+
* Why: Node honours NODE_USE_ENV_PROXY by putting EnvHttpProxyAgent on
|
|
6
|
+
* undici v1's dispatcher symbol. The npm undici uses v2; on load its
|
|
7
|
+
* `if (getGlobalDispatcher() === undefined) setGlobalDispatcher(new Agent())`
|
|
8
|
+
* reads v2 (undefined) and writes a plain Agent into BOTH v1 and v2,
|
|
9
|
+
* silently clobbering Node's proxy agent — after which every fetch ignores
|
|
10
|
+
* HTTPS_PROXY and direct-connects (ENETUNREACH behind corp ZTNA).
|
|
11
|
+
* Setting v2 here makes that check non-undefined, so npm undici skips it.
|
|
12
|
+
*
|
|
13
|
+
* MUST be the FIRST import in every entry point. Off-corp (no proxy env)
|
|
14
|
+
* this is a no-op, so non-docker / standalone deployments are unchanged.
|
|
15
|
+
*/
|
|
16
|
+
import { setGlobalDispatcher, EnvHttpProxyAgent } from 'undici';
|
|
17
|
+
|
|
18
|
+
if (process.env.HTTPS_PROXY || process.env.HTTP_PROXY ||
|
|
19
|
+
process.env.https_proxy || process.env.http_proxy) {
|
|
20
|
+
setGlobalDispatcher(new EnvHttpProxyAgent());
|
|
21
|
+
}
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
* Usage: npx tsx lib/terminal-standalone.ts
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
+
import './proxy-setup'; // MUST be first — see proxy-setup.ts header.
|
|
27
28
|
import { WebSocketServer, WebSocket } from 'ws';
|
|
28
29
|
import * as pty from 'node-pty';
|
|
29
30
|
import { execSync } from 'node:child_process';
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* FORGE_DATA_DIR — data directory
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
+
import './proxy-setup'; // MUST be first — see proxy-setup.ts header.
|
|
15
16
|
import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';
|
|
16
17
|
import { readdirSync, statSync } from 'node:fs';
|
|
17
18
|
import { join, resolve } from 'node:path';
|
package/package.json
CHANGED