mindwire 0.1.0 → 0.1.2

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.
@@ -0,0 +1,139 @@
1
+ import { type EnsureEvent } from "./host.js";
2
+ import type { Target, TargetHandle } from "./index.js";
3
+ /** Options for the {@link ssh} target. */
4
+ export interface SshOptions {
5
+ /** Host to connect to. */
6
+ host: string;
7
+ /** SSH port. Defaults to 22. */
8
+ port?: number;
9
+ /** SSH username. */
10
+ username: string;
11
+ /** Private key material (PEM). Highest-precedence auth. */
12
+ privateKey?: string | Buffer;
13
+ /** Path to a private key file (read at connect time). */
14
+ privateKeyPath?: string;
15
+ /** Passphrase for an encrypted private key. */
16
+ passphrase?: string;
17
+ /** Password auth. */
18
+ password?: string;
19
+ /** ssh-agent socket path. Defaults to `$SSH_AUTH_SOCK`. Used when no key/password is given. */
20
+ agent?: string;
21
+ /** Handshake timeout (ms). Defaults to 20000. */
22
+ readyTimeoutMs?: number;
23
+ /** Port the daemon listens on, on the REMOTE loopback. Defaults to 8790. */
24
+ daemonPort?: number;
25
+ /** `AGENT_TYPE` for the remote daemon. Defaults to the client's agent, then `claude-code`. */
26
+ agentType?: string;
27
+ /** `AGENT_CWD` — working directory agents run in, on the remote. Defaults to `/root`. */
28
+ agentCwd?: string;
29
+ /** Explicit path to a Linux `mindwired` to deploy (else resolved from the platform package). */
30
+ daemonBin?: string;
31
+ /** Redeploy when the running daemon's version differs from the SDK's bundled binary. */
32
+ autoUpdate?: boolean;
33
+ /** On `close()`, tear the tunnel down and end the SSH connection. Defaults to `true`. */
34
+ stopOnExit?: boolean;
35
+ /**
36
+ * Run the daemon **inside a Docker container** on the remote host instead of natively — a clean,
37
+ * reproducible, isolated environment per instance. mindwire ensures Docker is present, spins the
38
+ * container, deploys `mindwired` into it, and tunnels to its published loopback port. Docker is
39
+ * detected, never installed, unless you opt in with `install: "ifMissing"`.
40
+ */
41
+ docker?: {
42
+ /** Create + own a container from this image. */
43
+ image?: string;
44
+ /** Attach to an existing container (id or name) instead of creating one. */
45
+ container?: string;
46
+ /** Name for a container we create. */
47
+ name?: string;
48
+ /** Docker-on-host policy. `"never"` (default) detects and fails; `"ifMissing"` installs + starts it. */
49
+ install?: "never" | "ifMissing";
50
+ /** Extra args spliced into `docker run` (before the image), e.g. `["-e", "FOO=bar"]`. */
51
+ createArgs?: string[];
52
+ };
53
+ }
54
+ /**
55
+ * The SSH target. Returns a {@link Target} whose `connect()` opens an SSH connection, ensures
56
+ * `mindwired` runs on the remote, and points the SDK at a local tunnel to it.
57
+ *
58
+ * ```ts
59
+ * const mw = new Mindwire({ target: ssh({ host: "box.example.com", username: "root" }) });
60
+ * ```
61
+ */
62
+ export declare function ssh(opts: SshOptions): Target;
63
+ interface Ssh2Stream {
64
+ on(event: string, listener: (...args: any[]) => void): Ssh2Stream;
65
+ stderr?: {
66
+ on(event: string, listener: (...args: any[]) => void): unknown;
67
+ };
68
+ pipe(dest: any): any;
69
+ write?(chunk: unknown): unknown;
70
+ end?(chunk?: unknown): unknown;
71
+ close?(): unknown;
72
+ destroy?(): unknown;
73
+ }
74
+ interface Ssh2Sftp {
75
+ createWriteStream(path: string, opts?: {
76
+ mode?: number;
77
+ }): Ssh2Stream;
78
+ }
79
+ interface Ssh2Client {
80
+ on(event: string, listener: (...args: any[]) => void): Ssh2Client;
81
+ connect(cfg: Record<string, unknown>): void;
82
+ exec(command: string, cb: (err: Error | undefined, channel: Ssh2Stream) => void): void;
83
+ forwardOut(srcIP: string, srcPort: number, dstIP: string, dstPort: number, cb: (err: Error | undefined, channel: Ssh2Stream) => void): void;
84
+ sftp(cb: (err: Error | undefined, sftp: Ssh2Sftp) => void): void;
85
+ end(): void;
86
+ }
87
+ interface SshTunnel {
88
+ baseUrl: string;
89
+ close(): Promise<void>;
90
+ }
91
+ type MakeTunnel = (client: Ssh2Client, daemonPort: number) => Promise<SshTunnel>;
92
+ /** The resolved inputs {@link provisionSsh} needs — decoupled from `SshOptions` and the lazy import. */
93
+ export interface SshProvisionConfig {
94
+ /** Stable id for the handle (for logging). */
95
+ id: string;
96
+ /** Daemon port on the remote loopback. */
97
+ daemonPort: number;
98
+ /** `AGENT_TYPE` for the remote daemon. */
99
+ agent: string;
100
+ /** `AGENT_CWD` on the remote. */
101
+ agentCwd: string;
102
+ daemonBin?: string;
103
+ autoUpdate?: boolean;
104
+ /** Close the tunnel + end the SSH connection on `stop()`. */
105
+ stopOnExit?: boolean;
106
+ onLog?: (e: EnsureEvent) => void;
107
+ }
108
+ /**
109
+ * The provisioning flow, decoupled from the `ssh2` import and the tunnel implementation so it can be
110
+ * driven by an injected fake client + `makeTunnel` in tests. Ensures the daemon over the SSH
111
+ * connection, brings up the tunnel, and returns a handle pointed at `http://127.0.0.1:<localPort>`.
112
+ */
113
+ export declare function provisionSsh(client: Ssh2Client, makeTunnel: MakeTunnel, cfg: SshProvisionConfig): Promise<TargetHandle>;
114
+ /** The resolved inputs {@link provisionSshContainer} needs — the shared daemon knobs plus `docker`. */
115
+ export interface SshContainerProvisionConfig {
116
+ /** Stable id for the handle (for logging). */
117
+ id: string;
118
+ /** Port the daemon binds *inside* the container. */
119
+ daemonPort: number;
120
+ /** `AGENT_TYPE` for the in-container daemon. */
121
+ agent: string;
122
+ /** `AGENT_CWD` inside the container. */
123
+ agentCwd: string;
124
+ daemonBin?: string;
125
+ autoUpdate?: boolean;
126
+ /** Close the tunnel, `docker rm -f` a created container, and end the SSH connection on `stop()`. */
127
+ stopOnExit?: boolean;
128
+ onLog?: (e: EnsureEvent) => void;
129
+ /** Container knobs (image/attach/name/install/createArgs). */
130
+ docker: NonNullable<SshOptions["docker"]>;
131
+ }
132
+ /**
133
+ * Provision the daemon **in a container** on the remote host over SSH: bridge the SSH connection into a
134
+ * {@link SandboxHost}, hand it to the generic {@link provisionContainer} (ensure Docker → run container
135
+ * → deploy the daemon inside), then tunnel to the container's published loopback host port. Decoupled
136
+ * from the `ssh2` import + tunnel like {@link provisionSsh}, so tests drive it with a fake client.
137
+ */
138
+ export declare function provisionSshContainer(client: Ssh2Client, makeTunnel: MakeTunnel, cfg: SshContainerProvisionConfig): Promise<TargetHandle>;
139
+ export {};