@harness-fe/webpack 4.0.0-next.4 → 4.0.0-next.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/README.md +6 -1
- package/dist/plugin.d.ts +2 -0
- package/dist/plugin.js +23 -2
- package/package.json +5 -2
- package/src/plugin.ts +22 -1
package/README.md
CHANGED
|
@@ -39,7 +39,12 @@ The plugin auto-disables in production builds — zero overhead in your shipped
|
|
|
39
39
|
|
|
40
40
|
## Options
|
|
41
41
|
|
|
42
|
-
Same as [`@harness-fe/vite`](https://www.npmjs.com/package/@harness-fe/vite). All bundler
|
|
42
|
+
Same as [`@harness-fe/vite`](https://www.npmjs.com/package/@harness-fe/vite) — including `projectId` / `mcpUrl` / `token` for [team mode](https://github.com/Morphicai/harness-fe/blob/main/docs/gateway-team-mode.md). All bundler plugins share the option surface via the underlying `unplugin`.
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
// team mode: report as a distinct project into a shared daemon
|
|
46
|
+
harnessFE({ projectId: 'my-app' })
|
|
47
|
+
```
|
|
43
48
|
|
|
44
49
|
## Docs
|
|
45
50
|
|
package/dist/plugin.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export declare class HarnessFEWebpackPlugin {
|
|
|
27
27
|
private projectRoot;
|
|
28
28
|
private projectId;
|
|
29
29
|
private readonly mcpUrl;
|
|
30
|
+
private readonly baseMcpUrl;
|
|
30
31
|
private readonly token;
|
|
31
32
|
private mcpClient?;
|
|
32
33
|
private logCleanup?;
|
|
@@ -35,6 +36,7 @@ export declare class HarnessFEWebpackPlugin {
|
|
|
35
36
|
apply(compiler: any): void;
|
|
36
37
|
private installRuntimeEntry;
|
|
37
38
|
private installMcpHooks;
|
|
39
|
+
private ensureSharedGateway;
|
|
38
40
|
private installComponentMapAggregator;
|
|
39
41
|
private installHtmlInjection;
|
|
40
42
|
private installErrorForwarding;
|
package/dist/plugin.js
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
import { createRequire } from 'node:module';
|
|
24
24
|
import { fileURLToPath } from 'node:url';
|
|
25
25
|
import { dirname, resolve as resolvePath } from 'node:path';
|
|
26
|
-
import { createMcpClient, createBuildIdentity, installNodeLogCapture, appendTokenQuery, } from '@harness-fe/unplugin';
|
|
26
|
+
import { createMcpClient, createBuildIdentity, installNodeLogCapture, appendTokenQuery, resolveSoloTarget, } from '@harness-fe/unplugin';
|
|
27
27
|
import { DEFAULT_WS_PORT } from '@harness-fe/protocol';
|
|
28
28
|
import { getOrCreateComponentMap } from './shared-state.js';
|
|
29
29
|
const require = createRequire(import.meta.url);
|
|
@@ -41,6 +41,7 @@ export class HarnessFEWebpackPlugin {
|
|
|
41
41
|
projectRoot = process.cwd();
|
|
42
42
|
projectId;
|
|
43
43
|
mcpUrl;
|
|
44
|
+
baseMcpUrl;
|
|
44
45
|
token;
|
|
45
46
|
mcpClient;
|
|
46
47
|
logCleanup;
|
|
@@ -54,6 +55,7 @@ export class HarnessFEWebpackPlugin {
|
|
|
54
55
|
const baseUrl = options.mcpUrl ??
|
|
55
56
|
process.env.HARNESS_FE_URL ??
|
|
56
57
|
`ws://127.0.0.1:${DEFAULT_WS_PORT}`;
|
|
58
|
+
this.baseMcpUrl = baseUrl;
|
|
57
59
|
this.token = options.token ?? process.env.HARNESS_FE_TOKEN;
|
|
58
60
|
this.mcpUrl = appendTokenQuery(baseUrl, this.token);
|
|
59
61
|
this.identity = createBuildIdentity({
|
|
@@ -144,8 +146,18 @@ export class HarnessFEWebpackPlugin {
|
|
|
144
146
|
compiler.hooks.afterEnvironment.tap('harness-fe', () => {
|
|
145
147
|
const client = createMcpClient(ctx);
|
|
146
148
|
this.mcpClient = client;
|
|
147
|
-
client.connect();
|
|
148
149
|
this.logCleanup = installNodeLogCapture((name, payload) => client.emitEvent(name, payload));
|
|
150
|
+
// Solo (loopback + no token): ensure a shared local gateway is up, then
|
|
151
|
+
// connect. afterEnvironment is sync, so fire-and-forget and connect once
|
|
152
|
+
// the gateway answers (best-effort — if @harness-fe/cli isn't installed
|
|
153
|
+
// we just connect and let the client retry). Team never auto-spawns.
|
|
154
|
+
const solo = resolveSoloTarget(this.baseMcpUrl, Boolean(this.token));
|
|
155
|
+
if (solo) {
|
|
156
|
+
void this.ensureSharedGateway(solo).finally(() => client.connect());
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
client.connect();
|
|
160
|
+
}
|
|
149
161
|
});
|
|
150
162
|
compiler.hooks.shutdown?.tap('harness-fe', () => {
|
|
151
163
|
this.logCleanup?.();
|
|
@@ -154,6 +166,15 @@ export class HarnessFEWebpackPlugin {
|
|
|
154
166
|
this.mcpClient = undefined;
|
|
155
167
|
});
|
|
156
168
|
}
|
|
169
|
+
async ensureSharedGateway(target) {
|
|
170
|
+
try {
|
|
171
|
+
const { ensureSharedGateway } = await import('@harness-fe/cli/sharedGateway');
|
|
172
|
+
await ensureSharedGateway({ host: target.host, port: target.port });
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
/* @harness-fe/cli not installed, or gateway slow — client.connect() retries */
|
|
176
|
+
}
|
|
177
|
+
}
|
|
157
178
|
installComponentMapAggregator(compiler) {
|
|
158
179
|
const pluginId = this.pluginId;
|
|
159
180
|
compiler.hooks.compilation.tap('harness-fe', (compilation) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@harness-fe/webpack",
|
|
3
|
-
"version": "4.0.0-next.
|
|
3
|
+
"version": "4.0.0-next.5",
|
|
4
4
|
"description": "Native webpack plugin for Harness-FE: source-aware transforms, runtime injection, and MCP bridge. thread-loader compatible.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,7 +33,10 @@
|
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@harness-fe/protocol": "4.0.0-next.4",
|
|
36
|
-
"@harness-fe/unplugin": "4.0.0-next.
|
|
36
|
+
"@harness-fe/unplugin": "4.0.0-next.5"
|
|
37
|
+
},
|
|
38
|
+
"optionalDependencies": {
|
|
39
|
+
"@harness-fe/cli": "4.0.0-next.5"
|
|
37
40
|
},
|
|
38
41
|
"peerDependencies": {
|
|
39
42
|
"webpack": "^5.0.0"
|
package/src/plugin.ts
CHANGED
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
createBuildIdentity,
|
|
30
30
|
installNodeLogCapture,
|
|
31
31
|
appendTokenQuery,
|
|
32
|
+
resolveSoloTarget,
|
|
32
33
|
type ComponentLocation,
|
|
33
34
|
type HarnessFEOptions,
|
|
34
35
|
type McpClient,
|
|
@@ -59,6 +60,7 @@ export class HarnessFEWebpackPlugin {
|
|
|
59
60
|
private projectRoot: string = process.cwd();
|
|
60
61
|
private projectId: string;
|
|
61
62
|
private readonly mcpUrl: string;
|
|
63
|
+
private readonly baseMcpUrl: string;
|
|
62
64
|
private readonly token: string | undefined;
|
|
63
65
|
private mcpClient?: McpClient;
|
|
64
66
|
private logCleanup?: () => void;
|
|
@@ -74,6 +76,7 @@ export class HarnessFEWebpackPlugin {
|
|
|
74
76
|
options.mcpUrl ??
|
|
75
77
|
process.env.HARNESS_FE_URL ??
|
|
76
78
|
`ws://127.0.0.1:${DEFAULT_WS_PORT}`;
|
|
79
|
+
this.baseMcpUrl = baseUrl;
|
|
77
80
|
this.token = options.token ?? process.env.HARNESS_FE_TOKEN;
|
|
78
81
|
this.mcpUrl = appendTokenQuery(baseUrl, this.token);
|
|
79
82
|
this.identity = createBuildIdentity({
|
|
@@ -174,8 +177,17 @@ export class HarnessFEWebpackPlugin {
|
|
|
174
177
|
compiler.hooks.afterEnvironment.tap('harness-fe', () => {
|
|
175
178
|
const client = createMcpClient(ctx);
|
|
176
179
|
this.mcpClient = client;
|
|
177
|
-
client.connect();
|
|
178
180
|
this.logCleanup = installNodeLogCapture((name, payload) => client.emitEvent(name, payload));
|
|
181
|
+
// Solo (loopback + no token): ensure a shared local gateway is up, then
|
|
182
|
+
// connect. afterEnvironment is sync, so fire-and-forget and connect once
|
|
183
|
+
// the gateway answers (best-effort — if @harness-fe/cli isn't installed
|
|
184
|
+
// we just connect and let the client retry). Team never auto-spawns.
|
|
185
|
+
const solo = resolveSoloTarget(this.baseMcpUrl, Boolean(this.token));
|
|
186
|
+
if (solo) {
|
|
187
|
+
void this.ensureSharedGateway(solo).finally(() => client.connect());
|
|
188
|
+
} else {
|
|
189
|
+
client.connect();
|
|
190
|
+
}
|
|
179
191
|
});
|
|
180
192
|
|
|
181
193
|
compiler.hooks.shutdown?.tap('harness-fe', () => {
|
|
@@ -186,6 +198,15 @@ export class HarnessFEWebpackPlugin {
|
|
|
186
198
|
});
|
|
187
199
|
}
|
|
188
200
|
|
|
201
|
+
private async ensureSharedGateway(target: { host: string; port: number }): Promise<void> {
|
|
202
|
+
try {
|
|
203
|
+
const { ensureSharedGateway } = await import('@harness-fe/cli/sharedGateway');
|
|
204
|
+
await ensureSharedGateway({ host: target.host, port: target.port });
|
|
205
|
+
} catch {
|
|
206
|
+
/* @harness-fe/cli not installed, or gateway slow — client.connect() retries */
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
189
210
|
private installComponentMapAggregator(compiler: any): void {
|
|
190
211
|
const pluginId = this.pluginId;
|
|
191
212
|
compiler.hooks.compilation.tap('harness-fe', (compilation: any) => {
|