linkshell-cli 0.8.1 → 0.9.0
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/dist/cli/src/commands/host.d.ts +2 -0
- package/dist/cli/src/commands/host.js.map +1 -1
- package/dist/cli/src/commands/screen.d.ts +10 -0
- package/dist/cli/src/commands/screen.js +82 -74
- package/dist/cli/src/commands/screen.js.map +1 -1
- package/dist/cli/src/commands/setup.d.ts +11 -1
- package/dist/cli/src/commands/setup.js +100 -38
- package/dist/cli/src/commands/setup.js.map +1 -1
- package/dist/cli/src/index.js +17 -5
- package/dist/cli/src/index.js.map +1 -1
- package/dist/cli/tsconfig.tsbuildinfo +1 -1
- package/dist/host/src/input.d.ts +114 -29
- package/dist/host/src/input.js +214 -144
- package/dist/host/src/input.js.map +1 -1
- package/dist/host/src/rpc/server.js +1 -1
- package/dist/host/src/rpc/server.js.map +1 -1
- package/dist/host/src/screen-pacer.d.ts +76 -0
- package/dist/host/src/screen-pacer.js +165 -0
- package/dist/host/src/screen-pacer.js.map +1 -0
- package/dist/host/src/screen-viewer.d.ts +5 -0
- package/dist/host/src/screen-viewer.js +1263 -57
- package/dist/host/src/screen-viewer.js.map +1 -1
- package/dist/host/src/screen.d.ts +29 -32
- package/dist/host/src/screen.js +418 -138
- package/dist/host/src/screen.js.map +1 -1
- package/dist/host/src/terminals.d.ts +2 -2
- package/dist/host/src/terminals.js +1 -0
- package/dist/host/src/terminals.js.map +1 -1
- package/package.json +3 -3
- package/src/commands/host.ts +2 -0
- package/src/commands/screen.ts +78 -72
- package/src/commands/setup.ts +100 -60
- package/src/index.ts +16 -5
package/dist/host/src/input.d.ts
CHANGED
|
@@ -73,11 +73,11 @@ export declare const inputEvent: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
73
73
|
t: z.ZodLiteral<"text">;
|
|
74
74
|
s: z.ZodString;
|
|
75
75
|
}, "strip", z.ZodTypeAny, {
|
|
76
|
-
t: "text";
|
|
77
76
|
s: string;
|
|
78
|
-
}, {
|
|
79
77
|
t: "text";
|
|
78
|
+
}, {
|
|
80
79
|
s: string;
|
|
80
|
+
t: "text";
|
|
81
81
|
}>, z.ZodObject<{
|
|
82
82
|
t: z.ZodLiteral<"prompt">;
|
|
83
83
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -107,25 +107,92 @@ export interface HelperStatus {
|
|
|
107
107
|
trusted: boolean;
|
|
108
108
|
recording: boolean;
|
|
109
109
|
app: string;
|
|
110
|
+
/** The app can send the screen as a video track (it carries the media engine). */
|
|
111
|
+
video: boolean;
|
|
112
|
+
}
|
|
113
|
+
/** A display as the app sees it. `screen` is its number in everything said to the app. */
|
|
114
|
+
export interface AppDisplay {
|
|
115
|
+
screen: number;
|
|
116
|
+
name: string;
|
|
117
|
+
/** In pixels. */
|
|
118
|
+
w: number;
|
|
119
|
+
h: number;
|
|
120
|
+
main: boolean;
|
|
121
|
+
}
|
|
122
|
+
/** The picture asked of the app for a pipe that loses nothing: rates in bits a second. */
|
|
123
|
+
export interface StreamProfile {
|
|
124
|
+
width: number;
|
|
125
|
+
fps: number;
|
|
126
|
+
bitrate: number;
|
|
127
|
+
ceiling: number;
|
|
110
128
|
}
|
|
129
|
+
/** A stream under way. */
|
|
130
|
+
export interface AppStream {
|
|
131
|
+
/** Another profile, without stopping: a new size starts a new generation, at a keyframe. */
|
|
132
|
+
set(profile: StreamProfile): void;
|
|
133
|
+
/** The next frame a keyframe. */
|
|
134
|
+
key(): void;
|
|
135
|
+
end(): void;
|
|
136
|
+
}
|
|
137
|
+
/** How the app is to offer a screen as a video track. */
|
|
138
|
+
export interface VideoOffer {
|
|
139
|
+
/** Which of the system's displays. */
|
|
140
|
+
screen: number;
|
|
141
|
+
iceServers: {
|
|
142
|
+
urls: string[];
|
|
143
|
+
}[];
|
|
144
|
+
/** Frames a second; the app's own choice when left out. */
|
|
145
|
+
fps?: number;
|
|
146
|
+
}
|
|
147
|
+
/** What a viewer answers the app's offer with, and the candidates it finds. */
|
|
148
|
+
export type VideoSignal = {
|
|
149
|
+
t: "rtc.answer";
|
|
150
|
+
sdp: string;
|
|
151
|
+
} | {
|
|
152
|
+
t: "rtc.ice";
|
|
153
|
+
candidate: string;
|
|
154
|
+
sdpMid: string | null;
|
|
155
|
+
sdpMLineIndex: number | null;
|
|
156
|
+
};
|
|
157
|
+
export declare const videoSignal: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
158
|
+
t: z.ZodLiteral<"rtc.answer">;
|
|
159
|
+
sdp: z.ZodString;
|
|
160
|
+
}, "strip", z.ZodTypeAny, {
|
|
161
|
+
t: "rtc.answer";
|
|
162
|
+
sdp: string;
|
|
163
|
+
}, {
|
|
164
|
+
t: "rtc.answer";
|
|
165
|
+
sdp: string;
|
|
166
|
+
}>, z.ZodObject<{
|
|
167
|
+
t: z.ZodLiteral<"rtc.ice">;
|
|
168
|
+
candidate: z.ZodString;
|
|
169
|
+
sdpMid: z.ZodNullable<z.ZodString>;
|
|
170
|
+
sdpMLineIndex: z.ZodNullable<z.ZodNumber>;
|
|
171
|
+
}, "strip", z.ZodTypeAny, {
|
|
172
|
+
t: "rtc.ice";
|
|
173
|
+
candidate: string;
|
|
174
|
+
sdpMid: string | null;
|
|
175
|
+
sdpMLineIndex: number | null;
|
|
176
|
+
}, {
|
|
177
|
+
t: "rtc.ice";
|
|
178
|
+
candidate: string;
|
|
179
|
+
sdpMid: string | null;
|
|
180
|
+
sdpMLineIndex: number | null;
|
|
181
|
+
}>]>;
|
|
111
182
|
/**
|
|
112
|
-
* The app
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
183
|
+
* The app out of the archive it is shipped in, unpacked under the user's own
|
|
184
|
+
* directory. An archive, because a package can carry neither the links a
|
|
185
|
+
* framework is made of nor a program's permission to run; unpacked whole, the
|
|
186
|
+
* app is as it was signed. Always at the same place, so that an upgrade
|
|
187
|
+
* replaces the app instead of adding another: macOS has been seen to ask
|
|
188
|
+
* about recording again for the same app run from a new path. (A host still
|
|
189
|
+
* running the app being replaced keeps the one it has open.)
|
|
117
190
|
*/
|
|
118
|
-
export declare function
|
|
119
|
-
/**
|
|
191
|
+
export declare function unpackedApp(archive: string, at?: string): string | undefined;
|
|
192
|
+
/** LinkShell.app, where this installation has it: a Mac with Apple silicon, with `@linkshell/mac` installed beside the host. */
|
|
120
193
|
export declare function shippedApp(): string | undefined;
|
|
121
|
-
/**
|
|
122
|
-
export declare
|
|
123
|
-
/**
|
|
124
|
-
* What this process itself (so: the host, and the capture it starts) is
|
|
125
|
-
* allowed to do, and under which app's name. `ask` has the system put its
|
|
126
|
-
* question for that permission, and opens the settings page for it.
|
|
127
|
-
*/
|
|
128
|
-
export declare function hostAccess(log: (message: string) => void, ask?: "recording" | "control"): Promise<HelperStatus>;
|
|
194
|
+
/** What to tell someone whose Mac has no LinkShell.app: it is an Intel Mac (the app is built for Apple silicon only), or the package that carries it wasn't installed. */
|
|
195
|
+
export declare const NO_APP: string;
|
|
129
196
|
type Route = (message: Record<string, unknown>) => void;
|
|
130
197
|
declare class HelperApp {
|
|
131
198
|
private readonly app;
|
|
@@ -138,6 +205,7 @@ declare class HelperApp {
|
|
|
138
205
|
private readonly routes;
|
|
139
206
|
private readonly watchers;
|
|
140
207
|
private waiting;
|
|
208
|
+
private listing;
|
|
141
209
|
constructor(app: string, dryRun: boolean, log: (message: string) => void);
|
|
142
210
|
/** The app's end of the socket; opens the app when it isn't there. */
|
|
143
211
|
private link;
|
|
@@ -146,17 +214,34 @@ declare class HelperApp {
|
|
|
146
214
|
private write;
|
|
147
215
|
/** What the app may do. It says so as it connects; asked again, it looks again. */
|
|
148
216
|
access(): Promise<HelperStatus>;
|
|
149
|
-
/** The
|
|
150
|
-
|
|
217
|
+
/** The displays there are to watch. */
|
|
218
|
+
displays(): Promise<AppDisplay[]>;
|
|
219
|
+
/**
|
|
220
|
+
* Has the app capture a screen and encode it for a pipe that loses nothing:
|
|
221
|
+
* the socket to a viewer it couldn't reach directly. Whole frames come to
|
|
222
|
+
* `on.frame`, each with the generation of picture size it belongs to.
|
|
223
|
+
*/
|
|
224
|
+
stream(screen: number, profile: StreamProfile, on: {
|
|
225
|
+
frame(unit: Buffer, key: boolean, generation: number): void;
|
|
226
|
+
exit(error?: string): void;
|
|
227
|
+
}): Promise<AppStream>;
|
|
228
|
+
/**
|
|
229
|
+
* Opens LinkShell's own window for its permissions, on this computer: it says
|
|
230
|
+
* what each is for, has the system ask, takes the user to the switch, and
|
|
231
|
+
* ticks each off as it is turned on. Nothing appears when both are allowed
|
|
232
|
+
* already, and there is only ever one such window.
|
|
233
|
+
*/
|
|
234
|
+
ask(): Promise<void>;
|
|
151
235
|
/**
|
|
152
|
-
* Has the app
|
|
153
|
-
*
|
|
154
|
-
*
|
|
236
|
+
* Has the app offer a screen to one viewer as a video track. What the app
|
|
237
|
+
* says of it (`rtc.offer`, `rtc.ice`, `rtc.state`, `rtc.error`, and `gone`
|
|
238
|
+
* when the app itself went) comes to `route`; the viewer's answer goes back
|
|
239
|
+
* with `signal`. The picture and the viewer's hands then travel between the
|
|
240
|
+
* two of them, not through here.
|
|
155
241
|
*/
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}): Promise<() => void>;
|
|
242
|
+
offerVideo(id: string, offer: VideoOffer, route: Route): Promise<void>;
|
|
243
|
+
signal(id: string, signal: VideoSignal): void;
|
|
244
|
+
endVideo(id: string): void;
|
|
160
245
|
join(id: string, screen: number, route: Route, watcher: (status: HelperStatus) => void): Promise<void>;
|
|
161
246
|
send(id: string, event: InputEvent): void;
|
|
162
247
|
leave(id: string, watcher: (status: HelperStatus) => void): void;
|
|
@@ -171,19 +256,19 @@ export type { HelperApp };
|
|
|
171
256
|
export declare class InputControl {
|
|
172
257
|
private readonly listener;
|
|
173
258
|
private readonly log;
|
|
174
|
-
/** `app: false`
|
|
259
|
+
/** `app: false` runs the app's program as this process's child instead of having the system open it (tests). */
|
|
175
260
|
private readonly options;
|
|
176
261
|
private child?;
|
|
177
262
|
private joined?;
|
|
178
263
|
private stopped;
|
|
179
264
|
private started;
|
|
180
265
|
constructor(listener: InputListener, log: (message: string) => void,
|
|
181
|
-
/** `app: false`
|
|
266
|
+
/** `app: false` runs the app's program as this process's child instead of having the system open it (tests). */
|
|
182
267
|
options?: {
|
|
183
268
|
dryRun?: boolean;
|
|
184
269
|
app?: boolean;
|
|
185
270
|
});
|
|
186
|
-
/** Starts
|
|
271
|
+
/** Starts control of the display the app numbers `screen`. Reports through the listener; never throws. */
|
|
187
272
|
start(screen: number): Promise<void>;
|
|
188
273
|
private joinApp;
|
|
189
274
|
private spawn;
|