@cursorpool-dev/cli 0.5.8 → 0.5.9
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/node_modules/@cursor-pool/extension/dist/extension.js +46 -116
- package/node_modules/@cursor-pool/extension/package.json +3 -3
- package/node_modules/@cursor-pool/extension/src/api.ts +2 -17
- package/node_modules/@cursor-pool/extension/src/panel.ts +3 -26
- package/node_modules/@cursor-pool/extension/test/panel.test.ts +1 -34
- package/node_modules/@cursor-pool/patcher/package.json +2 -2
- package/node_modules/@cursor-pool/patcher/src/marker.ts +72 -7
- package/node_modules/@cursor-pool/patcher/src/workbenchAuthGateMarker.ts +80 -17
- package/node_modules/@cursor-pool/patcher/test/patchCursorAgentExec.test.ts +88 -13
- package/node_modules/@cursor-pool/patcher/test/patchCursorWorkbench.test.ts +151 -149
- package/node_modules/@cursor-pool/service/package.json +2 -2
- package/node_modules/@cursor-pool/service/src/platformSession.ts +7 -30
- package/node_modules/@cursor-pool/service/src/server.ts +1 -1
- package/node_modules/@cursor-pool/service/test/platformSession.test.ts +4 -5
- package/node_modules/@cursor-pool/service/test/server.test.ts +1 -130
- package/node_modules/@cursor-pool/shared/package.json +1 -1
- package/node_modules/@cursor-pool/shared/src/manifest.ts +0 -35
- package/node_modules/@cursor-pool/shared/test/manifest.test.ts +9 -43
- package/package.json +5 -7
- package/src/compat.ts +124 -196
- package/src/extensionBundle.ts +1 -1
- package/src/extensionLink.ts +8 -29
- package/src/install.ts +9 -62
- package/src/installRecord.ts +0 -2
- package/src/patchSet.ts +6 -12
- package/src/platform.ts +3 -3
- package/src/repair.ts +2 -10
- package/src/restore.ts +4 -12
- package/src/status.ts +0 -6
- package/src/trial.ts +2 -3
- package/test/compat.test.ts +59 -195
- package/test/e2e-install.test.ts +0 -53
- package/test/extensionLink.test.ts +26 -49
- package/test/install.test.ts +4 -64
- package/test/repair.test.ts +0 -1
- package/test/status.test.ts +0 -1
- package/test/trial.test.ts +15 -1
- package/node_modules/@cursor-pool/takeover-plans/package.json +0 -12
- package/node_modules/@cursor-pool/takeover-plans/src/index.ts +0 -22
- package/node_modules/@cursor-pool/takeover-plans/src/plans.ts +0 -37
- package/node_modules/@cursor-pool/takeover-plans/src/types.ts +0 -9
- package/node_modules/@cursor-pool/takeover-plans/test/registry.test.ts +0 -23
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
//
|
|
1
|
+
// packages/extension/src/api.ts
|
|
2
2
|
import { arch, hostname, platform as osPlatform } from "node:os";
|
|
3
3
|
|
|
4
|
-
//
|
|
4
|
+
// packages/service/src/health.ts
|
|
5
5
|
function buildHealth(runtime) {
|
|
6
6
|
return {
|
|
7
7
|
ok: true,
|
|
@@ -11,7 +11,7 @@ function buildHealth(runtime) {
|
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
//
|
|
14
|
+
// packages/shared/src/metadata.ts
|
|
15
15
|
var SAFE_METADATA_KEYS = [
|
|
16
16
|
"requestId",
|
|
17
17
|
"model",
|
|
@@ -31,7 +31,7 @@ function sanitizeRequestMetadata(input) {
|
|
|
31
31
|
return output;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
//
|
|
34
|
+
// packages/service/src/metadata.ts
|
|
35
35
|
var EXTENSION_STATUS_KEYS = ["connected", "cursorVersion", "clientVersion"];
|
|
36
36
|
function sanitizeServiceMetadata(input) {
|
|
37
37
|
return {
|
|
@@ -49,7 +49,7 @@ function sanitizeExtensionStatus(input) {
|
|
|
49
49
|
return output;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
//
|
|
52
|
+
// packages/service/src/platformSession.ts
|
|
53
53
|
import { chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
54
54
|
import { homedir } from "node:os";
|
|
55
55
|
import { dirname, join } from "node:path";
|
|
@@ -95,7 +95,7 @@ function asStatus(session) {
|
|
|
95
95
|
state: "logged-in",
|
|
96
96
|
user: session.user,
|
|
97
97
|
device: session.device,
|
|
98
|
-
mode:
|
|
98
|
+
mode: platformModeFromSession(session)
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
function isPlatformModeReleaseReason(value) {
|
|
@@ -121,24 +121,6 @@ function platformModeFromSession(session) {
|
|
|
121
121
|
}
|
|
122
122
|
return inactiveModeFromSession(session);
|
|
123
123
|
}
|
|
124
|
-
function routeStateFromSession(session) {
|
|
125
|
-
const routeToken = session?.routeToken;
|
|
126
|
-
if (!routeToken) {
|
|
127
|
-
return { state: "missing" };
|
|
128
|
-
}
|
|
129
|
-
const expiresAt = Date.parse(routeToken.expiresAt);
|
|
130
|
-
if (Number.isNaN(expiresAt)) {
|
|
131
|
-
return { state: "missing" };
|
|
132
|
-
}
|
|
133
|
-
if (expiresAt <= Date.now()) {
|
|
134
|
-
return { state: "expired", expiresAt: routeToken.expiresAt };
|
|
135
|
-
}
|
|
136
|
-
return { state: "ready", expiresAt: routeToken.expiresAt };
|
|
137
|
-
}
|
|
138
|
-
function statusModeFromSession(session) {
|
|
139
|
-
const mode = platformModeFromSession(session);
|
|
140
|
-
return mode.state === "active" ? { ...mode, route: routeStateFromSession(session) } : mode;
|
|
141
|
-
}
|
|
142
124
|
function clearPlatformMode(session) {
|
|
143
125
|
const {
|
|
144
126
|
platformMode: _platformMode,
|
|
@@ -397,10 +379,10 @@ function poolFailureToModeResult(reason, product, currentCredits) {
|
|
|
397
379
|
async function statusFromRequestError(error, session, options = {}) {
|
|
398
380
|
if (error.status === 401) {
|
|
399
381
|
const currentSession = await readPlatformSession(options) ?? session;
|
|
400
|
-
const { mode } = options.releaseActiveModeOnUnauthorized ? await releaseActivePlatformMode(currentSession, "invalid-token", options) : { mode:
|
|
382
|
+
const { mode } = options.releaseActiveModeOnUnauthorized ? await releaseActivePlatformMode(currentSession, "invalid-token", options) : { mode: platformModeFromSession(currentSession) };
|
|
401
383
|
return { state: "invalid-token", user: currentSession.user, device: currentSession.device, mode };
|
|
402
384
|
}
|
|
403
|
-
return { state: "offline", user: session.user, device: session.device, mode:
|
|
385
|
+
return { state: "offline", user: session.user, device: session.device, mode: platformModeFromSession(session) };
|
|
404
386
|
}
|
|
405
387
|
async function loginWithCode(options) {
|
|
406
388
|
const tokenResponse = await (options.exchangeDeviceToken ?? exchangeDeviceToken)({
|
|
@@ -460,7 +442,7 @@ async function platformStatus(options = {}) {
|
|
|
460
442
|
state: "logged-in",
|
|
461
443
|
user: released.session.user,
|
|
462
444
|
device: released.session.device,
|
|
463
|
-
mode: released.mode
|
|
445
|
+
mode: released.mode
|
|
464
446
|
};
|
|
465
447
|
}
|
|
466
448
|
async function platformCatalog(options = {}) {
|
|
@@ -512,7 +494,7 @@ async function platformCatalog(options = {}) {
|
|
|
512
494
|
return {
|
|
513
495
|
state: "logged-in",
|
|
514
496
|
account: { credits: account.value.credits },
|
|
515
|
-
mode
|
|
497
|
+
mode,
|
|
516
498
|
...selectedProductId ? { selectedProductId } : {},
|
|
517
499
|
products: catalogProducts
|
|
518
500
|
};
|
|
@@ -683,7 +665,7 @@ async function sendHeartbeat(options = {}) {
|
|
|
683
665
|
state: "logged-in",
|
|
684
666
|
user: released.session.user,
|
|
685
667
|
device: released.session.device,
|
|
686
|
-
mode: released.mode
|
|
668
|
+
mode: released.mode
|
|
687
669
|
};
|
|
688
670
|
}
|
|
689
671
|
async function logoutPlatform(options = {}) {
|
|
@@ -698,17 +680,17 @@ async function logoutPlatform(options = {}) {
|
|
|
698
680
|
return { state: "logged-out" };
|
|
699
681
|
}
|
|
700
682
|
|
|
701
|
-
//
|
|
683
|
+
// packages/service/src/runtime.ts
|
|
702
684
|
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
703
685
|
import { homedir as homedir2 } from "node:os";
|
|
704
686
|
import { dirname as dirname2, join as join2 } from "node:path";
|
|
705
687
|
import { randomUUID } from "node:crypto";
|
|
706
688
|
|
|
707
|
-
//
|
|
689
|
+
// packages/shared/src/runtime.ts
|
|
708
690
|
var DEFAULT_RUNTIME_FILE = "~/.cursor-pool/runtime.json";
|
|
709
691
|
var DEFAULT_DIAGNOSTICS_FILE = "~/.cursor-pool/diagnostics.jsonl";
|
|
710
692
|
|
|
711
|
-
//
|
|
693
|
+
// packages/service/src/runtime.ts
|
|
712
694
|
function createRuntimeId() {
|
|
713
695
|
return randomUUID();
|
|
714
696
|
}
|
|
@@ -739,7 +721,7 @@ async function readRuntimeInfo(options = {}) {
|
|
|
739
721
|
}
|
|
740
722
|
}
|
|
741
723
|
|
|
742
|
-
//
|
|
724
|
+
// packages/service/src/requestCheck.ts
|
|
743
725
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
744
726
|
var SAFE_MODEL_PATTERN = /^[A-Za-z0-9._:-]{1,96}$/;
|
|
745
727
|
var SECRET_PATTERN = /(api[_-]?key|authorization|bearer|cursor[_-]?auth|provider[_-]?secret|secret|token|sk-[A-Za-z0-9])/i;
|
|
@@ -781,10 +763,10 @@ function createRequestCheckStore() {
|
|
|
781
763
|
};
|
|
782
764
|
}
|
|
783
765
|
|
|
784
|
-
//
|
|
766
|
+
// packages/service/src/server.ts
|
|
785
767
|
import { createServer } from "node:http";
|
|
786
768
|
|
|
787
|
-
//
|
|
769
|
+
// packages/service/src/canary.ts
|
|
788
770
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
789
771
|
var isValidRequestId2 = (value) => typeof value === "string" && value.length > 0 && value.length <= 128;
|
|
790
772
|
function sanitizeAgentCanary(input, options) {
|
|
@@ -813,12 +795,12 @@ function createCanaryStore() {
|
|
|
813
795
|
};
|
|
814
796
|
}
|
|
815
797
|
|
|
816
|
-
//
|
|
798
|
+
// packages/service/src/diagnostics.ts
|
|
817
799
|
import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
818
800
|
import { dirname as dirname3, join as join3 } from "node:path";
|
|
819
801
|
import { homedir as homedir3 } from "node:os";
|
|
820
802
|
|
|
821
|
-
//
|
|
803
|
+
// packages/service/src/requestGateway.ts
|
|
822
804
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
823
805
|
var SAFE_MODEL_PATTERN2 = /^[A-Za-z0-9._:-]{1,96}$/;
|
|
824
806
|
var SAFE_REQUEST_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
@@ -1054,7 +1036,7 @@ function createGatewayStore() {
|
|
|
1054
1036
|
};
|
|
1055
1037
|
}
|
|
1056
1038
|
|
|
1057
|
-
//
|
|
1039
|
+
// packages/service/src/diagnostics.ts
|
|
1058
1040
|
var DEFAULT_MAX_DIAGNOSTICS = 20;
|
|
1059
1041
|
var BLOCKED_GATE_REASONS = /* @__PURE__ */ new Set([
|
|
1060
1042
|
"logged-out",
|
|
@@ -1317,7 +1299,7 @@ async function appendAgentGatewayDiagnostic(gateway, options = {}) {
|
|
|
1317
1299
|
await writeFile3(diagnosticsFile, content, "utf8");
|
|
1318
1300
|
}
|
|
1319
1301
|
|
|
1320
|
-
//
|
|
1302
|
+
// packages/service/src/requestGate.ts
|
|
1321
1303
|
var INVALID_SESSION_GATE = { state: "blocked", reason: "invalid-session" };
|
|
1322
1304
|
function invalidSessionGate() {
|
|
1323
1305
|
return { ...INVALID_SESSION_GATE };
|
|
@@ -1374,7 +1356,7 @@ async function evaluateRouteState(options = {}) {
|
|
|
1374
1356
|
return { state: "ready", expiresAt: routeToken.expiresAt };
|
|
1375
1357
|
}
|
|
1376
1358
|
|
|
1377
|
-
//
|
|
1359
|
+
// packages/service/src/takeover.ts
|
|
1378
1360
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
1379
1361
|
var SAFE_TOKEN_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
1380
1362
|
var SAFE_MODEL_PATTERN3 = /^[A-Za-z0-9._:-]{1,96}$/;
|
|
@@ -1425,7 +1407,7 @@ function createAgentTakeoverStore() {
|
|
|
1425
1407
|
};
|
|
1426
1408
|
}
|
|
1427
1409
|
|
|
1428
|
-
//
|
|
1410
|
+
// packages/shared/src/clientConfig.ts
|
|
1429
1411
|
import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile4 } from "node:fs/promises";
|
|
1430
1412
|
import { homedir as homedir4 } from "node:os";
|
|
1431
1413
|
import { dirname as dirname4, join as join4 } from "node:path";
|
|
@@ -1453,13 +1435,9 @@ async function readClientConfig(options = {}) {
|
|
|
1453
1435
|
}
|
|
1454
1436
|
}
|
|
1455
1437
|
|
|
1456
|
-
//
|
|
1438
|
+
// packages/service/src/server.ts
|
|
1457
1439
|
var LOOPBACK_HOST = "127.0.0.1";
|
|
1458
1440
|
var DEFAULT_PORT = 56393;
|
|
1459
|
-
var TRUSTED_RENDERER_ORIGINS = /* @__PURE__ */ new Set([
|
|
1460
|
-
"vscode-file://vscode-app",
|
|
1461
|
-
"null"
|
|
1462
|
-
]);
|
|
1463
1441
|
var localServices = /* @__PURE__ */ new Map();
|
|
1464
1442
|
async function resolvePlatformApiBaseUrl(options) {
|
|
1465
1443
|
if (options.platformApiBaseUrl) {
|
|
@@ -1492,37 +1470,18 @@ function writeJson(response, statusCode, payload) {
|
|
|
1492
1470
|
const body = JSON.stringify(payload);
|
|
1493
1471
|
response.writeHead(statusCode, {
|
|
1494
1472
|
"content-type": "application/json",
|
|
1495
|
-
"content-length": Buffer.byteLength(body)
|
|
1473
|
+
"content-length": Buffer.byteLength(body),
|
|
1474
|
+
"access-control-allow-origin": "*",
|
|
1475
|
+
"access-control-allow-methods": "GET,POST,OPTIONS",
|
|
1476
|
+
"access-control-allow-headers": "content-type"
|
|
1496
1477
|
});
|
|
1497
1478
|
response.end(body);
|
|
1498
1479
|
}
|
|
1499
|
-
function
|
|
1500
|
-
const origin = request.headers.origin;
|
|
1501
|
-
if (typeof origin !== "string") {
|
|
1502
|
-
return void 0;
|
|
1503
|
-
}
|
|
1504
|
-
if (TRUSTED_RENDERER_ORIGINS.has(origin) || origin.startsWith("vscode-webview://")) {
|
|
1505
|
-
return origin;
|
|
1506
|
-
}
|
|
1507
|
-
return void 0;
|
|
1508
|
-
}
|
|
1509
|
-
function applyCorsHeaders(request, response) {
|
|
1510
|
-
const origin = trustedRendererOrigin(request);
|
|
1511
|
-
if (!origin) {
|
|
1512
|
-
return false;
|
|
1513
|
-
}
|
|
1514
|
-
response.setHeader("access-control-allow-origin", origin);
|
|
1515
|
-
response.setHeader("access-control-allow-methods", "GET,POST,OPTIONS");
|
|
1516
|
-
response.setHeader("access-control-allow-headers", "content-type,authorization");
|
|
1517
|
-
return true;
|
|
1518
|
-
}
|
|
1519
|
-
function writeCorsPreflight(request, response) {
|
|
1520
|
-
if (!applyCorsHeaders(request, response)) {
|
|
1521
|
-
response.writeHead(403);
|
|
1522
|
-
response.end();
|
|
1523
|
-
return;
|
|
1524
|
-
}
|
|
1480
|
+
function writeCorsPreflight(response) {
|
|
1525
1481
|
response.writeHead(204, {
|
|
1482
|
+
"access-control-allow-origin": "*",
|
|
1483
|
+
"access-control-allow-methods": "GET,POST,OPTIONS",
|
|
1484
|
+
"access-control-allow-headers": "content-type",
|
|
1526
1485
|
"access-control-max-age": "600"
|
|
1527
1486
|
});
|
|
1528
1487
|
response.end();
|
|
@@ -1537,7 +1496,10 @@ function writeEventStream(response, events) {
|
|
|
1537
1496
|
"content-type": "text/event-stream; charset=utf-8",
|
|
1538
1497
|
"cache-control": "no-cache",
|
|
1539
1498
|
"connection": "keep-alive",
|
|
1540
|
-
"content-length": Buffer.byteLength(body)
|
|
1499
|
+
"content-length": Buffer.byteLength(body),
|
|
1500
|
+
"access-control-allow-origin": "*",
|
|
1501
|
+
"access-control-allow-methods": "GET,POST,OPTIONS",
|
|
1502
|
+
"access-control-allow-headers": "content-type,authorization"
|
|
1541
1503
|
});
|
|
1542
1504
|
response.end(body);
|
|
1543
1505
|
}
|
|
@@ -1761,10 +1723,9 @@ async function completeForwardAfterClientResponse(context) {
|
|
|
1761
1723
|
async function routeRequest(request, response, runtime, options, canaryStore, requestCheckStore, gatewayStore, takeoverStore, stop) {
|
|
1762
1724
|
try {
|
|
1763
1725
|
if (request.method === "OPTIONS") {
|
|
1764
|
-
writeCorsPreflight(
|
|
1726
|
+
writeCorsPreflight(response);
|
|
1765
1727
|
return;
|
|
1766
1728
|
}
|
|
1767
|
-
applyCorsHeaders(request, response);
|
|
1768
1729
|
if (request.method === "GET" && request.url === "/health") {
|
|
1769
1730
|
writeJson(response, 200, buildHealth(runtime));
|
|
1770
1731
|
return;
|
|
@@ -2089,7 +2050,7 @@ async function routeRequest(request, response, runtime, options, canaryStore, re
|
|
|
2089
2050
|
if (request.method === "POST" && request.url === "/shutdown") {
|
|
2090
2051
|
writeJson(response, 200, { ok: true });
|
|
2091
2052
|
response.once("finish", () => {
|
|
2092
|
-
void stop()
|
|
2053
|
+
void stop();
|
|
2093
2054
|
});
|
|
2094
2055
|
return;
|
|
2095
2056
|
}
|
|
@@ -2176,7 +2137,7 @@ async function startServer(options = {}) {
|
|
|
2176
2137
|
}
|
|
2177
2138
|
}
|
|
2178
2139
|
|
|
2179
|
-
//
|
|
2140
|
+
// packages/extension/src/runtime.ts
|
|
2180
2141
|
async function readRuntimeInfo2(options = {}) {
|
|
2181
2142
|
return readRuntimeInfo({ runtimeFile: options.runtimeFile });
|
|
2182
2143
|
}
|
|
@@ -2184,7 +2145,7 @@ async function writeRuntimeInfo2(runtime, options = {}) {
|
|
|
2184
2145
|
await writeRuntimeInfo(runtime, { runtimeFile: options.runtimeFile });
|
|
2185
2146
|
}
|
|
2186
2147
|
|
|
2187
|
-
//
|
|
2148
|
+
// packages/extension/src/api.ts
|
|
2188
2149
|
var DEFAULT_SERVICE_PORT = 56393;
|
|
2189
2150
|
var localExtensionServices = /* @__PURE__ */ new Map();
|
|
2190
2151
|
function buildExtensionDeviceInfo() {
|
|
@@ -2192,7 +2153,7 @@ function buildExtensionDeviceInfo() {
|
|
|
2192
2153
|
name: hostname(),
|
|
2193
2154
|
os: osPlatform(),
|
|
2194
2155
|
arch: arch(),
|
|
2195
|
-
extensionVersion: "0.5.
|
|
2156
|
+
extensionVersion: "0.5.9"
|
|
2196
2157
|
};
|
|
2197
2158
|
}
|
|
2198
2159
|
function serviceUrl(runtime, path) {
|
|
@@ -2287,16 +2248,6 @@ function normalizePlatformMode(value) {
|
|
|
2287
2248
|
};
|
|
2288
2249
|
}
|
|
2289
2250
|
if (mode?.state === "active" && typeof mode.productId === "string" && typeof mode.startedAt === "string") {
|
|
2290
|
-
const route = mode.route;
|
|
2291
|
-
if (route?.state === "ready" && typeof route.expiresAt === "string") {
|
|
2292
|
-
return { state: "active", productId: mode.productId, startedAt: mode.startedAt, route };
|
|
2293
|
-
}
|
|
2294
|
-
if (route?.state === "expired" && typeof route.expiresAt === "string") {
|
|
2295
|
-
return { state: "active", productId: mode.productId, startedAt: mode.startedAt, route };
|
|
2296
|
-
}
|
|
2297
|
-
if (route?.state === "missing") {
|
|
2298
|
-
return { state: "active", productId: mode.productId, startedAt: mode.startedAt, route };
|
|
2299
|
-
}
|
|
2300
2251
|
return { state: "active", productId: mode.productId, startedAt: mode.startedAt };
|
|
2301
2252
|
}
|
|
2302
2253
|
return null;
|
|
@@ -2498,22 +2449,7 @@ async function logoutPlatform2(runtimeFile, options = {}) {
|
|
|
2498
2449
|
return postJson({ runtimeFile, ...options }, "/platform/logout");
|
|
2499
2450
|
}
|
|
2500
2451
|
|
|
2501
|
-
//
|
|
2502
|
-
function panelModeIsTakeoverReady(mode) {
|
|
2503
|
-
return mode.startsWith("active ") && mode.endsWith(" route-ready");
|
|
2504
|
-
}
|
|
2505
|
-
function panelModeDisplay(mode) {
|
|
2506
|
-
if (panelModeIsTakeoverReady(mode)) {
|
|
2507
|
-
return "\u5E73\u53F0\u63A5\u7BA1";
|
|
2508
|
-
}
|
|
2509
|
-
if (mode.endsWith(" route-missing")) {
|
|
2510
|
-
return "\u5E73\u53F0\u672A\u63A5\u7BA1\uFF08\u8DEF\u7531\u7F3A\u5931\uFF09";
|
|
2511
|
-
}
|
|
2512
|
-
if (mode.endsWith(" route-expired")) {
|
|
2513
|
-
return "\u5E73\u53F0\u672A\u63A5\u7BA1\uFF08\u8DEF\u7531\u8FC7\u671F\uFF09";
|
|
2514
|
-
}
|
|
2515
|
-
return "\u5B98\u65B9\u6A21\u5F0F";
|
|
2516
|
-
}
|
|
2452
|
+
// packages/extension/src/panel.ts
|
|
2517
2453
|
function createPanelViewModel(status) {
|
|
2518
2454
|
const rows = [
|
|
2519
2455
|
{ label: "patch", value: status.patch },
|
|
@@ -2541,7 +2477,7 @@ function createPanelViewModel(status) {
|
|
|
2541
2477
|
rows.push({ label: "current product", value: status.selectedProductId });
|
|
2542
2478
|
}
|
|
2543
2479
|
const platformState = status.platform ?? "logged-out";
|
|
2544
|
-
const takeoverActive =
|
|
2480
|
+
const takeoverActive = status.mode.startsWith("active ");
|
|
2545
2481
|
const platformLoggedIn = platformState === "logged-in" || platformState === "offline" || platformState === "invalid-token";
|
|
2546
2482
|
return {
|
|
2547
2483
|
title: "Cursor Pool \u53F7\u6C60\u5BA2\u6237\u7AEF",
|
|
@@ -2562,13 +2498,7 @@ function createPanelViewModel(status) {
|
|
|
2562
2498
|
}
|
|
2563
2499
|
function formatPanelMode(mode) {
|
|
2564
2500
|
if (mode?.state === "active") {
|
|
2565
|
-
|
|
2566
|
-
return `active ${mode.productId} route-ready`;
|
|
2567
|
-
}
|
|
2568
|
-
if (mode.route?.state === "expired") {
|
|
2569
|
-
return `active ${mode.productId} route-expired`;
|
|
2570
|
-
}
|
|
2571
|
-
return `active ${mode.productId} route-missing`;
|
|
2501
|
+
return `active ${mode.productId}`;
|
|
2572
2502
|
}
|
|
2573
2503
|
if (mode?.state === "inactive" && mode.releaseReason) {
|
|
2574
2504
|
return `inactive ${mode.releaseReason}`;
|
|
@@ -2654,7 +2584,7 @@ function buildPanelHtml(viewModel) {
|
|
|
2654
2584
|
...valueFor("credits", "") ? [{ label: "\u79EF\u5206\u4F59\u989D", value: valueFor("credits") }] : [],
|
|
2655
2585
|
...valueFor("user", "") ? [{
|
|
2656
2586
|
label: "\u5F53\u524D\u6A21\u5F0F",
|
|
2657
|
-
value:
|
|
2587
|
+
value: valueFor("mode").startsWith("active ") ? "\u5E73\u53F0\u63A5\u7BA1" : "\u5B98\u65B9\u6A21\u5F0F"
|
|
2658
2588
|
}] : []
|
|
2659
2589
|
];
|
|
2660
2590
|
const rows = statusItems.map((row) => `<li><span>${escapeHtml(row.label)}</span><strong>${escapeHtml(row.value)}</strong></li>`).join("");
|
|
@@ -2905,7 +2835,7 @@ function registerStatusPanel(context, vscode, options = {}) {
|
|
|
2905
2835
|
return provider;
|
|
2906
2836
|
}
|
|
2907
2837
|
|
|
2908
|
-
//
|
|
2838
|
+
// packages/extension/src/extension.ts
|
|
2909
2839
|
async function appendDiagnostic(message) {
|
|
2910
2840
|
try {
|
|
2911
2841
|
const os = await new Function("specifier", "return import(specifier)")("node:os");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cursor-pool/extension",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.9",
|
|
4
4
|
"displayName": "Cursor Pool 平台模式",
|
|
5
5
|
"publisher": "cursor-pool",
|
|
6
6
|
"engines": {
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"./runtime": "./src/runtime.ts"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@cursor-pool/service": "0.5.
|
|
25
|
-
"@cursor-pool/shared": "0.5.
|
|
24
|
+
"@cursor-pool/service": "0.5.9",
|
|
25
|
+
"@cursor-pool/shared": "0.5.9"
|
|
26
26
|
},
|
|
27
27
|
"contributes": {
|
|
28
28
|
"viewsContainers": {
|
|
@@ -23,12 +23,7 @@ export type PlatformModeReleaseReason =
|
|
|
23
23
|
| 'device-inactive';
|
|
24
24
|
export type PlatformModeSnapshot =
|
|
25
25
|
| { state: 'inactive'; releaseReason?: PlatformModeReleaseReason; releasedAt?: string }
|
|
26
|
-
| {
|
|
27
|
-
state: 'active';
|
|
28
|
-
productId: string;
|
|
29
|
-
startedAt: string;
|
|
30
|
-
route?: { state: 'missing' } | { state: 'ready'; expiresAt: string } | { state: 'expired'; expiresAt: string };
|
|
31
|
-
};
|
|
26
|
+
| { state: 'active'; productId: string; startedAt: string };
|
|
32
27
|
export type PlatformModeResult =
|
|
33
28
|
| PlatformModeSnapshot
|
|
34
29
|
| { state: 'logged-out' }
|
|
@@ -119,7 +114,7 @@ export function buildExtensionDeviceInfo() {
|
|
|
119
114
|
name: hostname(),
|
|
120
115
|
os: osPlatform(),
|
|
121
116
|
arch: arch(),
|
|
122
|
-
extensionVersion: '0.5.
|
|
117
|
+
extensionVersion: '0.5.9',
|
|
123
118
|
};
|
|
124
119
|
}
|
|
125
120
|
|
|
@@ -260,16 +255,6 @@ function normalizePlatformMode(value: unknown): PlatformModeSnapshot | null {
|
|
|
260
255
|
typeof mode.productId === 'string' &&
|
|
261
256
|
typeof mode.startedAt === 'string'
|
|
262
257
|
) {
|
|
263
|
-
const route = mode.route;
|
|
264
|
-
if (route?.state === 'ready' && typeof route.expiresAt === 'string') {
|
|
265
|
-
return { state: 'active', productId: mode.productId, startedAt: mode.startedAt, route };
|
|
266
|
-
}
|
|
267
|
-
if (route?.state === 'expired' && typeof route.expiresAt === 'string') {
|
|
268
|
-
return { state: 'active', productId: mode.productId, startedAt: mode.startedAt, route };
|
|
269
|
-
}
|
|
270
|
-
if (route?.state === 'missing') {
|
|
271
|
-
return { state: 'active', productId: mode.productId, startedAt: mode.startedAt, route };
|
|
272
|
-
}
|
|
273
258
|
return { state: 'active', productId: mode.productId, startedAt: mode.startedAt };
|
|
274
259
|
}
|
|
275
260
|
return null;
|
|
@@ -49,23 +49,6 @@ export type PanelViewModel = {
|
|
|
49
49
|
error?: string;
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
-
function panelModeIsTakeoverReady(mode: string) {
|
|
53
|
-
return mode.startsWith('active ') && mode.endsWith(' route-ready');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function panelModeDisplay(mode: string) {
|
|
57
|
-
if (panelModeIsTakeoverReady(mode)) {
|
|
58
|
-
return '平台接管';
|
|
59
|
-
}
|
|
60
|
-
if (mode.endsWith(' route-missing')) {
|
|
61
|
-
return '平台未接管(路由缺失)';
|
|
62
|
-
}
|
|
63
|
-
if (mode.endsWith(' route-expired')) {
|
|
64
|
-
return '平台未接管(路由过期)';
|
|
65
|
-
}
|
|
66
|
-
return '官方模式';
|
|
67
|
-
}
|
|
68
|
-
|
|
69
52
|
type ExtensionContext = {
|
|
70
53
|
subscriptions?: { push: (subscription: unknown) => unknown };
|
|
71
54
|
};
|
|
@@ -146,7 +129,7 @@ export function createPanelViewModel(status: PanelStatus): PanelViewModel {
|
|
|
146
129
|
}
|
|
147
130
|
|
|
148
131
|
const platformState = status.platform ?? 'logged-out';
|
|
149
|
-
const takeoverActive =
|
|
132
|
+
const takeoverActive = status.mode.startsWith('active ');
|
|
150
133
|
const platformLoggedIn =
|
|
151
134
|
platformState === 'logged-in' || platformState === 'offline' || platformState === 'invalid-token';
|
|
152
135
|
|
|
@@ -171,13 +154,7 @@ export function createPanelViewModel(status: PanelStatus): PanelViewModel {
|
|
|
171
154
|
|
|
172
155
|
function formatPanelMode(mode: PlatformStatus['mode']) {
|
|
173
156
|
if (mode?.state === 'active') {
|
|
174
|
-
|
|
175
|
-
return `active ${mode.productId} route-ready`;
|
|
176
|
-
}
|
|
177
|
-
if (mode.route?.state === 'expired') {
|
|
178
|
-
return `active ${mode.productId} route-expired`;
|
|
179
|
-
}
|
|
180
|
-
return `active ${mode.productId} route-missing`;
|
|
157
|
+
return `active ${mode.productId}`;
|
|
181
158
|
}
|
|
182
159
|
if (mode?.state === 'inactive' && mode.releaseReason) {
|
|
183
160
|
return `inactive ${mode.releaseReason}`;
|
|
@@ -277,7 +254,7 @@ export function buildPanelHtml(viewModel: PanelViewModel): string {
|
|
|
277
254
|
...(valueFor('user', '')
|
|
278
255
|
? [{
|
|
279
256
|
label: '当前模式',
|
|
280
|
-
value:
|
|
257
|
+
value: valueFor('mode').startsWith('active ') ? '平台接管' : '官方模式',
|
|
281
258
|
}]
|
|
282
259
|
: []),
|
|
283
260
|
];
|
|
@@ -652,39 +652,6 @@ test('panel keeps active platform mode out of rendered status list', () => {
|
|
|
652
652
|
assert.doesNotMatch(html, /active prod_basic/);
|
|
653
653
|
});
|
|
654
654
|
|
|
655
|
-
test('panel only displays takeover when active route is ready', () => {
|
|
656
|
-
const ready = buildPanelHtml(createPanelViewModel({
|
|
657
|
-
patch: 'applied',
|
|
658
|
-
service: 'running',
|
|
659
|
-
compat: 'supported',
|
|
660
|
-
mode: 'active prod_basic route-ready',
|
|
661
|
-
platform: 'logged-in',
|
|
662
|
-
user: 'user@example.test',
|
|
663
|
-
}));
|
|
664
|
-
const missing = buildPanelHtml(createPanelViewModel({
|
|
665
|
-
patch: 'applied',
|
|
666
|
-
service: 'running',
|
|
667
|
-
compat: 'supported',
|
|
668
|
-
mode: 'active prod_basic route-missing',
|
|
669
|
-
platform: 'logged-in',
|
|
670
|
-
user: 'user@example.test',
|
|
671
|
-
}));
|
|
672
|
-
const expired = buildPanelHtml(createPanelViewModel({
|
|
673
|
-
patch: 'applied',
|
|
674
|
-
service: 'running',
|
|
675
|
-
compat: 'supported',
|
|
676
|
-
mode: 'active prod_basic route-expired',
|
|
677
|
-
platform: 'logged-in',
|
|
678
|
-
user: 'user@example.test',
|
|
679
|
-
}));
|
|
680
|
-
|
|
681
|
-
assert.match(ready, /当前模式<\/span><strong>平台接管<\/strong>/);
|
|
682
|
-
assert.match(missing, /当前模式<\/span><strong>平台未接管(路由缺失)<\/strong>/);
|
|
683
|
-
assert.match(expired, /当前模式<\/span><strong>平台未接管(路由过期)<\/strong>/);
|
|
684
|
-
assert.doesNotMatch(missing, /当前模式<\/span><strong>平台接管<\/strong>/);
|
|
685
|
-
assert.doesNotMatch(expired, /当前模式<\/span><strong>平台接管<\/strong>/);
|
|
686
|
-
});
|
|
687
|
-
|
|
688
655
|
test('sidebar view model shows inactive mode release reason', () => {
|
|
689
656
|
const viewModel = createPanelViewModel({
|
|
690
657
|
patch: 'applied',
|
|
@@ -1688,7 +1655,7 @@ test('API can login and logout through local service platform routes', async ()
|
|
|
1688
1655
|
assert.equal(typeof (requests[0]?.body.device as Record<string, unknown>).name, 'string');
|
|
1689
1656
|
assert.equal(typeof (requests[0]?.body.device as Record<string, unknown>).os, 'string');
|
|
1690
1657
|
assert.equal(typeof (requests[0]?.body.device as Record<string, unknown>).arch, 'string');
|
|
1691
|
-
assert.equal((requests[0]?.body.device as Record<string, unknown>).extensionVersion, '0.5.
|
|
1658
|
+
assert.equal((requests[0]?.body.device as Record<string, unknown>).extensionVersion, '0.5.9');
|
|
1692
1659
|
assert.equal(requests[1]?.method, 'POST');
|
|
1693
1660
|
assert.equal(requests[1]?.url, '/platform/logout');
|
|
1694
1661
|
} finally {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cursor-pool/patcher",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"exports": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"./marker": "./src/marker.ts"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@cursor-pool/shared": "0.5.
|
|
12
|
+
"@cursor-pool/shared": "0.5.9"
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
15
|
"test": "tsx --test test/*.test.ts"
|