dsh-xdpool 2.1.0 → 2.1.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/CHANGELOG.md +1012 -994
- package/README.en.md +7 -3
- package/README.md +7 -3
- package/assets/account-credits.png +0 -0
- package/cordis.patch.yml +48 -49
- package/lib/bin.js +37 -5
- package/lib/client.js +12 -4
- package/lib/index.js +55 -17
- package/package.json +137 -137
- package/screenshots.json +1 -1
- package/assets/settings-card.png +0 -0
package/README.en.md
CHANGED
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<a href="https://www.npmjs.com/package/dsh-xdpool"><img src="https://img.shields.io/npm/v/dsh-xdpool?style=flat-square&label=npm&color=cb3837" alt="npm version"></a>
|
|
5
|
-
<a href="https://www.npmjs.com/package/dsh-xdpool"><img src="https://img.shields.io/
|
|
5
|
+
<a href="https://www.npmjs.com/package/dsh-workbuddy-xdpool"><img src="https://img.shields.io/badge/downloads-9k%2Fmo%20%28prev%20name%29-cb3837?style=flat-square" alt="npm downloads under the previous name"></a>
|
|
6
6
|
<a href="LICENSE"><img src="https://img.shields.io/github/license/XDTrees/dsh-xdpool?style=flat-square" alt="MIT license"></a>
|
|
7
7
|
<a href="https://github.com/XDTrees/dsh-xdpool/stargazers"><img src="https://img.shields.io/github/stars/XDTrees/dsh-xdpool?style=flat-square" alt="GitHub stars"></a>
|
|
8
8
|
</p>
|
|
9
9
|
|
|
10
|
+
<p align="center">
|
|
11
|
+
<sub>Download stats still come from the previous package name <code>dsh-workbuddy-xdpool</code> (8,976/month as of 2026-10-12 — every download before the rename; the live shields badge kept getting rate-limited by the npm upstream, hence the snapshot figure). The new <code>dsh-xdpool</code> package accumulates its own stats, and the badge switches back to live data later.</sub>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
10
14
|
English | [中文](./README.md)
|
|
11
15
|
|
|
12
16
|
**Every free model quota you can get your hands on, wired into one DSH model pool.**
|
|
@@ -46,9 +50,9 @@ Then it grew into seven pages. Beyond the account pool: sign in to thirteen vend
|
|
|
46
50
|
|
|
47
51
|

