MCPcopy
hub / github.com/phuryn/claude-usage / start

Method start

vscode-extension/src/server-manager.ts:78–132  ·  view source on GitHub ↗

* Spawn the process and resolve when it answers HTTP, or reject if it * exits before that or the timeout fires. Callers are expected to wrap * port-collision recovery at a higher level (catch failure → pick new port * → new ServerManager).

()

Source from the content-addressed store, hash-verified

76 * → new ServerManager).
77 */
78 async start(): Promise<void> {
79 if (this._status !== "stopped" && this._status !== "failed" && this._status !== "exited") {
80 throw new Error(`cannot start: server is ${this._status}`);
81 }
82 this._status = "starting";
83 this.opts.output.appendLine(`[server] spawning: ${this.opts.command} ${this.opts.args.join(" ")}`);
84
85 let proc: SpawnedLike;
86 try {
87 proc = this.spawnFn(this.opts.command, this.opts.args);
88 } catch (err) {
89 this._status = "failed";
90 this.opts.output.appendLine(`[server] spawn failed: ${(err as Error).message}`);
91 throw err;
92 }
93 this.proc = proc;
94
95 proc.stdout?.on("data", (chunk) => this.opts.output.appendLine(`[server] ${chunk.toString().trimEnd()}`));
96 proc.stderr?.on("data", (chunk) => this.opts.output.appendLine(`[server:err] ${chunk.toString().trimEnd()}`));
97
98 let exitedEarly = false;
99 let earlyExitCode: number | null = null;
100 proc.on("exit", (code) => {
101 if (this._status === "starting" || this._status === "ready") {
102 exitedEarly = this._status === "starting";
103 earlyExitCode = code;
104 this._status = this._status === "starting" ? "failed" : "exited";
105 this.opts.output.appendLine(`[server] process exited with code ${code}`);
106 }
107 });
108 proc.on("error", (err) => {
109 this.opts.output.appendLine(`[server] error: ${err.message}`);
110 if (this._status === "starting") this._status = "failed";
111 });
112
113 const deadline = Date.now() + this.readinessTimeoutMs;
114 while (Date.now() < deadline) {
115 if (exitedEarly) {
116 throw new Error(`server exited before becoming ready (code ${earlyExitCode})`);
117 }
118 const healthy = await this.probeFn(this.opts.url);
119 if (healthy) {
120 // Process may have died after the probe but before we checked status.
121 if (this._status === "starting") {
122 this._status = "ready";
123 this.opts.output.appendLine(`[server] ready at ${this.opts.url}`);
124 return;
125 }
126 }
127 await delay(this.readinessPollMs);
128 }
129 this._status = "failed";
130 this.dispose();
131 throw new Error(`server did not become ready within ${this.readinessTimeoutMs}ms at ${this.opts.url}`);
132 }
133
134 dispose(): void {
135 if (this.proc) {

Callers 4

doStartupMethod · 0.95
cmd_dashboardFunction · 0.80
setUpClassMethod · 0.80

Calls 4

disposeMethod · 0.95
delayFunction · 0.85
onMethod · 0.80
appendLineMethod · 0.65

Tested by 1

setUpClassMethod · 0.64