@ycodium-ai/plugin-browser-workbench 0.2.2167 → 0.2.2488

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.
Files changed (3) hide show
  1. package/README.md +8 -5
  2. package/dist/index.js +65 -10
  3. package/package.json +4 -3
package/README.md CHANGED
@@ -29,7 +29,8 @@ token.
29
29
  ## Requirements
30
30
 
31
31
  A Ycodium server with plugin API version 2, including `process.spawn` for
32
- `data:bin/code` (at most two processes at once) and `ports.register`. The
32
+ `data:bin/code` and `data:bin/code.exe` (at most two processes at once) and
33
+ `ports.register`. The
33
34
  machine needs outbound HTTPS to `update.code.visualstudio.com` (and the CDN it
34
35
  redirects to) the first time the CLI is installed, unless you attach an
35
36
  external code-server instead.
@@ -89,10 +90,12 @@ The package builds its own code into `dist/index.js`. The host supplies the
89
90
  shared `@ycodium-ai/plugin-api` at runtime. The plugin requires plugin API
90
91
  version 2. Language catalogs live in `locales/`; only English is authored here.
91
92
 
92
- Known limits: Windows uses `bin/code` (the spawn whitelist), not `code.exe`.
93
- Server download progress is the size of `cli-data/serve-web/` because the CLI
94
- does not report bytes. The host does not auto-start the workbench after a
95
- server restart.
93
+ The CLI lands at `bin/code.exe` on Windows and `bin/code` elsewhere; Windows
94
+ cannot start an executable without its extension.
95
+
96
+ Known limits: Server download progress is the size of `cli-data/serve-web/`
97
+ because the CLI does not report bytes. The host does not auto-start the
98
+ workbench after a server restart.
96
99
 
97
100
  ## License
98
101
 