|
|
48
52
|
|
|
49
|
-
**
|
|
53
|
+
**Account credit detail (a pool account: credit packages, streak, today's check-in, the credit reserve)**
|
|
50
54
|
|
|
51
|
-

|
|
52
56
|
|
|
53
57
|
**The points-automation panel**
|
|
54
58
|
|
package/README.md
CHANGED
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<a href="https://www.npmjs.com/package/dsh-xdpool"><img src="https://img.shields.io/npm/v/dsh-xdpool?style=flat-square&label=npm&color=cb3837" alt="npm version"></a>
|
|
5
|
-
<a href="https://www.npmjs.com/package/dsh-xdpool"><img src="https://img.shields.io/
|
|
5
|
+
<a href="https://www.npmjs.com/package/dsh-workbuddy-xdpool"><img src="https://img.shields.io/badge/downloads-9k%2F%E6%9C%88%20%28%E6%97%A7%E5%90%8D%29-cb3837?style=flat-square" alt="npm downloads under the previous name"></a>
|
|
6
6
|
<a href="LICENSE"><img src="https://img.shields.io/github/license/XDTrees/dsh-xdpool?style=flat-square" alt="MIT license"></a>
|
|
7
7
|
<a href="https://github.com/XDTrees/dsh-xdpool/stargazers"><img src="https://img.shields.io/github/stars/XDTrees/dsh-xdpool?style=flat-square" alt="GitHub stars"></a>
|
|
8
8
|
</p>
|
|
9
9
|
|
|
10
|
+
<p align="center">
|
|
11
|
+
<sub>下载量统计沿用旧包名 <code>dsh-workbuddy-xdpool</code>(截至 2026-10-12 为 8,976 次/月,改名前的全部下载;shields 的实时徽章常被 npm 上游限流,所以这里用了快照数字)。新包 <code>dsh-xdpool</code> 的统计会随时间累积,之后徽章会换回实时数据。</sub>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
10
14
|
[English](./README.en.md) | 中文
|
|
11
15
|
|
|
12
16
|
**把你手上所有能白嫖的模型额度,接进 DSH 的同一个模型池。**
|
|
@@ -46,9 +50,9 @@
|
|
|
46
50
|
|
|
47
51
|

|
|
48
52
|
|
|
49
|
-
|
|
53
|
+
**账号积分详情(池中账号:积分包、连签天数、今日已签、保留积分)**
|
|
50
54
|
|
|
51
|
-

|
|
52
56
|
|
|
53
57
|
**积分自动化面板**
|
|
54
58
|
|
|
Binary file
|
package/cordis.patch.yml
CHANGED
|
@@ -1,49 +1,48 @@
|
|
|
1
|
-
# Register the
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
- insert:
|
|
5
|
-
- id: llm-xdpool
|
|
6
|
-
name: dsh-xdpool
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
# from
|
|
47
|
-
-
|
|
48
|
-
|
|
49
|
-
name: billion-context
|
|
1
|
+
# Register the XD Pool provider. Discovery is read-only: the plugin reuses the
|
|
2
|
+
# WorkBuddy desktop app's own sign-in files and never starts a separate OAuth
|
|
3
|
+
# flow. Requests rotate across every discovered account.
|
|
4
|
+
- insert:
|
|
5
|
+
- id: llm-xdpool
|
|
6
|
+
name: dsh-xdpool
|
|
7
|
+
# billion-context is deliberately NOT mounted by this layer.
|
|
8
|
+
#
|
|
9
|
+
# 2.0.0 tried to. It inserted a row (`billion-context-xdpool`) so a profile that
|
|
10
|
+
# had not installed the compressor would get one for free, and `src/billion-mount.ts`
|
|
11
|
+
# held a runtime `create()` as a second path for the same job. Measured against a
|
|
12
|
+
# profile that had ALREADY installed billion-context — which is the normal state
|
|
13
|
+
# for anyone using that feature, since `bili-native` comes from billion-context's
|
|
14
|
+
# own `dsh.bundle.patch.yml` — neither safeguard held:
|
|
15
|
+
#
|
|
16
|
+
# the host did not disable our duplicate row, and it did not resolve it to a
|
|
17
|
+
# no-op. It left `enabled: true` and ran the fiber to `failed`, because
|
|
18
|
+
# billion-context registers a cordis service under its own name and a second
|
|
19
|
+
# registration is refused outright (`service "…" has been registered at <…>`).
|
|
20
|
+
#
|
|
21
|
+
# So every user who had installed billion-context got a permanently failed entry
|
|
22
|
+
# in their plugin list — visible, unexplained, and pointing at us.
|
|
23
|
+
#
|
|
24
|
+
# The row below is kept, but DISABLED, for three reasons:
|
|
25
|
+
#
|
|
26
|
+
# 1. Addressability. `disabled: true` keeps the row's id resolvable, so a
|
|
27
|
+
# profile that wants to flip it on can do so with one edit instead of
|
|
28
|
+
# inventing a row.
|
|
29
|
+
# 2. It states the decision where the old attempt lived, where the next person
|
|
30
|
+
# to wonder "why doesn't the pool bring up the compressor?" will look.
|
|
31
|
+
# 3. It keeps `bili-native` (billion-context's own row) as the ONLY mount of
|
|
32
|
+
# that module, which is the arrangement that actually works.
|
|
33
|
+
#
|
|
34
|
+
# CONSEQUENCE, STATED PLAINLY
|
|
35
|
+
#
|
|
36
|
+
# A profile that has not installed billion-context sees the billion card report
|
|
37
|
+
# "not installed". That is the honest reading of the facts, and it is already a
|
|
38
|
+
# first-class state on that page — the page distinguishes not-installed from
|
|
39
|
+
# no-answer from ready precisely so this case reads as information rather than
|
|
40
|
+
# as a bug. Installing billion-context remains a decision the user makes; the
|
|
41
|
+
# pool no longer makes it for them.
|
|
42
|
+
#
|
|
43
|
+
# `src/billion-mount.ts` no longer calls `create()` for the same reason: with
|
|
44
|
+
# this row disabled, a runtime create would fight the very row it sits beside.
|
|
45
|
+
# The function still runs — it is what lets the card distinguish
|
|
46
|
+
# already-installed from not-installed — it just never mounts anything.
|
|
47
|
+
- id: billion-context-xdpool
|
|
48
|
+
disabled: true
|
package/lib/bin.js
CHANGED
|
@@ -224,6 +224,34 @@ function chatHeaders(credential) {
|
|
|
224
224
|
"X-Product": "SaaS"
|
|
225
225
|
};
|
|
226
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* The client-identity headers the desktop app puts on every chat completion.
|
|
229
|
+
*
|
|
230
|
+
* WHY THESE EXIST AND WHY THEY BELONG ON /v2/chat/completions ONLY
|
|
231
|
+
*
|
|
232
|
+
* The gateway attributes each request to a client, and that attribution is what
|
|
233
|
+
* surfaces in the user's billing console as the "使用端" column. The desktop app
|
|
234
|
+
* (`buildVlmGatewayHeaders` in its bundled `main/server.js`) sends
|
|
235
|
+
* `X-IDE-Type`/`X-IDE-Name`/`X-IDE-Version` on every `/v2/chat/completions`, so
|
|
236
|
+
* its traffic reads as "WorkBuddy". Our chat requests sent none of them, so the
|
|
237
|
+
* same spend attributed to nothing — the column showed "–" and the user's
|
|
238
|
+
* billing page looked like the requests had come from nowhere.
|
|
239
|
+
*
|
|
240
|
+
* They are deliberately NOT part of `chatHeaders()`, which is shared with the
|
|
241
|
+
* points-automation endpoints (`listTasks` / `acceptTasks`). Those are not chat
|
|
242
|
+
* completions, and the evidence for the desktop app sending identity headers on
|
|
243
|
+
* them is nil — adding identity headers to an endpoint that never carried them
|
|
244
|
+
* risks changing how that traffic is attributed or filtered, and the automation
|
|
245
|
+
* was never reported broken. Only the two chat completions get these.
|
|
246
|
+
*
|
|
247
|
+
* The version is the same literal `openConversation()` already sends, so both
|
|
248
|
+
* chat paths — the pool's and the automation's — claim the same client.
|
|
249
|
+
*/
|
|
250
|
+
const CHAT_IDENTITY_HEADERS = Object.freeze({
|
|
251
|
+
"X-IDE-Name": "WorkBuddy",
|
|
252
|
+
"X-IDE-Type": "WorkBuddy",
|
|
253
|
+
"X-IDE-Version": "5.5.6"
|
|
254
|
+
});
|
|
227
255
|
/** Refresh-endpoint headers; X-Refresh-Token appears here and nowhere else. */
|
|
228
256
|
function refreshHeaders(credential) {
|
|
229
257
|
const headers = {
|
|
@@ -819,7 +847,10 @@ var WorkBuddyUpstreamClient = class {
|
|
|
819
847
|
async completeChat(credential, prepared, signal) {
|
|
820
848
|
const response = await this.fetchImpl(`${chatBase(credential)}/v2/chat/completions`, {
|
|
821
849
|
method: "POST",
|
|
822
|
-
headers:
|
|
850
|
+
headers: {
|
|
851
|
+
...chatHeaders(credential),
|
|
852
|
+
...CHAT_IDENTITY_HEADERS
|
|
853
|
+
},
|
|
823
854
|
body: prepared,
|
|
824
855
|
...signal === void 0 ? {} : { signal }
|
|
825
856
|
});
|
|
@@ -836,7 +867,10 @@ var WorkBuddyUpstreamClient = class {
|
|
|
836
867
|
try {
|
|
837
868
|
response = await this.fetchImpl(`${chatBase(credential)}/v2/chat/completions`, {
|
|
838
869
|
method: "POST",
|
|
839
|
-
headers:
|
|
870
|
+
headers: {
|
|
871
|
+
...chatHeaders(credential),
|
|
872
|
+
...CHAT_IDENTITY_HEADERS
|
|
873
|
+
},
|
|
840
874
|
body: prepared,
|
|
841
875
|
...signal === void 0 ? {} : { signal }
|
|
842
876
|
});
|
|
@@ -1316,15 +1350,13 @@ var WorkBuddyUpstreamClient = class {
|
|
|
1316
1350
|
method: "POST",
|
|
1317
1351
|
headers: {
|
|
1318
1352
|
...chatHeaders(credential),
|
|
1353
|
+
...CHAT_IDENTITY_HEADERS,
|
|
1319
1354
|
"Accept": "text/event-stream",
|
|
1320
1355
|
"User-Agent": DESKTOP_TASK_UA,
|
|
1321
1356
|
"X-Conversation-ID": conversationId,
|
|
1322
1357
|
"X-Request-ID": String(Date.now()) + "000000",
|
|
1323
1358
|
"X-Agent-Intent": "craft",
|
|
1324
1359
|
"X-Agent-Type": "main",
|
|
1325
|
-
"X-IDE-Name": "WorkBuddy",
|
|
1326
|
-
"X-IDE-Type": "WorkBuddy",
|
|
1327
|
-
"X-IDE-Version": "5.5.6",
|
|
1328
1360
|
"x-codebuddy-request": "1",
|
|
1329
1361
|
...expertId === "" ? {} : { "X-Expert-Id": expertId }
|
|
1330
1362
|
},
|
package/lib/client.js
CHANGED
|
@@ -445,7 +445,6 @@ window.__ModuleLoader__.load({
|
|
|
445
445
|
sharing a line with a total. */
|
|
446
446
|
.dsm-xdpool-packages li{display:inline-flex;align-items:baseline;gap:5px;min-width:0;padding:1px 8px;border-radius:999px;border:1px solid var(--dsw-alias-border-l1,#2f3035);background:color-mix(in srgb, var(--dsw-alias-bg-layer-1,#191a1e) 62%, transparent);color:var(--dsw-alias-label-secondary,#c6c9d0);font-size:11px;line-height:17px}
|
|
447
447
|
.dsm-xdpool-packages-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
448
|
-
.dsm-xdpool-packages-value{color:var(--dsw-alias-label-tertiary,#999);font-variant-numeric:tabular-nums}
|
|
449
448
|
/* Per-package deadline: the upstream grants one-off packs at arbitrary clock
|
|
450
449
|
times, so each pack carries its own timestamp. It sits inside its own chip on
|
|
451
450
|
its own line — a pack name plus two timestamps did not fit on one line, and
|
|
@@ -453,8 +452,17 @@ window.__ModuleLoader__.load({
|
|
|
453
452
|
.dsm-xdpool-packages-when{color:var(--dsw-alias-label-tertiary,#9aa0a8);font-size:10.5px;line-height:15px;font-variant-numeric:tabular-nums}
|
|
454
453
|
.dsm-xdpool-packages-when-soon{color:var(--dsw-alias-state-warning-primary,#d97706)}
|
|
455
454
|
/* The balance. Still the most important figure on the row — colour and weight,
|
|
456
|
-
not size: at 28px it outweighed the account name it belongs to.
|
|
457
|
-
|
|
455
|
+
not size: at 28px it outweighed the account name it belongs to. The green is
|
|
456
|
+
pinned rather than taken from the theme alias: at 16px/700 the alias green
|
|
457
|
+
read darker than the 11px figures beside it on the same row — the same hex
|
|
458
|
+
looks dimmer in large bold type than in small text — and the user read the
|
|
459
|
+
balance as grey next to the bright green streak chips. A slightly brighter
|
|
460
|
+
literal keeps the two readings of "green" on this row identical. */
|
|
461
|
+
.dsm-xdpool-total-value{color:#2fbf7f;font-size:16px;line-height:22px;font-weight:700;letter-spacing:-.2px;white-space:nowrap;font-variant-numeric:tabular-nums}
|
|
462
|
+
/* Per-package figures share the balance's green: they are the same credit
|
|
463
|
+
balance broken down, and rendering them in grey made the packages look
|
|
464
|
+
spent while the total looked alive. */
|
|
465
|
+
.dsm-xdpool-packages-value{color:#2fbf7f;font-variant-numeric:tabular-nums}
|
|
458
466
|
/* Model directory list. */
|
|
459
467
|
.dsm-xdpool-models{gap:10px}
|
|
460
468
|
.dsm-xdpool-models-head{display:flex;align-items:center;justify-content:space-between;gap:12px}
|
|
@@ -5177,7 +5185,7 @@ window.__ModuleLoader__.load({
|
|
|
5177
5185
|
*
|
|
5178
5186
|
* @module dsh-xdpool/version
|
|
5179
5187
|
*/
|
|
5180
|
-
const POOL_VERSION = "2.1.
|
|
5188
|
+
const POOL_VERSION = "2.1.1";
|
|
5181
5189
|
//#endregion
|
|
5182
5190
|
//#region src/client/PoolCard.tsx
|
|
5183
5191
|
/**
|
package/lib/index.js
CHANGED
|
@@ -275,6 +275,34 @@ function chatHeaders(credential) {
|
|
|
275
275
|
"X-Product": "SaaS"
|
|
276
276
|
};
|
|
277
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* The client-identity headers the desktop app puts on every chat completion.
|
|
280
|
+
*
|
|
281
|
+
* WHY THESE EXIST AND WHY THEY BELONG ON /v2/chat/completions ONLY
|
|
282
|
+
*
|
|
283
|
+
* The gateway attributes each request to a client, and that attribution is what
|
|
284
|
+
* surfaces in the user's billing console as the "使用端" column. The desktop app
|
|
285
|
+
* (`buildVlmGatewayHeaders` in its bundled `main/server.js`) sends
|
|
286
|
+
* `X-IDE-Type`/`X-IDE-Name`/`X-IDE-Version` on every `/v2/chat/completions`, so
|
|
287
|
+
* its traffic reads as "WorkBuddy". Our chat requests sent none of them, so the
|
|
288
|
+
* same spend attributed to nothing — the column showed "–" and the user's
|
|
289
|
+
* billing page looked like the requests had come from nowhere.
|
|
290
|
+
*
|
|
291
|
+
* They are deliberately NOT part of `chatHeaders()`, which is shared with the
|
|
292
|
+
* points-automation endpoints (`listTasks` / `acceptTasks`). Those are not chat
|
|
293
|
+
* completions, and the evidence for the desktop app sending identity headers on
|
|
294
|
+
* them is nil — adding identity headers to an endpoint that never carried them
|
|
295
|
+
* risks changing how that traffic is attributed or filtered, and the automation
|
|
296
|
+
* was never reported broken. Only the two chat completions get these.
|
|
297
|
+
*
|
|
298
|
+
* The version is the same literal `openConversation()` already sends, so both
|
|
299
|
+
* chat paths — the pool's and the automation's — claim the same client.
|
|
300
|
+
*/
|
|
301
|
+
const CHAT_IDENTITY_HEADERS = Object.freeze({
|
|
302
|
+
"X-IDE-Name": "WorkBuddy",
|
|
303
|
+
"X-IDE-Type": "WorkBuddy",
|
|
304
|
+
"X-IDE-Version": "5.5.6"
|
|
305
|
+
});
|
|
278
306
|
/** Refresh-endpoint headers; X-Refresh-Token appears here and nowhere else. */
|
|
279
307
|
function refreshHeaders(credential) {
|
|
280
308
|
const headers = {
|
|
@@ -979,7 +1007,10 @@ var WorkBuddyUpstreamClient = class {
|
|
|
979
1007
|
async completeChat(credential, prepared, signal) {
|
|
980
1008
|
const response = await this.fetchImpl(`${chatBase(credential)}/v2/chat/completions`, {
|
|
981
1009
|
method: "POST",
|
|
982
|
-
headers:
|
|
1010
|
+
headers: {
|
|
1011
|
+
...chatHeaders(credential),
|
|
1012
|
+
...CHAT_IDENTITY_HEADERS
|
|
1013
|
+
},
|
|
983
1014
|
body: prepared,
|
|
984
1015
|
...signal === void 0 ? {} : { signal }
|
|
985
1016
|
});
|
|
@@ -996,7 +1027,10 @@ var WorkBuddyUpstreamClient = class {
|
|
|
996
1027
|
try {
|
|
997
1028
|
response = await this.fetchImpl(`${chatBase(credential)}/v2/chat/completions`, {
|
|
998
1029
|
method: "POST",
|
|
999
|
-
headers:
|
|
1030
|
+
headers: {
|
|
1031
|
+
...chatHeaders(credential),
|
|
1032
|
+
...CHAT_IDENTITY_HEADERS
|
|
1033
|
+
},
|
|
1000
1034
|
body: prepared,
|
|
1001
1035
|
...signal === void 0 ? {} : { signal }
|
|
1002
1036
|
});
|
|
@@ -1476,15 +1510,13 @@ var WorkBuddyUpstreamClient = class {
|
|
|
1476
1510
|
method: "POST",
|
|
1477
1511
|
headers: {
|
|
1478
1512
|
...chatHeaders(credential),
|
|
1513
|
+
...CHAT_IDENTITY_HEADERS,
|
|
1479
1514
|
"Accept": "text/event-stream",
|
|
1480
1515
|
"User-Agent": DESKTOP_TASK_UA,
|
|
1481
1516
|
"X-Conversation-ID": conversationId,
|
|
1482
1517
|
"X-Request-ID": String(Date.now()) + "000000",
|
|
1483
1518
|
"X-Agent-Intent": "craft",
|
|
1484
1519
|
"X-Agent-Type": "main",
|
|
1485
|
-
"X-IDE-Name": "WorkBuddy",
|
|
1486
|
-
"X-IDE-Type": "WorkBuddy",
|
|
1487
|
-
"X-IDE-Version": "5.5.6",
|
|
1488
1520
|
"x-codebuddy-request": "1",
|
|
1489
1521
|
...expertId === "" ? {} : { "X-Expert-Id": expertId }
|
|
1490
1522
|
},
|
|
@@ -11334,21 +11366,32 @@ function createWorkBuddyAdapter(options) {
|
|
|
11334
11366
|
/** The package name the loader resolves, exactly as our patch row names it. */
|
|
11335
11367
|
const BILLION_PACKAGE = "billion-context";
|
|
11336
11368
|
/**
|
|
11337
|
-
* Is this package
|
|
11369
|
+
* Is this package installed and able to run?
|
|
11370
|
+
*
|
|
11371
|
+
* Any entry whose name matches counts — including one whose fiber has not
|
|
11372
|
+
* started yet. When this function still decided whether to mount, a fiber-less
|
|
11373
|
+
* entry had to be treated as absent: treating an import-in-flight as present
|
|
11374
|
+
* would have skipped the mount and left the compressor never starting. Now that
|
|
11375
|
+
* nothing mounts, the distinction only picks a label, and the honest one is
|
|
11376
|
+
* "installed": a user watching billion-context's own boot does not want the
|
|
11377
|
+
* card telling them it is missing while its proxy is half-way up.
|
|
11338
11378
|
*
|
|
11339
|
-
*
|
|
11340
|
-
*
|
|
11341
|
-
*
|
|
11379
|
+
* A DISABLED entry does not count. `loader.entries()` yields disabled rows too
|
|
11380
|
+
* — the host skips starting them, it does not drop them — and our own patch
|
|
11381
|
+
* row is disabled on purpose. Counting it would make every profile that never
|
|
11382
|
+
* installed billion-context read as "installed", which is precisely the lie the
|
|
11383
|
+
* card must not tell.
|
|
11342
11384
|
*/
|
|
11343
11385
|
function mountedInLoader(loader, packageName) {
|
|
11344
11386
|
for (const entry of loader.entries()) {
|
|
11345
11387
|
if (entry.options?.name !== packageName) continue;
|
|
11346
|
-
if (entry.
|
|
11388
|
+
if (entry.options?.disabled === true) continue;
|
|
11389
|
+
return true;
|
|
11347
11390
|
}
|
|
11348
11391
|
return false;
|
|
11349
11392
|
}
|
|
11350
11393
|
/**
|
|
11351
|
-
*
|
|
11394
|
+
* Report whether the compressor is already running. Never mounts.
|
|
11352
11395
|
*
|
|
11353
11396
|
* Resolves rather than rejects on every path: a compressor that will not start
|
|
11354
11397
|
* is a card that says so, never a pool that fails to boot. The pool's own model
|
|
@@ -11369,12 +11412,7 @@ async function mountBillionContext(ctx, logger) {
|
|
|
11369
11412
|
logger.info?.(`[xdpool] billion-context is already mounted; leaving it alone`);
|
|
11370
11413
|
return { state: "already-mounted" };
|
|
11371
11414
|
}
|
|
11372
|
-
|
|
11373
|
-
id: "billion-context-xdpool",
|
|
11374
|
-
name: BILLION_PACKAGE
|
|
11375
|
-
});
|
|
11376
|
-
logger.info?.(`[xdpool] mounted billion-context for the billion card`);
|
|
11377
|
-
return { state: "mounted" };
|
|
11415
|
+
return { state: "not-required" };
|
|
11378
11416
|
} catch (error) {
|
|
11379
11417
|
return {
|
|
11380
11418
|
state: "unavailable",
|