@harness-fe/webpack 4.0.0-next.0 → 4.0.0-next.11

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 MorphixAI
3
+ Copyright (c) 2026 MorphixAI
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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-specific plugins share the same option surface via the underlying `unplugin`.
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.0",
3
+ "version": "4.0.0-next.11",
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",
@@ -32,8 +32,11 @@
32
32
  "LICENSE"
33
33
  ],
34
34
  "dependencies": {
35
- "@harness-fe/protocol": "4.0.0-next.0",
36
- "@harness-fe/unplugin": "4.0.0-next.0"
35
+ "@harness-fe/protocol": "4.0.0-next.8",
36
+ "@harness-fe/unplugin": "4.0.0-next.11"
37
+ },
38
+ "optionalDependencies": {
39
+ "@harness-fe/cli": "4.0.0-next.11"
37
40
  },
38
41
  "peerDependencies": {
39
42
  "webpack": "^5.0.0"
@@ -41,7 +44,7 @@
41
44
  "devDependencies": {
42
45
  "typescript": "^5.6.0",
43
46
  "vitest": "^2.1.9",
44
- "webpack": "^5.107.0"
47
+ "webpack": "^5.107.2"
45
48
  },
46
49
  "publishConfig": {
47
50
  "access": "public"
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) => {