dsh-plugin-lcu 0.1.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/LICENSE +21 -0
- package/README.md +316 -0
- package/cordis.patch.yml +23 -0
- package/dev-types/dsh.d.ts +292 -0
- package/docs/README.zh.md +291 -0
- package/lib/approval.js +152 -0
- package/lib/approval.js.map +1 -0
- package/lib/connection.js +384 -0
- package/lib/connection.js.map +1 -0
- package/lib/diag.js +52 -0
- package/lib/diag.js.map +1 -0
- package/lib/host-guard.js +137 -0
- package/lib/host-guard.js.map +1 -0
- package/lib/index.js +318 -0
- package/lib/index.js.map +1 -0
- package/lib/tool.js +262 -0
- package/lib/tool.js.map +1 -0
- package/lib/types/approval.d.ts +71 -0
- package/lib/types/approval.d.ts.map +1 -0
- package/lib/types/connection.d.ts +178 -0
- package/lib/types/connection.d.ts.map +1 -0
- package/lib/types/diag.d.ts +17 -0
- package/lib/types/diag.d.ts.map +1 -0
- package/lib/types/host-guard.d.ts +46 -0
- package/lib/types/host-guard.d.ts.map +1 -0
- package/lib/types/index.d.ts +49 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/tool.d.ts +90 -0
- package/lib/types/tool.d.ts.map +1 -0
- package/package.json +79 -0
- package/scripts/codex-baseline.json +10 -0
- package/scripts/gen-presets.mjs +266 -0
- package/scripts/probe-lcu.mjs +154 -0
- package/scripts/update-codex.mjs +525 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LCU approval shapes.
|
|
3
|
+
*
|
|
4
|
+
* LCU's original runtime asks the host before it touches an app, and the request
|
|
5
|
+
* is a specific `elicitation/create` form. This ports the recognition and
|
|
6
|
+
* mapping rules from LCU's own shared client so a DSH host presents exactly the
|
|
7
|
+
* choices the runtime offered — no more (granting an unoffered persistence scope
|
|
8
|
+
* would let the agent keep desktop access the runtime meant to bound) and no
|
|
9
|
+
* fewer (dropping `always` would nag the user every turn).
|
|
10
|
+
*
|
|
11
|
+
* @module dsh-plugin-lcu/approval
|
|
12
|
+
*/
|
|
13
|
+
import type { LcuElicitationRequest, LcuElicitationResponse } from './connection.ts';
|
|
14
|
+
/** One choice a native-app approval may offer. */
|
|
15
|
+
export interface ApprovalChoice {
|
|
16
|
+
readonly value: 'once' | 'session' | 'always' | 'decline';
|
|
17
|
+
readonly label: string;
|
|
18
|
+
}
|
|
19
|
+
/** A recognized native-app approval request. */
|
|
20
|
+
export interface NativeAppApproval {
|
|
21
|
+
readonly message: string;
|
|
22
|
+
readonly resource: string;
|
|
23
|
+
readonly choices: readonly ApprovalChoice[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Recognize the runtime's native-app approval request.
|
|
27
|
+
*
|
|
28
|
+
* The shape is deliberately narrow: an empty-schema form whose `_meta` names the
|
|
29
|
+
* computer-use connector and a concrete app. Every other elicitation the server
|
|
30
|
+
* may send is *not* this, and must be handled elsewhere or cancelled.
|
|
31
|
+
*
|
|
32
|
+
* @param request - one `elicitation/create` payload.
|
|
33
|
+
* @returns the recognized request, or `undefined` when it is a different shape.
|
|
34
|
+
*/
|
|
35
|
+
export declare function nativeAppApproval(request: LcuElicitationRequest): NativeAppApproval | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Map the user's choice back to the response the runtime accepts.
|
|
38
|
+
*
|
|
39
|
+
* @param request - the same payload the choices came from.
|
|
40
|
+
* @param value - the chosen value, or `'cancel'` for a dismissed prompt.
|
|
41
|
+
* @returns an accept/decline/cancel answer; anything unrecognized cancels.
|
|
42
|
+
*/
|
|
43
|
+
export declare function nativeAppApprovalResponse(request: LcuElicitationRequest, value: string): LcuElicitationResponse;
|
|
44
|
+
/**
|
|
45
|
+
* Map a presented option label back to the value the runtime accepts.
|
|
46
|
+
*
|
|
47
|
+
* These are different strings: the question surface answers with the option's
|
|
48
|
+
* LABEL (`"Always allow"`), while the elicitation response needs the choice
|
|
49
|
+
* VALUE (`"always"`). Passing the label straight through looks up nothing and
|
|
50
|
+
* silently cancels a choice the user actually made.
|
|
51
|
+
*
|
|
52
|
+
* @param approval - the request the labels were presented for.
|
|
53
|
+
* @param label - the label the user selected, or `undefined` when dismissed.
|
|
54
|
+
* @returns the choice value, or `'cancel'` when the label matches no option.
|
|
55
|
+
*/
|
|
56
|
+
export declare function approvalValueForLabel(approval: NativeAppApproval, label: string | undefined): string;
|
|
57
|
+
/** The exact origin a browser-site approval names, when it names one. */
|
|
58
|
+
export declare function originApprovalOrigin(request: LcuElicitationRequest): string | undefined;
|
|
59
|
+
/** Whether the request names an already-authorized exact origin. */
|
|
60
|
+
export declare function isPreApprovedOrigin(request: LcuElicitationRequest, allowedOrigins: ReadonlySet<string>): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Normalize a set of user-configured origins.
|
|
63
|
+
*
|
|
64
|
+
* Only exact HTTP(S) origins are accepted; anything else is dropped rather than
|
|
65
|
+
* widened, because a relaxed match here is a site the user never approved.
|
|
66
|
+
*
|
|
67
|
+
* @param values - raw origin strings from configuration.
|
|
68
|
+
* @returns the accepted origins.
|
|
69
|
+
*/
|
|
70
|
+
export declare function normalizeOrigins(values: readonly string[]): Set<string>;
|
|
71
|
+
//# sourceMappingURL=approval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval.d.ts","sourceRoot":"","sources":["../../src/approval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAEpF,kDAAkD;AAClD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAA;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,gDAAgD;AAChD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAA;CAC5C;AAgBD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,GAAG,iBAAiB,GAAG,SAAS,CAsB/F;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,qBAAqB,EAC9B,KAAK,EAAE,MAAM,GACZ,sBAAsB,CAYxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGpG;AAED,yEAAyE;AACzE,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,GAAG,SAAS,CAWvF;AAED,oEAAoE;AACpE,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,qBAAqB,EAC9B,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,GAClC,OAAO,CAGT;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAavE"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The LCU MCP client.
|
|
3
|
+
*
|
|
4
|
+
* Why not `@modelcontextprotocol/sdk` or the host's `@modelcontextprotocol/client`:
|
|
5
|
+
* the harness's own MCP bridge declares `capabilities: {}` and therefore cannot
|
|
6
|
+
* answer elicitation, which is how LCU asks for per-app approval; and pulling a
|
|
7
|
+
* second SDK into a profile plugin would pin a version the host does not own.
|
|
8
|
+
* MCP over stdio is newline-delimited JSON-RPC, so the wire is small enough to
|
|
9
|
+
* own here and keeps this plugin dependency-free at runtime.
|
|
10
|
+
*
|
|
11
|
+
* Contract kept from `amontlabs/lcu`:
|
|
12
|
+
* - declare `capabilities.elicitation` and answer `elicitation/create`
|
|
13
|
+
* - expose only `js` and `js_reset` to the model; `turn_ended` and
|
|
14
|
+
* `js_add_node_module_dir` are host-only
|
|
15
|
+
* - inject the server's `initialize.instructions` into model context
|
|
16
|
+
* - fail closed: an elicitation with no handler, or any unknown shape, cancels
|
|
17
|
+
* - approvals never time out; a pending approval freezes the call deadline
|
|
18
|
+
*
|
|
19
|
+
* @module dsh-plugin-lcu/connection
|
|
20
|
+
*/
|
|
21
|
+
/** One tool as the server describes it. */
|
|
22
|
+
export interface LcuTool {
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly description: string;
|
|
25
|
+
readonly inputSchema: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
/** A single MCP content block, text or image. */
|
|
28
|
+
export type LcuContentBlock = {
|
|
29
|
+
readonly type: 'text';
|
|
30
|
+
readonly text: string;
|
|
31
|
+
} | {
|
|
32
|
+
readonly type: 'image';
|
|
33
|
+
readonly data: string;
|
|
34
|
+
readonly mimeType: string;
|
|
35
|
+
} | {
|
|
36
|
+
readonly type: string;
|
|
37
|
+
readonly [key: string]: unknown;
|
|
38
|
+
};
|
|
39
|
+
/** The result of one `tools/call`. */
|
|
40
|
+
export interface LcuCallResult {
|
|
41
|
+
readonly content: readonly LcuContentBlock[];
|
|
42
|
+
readonly isError: boolean;
|
|
43
|
+
readonly structuredContent?: unknown;
|
|
44
|
+
}
|
|
45
|
+
/** An `elicitation/create` request as the server sends it. */
|
|
46
|
+
export interface LcuElicitationRequest {
|
|
47
|
+
readonly message?: string;
|
|
48
|
+
readonly mode?: string;
|
|
49
|
+
readonly requestedSchema?: unknown;
|
|
50
|
+
readonly _meta?: Record<string, unknown>;
|
|
51
|
+
readonly [key: string]: unknown;
|
|
52
|
+
}
|
|
53
|
+
/** What a host may answer. Anything else is normalized to `cancel`. */
|
|
54
|
+
export type LcuElicitationResponse = {
|
|
55
|
+
readonly action: 'accept';
|
|
56
|
+
readonly content?: Record<string, unknown>;
|
|
57
|
+
readonly _meta?: Record<string, unknown>;
|
|
58
|
+
} | {
|
|
59
|
+
readonly action: 'decline';
|
|
60
|
+
} | {
|
|
61
|
+
readonly action: 'cancel';
|
|
62
|
+
};
|
|
63
|
+
/** Tools the model may see. Everything else is host-only. */
|
|
64
|
+
export declare const MODEL_TOOL_NAMES: readonly string[];
|
|
65
|
+
/** Host-only tools, named so a mistake is loud rather than silent. */
|
|
66
|
+
export declare const HOST_ONLY_TOOL_NAMES: readonly string[];
|
|
67
|
+
/** Lifecycle events the server accepts for `turn_ended`. */
|
|
68
|
+
export type LcuTurnEndEvent = 'Stop' | 'Interrupt' | 'SubagentStop';
|
|
69
|
+
/** Connection options. */
|
|
70
|
+
export interface LcuConnectionOptions {
|
|
71
|
+
/** Executable to spawn; defaults to the installed `lcu` launcher. */
|
|
72
|
+
readonly command: string;
|
|
73
|
+
/** Extra arguments, e.g. `['--chrome']` to enable the browser surface. */
|
|
74
|
+
readonly args?: readonly string[];
|
|
75
|
+
/** Extra environment layered over the current process environment. */
|
|
76
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
77
|
+
/** Working directory for the child process. */
|
|
78
|
+
readonly cwd?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Answer one elicitation. Omit to fail closed: every approval then cancels,
|
|
81
|
+
* which is what LCU expects from a host that cannot present the request.
|
|
82
|
+
*/
|
|
83
|
+
readonly onElicitation?: (request: LcuElicitationRequest, signal: AbortSignal) => Promise<LcuElicitationResponse>;
|
|
84
|
+
/** Called whenever the server's tool list changes. */
|
|
85
|
+
readonly onToolsChanged?: (tools: readonly LcuTool[]) => void;
|
|
86
|
+
/** Receives child-process stderr lines; never model-visible. */
|
|
87
|
+
readonly onStderr?: (line: string) => void;
|
|
88
|
+
}
|
|
89
|
+
/** Where a request is in its lifecycle, for a diagnostic that names the stage. */
|
|
90
|
+
export type LcuStage = 'spawn' | 'initialize' | 'tools/list' | 'tools/call' | 'turn_ended';
|
|
91
|
+
/**
|
|
92
|
+
* Code for the turn-cleanup timeout: the original host stopped waiting for its
|
|
93
|
+
* per-turn cleanup. The cleanup keeps running in the worker and the runtime
|
|
94
|
+
* retries it before the next action, so this is a warning the caller should
|
|
95
|
+
* surface rather than a reason to abort the session.
|
|
96
|
+
*/
|
|
97
|
+
export declare const TURN_CLEANUP_TIMEOUT_CODE = "LCU_TURN_CLEANUP_TIMEOUT";
|
|
98
|
+
/** A failure that names the protocol stage it happened at. */
|
|
99
|
+
export declare class LcuError extends Error {
|
|
100
|
+
readonly stage: LcuStage;
|
|
101
|
+
/** Stable machine-readable classification, when one applies. */
|
|
102
|
+
readonly code?: string;
|
|
103
|
+
constructor(stage: LcuStage, message: string, cause?: unknown, code?: string);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Classify a failed `turn_ended` call.
|
|
107
|
+
*
|
|
108
|
+
* The runtime reports its own cleanup timeout as an ordinary error result with a
|
|
109
|
+
* recognizable detail. Missing it would let a stalled cleanup look like a
|
|
110
|
+
* healthy turn, which is exactly what LCU's contract asks a host not to do.
|
|
111
|
+
*
|
|
112
|
+
* @param result - the failed call's result.
|
|
113
|
+
* @returns the classified error, or `undefined` when the call succeeded.
|
|
114
|
+
*/
|
|
115
|
+
export declare function classifyTurnEndFailure(result: LcuCallResult): LcuError | undefined;
|
|
116
|
+
/**
|
|
117
|
+
* Answer one elicitation, failing closed on every unexpected shape.
|
|
118
|
+
*
|
|
119
|
+
* LCU requires this exact discipline: a host that cannot present the request,
|
|
120
|
+
* a handler that throws, or an answer that is not one of the three actions must
|
|
121
|
+
* all end as `cancel`, because anything else would silently grant desktop access.
|
|
122
|
+
*
|
|
123
|
+
* @param handler - the host's presenter, or `undefined` when there is none.
|
|
124
|
+
* @param request - the server's elicitation params.
|
|
125
|
+
* @param activeCalls - signals of in-flight tool calls; aborting one cancels.
|
|
126
|
+
* @returns an answer the server accepts; never rejects.
|
|
127
|
+
*/
|
|
128
|
+
export declare function resolveElicitation(handler: LcuConnectionOptions['onElicitation'], request: LcuElicitationRequest, activeCalls?: ReadonlySet<AbortSignal>): Promise<LcuElicitationResponse>;
|
|
129
|
+
/**
|
|
130
|
+
* One long-lived connection to the `lcu` MCP server.
|
|
131
|
+
*
|
|
132
|
+
* The connection is per Agent/Session: LCU carries a persistent JavaScript
|
|
133
|
+
* session on its side, and its approvals are scoped to a real host session and
|
|
134
|
+
* turn, so sharing one connection across agents would interleave both.
|
|
135
|
+
*/
|
|
136
|
+
export declare class LcuConnection {
|
|
137
|
+
#private;
|
|
138
|
+
constructor(options: LcuConnectionOptions);
|
|
139
|
+
/** The server's `initialize.instructions`, injected into model context. */
|
|
140
|
+
get instructions(): string;
|
|
141
|
+
/** Server identity, for diagnostics. */
|
|
142
|
+
get serverInfo(): {
|
|
143
|
+
name?: string;
|
|
144
|
+
version?: string;
|
|
145
|
+
};
|
|
146
|
+
/** Everything the server advertised, including host-only tools. */
|
|
147
|
+
get allTools(): readonly LcuTool[];
|
|
148
|
+
/** The tools the model may see, in server order. */
|
|
149
|
+
modelTools(): LcuTool[];
|
|
150
|
+
/**
|
|
151
|
+
* Spawn `lcu`, complete the MCP handshake, and discover tools.
|
|
152
|
+
*
|
|
153
|
+
* @throws {LcuError} when the process cannot start or the handshake fails.
|
|
154
|
+
*/
|
|
155
|
+
connect(signal?: AbortSignal): Promise<void>;
|
|
156
|
+
/**
|
|
157
|
+
* Call one tool. `js_reset` and `js` are the model-facing ones; the host-only
|
|
158
|
+
* tools are reachable here too because the lifecycle needs `turn_ended`.
|
|
159
|
+
*
|
|
160
|
+
* Requests carry no client-side deadline by default: a pause for a human
|
|
161
|
+
* approval must not look like a hung call.
|
|
162
|
+
*/
|
|
163
|
+
callTool(name: string, args: Readonly<Record<string, unknown>>, options?: {
|
|
164
|
+
readonly timeoutMs?: number;
|
|
165
|
+
readonly signal?: AbortSignal;
|
|
166
|
+
}): Promise<LcuCallResult>;
|
|
167
|
+
/**
|
|
168
|
+
* Tell the server a host turn ended, so its per-turn cleanup runs.
|
|
169
|
+
*
|
|
170
|
+
* @param sessionId - the real host session id, and nothing synthetic.
|
|
171
|
+
* @param turnId - the real host turn id.
|
|
172
|
+
* @param event - `Stop`, `Interrupt`, or `SubagentStop`.
|
|
173
|
+
*/
|
|
174
|
+
turnEnded(sessionId: string, turnId: string, event?: LcuTurnEndEvent): Promise<void>;
|
|
175
|
+
/** Close the connection, terminating the child process. */
|
|
176
|
+
close(): Promise<void>;
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best-effort diagnostic log for the LCU attach path.
|
|
3
|
+
*
|
|
4
|
+
* The harness exposes plugin logs only through surfaces a running session
|
|
5
|
+
* cannot read, and a failing `agent/created` listener is swallowed silently. So
|
|
6
|
+
* the attach decision writes here: one line per branch, including the errors
|
|
7
|
+
* that would otherwise vanish. It never throws and never changes behavior.
|
|
8
|
+
*
|
|
9
|
+
* Set `LCU_DIAG=0` to disable. The file is `~/.dsh/lcu-diag.log`.
|
|
10
|
+
*
|
|
11
|
+
* @module dsh-plugin-lcu/diag
|
|
12
|
+
*/
|
|
13
|
+
/** Append one diagnostic line; silently does nothing if the file cannot be written. */
|
|
14
|
+
export declare function diag(message: string): void;
|
|
15
|
+
/** Describe a value for the log without dumping unbounded data. */
|
|
16
|
+
export declare function describe(value: unknown): string;
|
|
17
|
+
//# sourceMappingURL=diag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diag.d.ts","sourceRoot":"","sources":["../../src/diag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAWH,uFAAuF;AACvF,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAU1C;AAED,mEAAmE;AACnE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAS/C"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agent-host guard.
|
|
3
|
+
*
|
|
4
|
+
* LCU refuses to approve the application that is hosting the agent, because
|
|
5
|
+
* computer use can click anything an approved app shows — including the very
|
|
6
|
+
* approval prompt — so approving the host would let the agent approve itself.
|
|
7
|
+
*
|
|
8
|
+
* LCU's own shared client does this; a host that replaces that client owns the
|
|
9
|
+
* rule. This is the DSH implementation: the agent's own process ancestry plus a
|
|
10
|
+
* static list of dedicated agent hosts and terminals.
|
|
11
|
+
*
|
|
12
|
+
* A failed or unavailable process lookup falls back to the static list, so the
|
|
13
|
+
* guard degrades to "known hosts are refused" rather than "nothing is refused".
|
|
14
|
+
*
|
|
15
|
+
* @module dsh-plugin-lcu/host-guard
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Dedicated agent hosts, terminals, and this harness.
|
|
19
|
+
*
|
|
20
|
+
* Editors and IDEs are deliberately absent: they are common computer-use
|
|
21
|
+
* targets, and when an editor hosts the agent its bundle is an ancestor of this
|
|
22
|
+
* process, which the dynamic check already refuses.
|
|
23
|
+
*/
|
|
24
|
+
export declare const STATIC_HOST_BUNDLE_IDS: readonly string[];
|
|
25
|
+
/** The enclosing `.app` bundle of an executable path, if any. */
|
|
26
|
+
export declare function enclosingAppBundle(executablePath: string): string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* The bundle identifiers of every `.app` on this process's ancestry.
|
|
29
|
+
*
|
|
30
|
+
* This is the dynamic half of the guard: whatever application actually launched
|
|
31
|
+
* DSH — a terminal, an editor, a launcher — is refused by construction, even
|
|
32
|
+
* when it is not on the static list.
|
|
33
|
+
*
|
|
34
|
+
* @returns the ancestor bundle identifiers; empty when the lookup fails.
|
|
35
|
+
*/
|
|
36
|
+
export declare function ancestorBundleIds(): Promise<ReadonlySet<string>>;
|
|
37
|
+
/**
|
|
38
|
+
* Whether an approval would grant the agent control of its own host.
|
|
39
|
+
*
|
|
40
|
+
* @param app - the app the runtime is asking about: a display name, bundle id, or path.
|
|
41
|
+
* @returns `true` when the request must be declined without asking the user.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isAgentHostApp(app: string): Promise<boolean>;
|
|
44
|
+
/** Reset the memoized ancestry; for tests only. */
|
|
45
|
+
export declare function resetAncestorCache(): void;
|
|
46
|
+
//# sourceMappingURL=host-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-guard.d.ts","sourceRoot":"","sources":["../../src/host-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAenD,CAAA;AAgBD,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQ7E;AAUD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAqBtE;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBlE;AAED,mDAAmD;AACnD,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dsh-plugin-lcu` — drive the desktop and Chrome from DeepSeek Harness.
|
|
3
|
+
*
|
|
4
|
+
* The plugin is one root-scoped row. It does not open anything at load time:
|
|
5
|
+
* LCU (and the CUA runtime behind it) starts only for an Agent whose preset is
|
|
6
|
+
* listed in `presets`, and stops when that Agent is disposed. That keeps a
|
|
7
|
+
* heavy, permission-bearing capability off every session that does not need it.
|
|
8
|
+
*
|
|
9
|
+
* Visibility is decided per Agent rather than by mounting rows inside a preset,
|
|
10
|
+
* because the server owns the tool schemas: they can only be fetched after the
|
|
11
|
+
* handshake, so the tools are registered into the Agent's own context once its
|
|
12
|
+
* connection is up.
|
|
13
|
+
*
|
|
14
|
+
* @module dsh-plugin-lcu
|
|
15
|
+
*/
|
|
16
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
17
|
+
import { resolveElicitation } from './connection.ts';
|
|
18
|
+
export declare const name = "lcu";
|
|
19
|
+
export declare const inject: string[];
|
|
20
|
+
/** Plugin configuration. */
|
|
21
|
+
export interface Config {
|
|
22
|
+
/** LCU launcher; defaults to the installed path, overridable for a custom prefix. */
|
|
23
|
+
command?: string;
|
|
24
|
+
/** Enable the Chrome surface (`lcu --chrome`); needs the extension and site approvals. */
|
|
25
|
+
chrome?: boolean;
|
|
26
|
+
/** Enable the original computer-audio recording API (`lcu --audio`). */
|
|
27
|
+
audio?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Agent preset ids whose sessions get the tools.
|
|
30
|
+
*
|
|
31
|
+
* Presets are independent compositions, so this is an explicit list rather
|
|
32
|
+
* than a capability the preset itself declares; `heavy` is the preset the
|
|
33
|
+
* generator script builds for this plugin.
|
|
34
|
+
*/
|
|
35
|
+
presets?: string[];
|
|
36
|
+
/** Exact HTTP(S) origins pre-approved for browser access, never widened. */
|
|
37
|
+
allowedOrigins?: string[];
|
|
38
|
+
/** Prompt section order for the injected LCU instructions. */
|
|
39
|
+
sectionOrder?: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Mount the LCU capability.
|
|
43
|
+
*
|
|
44
|
+
* @param ctx - the host context this row mounts into.
|
|
45
|
+
* @param config - the row's configuration.
|
|
46
|
+
*/
|
|
47
|
+
export declare function apply(ctx: Context, config: Config): void;
|
|
48
|
+
export { resolveElicitation };
|
|
49
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAKlD,OAAO,EAC+C,kBAAkB,EAEvE,MAAM,iBAAiB,CAAA;AAKxB,eAAO,MAAM,IAAI,QAAQ,CAAA;AACzB,eAAO,MAAM,MAAM,UAA4B,CAAA;AAQ/C,4BAA4B;AAC5B,MAAM,WAAW,MAAM;IACrB,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AA2BD;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAiQxD;AAYD,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-facing tools for LCU.
|
|
3
|
+
*
|
|
4
|
+
* The server owns the tool contract: `js` carries a ~1.5 KB description that is
|
|
5
|
+
* the API manual, and the model is told to read documentation out of the first
|
|
6
|
+
* tool result. So the definitions here are the server's, passed through
|
|
7
|
+
* unchanged — this module only adapts the transport (canonical value, text
|
|
8
|
+
* fallback, durable images) and enforces the visibility rule that only `js` and
|
|
9
|
+
* `js_reset` may reach the model.
|
|
10
|
+
*
|
|
11
|
+
* @module dsh-plugin-lcu/tool
|
|
12
|
+
*/
|
|
13
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
14
|
+
import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
|
|
15
|
+
import type { LcuConnection, LcuContentBlock, LcuTool } from './connection.ts';
|
|
16
|
+
interface ImageBlock {
|
|
17
|
+
readonly type: 'image';
|
|
18
|
+
readonly data: string;
|
|
19
|
+
readonly mimeType: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The model-facing text for one MCP result.
|
|
23
|
+
*
|
|
24
|
+
* LCU returns documentation and command output as text, and screenshots as
|
|
25
|
+
* separate image blocks, so joining the text blocks is the whole projection;
|
|
26
|
+
* images are appended by {@link prepareProjection}.
|
|
27
|
+
*
|
|
28
|
+
* @param content - the raw MCP content array.
|
|
29
|
+
* @param toolName - the tool, for the empty-result diagnostic.
|
|
30
|
+
* @returns text for the model, never empty.
|
|
31
|
+
*/
|
|
32
|
+
export declare function extractText(content: readonly LcuContentBlock[], toolName: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Decode one image block, rejecting anything the store would not accept.
|
|
35
|
+
*
|
|
36
|
+
* @param block - a declared MCP image block.
|
|
37
|
+
* @returns the decoded attachment payload.
|
|
38
|
+
* @throws {Error} when the media type is not admitted or the base64 is not canonical.
|
|
39
|
+
*/
|
|
40
|
+
export declare function decodeImage(block: ImageBlock): {
|
|
41
|
+
data: Buffer;
|
|
42
|
+
mediaType: string;
|
|
43
|
+
};
|
|
44
|
+
/** Stable diagnostic text for an image the host could not admit. */
|
|
45
|
+
export declare function imageDiagnostic(block: unknown, reason: string): string;
|
|
46
|
+
/** Host-owned hooks around one call. */
|
|
47
|
+
export interface LcuToolOptions {
|
|
48
|
+
/**
|
|
49
|
+
* Awaited before every call, and its rejection fails the call.
|
|
50
|
+
*
|
|
51
|
+
* The runtime's per-turn cleanup is asynchronous: when it outlives the host's
|
|
52
|
+
* wait, acting on the desktop before it finishes is unsafe. This is where the
|
|
53
|
+
* host retries it and refuses the call if it still has not settled.
|
|
54
|
+
*/
|
|
55
|
+
readonly beforeCall?: () => Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build one model-facing tool from a server descriptor.
|
|
59
|
+
*
|
|
60
|
+
* @param descriptor - the tool as `tools/list` reported it.
|
|
61
|
+
* @param connection - the connection this agent's calls go through.
|
|
62
|
+
* @param ctx - the plugin context, used for the attachment store.
|
|
63
|
+
* @param options - host hooks around the call.
|
|
64
|
+
* @returns a registrable tool definition.
|
|
65
|
+
*/
|
|
66
|
+
export declare function createLcuTool(descriptor: LcuTool, connection: LcuConnection, ctx: Context, options?: LcuToolOptions): ToolDefinition;
|
|
67
|
+
/**
|
|
68
|
+
* Build every model-facing tool for one agent's connection.
|
|
69
|
+
*
|
|
70
|
+
* @param connection - the connected LCU session.
|
|
71
|
+
* @param ctx - the plugin context.
|
|
72
|
+
* @returns tool definitions for `js` and `js_reset`, in server order.
|
|
73
|
+
* @throws {LcuError} when the server does not expose the model tools.
|
|
74
|
+
*/
|
|
75
|
+
export declare function buildLcuTools(connection: LcuConnection, ctx: Context, options?: LcuToolOptions): ToolDefinition[];
|
|
76
|
+
/**
|
|
77
|
+
* Register the model-facing tools in one agent's scope.
|
|
78
|
+
*
|
|
79
|
+
* Registration is per agent rather than at plugin mount because the server owns
|
|
80
|
+
* the schemas: they can only be fetched after connecting, and an agent only
|
|
81
|
+
* needs the capability once it exists.
|
|
82
|
+
*
|
|
83
|
+
* @param agentCtx - the agent's own context; its registrations unwind on disposal.
|
|
84
|
+
* @param connection - the agent's connected LCU session.
|
|
85
|
+
* @param ctx - the plugin context.
|
|
86
|
+
* @returns a disposer that unregisters every tool.
|
|
87
|
+
*/
|
|
88
|
+
export declare function registerLcuTools(agentCtx: Context, connection: LcuConnection, ctx: Context, options?: LcuToolOptions): () => void;
|
|
89
|
+
export {};
|
|
90
|
+
//# sourceMappingURL=tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,KAAK,EAAE,cAAc,EAAsD,MAAM,wBAAwB,CAAA;AAEhH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAS9E,UAAU,UAAU;IAClB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWzF;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAQlF;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGtE;AAgGD,wCAAwC;AACxC,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1C;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,OAAO,EACnB,UAAU,EAAE,aAAa,EACzB,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE,cAAmB,GAC3B,cAAc,CAuDhB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,aAAa,EACzB,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE,cAAmB,GAC3B,cAAc,EAAE,CAOlB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,aAAa,EACzB,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE,cAAmB,GAC3B,MAAM,IAAI,CAKZ"}
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-plugin-lcu",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Drive the desktop and Chrome from DeepSeek Harness through LCU (Codex computer use, decoupled from the app).",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"dsh-plugin",
|
|
7
|
+
"deepseek-harness",
|
|
8
|
+
"dsh",
|
|
9
|
+
"computer-use",
|
|
10
|
+
"browser-use",
|
|
11
|
+
"lcu",
|
|
12
|
+
"codex",
|
|
13
|
+
"cua"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": {
|
|
17
|
+
"name": "Kanner",
|
|
18
|
+
"email": "kanner.chen@gmail.com"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/ckanner/dsh-plugin-lcu.git"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://github.com/ckanner/dsh-plugin-lcu#readme",
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/ckanner/dsh-plugin-lcu/issues"
|
|
27
|
+
},
|
|
28
|
+
"type": "module",
|
|
29
|
+
"main": "lib/index.js",
|
|
30
|
+
"types": "lib/types/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./lib/types/index.d.ts",
|
|
34
|
+
"default": "./lib/index.js"
|
|
35
|
+
},
|
|
36
|
+
"./package.json": "./package.json"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"lib",
|
|
40
|
+
"cordis.patch.yml",
|
|
41
|
+
"scripts",
|
|
42
|
+
"dev-types",
|
|
43
|
+
"docs/README.zh.md"
|
|
44
|
+
],
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": "^22.19.0 || >=24.0.0"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"dsh": {
|
|
52
|
+
"bundle": {
|
|
53
|
+
"patch": "./cordis.patch.yml"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "tsc -p tsconfig.build.json",
|
|
58
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
59
|
+
"test": "node --test \"tests/*.spec.ts\"",
|
|
60
|
+
"prepare": "npm run build",
|
|
61
|
+
"presets": "node scripts/gen-presets.mjs",
|
|
62
|
+
"probe": "node scripts/probe-lcu.mjs",
|
|
63
|
+
"update-codex": "node scripts/update-codex.mjs"
|
|
64
|
+
},
|
|
65
|
+
"peerDependencies": {
|
|
66
|
+
"@deepseek-ai/cordis": ">=0.0.1-rc.1 <0.3.0",
|
|
67
|
+
"@deepseek-ai/dsh-tools": ">=0.0.1-rc.1 <0.3.0",
|
|
68
|
+
"@deepseek-ai/dsh-system-prompt": ">=0.0.1-rc.1 <0.3.0"
|
|
69
|
+
},
|
|
70
|
+
"peerDependenciesMeta": {
|
|
71
|
+
"@deepseek-ai/cordis": { "optional": true },
|
|
72
|
+
"@deepseek-ai/dsh-tools": { "optional": true },
|
|
73
|
+
"@deepseek-ai/dsh-system-prompt": { "optional": true }
|
|
74
|
+
},
|
|
75
|
+
"devDependencies": {
|
|
76
|
+
"@types/node": "^22.20.5",
|
|
77
|
+
"typescript": "^5.9.0"
|
|
78
|
+
}
|
|
79
|
+
}
|