linkshell-cli 0.8.2 → 0.10.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/README.md +11 -6
- package/dist/cli/src/commands/gateway.d.ts +2 -0
- package/dist/cli/src/commands/gateway.js +29 -0
- package/dist/cli/src/commands/gateway.js.map +1 -0
- package/dist/cli/src/commands/host.d.ts +4 -0
- package/dist/cli/src/commands/host.js +12 -2
- 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 +102 -38
- package/dist/cli/src/commands/setup.js.map +1 -1
- package/dist/cli/src/index.js +28 -338
- package/dist/cli/src/index.js.map +1 -1
- package/dist/cli/src/utils/daemon.d.ts +0 -7
- package/dist/cli/src/utils/daemon.js +1 -18
- package/dist/cli/src/utils/daemon.js.map +1 -1
- package/dist/cli/tsconfig.tsbuildinfo +1 -1
- package/dist/gateway/src/accounts.d.ts +6 -0
- package/dist/gateway/src/accounts.js +32 -0
- package/dist/gateway/src/accounts.js.map +1 -0
- package/dist/gateway/src/index.d.ts +4 -0
- package/dist/gateway/src/index.js +5 -0
- package/dist/gateway/src/index.js.map +1 -0
- package/dist/gateway/src/main.d.ts +1 -0
- package/dist/gateway/src/main.js +57 -0
- package/dist/gateway/src/main.js.map +1 -0
- package/dist/gateway/src/rate-limit.d.ts +22 -0
- package/dist/gateway/src/rate-limit.js +66 -0
- package/dist/gateway/src/rate-limit.js.map +1 -0
- package/dist/gateway/src/relay.d.ts +84 -0
- package/dist/gateway/src/relay.js +434 -0
- package/dist/gateway/src/relay.js.map +1 -0
- package/dist/gateway/src/serve.d.ts +34 -0
- package/dist/gateway/src/serve.js +102 -0
- package/dist/gateway/src/serve.js.map +1 -0
- package/dist/gateway/src/store.d.ts +35 -0
- package/dist/gateway/src/store.js +109 -0
- package/dist/gateway/src/store.js.map +1 -0
- package/dist/gateway/src/subscription.d.ts +18 -0
- package/dist/gateway/src/subscription.js +46 -0
- package/dist/gateway/src/subscription.js.map +1 -0
- package/dist/host/src/drivers/claude/transcript.d.ts +23 -23
- package/dist/host/src/fs.d.ts +3 -3
- package/dist/host/src/input.d.ts +112 -27
- 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 +25 -11
- package/dist/host/src/screen-pacer.js +28 -6
- package/dist/host/src/screen-pacer.js.map +1 -1
- package/dist/host/src/screen-viewer.d.ts +5 -0
- package/dist/host/src/screen-viewer.js +1231 -55
- package/dist/host/src/screen-viewer.js.map +1 -1
- package/dist/host/src/screen.d.ts +19 -10
- package/dist/host/src/screen.js +314 -108
- package/dist/host/src/screen.js.map +1 -1
- package/dist/host/src/terminals.d.ts +1 -1
- package/dist/host/src/terminals.js +1 -0
- package/dist/host/src/terminals.js.map +1 -1
- package/dist/wire/src/model.d.ts +6 -6
- package/dist/wire/src/relay.d.ts +8 -8
- package/dist/wire/src/rpc.d.ts +818 -818
- package/dist/wire/src/updates.d.ts +18 -18
- package/package.json +6 -15
- package/src/commands/gateway.ts +31 -0
- package/src/commands/host.ts +15 -2
- package/src/commands/screen.ts +78 -72
- package/src/commands/setup.ts +102 -60
- package/src/index.ts +29 -433
- package/src/utils/daemon.ts +2 -27
- package/dist/cli/src/config.d.ts +0 -14
- package/dist/cli/src/config.js +0 -23
- package/dist/cli/src/config.js.map +0 -1
- package/dist/cli/src/machine-id.d.ts +0 -6
- package/dist/cli/src/machine-id.js +0 -50
- package/dist/cli/src/machine-id.js.map +0 -1
- package/dist/cli/src/providers.d.ts +0 -13
- package/dist/cli/src/providers.js +0 -77
- package/dist/cli/src/providers.js.map +0 -1
- package/dist/cli/src/runtime/acp/acp-client.d.ts +0 -128
- package/dist/cli/src/runtime/acp/acp-client.js +0 -430
- package/dist/cli/src/runtime/acp/acp-client.js.map +0 -1
- package/dist/cli/src/runtime/acp/agent-process-discovery.d.ts +0 -48
- package/dist/cli/src/runtime/acp/agent-process-discovery.js +0 -278
- package/dist/cli/src/runtime/acp/agent-process-discovery.js.map +0 -1
- package/dist/cli/src/runtime/acp/agent-session.d.ts +0 -62
- package/dist/cli/src/runtime/acp/agent-session.js +0 -1081
- package/dist/cli/src/runtime/acp/agent-session.js.map +0 -1
- package/dist/cli/src/runtime/acp/agent-workspace.d.ts +0 -311
- package/dist/cli/src/runtime/acp/agent-workspace.js +0 -6083
- package/dist/cli/src/runtime/acp/agent-workspace.js.map +0 -1
- package/dist/cli/src/runtime/acp/claude-sdk-client.d.ts +0 -121
- package/dist/cli/src/runtime/acp/claude-sdk-client.js +0 -1147
- package/dist/cli/src/runtime/acp/claude-sdk-client.js.map +0 -1
- package/dist/cli/src/runtime/acp/claude-stream-json-client.d.ts +0 -53
- package/dist/cli/src/runtime/acp/claude-stream-json-client.js +0 -552
- package/dist/cli/src/runtime/acp/claude-stream-json-client.js.map +0 -1
- package/dist/cli/src/runtime/acp/json-rpc.d.ts +0 -22
- package/dist/cli/src/runtime/acp/json-rpc.js +0 -160
- package/dist/cli/src/runtime/acp/json-rpc.js.map +0 -1
- package/dist/cli/src/runtime/acp/provider-resolver.d.ts +0 -16
- package/dist/cli/src/runtime/acp/provider-resolver.js +0 -132
- package/dist/cli/src/runtime/acp/provider-resolver.js.map +0 -1
- package/dist/cli/src/runtime/bridge-session.d.ts +0 -97
- package/dist/cli/src/runtime/bridge-session.js +0 -1364
- package/dist/cli/src/runtime/bridge-session.js.map +0 -1
- package/dist/cli/src/runtime/hook-command.d.ts +0 -9
- package/dist/cli/src/runtime/hook-command.js +0 -80
- package/dist/cli/src/runtime/hook-command.js.map +0 -1
- package/dist/cli/src/runtime/screen-fallback.d.ts +0 -22
- package/dist/cli/src/runtime/screen-fallback.js +0 -202
- package/dist/cli/src/runtime/screen-fallback.js.map +0 -1
- package/dist/cli/src/runtime/screen-share.d.ts +0 -34
- package/dist/cli/src/runtime/screen-share.js +0 -376
- package/dist/cli/src/runtime/screen-share.js.map +0 -1
- package/dist/cli/src/runtime/scrollback.d.ts +0 -11
- package/dist/cli/src/runtime/scrollback.js +0 -33
- package/dist/cli/src/runtime/scrollback.js.map +0 -1
- package/dist/cli/src/runtime/usage-report.d.ts +0 -34
- package/dist/cli/src/runtime/usage-report.js +0 -332
- package/dist/cli/src/runtime/usage-report.js.map +0 -1
- package/dist/cli/src/utils/keep-awake.d.ts +0 -6
- package/dist/cli/src/utils/keep-awake.js +0 -48
- package/dist/cli/src/utils/keep-awake.js.map +0 -1
- package/dist/cli/src/utils/lan-ip.d.ts +0 -9
- package/dist/cli/src/utils/lan-ip.js +0 -61
- package/dist/cli/src/utils/lan-ip.js.map +0 -1
- package/dist/host/src/input-helper.d.ts +0 -1
- package/dist/host/src/input-helper.js +0 -564
- package/dist/host/src/input-helper.js.map +0 -1
- package/dist/shared-protocol/src/index.d.ts +0 -17029
- package/dist/shared-protocol/src/index.js +0 -1064
- package/dist/shared-protocol/src/index.js.map +0 -1
- package/scripts/copy-web.mjs +0 -34
- package/src/config.ts +0 -36
- package/src/machine-id.ts +0 -61
- package/src/providers.ts +0 -97
- package/src/runtime/acp/acp-client.ts +0 -521
- package/src/runtime/acp/agent-process-discovery.ts +0 -308
- package/src/runtime/acp/agent-session.ts +0 -1186
- package/src/runtime/acp/agent-workspace.ts +0 -6590
- package/src/runtime/acp/claude-sdk-client.ts +0 -1221
- package/src/runtime/acp/claude-stream-json-client.ts +0 -633
- package/src/runtime/acp/json-rpc.ts +0 -184
- package/src/runtime/acp/provider-resolver.ts +0 -154
- package/src/runtime/bridge-session.ts +0 -1549
- package/src/runtime/hook-command.ts +0 -73
- package/src/runtime/screen-fallback.ts +0 -235
- package/src/runtime/screen-share.ts +0 -426
- package/src/runtime/scrollback.ts +0 -43
- package/src/runtime/usage-report.ts +0 -342
- package/src/utils/keep-awake.ts +0 -61
- package/src/utils/lan-ip.ts +0 -61
- package/web/assets/FileBrowser-wOAfY-xj.js +0 -2
- package/web/assets/PortPreview-Cbvv7yzA.js +0 -2
- package/web/assets/TerminalPanel-CTSklkct.js +0 -1
- package/web/assets/UsageDashboard-CJ1AsNmd.js +0 -1
- package/web/assets/index-BsnDaeCt.css +0 -33
- package/web/assets/index-q85psYZ5.js +0 -36
- package/web/assets/vendor-highlight-NXWAAyIv.js +0 -5
- package/web/assets/vendor-react-M7xG3qiw.js +0 -49
- package/web/assets/vendor-xterm-D15THcI4.js +0 -9
- package/web/index.html +0 -37
- package/web/logos/claude.png +0 -0
- package/web/logos/codex.png +0 -0
- package/web/logos/copilot.png +0 -0
- package/web/logos/gemini.png +0 -0
- package/web/logos/linkshell-1024.png +0 -0
- package/web/logos/linkshell-splash.png +0 -0
- package/web/logos/linkshell.png +0 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { DatabaseSync } from "node:sqlite";
|
|
2
|
+
export class GatewayStore {
|
|
3
|
+
db;
|
|
4
|
+
constructor(path) {
|
|
5
|
+
this.db = new DatabaseSync(path);
|
|
6
|
+
this.db.exec(`
|
|
7
|
+
PRAGMA journal_mode = WAL;
|
|
8
|
+
CREATE TABLE IF NOT EXISTS peers (
|
|
9
|
+
id TEXT PRIMARY KEY,
|
|
10
|
+
role TEXT NOT NULL,
|
|
11
|
+
sign_key TEXT NOT NULL,
|
|
12
|
+
box_key TEXT NOT NULL,
|
|
13
|
+
name TEXT NOT NULL,
|
|
14
|
+
platform TEXT,
|
|
15
|
+
user_id TEXT,
|
|
16
|
+
last_seen INTEGER NOT NULL
|
|
17
|
+
);
|
|
18
|
+
CREATE INDEX IF NOT EXISTS peers_by_user ON peers (user_id);
|
|
19
|
+
CREATE TABLE IF NOT EXISTS links (
|
|
20
|
+
machine_id TEXT NOT NULL,
|
|
21
|
+
device_id TEXT NOT NULL,
|
|
22
|
+
created_at INTEGER NOT NULL,
|
|
23
|
+
PRIMARY KEY (machine_id, device_id)
|
|
24
|
+
) WITHOUT ROWID;
|
|
25
|
+
CREATE INDEX IF NOT EXISTS links_by_device ON links (device_id);
|
|
26
|
+
`);
|
|
27
|
+
}
|
|
28
|
+
close() {
|
|
29
|
+
this.db.close();
|
|
30
|
+
}
|
|
31
|
+
peer(id) {
|
|
32
|
+
const row = this.db.prepare("SELECT * FROM peers WHERE id = ?").get(id);
|
|
33
|
+
return row ? toPeer(row) : undefined;
|
|
34
|
+
}
|
|
35
|
+
upsertPeer(peer) {
|
|
36
|
+
this.db
|
|
37
|
+
.prepare(`INSERT INTO peers (id, role, sign_key, box_key, name, platform, user_id, last_seen)
|
|
38
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
39
|
+
ON CONFLICT(id) DO UPDATE SET box_key = excluded.box_key, name = excluded.name,
|
|
40
|
+
platform = excluded.platform, user_id = excluded.user_id, last_seen = excluded.last_seen`)
|
|
41
|
+
.run(peer.id, peer.role, peer.signKey, peer.boxKey, peer.name, peer.platform ?? null, peer.userId ?? null, peer.lastSeen);
|
|
42
|
+
}
|
|
43
|
+
touch(id, at = Date.now()) {
|
|
44
|
+
this.db.prepare("UPDATE peers SET last_seen = ? WHERE id = ?").run(at, id);
|
|
45
|
+
}
|
|
46
|
+
link(machineId, deviceId, at = Date.now()) {
|
|
47
|
+
this.db.prepare("INSERT OR IGNORE INTO links (machine_id, device_id, created_at) VALUES (?, ?, ?)").run(machineId, deviceId, at);
|
|
48
|
+
}
|
|
49
|
+
unlink(machineId, deviceId) {
|
|
50
|
+
return this.db.prepare("DELETE FROM links WHERE machine_id = ? AND device_id = ?").run(machineId, deviceId).changes > 0;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Takes a peer off its account: the account's other peers no longer reach it, or list it. Its
|
|
54
|
+
* keys and pairings stay, and signing in again puts it back.
|
|
55
|
+
*/
|
|
56
|
+
disown(id) {
|
|
57
|
+
return this.db.prepare("UPDATE peers SET user_id = NULL WHERE id = ? AND user_id IS NOT NULL").run(id).changes > 0;
|
|
58
|
+
}
|
|
59
|
+
linkedAt(machineId, deviceId) {
|
|
60
|
+
const row = this.db.prepare("SELECT created_at FROM links WHERE machine_id = ? AND device_id = ?").get(machineId, deviceId);
|
|
61
|
+
return row?.created_at;
|
|
62
|
+
}
|
|
63
|
+
/** Peers of the other role that `id` may reach: linked, or owned by the same account. */
|
|
64
|
+
reachable(id) {
|
|
65
|
+
const self = this.peer(id);
|
|
66
|
+
if (!self)
|
|
67
|
+
return [];
|
|
68
|
+
const other = self.role === "machine" ? "device" : "machine";
|
|
69
|
+
const linked = (self.role === "machine"
|
|
70
|
+
? this.db.prepare("SELECT p.*, l.created_at AS paired_at FROM links l JOIN peers p ON p.id = l.device_id WHERE l.machine_id = ?").all(id)
|
|
71
|
+
: this.db.prepare("SELECT p.*, l.created_at AS paired_at FROM links l JOIN peers p ON p.id = l.machine_id WHERE l.device_id = ?").all(id));
|
|
72
|
+
const out = new Map();
|
|
73
|
+
for (const row of linked)
|
|
74
|
+
out.set(String(row.id), { peer: toPeer(row), via: "paired", pairedAt: Number(row.paired_at) });
|
|
75
|
+
if (self.userId) {
|
|
76
|
+
const owned = this.db.prepare("SELECT * FROM peers WHERE user_id = ? AND role = ?").all(self.userId, other);
|
|
77
|
+
for (const row of owned)
|
|
78
|
+
if (!out.has(String(row.id)))
|
|
79
|
+
out.set(String(row.id), { peer: toPeer(row), via: "account" });
|
|
80
|
+
}
|
|
81
|
+
return [...out.values()];
|
|
82
|
+
}
|
|
83
|
+
/** How `from` may reach `to`, or undefined when it may not. */
|
|
84
|
+
route(from, to) {
|
|
85
|
+
const a = this.peer(from);
|
|
86
|
+
const b = this.peer(to);
|
|
87
|
+
if (!a || !b || a.role === b.role)
|
|
88
|
+
return undefined;
|
|
89
|
+
const [machine, device] = a.role === "machine" ? [a, b] : [b, a];
|
|
90
|
+
if (this.linkedAt(machine.id, device.id) !== undefined)
|
|
91
|
+
return "paired";
|
|
92
|
+
if (a.userId && a.userId === b.userId)
|
|
93
|
+
return "account";
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function toPeer(row) {
|
|
98
|
+
return {
|
|
99
|
+
id: String(row.id),
|
|
100
|
+
role: row.role,
|
|
101
|
+
signKey: String(row.sign_key),
|
|
102
|
+
boxKey: String(row.box_key),
|
|
103
|
+
name: String(row.name),
|
|
104
|
+
platform: row.platform ? String(row.platform) : undefined,
|
|
105
|
+
userId: row.user_id ? String(row.user_id) : undefined,
|
|
106
|
+
lastSeen: Number(row.last_seen),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../gateway/src/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { GatewayOptions } from "./relay.js";
|
|
2
|
+
export interface SubscriptionCheck {
|
|
3
|
+
/** "unknown": the lookup itself failed, which says nothing about the account. */
|
|
4
|
+
status: "active" | "inactive" | "unknown";
|
|
5
|
+
reason?: string;
|
|
6
|
+
}
|
|
7
|
+
export type CheckSubscription = (userId: string) => Promise<SubscriptionCheck>;
|
|
8
|
+
export declare function supabaseSubscriptions(supabase: {
|
|
9
|
+
url: string;
|
|
10
|
+
anonKey: string;
|
|
11
|
+
serviceRoleKey: string;
|
|
12
|
+
}): CheckSubscription;
|
|
13
|
+
/**
|
|
14
|
+
* The official gateway's rule for who may connect: a computer needs an active
|
|
15
|
+
* Pro account. Devices only reach computers they're paired with or share an
|
|
16
|
+
* account with, so they need nothing more.
|
|
17
|
+
*/
|
|
18
|
+
export declare function requirePro(check: CheckSubscription, warn: (message: string) => void): NonNullable<GatewayOptions["admit"]>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export function supabaseSubscriptions(supabase) {
|
|
2
|
+
return async (userId) => {
|
|
3
|
+
if (!supabase.url || !supabase.anonKey)
|
|
4
|
+
return { status: "unknown", reason: "missing_supabase_config" };
|
|
5
|
+
if (!supabase.serviceRoleKey)
|
|
6
|
+
return { status: "unknown", reason: "missing_service_role_key" };
|
|
7
|
+
try {
|
|
8
|
+
const response = await fetch(`${supabase.url}/rest/v1/profiles?id=eq.${userId}&select=plan,plan_expires_at&limit=1`, {
|
|
9
|
+
headers: { Authorization: `Bearer ${supabase.serviceRoleKey}`, apikey: supabase.anonKey },
|
|
10
|
+
signal: AbortSignal.timeout(5_000),
|
|
11
|
+
});
|
|
12
|
+
if (!response.ok)
|
|
13
|
+
return { status: "unknown", reason: `profile_lookup_http_${response.status}` };
|
|
14
|
+
const profiles = (await response.json());
|
|
15
|
+
const profile = profiles[0];
|
|
16
|
+
if (!profile)
|
|
17
|
+
return { status: "unknown", reason: "profile_not_found" };
|
|
18
|
+
const active = profile.plan === "pro" && !!profile.plan_expires_at && new Date(profile.plan_expires_at) > new Date();
|
|
19
|
+
return { status: active ? "active" : "inactive" };
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return { status: "unknown", reason: "profile_lookup_failed" };
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The official gateway's rule for who may connect: a computer needs an active
|
|
28
|
+
* Pro account. Devices only reach computers they're paired with or share an
|
|
29
|
+
* account with, so they need nothing more.
|
|
30
|
+
*/
|
|
31
|
+
export function requirePro(check, warn) {
|
|
32
|
+
return async ({ role, userId }) => {
|
|
33
|
+
if (role !== "machine")
|
|
34
|
+
return undefined;
|
|
35
|
+
if (!userId)
|
|
36
|
+
return "官方网关需要登录 Pro 账号:在电脑上运行 linkshell login";
|
|
37
|
+
const subscription = await check(userId);
|
|
38
|
+
// A lookup failure isn't a lapsed subscription; don't lock people out over it.
|
|
39
|
+
if (subscription.status === "inactive")
|
|
40
|
+
return "官方网关需要 Pro 订阅:https://itool.tech";
|
|
41
|
+
if (subscription.status === "unknown")
|
|
42
|
+
warn(`subscription check unavailable (${subscription.reason}); admitting ${userId}`);
|
|
43
|
+
return undefined;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=subscription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../../../gateway/src/subscription.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,qBAAqB,CAAC,QAAkE;IACtG,OAAO,KAAK,EAAE,MAAM,EAAE,EAAE;QACtB,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO;YAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;QACxG,IAAI,CAAC,QAAQ,CAAC,cAAc;YAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,0BAA0B,EAAE,CAAC;QAC/F,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,CAAC,GAAG,2BAA2B,MAAM,sCAAsC,EAAE;gBACnH,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,OAAO,EAAE;gBACzF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;aACnC,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,uBAAuB,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YACjG,MAAM,QAAQ,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuD,CAAC;YAC/F,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,CAAC,OAAO;gBAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;YACxE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,eAAe,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;YACrH,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;QAChE,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAwB,EAAE,IAA+B;IAClF,OAAO,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QAChC,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACzC,IAAI,CAAC,MAAM;YAAE,OAAO,wCAAwC,CAAC;QAC7D,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;QACzC,+EAA+E;QAC/E,IAAI,YAAY,CAAC,MAAM,KAAK,UAAU;YAAE,OAAO,kCAAkC,CAAC;QAClF,IAAI,YAAY,CAAC,MAAM,KAAK,SAAS;YAAE,IAAI,CAAC,mCAAmC,YAAY,CAAC,MAAM,gBAAgB,MAAM,EAAE,CAAC,CAAC;QAC5H,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -33,7 +33,6 @@ export declare function transcriptLine(raw: string, options?: {
|
|
|
33
33
|
/** Parses a whole transcript file. */
|
|
34
34
|
/** When each transcript update happened, for history import. */
|
|
35
35
|
export declare const transcriptTimes: WeakMap<{
|
|
36
|
-
sessionUpdate: "user_message_chunk";
|
|
37
36
|
content: {
|
|
38
37
|
type: "text";
|
|
39
38
|
text: string;
|
|
@@ -43,15 +42,14 @@ export declare const transcriptTimes: WeakMap<{
|
|
|
43
42
|
data?: string | undefined;
|
|
44
43
|
uri?: string | undefined;
|
|
45
44
|
} | {
|
|
46
|
-
name: string;
|
|
47
45
|
type: "resource_link";
|
|
46
|
+
name: string;
|
|
48
47
|
uri: string;
|
|
49
48
|
kind?: "agent" | "file" | "skill" | undefined;
|
|
50
49
|
};
|
|
50
|
+
sessionUpdate: "user_message_chunk";
|
|
51
51
|
messageId?: string | undefined;
|
|
52
52
|
} | {
|
|
53
|
-
sessionUpdate: "agent_message_chunk";
|
|
54
|
-
messageId: string;
|
|
55
53
|
content: {
|
|
56
54
|
type: "text";
|
|
57
55
|
text: string;
|
|
@@ -61,15 +59,15 @@ export declare const transcriptTimes: WeakMap<{
|
|
|
61
59
|
data?: string | undefined;
|
|
62
60
|
uri?: string | undefined;
|
|
63
61
|
} | {
|
|
64
|
-
name: string;
|
|
65
62
|
type: "resource_link";
|
|
63
|
+
name: string;
|
|
66
64
|
uri: string;
|
|
67
65
|
kind?: "agent" | "file" | "skill" | undefined;
|
|
68
66
|
};
|
|
67
|
+
sessionUpdate: "agent_message_chunk";
|
|
68
|
+
messageId: string;
|
|
69
69
|
parentToolCallId?: string | undefined;
|
|
70
70
|
} | {
|
|
71
|
-
sessionUpdate: "agent_thought_chunk";
|
|
72
|
-
messageId: string;
|
|
73
71
|
content: {
|
|
74
72
|
type: "text";
|
|
75
73
|
text: string;
|
|
@@ -79,16 +77,18 @@ export declare const transcriptTimes: WeakMap<{
|
|
|
79
77
|
data?: string | undefined;
|
|
80
78
|
uri?: string | undefined;
|
|
81
79
|
} | {
|
|
82
|
-
name: string;
|
|
83
80
|
type: "resource_link";
|
|
81
|
+
name: string;
|
|
84
82
|
uri: string;
|
|
85
83
|
kind?: "agent" | "file" | "skill" | undefined;
|
|
86
84
|
};
|
|
85
|
+
sessionUpdate: "agent_thought_chunk";
|
|
86
|
+
messageId: string;
|
|
87
87
|
parentToolCallId?: string | undefined;
|
|
88
88
|
} | {
|
|
89
|
-
status: "
|
|
89
|
+
status: "failed" | "pending" | "in_progress" | "completed";
|
|
90
|
+
kind: "search" | "read" | "edit" | "delete" | "move" | "execute" | "think" | "fetch" | "other";
|
|
90
91
|
title: string;
|
|
91
|
-
kind: "read" | "edit" | "delete" | "move" | "search" | "execute" | "think" | "fetch" | "other";
|
|
92
92
|
toolCallId: string;
|
|
93
93
|
sessionUpdate: "tool_call";
|
|
94
94
|
detail?: {
|
|
@@ -98,12 +98,12 @@ export declare const transcriptTimes: WeakMap<{
|
|
|
98
98
|
} | {
|
|
99
99
|
type: "subagent";
|
|
100
100
|
action: "message" | "spawn" | "wait" | "stop" | "resume" | "list";
|
|
101
|
-
model?: string | undefined;
|
|
102
101
|
task?: string | undefined;
|
|
103
102
|
agentType?: string | undefined;
|
|
103
|
+
model?: string | undefined;
|
|
104
104
|
} | {
|
|
105
|
-
name: string;
|
|
106
105
|
type: "skill";
|
|
106
|
+
name: string;
|
|
107
107
|
description?: string | undefined;
|
|
108
108
|
} | {
|
|
109
109
|
type: "web_search";
|
|
@@ -132,8 +132,8 @@ export declare const transcriptTimes: WeakMap<{
|
|
|
132
132
|
data?: string | undefined;
|
|
133
133
|
uri?: string | undefined;
|
|
134
134
|
} | {
|
|
135
|
-
name: string;
|
|
136
135
|
type: "resource_link";
|
|
136
|
+
name: string;
|
|
137
137
|
uri: string;
|
|
138
138
|
kind?: "agent" | "file" | "skill" | undefined;
|
|
139
139
|
};
|
|
@@ -161,6 +161,8 @@ export declare const transcriptTimes: WeakMap<{
|
|
|
161
161
|
} | {
|
|
162
162
|
toolCallId: string;
|
|
163
163
|
sessionUpdate: "tool_call_update";
|
|
164
|
+
status?: "failed" | "pending" | "in_progress" | "completed" | undefined;
|
|
165
|
+
title?: string | undefined;
|
|
164
166
|
detail?: {
|
|
165
167
|
type: "mcp";
|
|
166
168
|
tool: string;
|
|
@@ -168,12 +170,12 @@ export declare const transcriptTimes: WeakMap<{
|
|
|
168
170
|
} | {
|
|
169
171
|
type: "subagent";
|
|
170
172
|
action: "message" | "spawn" | "wait" | "stop" | "resume" | "list";
|
|
171
|
-
model?: string | undefined;
|
|
172
173
|
task?: string | undefined;
|
|
173
174
|
agentType?: string | undefined;
|
|
175
|
+
model?: string | undefined;
|
|
174
176
|
} | {
|
|
175
|
-
name: string;
|
|
176
177
|
type: "skill";
|
|
178
|
+
name: string;
|
|
177
179
|
description?: string | undefined;
|
|
178
180
|
} | {
|
|
179
181
|
type: "web_search";
|
|
@@ -191,8 +193,6 @@ export declare const transcriptTimes: WeakMap<{
|
|
|
191
193
|
text: string;
|
|
192
194
|
more?: number | undefined;
|
|
193
195
|
} | undefined;
|
|
194
|
-
status?: "pending" | "in_progress" | "completed" | "failed" | undefined;
|
|
195
|
-
title?: string | undefined;
|
|
196
196
|
content?: ({
|
|
197
197
|
type: "content";
|
|
198
198
|
content: {
|
|
@@ -204,8 +204,8 @@ export declare const transcriptTimes: WeakMap<{
|
|
|
204
204
|
data?: string | undefined;
|
|
205
205
|
uri?: string | undefined;
|
|
206
206
|
} | {
|
|
207
|
-
name: string;
|
|
208
207
|
type: "resource_link";
|
|
208
|
+
name: string;
|
|
209
209
|
uri: string;
|
|
210
210
|
kind?: "agent" | "file" | "skill" | undefined;
|
|
211
211
|
};
|
|
@@ -259,14 +259,14 @@ export declare const transcriptTimes: WeakMap<{
|
|
|
259
259
|
parentToolCallId?: string | undefined;
|
|
260
260
|
} | {
|
|
261
261
|
options: {
|
|
262
|
-
name: string;
|
|
263
262
|
values: {
|
|
264
|
-
name: string;
|
|
265
263
|
value: string;
|
|
264
|
+
name: string;
|
|
266
265
|
description?: string | undefined;
|
|
267
266
|
}[];
|
|
268
267
|
id: string;
|
|
269
|
-
|
|
268
|
+
name: string;
|
|
269
|
+
category: "mode" | "other" | "model" | "effort";
|
|
270
270
|
current: string;
|
|
271
271
|
}[];
|
|
272
272
|
sessionUpdate: "ls_config";
|
|
@@ -283,15 +283,15 @@ export declare const transcriptTimes: WeakMap<{
|
|
|
283
283
|
stopReason?: "error" | "end_turn" | "cancelled" | "max_tokens" | "refusal" | undefined;
|
|
284
284
|
} | {
|
|
285
285
|
options: {
|
|
286
|
+
optionId: string;
|
|
286
287
|
name: string;
|
|
287
288
|
kind: "allow_once" | "allow_always" | "reject_once" | "reject_always";
|
|
288
|
-
optionId: string;
|
|
289
289
|
}[];
|
|
290
290
|
title: string;
|
|
291
291
|
requestId: string;
|
|
292
292
|
sessionUpdate: "ls_permission";
|
|
293
|
-
detail?: string | undefined;
|
|
294
293
|
toolCallId?: string | undefined;
|
|
294
|
+
detail?: string | undefined;
|
|
295
295
|
questions?: {
|
|
296
296
|
id: string;
|
|
297
297
|
kind: "text" | "choice" | "choices";
|
package/dist/host/src/fs.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ export declare function listDirectory(input: {
|
|
|
4
4
|
files?: boolean;
|
|
5
5
|
}): Promise<{
|
|
6
6
|
entries: {
|
|
7
|
-
name: string;
|
|
8
7
|
path: string;
|
|
8
|
+
name: string;
|
|
9
9
|
file?: boolean | undefined;
|
|
10
10
|
project?: boolean | undefined;
|
|
11
11
|
size?: number | undefined;
|
|
@@ -15,8 +15,8 @@ export declare function listDirectory(input: {
|
|
|
15
15
|
home: string;
|
|
16
16
|
} | {
|
|
17
17
|
entries: {
|
|
18
|
-
name: string;
|
|
19
18
|
path: string;
|
|
19
|
+
name: string;
|
|
20
20
|
file?: boolean | undefined;
|
|
21
21
|
project?: boolean | undefined;
|
|
22
22
|
size?: number | undefined;
|
|
@@ -35,8 +35,8 @@ export declare function searchDirectories(input: {
|
|
|
35
35
|
limit: number;
|
|
36
36
|
}, budgetMs?: number): Promise<{
|
|
37
37
|
entries: {
|
|
38
|
-
name: string;
|
|
39
38
|
path: string;
|
|
39
|
+
name: string;
|
|
40
40
|
file?: boolean | undefined;
|
|
41
41
|
project?: boolean | undefined;
|
|
42
42
|
size?: number | undefined;
|
package/dist/host/src/input.d.ts
CHANGED
|
@@ -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;
|
|
110
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;
|
|
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
|
+
sdp: string;
|
|
162
|
+
t: "rtc.answer";
|
|
163
|
+
}, {
|
|
164
|
+
sdp: string;
|
|
165
|
+
t: "rtc.answer";
|
|
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;
|