package/dist/index.js CHANGED
@@ -37,6 +37,8 @@ var attachNoListenerMessage = (port) => catalog.attach.noListener.replace("{{por
37
37
 
38
38
  // src/progress.ts
39
39
  var PROGRESS_BUFFER_LIMIT = 64;
40
+ var PROGRESS_OUTPUT_TAIL = 16;
41
+ var PROGRESS_THROTTLE_MS = 200;
40
42
  var computeTransfer = (input) => {
41
43
  const elapsedSec = (input.nowMs - input.startedAtMs) / 1e3;
42
44
  return {
@@ -56,18 +58,62 @@ var progressEvent = (input) => ({
56
58
  });
57
59
  var ProgressBus = class {
58
60
  listeners = /* @__PURE__ */ new Set();
59
- latest = [];
61
+ /** 进行中这一轮的事件,空闲时为 null。每个阶段的 progress 只留最新一条,输出行只留尾巴。 */
62
+ run = null;
63
+ /** 每个阶段上一条放行的 progress 的时刻(毫秒)。 */
64
+ progressAt = /* @__PURE__ */ new Map();
65
+ beginRun() {
66
+ this.run = [];
67
+ this.progressAt.clear();
68
+ }
69
+ endRun() {
70
+ this.run = null;
71
+ this.progressAt.clear();
72
+ }
73
+ /** 空闲时直接丢:两轮之间 serve-web 还在输出,没人要,也不能漏进下一轮。 */
60
74
  emit(event) {
61
- this.latest = [...this.latest, event].slice(-PROGRESS_BUFFER_LIMIT);
75
+ const run = this.run;
76
+ if (run === null) return;
77
+ switch (event.status) {
78
+ case "progress":
79
+ if (this.throttled(event)) return;
80
+ removeFirst(
81
+ run,
82
+ (earlier) => earlier.status === "progress" && earlier.stage === event.stage
83
+ );
84
+ break;
85
+ case "output":
86
+ if (run.filter((earlier) => earlier.status === "output").length >= PROGRESS_OUTPUT_TAIL) {
87
+ removeFirst(run, (earlier) => earlier.status === "output");
88
+ }
89
+ break;
90
+ default:
91
+ this.progressAt.delete(event.stage);
92
+ }
93
+ run.push(event);
62
94
  for (const listener of this.listeners) listener(event);
63
95
  }
64
96
  subscribe(listener) {
65
- for (const event of this.latest) listener(event);
97
+ for (const event of this.run ?? []) listener(event);
66
98
  this.listeners.add(listener);
67
99
  return () => {
68
100
  this.listeners.delete(listener);
69
101
  };
70
102
  }
103
+ throttled(event) {
104
+ const at = Date.parse(event.at);
105
+ const last = this.progressAt.get(event.stage);
106
+ if (last !== void 0 && at - last < PROGRESS_THROTTLE_MS && !transferDone(event.transfer)) {
107
+ return true;
108
+ }
109
+ this.progressAt.set(event.stage, at);
110
+ return false;
111
+ }
112
+ };
113
+ var transferDone = (transfer) => transfer !== void 0 && transfer.totalBytes !== null && transfer.transferredBytes >= transfer.totalBytes;
114
+ var removeFirst = (items, matches) => {
115
+ const index = items.findIndex(matches);
116
+ if (index !== -1) items.splice(index, 1);
71
117
  };
72
118
 
73
119
  // src/runtime.ts
@@ -266,8 +312,8 @@ var extractCliBinary = async (archive, kind) => {
266
312
  // src/platform.ts
267
313
  import * as NodeProcess from "node:process";
268
314
  var CLI_DOWNLOAD_BASE_URL = "https://update.code.visualstudio.com/latest";
269
- var CLI_PROGRAM_SELECTOR = "data:bin/code";
270
- var CLI_RELATIVE_PATH = "bin/code";
315
+ var cliRelativePath = (platform3 = NodeProcess.platform) => platform3 === "win32" ? "bin/code.exe" : "bin/code";
316
+ var cliProgramSelector = (platform3 = NodeProcess.platform) => `data:${cliRelativePath(platform3)}`;
271
317
  var detectCliPlatform = (platform3 = NodeProcess.platform, arch3 = NodeProcess.arch) => {
272
318
  if (platform3 === "linux" && arch3 === "x64") return "linux-x64";
273
319
  if (platform3 === "linux" && arch3 === "arm64") return "linux-arm64";
@@ -286,7 +332,7 @@ import * as NodePath from "node:path";
286
332
  var workbenchPaths = (dataDir) => ({
287
333
  dataDir,
288
334
  binDir: NodePath.join(dataDir, "bin"),
289
- cliPath: NodePath.join(dataDir, CLI_RELATIVE_PATH),
335
+ cliPath: NodePath.join(dataDir, cliRelativePath()),
290
336
  cliDataDir: NodePath.join(dataDir, "cli-data"),
291
337
  serverDataDir: NodePath.join(dataDir, "server-data"),
292
338
  tokenPath: NodePath.join(dataDir, "serve-web-token"),
@@ -435,7 +481,7 @@ var parseCliVersion = (stdout) => {
435
481
  var cliIsInstalled = (paths) => fileExists(paths.cliPath);
436
482
  var readInstalledCliVersion = async (processApi) => {
437
483
  const result = await processApi.run({
438
- program: CLI_PROGRAM_SELECTOR,
484
+ program: cliProgramSelector(),
439
485
  args: ["--version"],
440
486
  timeoutMs: 15e3
441
487
  });
@@ -702,7 +748,7 @@ var startServeWeb = async (input) => {
702
748
  await ensureDataDirs(input.paths);
703
749
  await ensureServeWebToken(input.paths);
704
750
  const handle = await input.processApi.spawn({
705
- program: CLI_PROGRAM_SELECTOR,
751
+ program: cliProgramSelector(),
706
752
  args: [...serveWebArgs(input.paths)]
707
753
  });
708
754
  try {
@@ -902,7 +948,7 @@ var WorkbenchRuntime = class {
902
948
  return this.enqueue(() => this.readStatus());
903
949
  }
904
950
  open(payload) {
905
- return this.enqueue(() => this.runOpen(payload));
951
+ return this.enqueue(() => this.inRun(() => this.runOpen(payload)));
906
952
  }
907
953
  stop() {
908
954
  return this.enqueue(async () => {
@@ -911,7 +957,7 @@ var WorkbenchRuntime = class {
911
957
  });
912
958
  }
913
959
  update() {
914
- return this.enqueue(() => this.runUpdate());
960
+ return this.enqueue(() => this.inRun(() => this.runUpdate()));
915
961
  }
916
962
  attach(port) {
917
963
  return this.enqueue(async () => {
@@ -935,6 +981,15 @@ var WorkbenchRuntime = class {
935
981
  );
936
982
  return run;
937
983
  }
984
+ /** 一轮 open / update 的进度只重放给这一轮。包在 enqueue 里:排着队的下一轮碰不到正在跑的这一轮。 */
985
+ async inRun(fn) {
986
+ this.bus.beginRun();
987
+ try {
988
+ return await fn();
989
+ } finally {
990
+ this.bus.endRun();
991
+ }
992
+ }
938
993
  emit(event) {
939
994
  this.bus.emit(event);
940
995
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/plugin-browser-workbench",
3
- "version": "0.2.2167",
3
+ "version": "0.2.2488",
4
4
  "description": "Installs the official VS Code CLI on this machine and opens it in a system browser.",
5
5
  "keywords": [
6
6
  "browser-workbench",
@@ -23,7 +23,7 @@
23
23
  "esbuild": "0.28.1",
24
24
  "typescript": "~6.0.3",
25
25
  "vite-plus": "0.2.2",
26
- "@ycodium-ai/plugin-api": "0.2.2167"
26
+ "@ycodium-ai/plugin-api": "0.2.2488"
27
27
  },
28
28
  "ycodium": {
29
29
  "plugin": "./dist/index.js",
@@ -34,7 +34,8 @@
34
34
  {
35
35
  "kind": "process.spawn",
36
36
  "programs": [
37
- "data:bin/code"
37
+ "data:bin/code",
38
+ "data:bin/code.exe"
38
39
  ],
39
40
  "maxConcurrent": 2
40
41
  },