@lengmoxxl/sdk 0.1.3 → 0.1.4
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/README.md +2 -2
- package/dist/agent.d.ts +0 -4
- package/dist/connection.d.ts +1 -0
- package/dist/index.cjs +12 -54
- package/dist/index.d.ts +2 -1
- package/dist/types.d.ts +3 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,8 +32,8 @@ connection.disconnect();
|
|
|
32
32
|
|
|
33
33
|
`openMachine` returns a `MachineConnection`; every call opens its own. Sharing one belongs to the caller: a
|
|
34
34
|
connection is reference counted, so callers that hand the same one around keep it alive until the last
|
|
35
|
-
`disconnect()`. `openMachine({ type: 'ssh', host, agent })`
|
|
36
|
-
|
|
35
|
+
`disconnect()`. `openMachine({ type: 'ssh', host, agent })` calls `agent(host)` before it connects: putting
|
|
36
|
+
the carrier agent on the host belongs to the app that embeds the SDK.
|
|
37
37
|
|
|
38
38
|
- `connection.pty` - `list`, `cwd`, `create`, `attach`, `close`
|
|
39
39
|
- `connection.fs` - `stat`, `readDirectory`, `readFile`
|
package/dist/agent.d.ts
CHANGED
package/dist/connection.d.ts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -30,14 +30,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
agentCommand: () => agentCommand,
|
|
33
34
|
openMachine: () => openMachine
|
|
34
35
|
});
|
|
35
36
|
module.exports = __toCommonJS(index_exports);
|
|
36
37
|
|
|
37
38
|
// connection.ts
|
|
38
|
-
var
|
|
39
|
+
var import_node_child_process = require("node:child_process");
|
|
39
40
|
var import_node_net = require("node:net");
|
|
40
|
-
var
|
|
41
|
+
var import_node_util = require("node:util");
|
|
41
42
|
var import_ws = __toESM(require("ws"));
|
|
42
43
|
|
|
43
44
|
// pty.ts
|
|
@@ -111,61 +112,14 @@ var Pty = class {
|
|
|
111
112
|
};
|
|
112
113
|
|
|
113
114
|
// agent.ts
|
|
114
|
-
var import_node_child_process = require("node:child_process");
|
|
115
|
-
var import_node_util = require("node:util");
|
|
116
|
-
var exec = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
117
|
-
var DOWNLOAD_TIMEOUT = 3e4;
|
|
118
115
|
function agentCommand(command) {
|
|
119
116
|
const home = process.env.WANGCAI_HOME;
|
|
120
117
|
const exportHome = home ? `export WANGCAI_HOME='${home.replace(/'/g, String.raw`'\''`)}'; ` : "";
|
|
121
118
|
return `${exportHome}export PATH="$HOME/.local/bin:$PATH"; ${command}`;
|
|
122
119
|
}
|
|
123
|
-
async function ensureAgent(host, { version, prefixes, signal }) {
|
|
124
|
-
const targets = {
|
|
125
|
-
"Darwin x86_64": "x86_64-apple-darwin",
|
|
126
|
-
"Darwin arm64": "aarch64-apple-darwin",
|
|
127
|
-
"Linux x86_64": "x86_64-unknown-linux-musl"
|
|
128
|
-
};
|
|
129
|
-
const remote = (command) => ["-T", "-o", "BatchMode=yes", "-o", "ConnectTimeout=8", host, command];
|
|
130
|
-
const probe = await exec("ssh", remote(agentCommand("uname -s -m; wangcai --version 2>/dev/null; true")), { timeout: 3e4, signal }).catch(() => void 0);
|
|
131
|
-
const [platform, installed] = (probe?.stdout ?? "").split("\n").map((line) => line.trim());
|
|
132
|
-
if (!platform) return;
|
|
133
|
-
const target = targets[platform];
|
|
134
|
-
if (!target) throw new Error(`${platform} \u4E0A\u6682\u4E0D\u652F\u6301\u81EA\u52A8\u5B89\u88C5 agent`);
|
|
135
|
-
if (installed === `wangcai ${version}`) return;
|
|
136
|
-
const failures = [];
|
|
137
|
-
for (const prefix of prefixes) {
|
|
138
|
-
signal?.throwIfAborted();
|
|
139
|
-
const url = `${prefix}/v${version}/wangcai-${target}`;
|
|
140
|
-
const deadline = AbortSignal.timeout(DOWNLOAD_TIMEOUT);
|
|
141
|
-
let binary;
|
|
142
|
-
try {
|
|
143
|
-
const response = await fetch(url, { signal: signal ? AbortSignal.any([signal, deadline]) : deadline });
|
|
144
|
-
if (!response.ok) throw new Error(`${response.status} ${response.statusText}`);
|
|
145
|
-
binary = Buffer.from(await response.arrayBuffer());
|
|
146
|
-
} catch (error) {
|
|
147
|
-
failures.push(`${url}
|
|
148
|
-
${error instanceof Error ? error.message : String(error)}`);
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
await new Promise((resolve, reject) => {
|
|
152
|
-
const child = (0, import_node_child_process.spawn)("ssh", remote("mkdir -p ~/.local/bin && cat > ~/.local/bin/.wangcai.tmp && chmod 755 ~/.local/bin/.wangcai.tmp && mv ~/.local/bin/.wangcai.tmp ~/.local/bin/wangcai"), { stdio: ["pipe", "ignore", "pipe"] });
|
|
153
|
-
let stderr = "";
|
|
154
|
-
child.stderr.on("data", (chunk) => {
|
|
155
|
-
stderr += chunk;
|
|
156
|
-
});
|
|
157
|
-
child.on("error", reject);
|
|
158
|
-
child.on("close", (code) => code === 0 ? resolve() : reject(new Error(stderr.trim() || `\u5199\u5165 agent \u5931\u8D25\uFF08ssh \u9000\u51FA\u7801 ${code}\uFF09`)));
|
|
159
|
-
child.stdin.end(binary);
|
|
160
|
-
});
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
throw new Error(`\u4E0B\u8F7D agent \u5931\u8D25\uFF1A
|
|
164
|
-
${failures.join("\n\n")}`);
|
|
165
|
-
}
|
|
166
120
|
|
|
167
121
|
// connection.ts
|
|
168
|
-
var
|
|
122
|
+
var exec = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
169
123
|
var MachineConnection = class {
|
|
170
124
|
constructor(options) {
|
|
171
125
|
this.options = options;
|
|
@@ -178,6 +132,8 @@ var MachineConnection = class {
|
|
|
178
132
|
}
|
|
179
133
|
listeners = /* @__PURE__ */ new Set();
|
|
180
134
|
terminals = /* @__PURE__ */ new Map();
|
|
135
|
+
// Where the daemon listens: the window reaches it with this.
|
|
136
|
+
port;
|
|
181
137
|
instance;
|
|
182
138
|
ready;
|
|
183
139
|
resolveReady;
|
|
@@ -300,12 +256,12 @@ var MachineConnection = class {
|
|
|
300
256
|
let info;
|
|
301
257
|
let port;
|
|
302
258
|
if (this.options.type === "local") {
|
|
303
|
-
const { stdout } = await
|
|
259
|
+
const { stdout } = await exec(this.options.binary ?? "wangcai", ["server", "start", "--json"], { timeout: 15e3 });
|
|
304
260
|
info = JSON.parse(stdout);
|
|
305
261
|
port = info.port;
|
|
306
262
|
} else {
|
|
307
|
-
if (this.options.agent) await
|
|
308
|
-
const { stdout } = await
|
|
263
|
+
if (this.options.agent) await this.options.agent(this.options.host, this.options.signal);
|
|
264
|
+
const { stdout } = await exec("ssh", [
|
|
309
265
|
"-T",
|
|
310
266
|
"-o",
|
|
311
267
|
"BatchMode=yes",
|
|
@@ -319,6 +275,7 @@ var MachineConnection = class {
|
|
|
319
275
|
if (!current()) return;
|
|
320
276
|
port = await this.forward(info.port, current);
|
|
321
277
|
}
|
|
278
|
+
this.port = port;
|
|
322
279
|
if (!current()) return;
|
|
323
280
|
const socket = new import_ws.default(`ws://127.0.0.1:${port}`, { handshakeTimeout: 5e3, maxPayload: 64 * 1024 * 1024 });
|
|
324
281
|
this.ws = socket;
|
|
@@ -415,7 +372,7 @@ var MachineConnection = class {
|
|
|
415
372
|
const port = reservation.address().port;
|
|
416
373
|
await new Promise((resolve) => reservation.close(() => resolve()));
|
|
417
374
|
if (!current()) throw new Error("Connection cancelled");
|
|
418
|
-
const tunnel = (0,
|
|
375
|
+
const tunnel = (0, import_node_child_process.spawn)("ssh", [
|
|
419
376
|
"-N",
|
|
420
377
|
"-T",
|
|
421
378
|
"-o",
|
|
@@ -521,5 +478,6 @@ async function openMachine(options) {
|
|
|
521
478
|
}
|
|
522
479
|
// Annotate the CommonJS export names for ESM import in node:
|
|
523
480
|
0 && (module.exports = {
|
|
481
|
+
agentCommand,
|
|
524
482
|
openMachine
|
|
525
483
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MachineConnection } from './connection';
|
|
2
2
|
import type { ConnectionOptions } from './types';
|
|
3
|
-
export
|
|
3
|
+
export { agentCommand } from './agent';
|
|
4
|
+
export type { ConnectionOptions, FileClick, Machine, MachineState, Session, Size, Output, Snapshot, TerminalEvent, DirectoryEntry, ExecOptions, ExecResult, InstallAgent, Profile, Theme, WorkspaceActive, WorkspaceRow, WorkspaceMenuItem } from './types';
|
|
4
5
|
export type { MachineConnection } from './connection';
|
|
5
6
|
export type { Pty } from './pty';
|
|
6
7
|
/** Opens one connection to a machine and waits for it to be ready. */
|
package/dist/types.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
prefixes: string[];
|
|
4
|
-
}
|
|
1
|
+
/** What puts the agent on an ssh machine, which the SDK calls before it connects to it. */
|
|
2
|
+
export type InstallAgent = (host: string, signal?: AbortSignal) => Promise<void>;
|
|
5
3
|
/**
|
|
6
4
|
* The workspace protocol. A plugin that init.ts lists under `workspaces` is a workspace provider, and
|
|
7
5
|
* the app drives it through these `ui` methods:
|
|
@@ -58,7 +56,7 @@ export type ConnectionOptions = {
|
|
|
58
56
|
} | {
|
|
59
57
|
type: 'ssh';
|
|
60
58
|
host: string;
|
|
61
|
-
agent?:
|
|
59
|
+
agent?: InstallAgent;
|
|
62
60
|
signal?: AbortSignal;
|
|
63
61
|
};
|
|
64
62
|
export interface Size {
|