@huaqiu/dsh-eda-host 0.3.20 → 0.3.22
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/cordis.patch.yml +7 -4
- package/lib/index.d.mts +44 -6
- package/lib/index.mjs +40 -23
- package/package.json +2 -2
- package/src/client.ts +24 -1
- package/src/index.ts +60 -45
package/cordis.patch.yml
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# DSH bundle patch: inserts the Huaqiu EDA host netlist tool plugin.
|
|
2
|
-
# The entry inject
|
|
3
|
-
# export const inject)
|
|
4
|
-
#
|
|
2
|
+
# The entry `inject` MUST match the node-half module contract (`src/index.ts`
|
|
3
|
+
# `export const inject`): `hqEdge` + `tools`. `hqEdge` is REQUIRED — the
|
|
4
|
+
# edge-bridge (HOST) provides it and its `baseUrl` is the loopback HQ Edge
|
|
5
|
+
# endpoint the netlist tools fetch from (`createNodeHqEdge(upstreamRoot,…)` →
|
|
6
|
+
# `get baseUrl()`). Omitting `hqEdge` from inject makes `apply()`'s
|
|
7
|
+
# `ctx.hqEdge` access throw `cannot get property "hqEdge" without inject`.
|
|
5
8
|
- insert:
|
|
6
9
|
- id: huaqiu-dsh-eda-host
|
|
7
10
|
name: '@huaqiu/dsh-eda-host'
|
|
8
|
-
inject: ['tools']
|
|
11
|
+
inject: ['hqEdge', 'tools']
|
package/lib/index.d.mts
CHANGED
|
@@ -89,20 +89,58 @@ interface EdaHostClient {
|
|
|
89
89
|
//#region src/index.d.ts
|
|
90
90
|
/** Plugin id — matches package.json. */
|
|
91
91
|
declare const name = "@huaqiu/dsh-eda-host";
|
|
92
|
-
/**
|
|
93
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Cordis services this half depends on.
|
|
94
|
+
*
|
|
95
|
+
* `hqEdge` is REQUIRED: the edge-bridge (the HOST) provides the node-side
|
|
96
|
+
* `hqEdge` service whose `baseUrl` is the loopback HQ Edge endpoint
|
|
97
|
+
* (`createNodeHqEdge(upstreamRoot, …)` → `get baseUrl()`). Without it the
|
|
98
|
+
* plugin cannot reach hq-edge at all — by design it cannot work standalone
|
|
99
|
+
* (the user-confirmed contract is "eda-host cannot work without hqEdge").
|
|
100
|
+
* Declaring it here is what lets `apply()` read `ctx.hqEdge` without Cordis
|
|
101
|
+
* throwing `cannot get property "hqEdge" without inject` (its context proxy
|
|
102
|
+
* walks the fiber tree and throws at the root fiber when the service was
|
|
103
|
+
* never injected into this plugin's fiber).
|
|
104
|
+
*
|
|
105
|
+
* `tools` is the DSH node runtime tool registry used to register the netlist
|
|
106
|
+
* tools.
|
|
107
|
+
*/
|
|
108
|
+
declare const inject: readonly ["hqEdge", "tools"];
|
|
94
109
|
declare module '@deepseek-ai/cordis' {
|
|
95
110
|
interface Context {
|
|
96
111
|
edaHost: EdaHostClient;
|
|
112
|
+
/**
|
|
113
|
+
* Provided by the hq-edge `edge-bridge` plugin (the HOST). `baseUrl` is the
|
|
114
|
+
* loopback HQ Edge endpoint, e.g. "http://localhost:18080". We read it
|
|
115
|
+
* lazily so this plugin does not hard-depend on the bridge and still works
|
|
116
|
+
* in standalone DSH installs (where the service is absent).
|
|
117
|
+
*/
|
|
118
|
+
/**
|
|
119
|
+
* Provided by the hq-edge `edge-bridge` plugin (the HOST). `baseUrl` is the
|
|
120
|
+
* loopback HQ Edge endpoint, e.g. "http://localhost:18080". This is a
|
|
121
|
+
* REQUIRED inject (see `export const inject` above): `apply()` reads
|
|
122
|
+
* `ctx.hqEdge` to resolve the endpoint, so the service must be present or
|
|
123
|
+
* Cordis throws `cannot get property "hqEdge" without inject`. When present
|
|
124
|
+
* but its `baseUrl` is empty, the netlist tools degrade to a clear
|
|
125
|
+
* FAILED_PRECONDITION rather than throwing at load time.
|
|
126
|
+
*/
|
|
127
|
+
hqEdge: {
|
|
128
|
+
baseUrl?: string;
|
|
129
|
+
};
|
|
97
130
|
}
|
|
98
131
|
}
|
|
99
132
|
/**
|
|
100
133
|
* Host plugin body — provide `edaHost` and register the three netlist tools.
|
|
101
134
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
135
|
+
* The HQ Edge endpoint is resolved **lazily at request time** (see
|
|
136
|
+
* `getHqEdgeBaseUrl`): the edge-bridge plugin provides `ctx.hqEdge.baseUrl`,
|
|
137
|
+
* which wins over the static `config.hqEdgeBaseUrl` / `HQ_EDGE_BASE_URL` env
|
|
138
|
+
* fallback. This matches how `@huaqiu/dsh-artifacts` and `@huaqiu/dsh-tool-
|
|
139
|
+
* symbol-footprint` reach hq-edge, and means the URL is correct even when this
|
|
140
|
+
* plugin is applied before the bridge. When no host URL is available at call
|
|
141
|
+
* time, the tools degrade to a clear FAILED_PRECONDITION instead of throwing at
|
|
142
|
+
* load time — so the plugin still installs in standalone DSH where hq-edge is
|
|
143
|
+
* absent.
|
|
106
144
|
*
|
|
107
145
|
* @param ctx - real cordis context (node side).
|
|
108
146
|
* @returns disposer — unregisters the tools on plugin dispose.
|
package/lib/index.mjs
CHANGED
|
@@ -51,7 +51,12 @@ function statusToKind(status) {
|
|
|
51
51
|
function createEdaHostClient(config, deps = {}) {
|
|
52
52
|
const fetchImpl = deps.fetchImpl ?? globalThis.fetch;
|
|
53
53
|
async function fetchScope(scope) {
|
|
54
|
-
const
|
|
54
|
+
const baseUrl = deps.baseUrlResolver?.()?.trim() ?? config.hqEdgeBaseUrl?.trim() ?? "";
|
|
55
|
+
if (baseUrl.length === 0) throw new NetlistError("FAILED_PRECONDITION", "eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — netlist tools require the hq-edge EDA host bridge.");
|
|
56
|
+
const url = netlistUrlOf({
|
|
57
|
+
...config,
|
|
58
|
+
hqEdgeBaseUrl: baseUrl
|
|
59
|
+
}, scope);
|
|
55
60
|
let response;
|
|
56
61
|
try {
|
|
57
62
|
response = await fetchImpl(url, {
|
|
@@ -159,16 +164,36 @@ function createNetListTools(env) {
|
|
|
159
164
|
//#region src/index.ts
|
|
160
165
|
/** Plugin id — matches package.json. */
|
|
161
166
|
const name = "@huaqiu/dsh-eda-host";
|
|
162
|
-
/**
|
|
163
|
-
|
|
167
|
+
/**
|
|
168
|
+
* Cordis services this half depends on.
|
|
169
|
+
*
|
|
170
|
+
* `hqEdge` is REQUIRED: the edge-bridge (the HOST) provides the node-side
|
|
171
|
+
* `hqEdge` service whose `baseUrl` is the loopback HQ Edge endpoint
|
|
172
|
+
* (`createNodeHqEdge(upstreamRoot, …)` → `get baseUrl()`). Without it the
|
|
173
|
+
* plugin cannot reach hq-edge at all — by design it cannot work standalone
|
|
174
|
+
* (the user-confirmed contract is "eda-host cannot work without hqEdge").
|
|
175
|
+
* Declaring it here is what lets `apply()` read `ctx.hqEdge` without Cordis
|
|
176
|
+
* throwing `cannot get property "hqEdge" without inject` (its context proxy
|
|
177
|
+
* walks the fiber tree and throws at the root fiber when the service was
|
|
178
|
+
* never injected into this plugin's fiber).
|
|
179
|
+
*
|
|
180
|
+
* `tools` is the DSH node runtime tool registry used to register the netlist
|
|
181
|
+
* tools.
|
|
182
|
+
*/
|
|
183
|
+
const inject = ["hqEdge", "tools"];
|
|
164
184
|
const log = getLogger("dsh-eda-host");
|
|
165
185
|
/**
|
|
166
186
|
* Host plugin body — provide `edaHost` and register the three netlist tools.
|
|
167
187
|
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
188
|
+
* The HQ Edge endpoint is resolved **lazily at request time** (see
|
|
189
|
+
* `getHqEdgeBaseUrl`): the edge-bridge plugin provides `ctx.hqEdge.baseUrl`,
|
|
190
|
+
* which wins over the static `config.hqEdgeBaseUrl` / `HQ_EDGE_BASE_URL` env
|
|
191
|
+
* fallback. This matches how `@huaqiu/dsh-artifacts` and `@huaqiu/dsh-tool-
|
|
192
|
+
* symbol-footprint` reach hq-edge, and means the URL is correct even when this
|
|
193
|
+
* plugin is applied before the bridge. When no host URL is available at call
|
|
194
|
+
* time, the tools degrade to a clear FAILED_PRECONDITION instead of throwing at
|
|
195
|
+
* load time — so the plugin still installs in standalone DSH where hq-edge is
|
|
196
|
+
* absent.
|
|
172
197
|
*
|
|
173
198
|
* @param ctx - real cordis context (node side).
|
|
174
199
|
* @returns disposer — unregisters the tools on plugin dispose.
|
|
@@ -176,31 +201,23 @@ const log = getLogger("dsh-eda-host");
|
|
|
176
201
|
function apply(ctx, config = {}) {
|
|
177
202
|
if (!ctx.tools || typeof ctx.tools.register !== "function") throw new Error("@huaqiu/dsh-eda-host requires the DSH `tools` service (ctx.tools.register).");
|
|
178
203
|
const resolved = resolveEdaHostConfig(config);
|
|
204
|
+
const getHqEdgeBaseUrl = () => {
|
|
205
|
+
const hq = ctx.hqEdge;
|
|
206
|
+
return hq?.baseUrl && hq.baseUrl.trim().length > 0 ? hq.baseUrl : void 0;
|
|
207
|
+
};
|
|
179
208
|
log.info("applying dsh-eda-host node half", {
|
|
180
|
-
|
|
181
|
-
|
|
209
|
+
hasConfigHost: hasHost(resolved),
|
|
210
|
+
hqEdgeBaseUrlFromConfig: resolved.hqEdgeBaseUrl ?? null,
|
|
182
211
|
netlistPathPrefix: resolved.netlistPathPrefix
|
|
183
212
|
});
|
|
184
|
-
|
|
185
|
-
if (hasHost(resolved)) client = createEdaHostClient(resolved);
|
|
186
|
-
else client = {
|
|
187
|
-
getProjectNetlist: async () => {
|
|
188
|
-
throw new NetlistError("FAILED_PRECONDITION", "eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — netlist tools require the hq-edge EDA host bridge.");
|
|
189
|
-
},
|
|
190
|
-
getSelectionNetlist: async () => {
|
|
191
|
-
throw new NetlistError("FAILED_PRECONDITION", "eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — netlist tools require the hq-edge EDA host bridge.");
|
|
192
|
-
},
|
|
193
|
-
getActivePageNetlist: async () => {
|
|
194
|
-
throw new NetlistError("FAILED_PRECONDITION", "eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — netlist tools require the hq-edge EDA host bridge.");
|
|
195
|
-
}
|
|
196
|
-
};
|
|
213
|
+
const client = createEdaHostClient(resolved, { baseUrlResolver: getHqEdgeBaseUrl });
|
|
197
214
|
ctx.effect(() => ctx.provide("edaHost", client));
|
|
198
215
|
const tools = createNetListTools({ client });
|
|
199
216
|
const disposers = [];
|
|
200
217
|
for (const tool of tools) disposers.push(ctx.tools.register(tool));
|
|
201
218
|
log.info("dsh-eda-host node half ready", {
|
|
202
219
|
tools: 3,
|
|
203
|
-
|
|
220
|
+
configHostMode: hasHost(resolved)
|
|
204
221
|
});
|
|
205
222
|
return () => {
|
|
206
223
|
for (const dispose of disposers) try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huaqiu/dsh-eda-host",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.22",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./lib/index.mjs",
|
|
6
6
|
"types": "./lib/index.d.mts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@deepseek-ai/dsh-tools": "^0.1.0-rc.0"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@huaqiu/dsh-plugin-log": "0.3.
|
|
25
|
+
"@huaqiu/dsh-plugin-log": "0.3.22"
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
28
|
"lib",
|
package/src/client.ts
CHANGED
|
@@ -17,6 +17,16 @@ import {
|
|
|
17
17
|
|
|
18
18
|
export interface EdaHostClientDeps {
|
|
19
19
|
fetchImpl?: typeof fetch
|
|
20
|
+
/**
|
|
21
|
+
* Optional late-bound resolver for the HQ Edge base URL. When supplied it is
|
|
22
|
+
* consulted on EVERY request and takes priority over the static `config`
|
|
23
|
+
* value. This lets the node half read the endpoint from the `ctx.hqEdge`
|
|
24
|
+
* service the edge-bridge plugin provides — the same pattern `@huaqiu/
|
|
25
|
+
* dsh-artifacts` and `@huaqiu/dsh-tool-symbol-footprint` use — so the URL is
|
|
26
|
+
* picked up even if this plugin is applied before the bridge, and stays
|
|
27
|
+
* correct in standalone installs where no host is present.
|
|
28
|
+
*/
|
|
29
|
+
baseUrlResolver?: () => string | undefined
|
|
20
30
|
}
|
|
21
31
|
|
|
22
32
|
export interface EdaHostClient {
|
|
@@ -43,7 +53,20 @@ export function createEdaHostClient(
|
|
|
43
53
|
const fetchImpl = deps.fetchImpl ?? globalThis.fetch
|
|
44
54
|
|
|
45
55
|
async function fetchScope(scope: NetlistScope): Promise<SchematicNetlist> {
|
|
46
|
-
|
|
56
|
+
// Resolve the host endpoint per request. A resolver (ctx.hqEdge) wins over
|
|
57
|
+
// the static config/env value; if neither yields a URL we degrade to the
|
|
58
|
+
// same clear FAILED_PRECONDITION the standalone install path uses.
|
|
59
|
+
const baseUrl = deps.baseUrlResolver?.()?.trim()
|
|
60
|
+
?? config.hqEdgeBaseUrl?.trim()
|
|
61
|
+
?? ''
|
|
62
|
+
if (baseUrl.length === 0) {
|
|
63
|
+
throw new NetlistError(
|
|
64
|
+
'FAILED_PRECONDITION',
|
|
65
|
+
'eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — ' +
|
|
66
|
+
'netlist tools require the hq-edge EDA host bridge.',
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
const url = netlistUrlOf({ ...config, hqEdgeBaseUrl: baseUrl }, scope)
|
|
47
70
|
|
|
48
71
|
let response: Response
|
|
49
72
|
try {
|
package/src/index.ts
CHANGED
|
@@ -13,9 +13,12 @@
|
|
|
13
13
|
* This plugin owns DSH integration only: it translates tool calls into hq-edge
|
|
14
14
|
* requests and returns the semantic `SchematicNetlist`. It contains no
|
|
15
15
|
* KiCad-specific logic, no schematic parsing, and no host IPC. The plugin is
|
|
16
|
-
* self-contained — no `@hqedge/*` dependency
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* self-contained — no `@hqedge/*` dependency. The base URL is resolved at
|
|
17
|
+
* request time in this order: (1) the `ctx.hqEdge.baseUrl` service provided by
|
|
18
|
+
* the edge-bridge HOST (the loopback HQ Edge endpoint), then (2) the
|
|
19
|
+
* supervisor's overlay config (`hqEdgeBaseUrl`), then (3) `HQ_EDGE_BASE_URL`
|
|
20
|
+
* env fallback (same convention as `@huaqiu/dsh-auth`). `hqEdge` is a REQUIRED
|
|
21
|
+
* inject — the plugin cannot reach hq-edge without the bridge.
|
|
19
22
|
*
|
|
20
23
|
* @module @huaqiu/dsh-eda-host
|
|
21
24
|
*/
|
|
@@ -24,13 +27,27 @@ import { getLogger } from '@huaqiu/dsh-plugin-log'
|
|
|
24
27
|
import { createEdaHostClient, type EdaHostClient } from './client.js'
|
|
25
28
|
import { hasHost, resolveEdaHostConfig, type EdaHostConfig } from './config.js'
|
|
26
29
|
import { createNetListTools } from './tools.js'
|
|
27
|
-
import { NetlistError } from './types.js'
|
|
28
30
|
|
|
29
31
|
/** Plugin id — matches package.json. */
|
|
30
32
|
export const name = '@huaqiu/dsh-eda-host'
|
|
31
33
|
|
|
32
|
-
/**
|
|
33
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Cordis services this half depends on.
|
|
36
|
+
*
|
|
37
|
+
* `hqEdge` is REQUIRED: the edge-bridge (the HOST) provides the node-side
|
|
38
|
+
* `hqEdge` service whose `baseUrl` is the loopback HQ Edge endpoint
|
|
39
|
+
* (`createNodeHqEdge(upstreamRoot, …)` → `get baseUrl()`). Without it the
|
|
40
|
+
* plugin cannot reach hq-edge at all — by design it cannot work standalone
|
|
41
|
+
* (the user-confirmed contract is "eda-host cannot work without hqEdge").
|
|
42
|
+
* Declaring it here is what lets `apply()` read `ctx.hqEdge` without Cordis
|
|
43
|
+
* throwing `cannot get property "hqEdge" without inject` (its context proxy
|
|
44
|
+
* walks the fiber tree and throws at the root fiber when the service was
|
|
45
|
+
* never injected into this plugin's fiber).
|
|
46
|
+
*
|
|
47
|
+
* `tools` is the DSH node runtime tool registry used to register the netlist
|
|
48
|
+
* tools.
|
|
49
|
+
*/
|
|
50
|
+
export const inject = ['hqEdge', 'tools'] as const
|
|
34
51
|
|
|
35
52
|
export type { EdaHostConfig } from './config.js'
|
|
36
53
|
export type { EdaHostClient } from './client.js'
|
|
@@ -48,6 +65,22 @@ export { NetlistError } from './types.js'
|
|
|
48
65
|
declare module '@deepseek-ai/cordis' {
|
|
49
66
|
interface Context {
|
|
50
67
|
edaHost: EdaHostClient
|
|
68
|
+
/**
|
|
69
|
+
* Provided by the hq-edge `edge-bridge` plugin (the HOST). `baseUrl` is the
|
|
70
|
+
* loopback HQ Edge endpoint, e.g. "http://localhost:18080". We read it
|
|
71
|
+
* lazily so this plugin does not hard-depend on the bridge and still works
|
|
72
|
+
* in standalone DSH installs (where the service is absent).
|
|
73
|
+
*/
|
|
74
|
+
/**
|
|
75
|
+
* Provided by the hq-edge `edge-bridge` plugin (the HOST). `baseUrl` is the
|
|
76
|
+
* loopback HQ Edge endpoint, e.g. "http://localhost:18080". This is a
|
|
77
|
+
* REQUIRED inject (see `export const inject` above): `apply()` reads
|
|
78
|
+
* `ctx.hqEdge` to resolve the endpoint, so the service must be present or
|
|
79
|
+
* Cordis throws `cannot get property "hqEdge" without inject`. When present
|
|
80
|
+
* but its `baseUrl` is empty, the netlist tools degrade to a clear
|
|
81
|
+
* FAILED_PRECONDITION rather than throwing at load time.
|
|
82
|
+
*/
|
|
83
|
+
hqEdge: { baseUrl?: string }
|
|
51
84
|
}
|
|
52
85
|
}
|
|
53
86
|
|
|
@@ -58,10 +91,15 @@ const log = getLogger(COMPONENT)
|
|
|
58
91
|
/**
|
|
59
92
|
* Host plugin body — provide `edaHost` and register the three netlist tools.
|
|
60
93
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
94
|
+
* The HQ Edge endpoint is resolved **lazily at request time** (see
|
|
95
|
+
* `getHqEdgeBaseUrl`): the edge-bridge plugin provides `ctx.hqEdge.baseUrl`,
|
|
96
|
+
* which wins over the static `config.hqEdgeBaseUrl` / `HQ_EDGE_BASE_URL` env
|
|
97
|
+
* fallback. This matches how `@huaqiu/dsh-artifacts` and `@huaqiu/dsh-tool-
|
|
98
|
+
* symbol-footprint` reach hq-edge, and means the URL is correct even when this
|
|
99
|
+
* plugin is applied before the bridge. When no host URL is available at call
|
|
100
|
+
* time, the tools degrade to a clear FAILED_PRECONDITION instead of throwing at
|
|
101
|
+
* load time — so the plugin still installs in standalone DSH where hq-edge is
|
|
102
|
+
* absent.
|
|
65
103
|
*
|
|
66
104
|
* @param ctx - real cordis context (node side).
|
|
67
105
|
* @returns disposer — unregisters the tools on plugin dispose.
|
|
@@ -74,44 +112,21 @@ export function apply(ctx: Context, config: Partial<EdaHostConfig> = {}): () =>
|
|
|
74
112
|
}
|
|
75
113
|
|
|
76
114
|
const resolved = resolveEdaHostConfig(config)
|
|
115
|
+
|
|
116
|
+
// Late-bound host endpoint: prefer the edge-bridge service, then the overlay
|
|
117
|
+
// config / env value. Consulted on every request (see client.ts).
|
|
118
|
+
const getHqEdgeBaseUrl = (): string | undefined => {
|
|
119
|
+
const hq = ctx.hqEdge
|
|
120
|
+
return hq?.baseUrl && hq.baseUrl.trim().length > 0 ? hq.baseUrl : undefined
|
|
121
|
+
}
|
|
122
|
+
|
|
77
123
|
log.info('applying dsh-eda-host node half', {
|
|
78
|
-
|
|
79
|
-
|
|
124
|
+
hasConfigHost: hasHost(resolved),
|
|
125
|
+
hqEdgeBaseUrlFromConfig: resolved.hqEdgeBaseUrl ?? null,
|
|
80
126
|
netlistPathPrefix: resolved.netlistPathPrefix,
|
|
81
127
|
})
|
|
82
128
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (hasHost(resolved)) {
|
|
86
|
-
client = createEdaHostClient(resolved)
|
|
87
|
-
} else {
|
|
88
|
-
// Standalone install (no hq-edge supervisor): every scope degrades to
|
|
89
|
-
// FAILED_PRECONDITION with a clear message.
|
|
90
|
-
const unavailable: EdaHostClient = {
|
|
91
|
-
getProjectNetlist: async () => {
|
|
92
|
-
throw new NetlistError(
|
|
93
|
-
'FAILED_PRECONDITION',
|
|
94
|
-
'eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — ' +
|
|
95
|
-
'netlist tools require the hq-edge EDA host bridge.',
|
|
96
|
-
)
|
|
97
|
-
},
|
|
98
|
-
getSelectionNetlist: async () => {
|
|
99
|
-
throw new NetlistError(
|
|
100
|
-
'FAILED_PRECONDITION',
|
|
101
|
-
'eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — ' +
|
|
102
|
-
'netlist tools require the hq-edge EDA host bridge.',
|
|
103
|
-
)
|
|
104
|
-
},
|
|
105
|
-
getActivePageNetlist: async () => {
|
|
106
|
-
throw new NetlistError(
|
|
107
|
-
'FAILED_PRECONDITION',
|
|
108
|
-
'eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — ' +
|
|
109
|
-
'netlist tools require the hq-edge EDA host bridge.',
|
|
110
|
-
)
|
|
111
|
-
},
|
|
112
|
-
}
|
|
113
|
-
client = unavailable
|
|
114
|
-
}
|
|
129
|
+
const client = createEdaHostClient(resolved, { baseUrlResolver: getHqEdgeBaseUrl })
|
|
115
130
|
|
|
116
131
|
ctx.effect(() => ctx.provide('edaHost', client))
|
|
117
132
|
|
|
@@ -121,7 +136,7 @@ export function apply(ctx: Context, config: Partial<EdaHostConfig> = {}): () =>
|
|
|
121
136
|
disposers.push(ctx.tools.register(tool))
|
|
122
137
|
}
|
|
123
138
|
|
|
124
|
-
log.info('dsh-eda-host node half ready', { tools: 3,
|
|
139
|
+
log.info('dsh-eda-host node half ready', { tools: 3, configHostMode: hasHost(resolved) })
|
|
125
140
|
|
|
126
141
|
return () => {
|
|
127
142
|
for (const dispose of disposers) {
|