codex-computer-use-mcp 0.2.0 → 0.3.1
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/ARCHITECTURE.md +19 -3
- package/CONTRIBUTING.md +1 -1
- package/MIGRATION.md +33 -5
- package/PROOF.md +34 -5
- package/README.md +19 -13
- package/SECURITY.md +12 -10
- package/dist/audit.d.ts +1 -1
- package/dist/direct-broker.d.ts +43 -6
- package/dist/direct-broker.js +92 -45
- package/dist/direct-broker.js.map +1 -1
- package/dist/direct-service.d.ts +3 -1
- package/dist/direct-service.js +11 -6
- package/dist/direct-service.js.map +1 -1
- package/dist/mcp-elicitation.d.ts +8 -0
- package/dist/mcp-elicitation.js +47 -0
- package/dist/mcp-elicitation.js.map +1 -0
- package/dist/mcp-server.js +44 -42
- package/dist/mcp-server.js.map +1 -1
- package/dist/tools.d.ts +12 -6
- package/dist/tools.js +93 -23
- package/dist/tools.js.map +1 -1
- package/docs/adr/0001-standalone-code-mode-mcp.md +45 -0
- package/integrations/pi/README.md +16 -6
- package/integrations/pi/index.ts +156 -31
- package/integrations/pi/mcp.json.example +1 -1
- package/npm-shrinkwrap.json +27 -30
- package/package.json +5 -4
package/integrations/pi/index.ts
CHANGED
|
@@ -4,52 +4,95 @@ import { getAgentDir, truncateHead, type ExtensionAPI } from "@earendil-works/pi
|
|
|
4
4
|
import { Text } from "@earendil-works/pi-tui";
|
|
5
5
|
import { Type, type TSchema } from "typebox";
|
|
6
6
|
import { executeDirectTool, getDirectStatus } from "../../dist/direct-service.js";
|
|
7
|
-
import type {
|
|
7
|
+
import type {
|
|
8
|
+
DirectBrokerElicitationRequest,
|
|
9
|
+
DirectBrokerElicitationResponse,
|
|
10
|
+
} from "../../dist/direct-broker.js";
|
|
11
|
+
import { OFFICIAL_TOOL_METADATA, type DirectMethod } from "../../dist/tools.js";
|
|
8
12
|
|
|
9
|
-
const App = Type.String({
|
|
10
|
-
const Element = Type.String({ minLength: 1, maxLength: 200, description: "Element identifier from computer_use_get_app_state" });
|
|
11
|
-
const Coordinate = Type.Number({ minimum: 0, maximum: 1_000_000 });
|
|
13
|
+
const App = Type.String({ description: "App name, full app path, or unambiguous bundle identifier" });
|
|
12
14
|
|
|
13
15
|
const ToolParameters: Record<DirectMethod, TSchema> = {
|
|
14
16
|
list_apps: Type.Object({}, { additionalProperties: false }),
|
|
15
17
|
get_app_state: Type.Object({ app: App }, { additionalProperties: false }),
|
|
16
18
|
click: Type.Object({
|
|
17
19
|
app: App,
|
|
18
|
-
click_count: Type.Optional(Type.Integer({
|
|
19
|
-
element_index: Type.Optional(Element),
|
|
20
|
-
mouse_button: Type.Optional(StringEnum(["left", "right", "middle"] as const)),
|
|
21
|
-
x: Type.Optional(
|
|
22
|
-
y: Type.Optional(
|
|
20
|
+
click_count: Type.Optional(Type.Integer({ description: "Number of clicks. Defaults to 1" })),
|
|
21
|
+
element_index: Type.Optional(Type.String({ description: "Element index to click" })),
|
|
22
|
+
mouse_button: Type.Optional(StringEnum(["left", "right", "middle"] as const, { description: "Mouse button to click. Defaults to left." })),
|
|
23
|
+
x: Type.Optional(Type.Number({ description: "X coordinate in screenshot pixel coordinates" })),
|
|
24
|
+
y: Type.Optional(Type.Number({ description: "Y coordinate in screenshot pixel coordinates" })),
|
|
23
25
|
}, { additionalProperties: false }),
|
|
24
|
-
perform_secondary_action: Type.Object({
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
perform_secondary_action: Type.Object({
|
|
27
|
+
app: App,
|
|
28
|
+
element_index: Type.String({ description: "Element identifier" }),
|
|
29
|
+
action: Type.String({ description: "Secondary accessibility action name" }),
|
|
30
|
+
}, { additionalProperties: false }),
|
|
31
|
+
set_value: Type.Object({
|
|
27
32
|
app: App,
|
|
28
|
-
element_index: Element,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
element_index: Type.String({ description: "Element identifier" }),
|
|
34
|
+
value: Type.String({ description: "Value to assign" }),
|
|
35
|
+
}, { additionalProperties: false }),
|
|
36
|
+
select_text: Type.Object({
|
|
37
|
+
app: Type.String({ description: "App name or bundle identifier" }),
|
|
38
|
+
element_index: Type.String({ description: "Text element identifier" }),
|
|
39
|
+
text: Type.String({ description: "Target text as shown in the accessibility tree" }),
|
|
40
|
+
prefix: Type.Optional(Type.String({ description: "Optional text immediately before the target, used to disambiguate repeated matches" })),
|
|
41
|
+
selection: Type.Optional(StringEnum(["text", "cursor_before", "cursor_after"] as const, { description: "Whether to select the text or place the cursor before or after it. Defaults to text." })),
|
|
42
|
+
suffix: Type.Optional(Type.String({ description: "Optional text immediately after the target, used to disambiguate repeated matches" })),
|
|
33
43
|
}, { additionalProperties: false }),
|
|
34
44
|
scroll: Type.Object({
|
|
35
45
|
app: App,
|
|
36
|
-
element_index: Element,
|
|
37
|
-
direction:
|
|
38
|
-
pages: Type.Optional(Type.Number({
|
|
46
|
+
element_index: Type.String({ description: "Element identifier" }),
|
|
47
|
+
direction: Type.String({ description: "Scroll direction: up, down, left, or right" }),
|
|
48
|
+
pages: Type.Optional(Type.Number({ description: "Number of pages to scroll. Fractional values are supported. Defaults to 1" })),
|
|
39
49
|
}, { additionalProperties: false }),
|
|
40
|
-
drag: Type.Object({
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
drag: Type.Object({
|
|
51
|
+
app: App,
|
|
52
|
+
from_x: Type.Number({ description: "Start X coordinate" }),
|
|
53
|
+
from_y: Type.Number({ description: "Start Y coordinate" }),
|
|
54
|
+
to_x: Type.Number({ description: "End X coordinate" }),
|
|
55
|
+
to_y: Type.Number({ description: "End Y coordinate" }),
|
|
56
|
+
}, { additionalProperties: false }),
|
|
57
|
+
press_key: Type.Object({ app: App, key: Type.String({ description: "Key or key combination to press" }) }, { additionalProperties: false }),
|
|
58
|
+
type_text: Type.Object({ app: App, text: Type.String({ description: "Literal text to type" }) }, { additionalProperties: false }),
|
|
43
59
|
};
|
|
44
60
|
|
|
45
61
|
function toolDescription(method: DirectMethod): string {
|
|
46
|
-
return
|
|
62
|
+
return OFFICIAL_TOOL_METADATA[method].description;
|
|
47
63
|
}
|
|
48
64
|
|
|
49
65
|
function titleFor(method: DirectMethod): string {
|
|
50
66
|
return method.split("_").map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`).join(" ");
|
|
51
67
|
}
|
|
52
68
|
|
|
69
|
+
const INSPECTION_METHODS = new Set<DirectMethod>(["list_apps", "get_app_state"]);
|
|
70
|
+
export const INSPECTION_TOOL_NAMES = [
|
|
71
|
+
"computer_use_list_apps",
|
|
72
|
+
"computer_use_get_app_state",
|
|
73
|
+
] as const;
|
|
74
|
+
export const INTERACTION_TOOL_NAMES = [
|
|
75
|
+
"computer_use_click",
|
|
76
|
+
"computer_use_perform_secondary_action",
|
|
77
|
+
"computer_use_set_value",
|
|
78
|
+
"computer_use_select_text",
|
|
79
|
+
"computer_use_scroll",
|
|
80
|
+
"computer_use_drag",
|
|
81
|
+
"computer_use_press_key",
|
|
82
|
+
"computer_use_type_text",
|
|
83
|
+
] as const;
|
|
84
|
+
|
|
85
|
+
export function setInitialComputerUseTools(pi: Pick<ExtensionAPI, "getActiveTools" | "setActiveTools">): void {
|
|
86
|
+
const interactionTools = new Set<string>(INTERACTION_TOOL_NAMES);
|
|
87
|
+
const preserved = pi.getActiveTools().filter((name) => !interactionTools.has(name));
|
|
88
|
+
pi.setActiveTools([...new Set([...preserved, ...INSPECTION_TOOL_NAMES])]);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function activateInteractionTools(pi: Pick<ExtensionAPI, "getActiveTools" | "setActiveTools">): void {
|
|
92
|
+
const active = pi.getActiveTools();
|
|
93
|
+
pi.setActiveTools([...new Set([...active, ...INTERACTION_TOOL_NAMES])]);
|
|
94
|
+
}
|
|
95
|
+
|
|
53
96
|
function toPiContent(content: Array<Record<string, unknown>>): Array<{ type: "text"; text: string } | { type: "image"; data: string; mimeType: string }> {
|
|
54
97
|
const result: Array<{ type: "text"; text: string } | { type: "image"; data: string; mimeType: string }> = [];
|
|
55
98
|
for (const block of content) {
|
|
@@ -75,6 +118,74 @@ function errorText(content: Array<Record<string, unknown>>): string {
|
|
|
75
118
|
.slice(0, 2_000) || "Official Computer Use returned an error";
|
|
76
119
|
}
|
|
77
120
|
|
|
121
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
122
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function initialFormContent(schema: unknown): Record<string, unknown> {
|
|
126
|
+
if (!isRecord(schema) || !isRecord(schema.properties)) return {};
|
|
127
|
+
const content: Record<string, unknown> = {};
|
|
128
|
+
for (const [key, rawProperty] of Object.entries(schema.properties)) {
|
|
129
|
+
if (!isRecord(rawProperty)) continue;
|
|
130
|
+
if (rawProperty.default !== undefined) content[key] = rawProperty.default;
|
|
131
|
+
else if (Array.isArray(rawProperty.enum) && rawProperty.enum.length > 0) content[key] = rawProperty.enum[0];
|
|
132
|
+
else if (rawProperty.type === "boolean") content[key] = false;
|
|
133
|
+
else if (rawProperty.type === "number" || rawProperty.type === "integer") content[key] = 0;
|
|
134
|
+
else if (rawProperty.type === "array") content[key] = [];
|
|
135
|
+
else content[key] = "";
|
|
136
|
+
}
|
|
137
|
+
return content;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export async function handleOfficialElicitation(
|
|
141
|
+
request: DirectBrokerElicitationRequest,
|
|
142
|
+
ctx: { hasUI: boolean; ui: {
|
|
143
|
+
select(title: string, options: string[]): Promise<string | undefined>;
|
|
144
|
+
editor(title: string, prefill?: string): Promise<string | undefined>;
|
|
145
|
+
notify(message: string, type?: "info" | "warning" | "error"): void;
|
|
146
|
+
} },
|
|
147
|
+
openUrl: (url: string) => Promise<boolean>,
|
|
148
|
+
): Promise<DirectBrokerElicitationResponse> {
|
|
149
|
+
if (!ctx.hasUI) return { action: "cancel" };
|
|
150
|
+
const message = typeof request.message === "string" ? request.message : "Official Computer Use requests input";
|
|
151
|
+
|
|
152
|
+
if (request.mode === "url") {
|
|
153
|
+
if (typeof request.url !== "string") return { action: "cancel" };
|
|
154
|
+
const choice = await ctx.ui.select(`${message}\n${request.url}`, ["Open URL", "Decline", "Cancel"]);
|
|
155
|
+
if (choice === "Decline") return { action: "decline" };
|
|
156
|
+
if (choice !== "Open URL") return { action: "cancel" };
|
|
157
|
+
if (!await openUrl(request.url)) {
|
|
158
|
+
ctx.ui.notify("Could not open the official Computer Use URL.", "error");
|
|
159
|
+
return { action: "cancel" };
|
|
160
|
+
}
|
|
161
|
+
return { action: "accept" };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (request.mode !== undefined && request.mode !== "form" && request.mode !== "openai/form") {
|
|
165
|
+
ctx.ui.notify(`Official Computer Use sent an unsupported elicitation mode: ${request.mode}`, "warning");
|
|
166
|
+
return { action: "cancel" };
|
|
167
|
+
}
|
|
168
|
+
const openAiForm = request.mode === "openai/form";
|
|
169
|
+
if (request.requestedSchema === undefined || (!openAiForm && !isRecord(request.requestedSchema))) return { action: "cancel" };
|
|
170
|
+
const choice = await ctx.ui.select(message, ["Respond", "Decline", "Cancel"]);
|
|
171
|
+
if (choice === "Decline") return { action: "decline" };
|
|
172
|
+
if (choice !== "Respond") return { action: "cancel" };
|
|
173
|
+
let prefill = JSON.stringify(initialFormContent(request.requestedSchema), null, 2);
|
|
174
|
+
const title = `${message}\nSchema: ${JSON.stringify(request.requestedSchema)}`;
|
|
175
|
+
while (true) {
|
|
176
|
+
const edited = await ctx.ui.editor(title, prefill);
|
|
177
|
+
if (edited === undefined) return { action: "cancel" };
|
|
178
|
+
prefill = edited;
|
|
179
|
+
try {
|
|
180
|
+
const content = JSON.parse(edited);
|
|
181
|
+
if (!openAiForm && !isRecord(content)) throw new Error("Response must be a JSON object");
|
|
182
|
+
return { action: "accept", content };
|
|
183
|
+
} catch (error) {
|
|
184
|
+
ctx.ui.notify(error instanceof Error ? error.message : "Response must be valid JSON", "error");
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
78
189
|
export default function directComputerUse(pi: ExtensionAPI) {
|
|
79
190
|
const stateRoot = process.env.CODEX_COMPUTER_USE_HOME || path.join(getAgentDir(), "direct-computer-use");
|
|
80
191
|
|
|
@@ -89,27 +200,39 @@ export default function directComputerUse(pi: ExtensionAPI) {
|
|
|
89
200
|
const methods = Object.keys(ToolParameters) as DirectMethod[];
|
|
90
201
|
for (const method of methods) {
|
|
91
202
|
const piName = `computer_use_${method}`;
|
|
92
|
-
|
|
93
|
-
name: piName,
|
|
94
|
-
label: titleFor(method),
|
|
95
|
-
description: toolDescription(method),
|
|
203
|
+
const inspectionPromptMetadata = INSPECTION_METHODS.has(method) ? {
|
|
96
204
|
promptSnippet: `${titleFor(method)} through the official signed macOS Computer Use service`,
|
|
97
205
|
promptGuidelines: [
|
|
98
206
|
`${piName} is a direct typed tool: choose its arguments yourself; it does not invoke a nested planner or model.`,
|
|
99
|
-
|
|
100
|
-
`${piName} must not be used for credentials, authentication, payments, external messages, or destructive actions without the user's explicit request; this wrapper will not open a permission prompt.`,
|
|
207
|
+
`Call computer_use_get_app_state once per assistant turn before interacting with an app.`,
|
|
101
208
|
],
|
|
209
|
+
} : {};
|
|
210
|
+
pi.registerTool({
|
|
211
|
+
name: piName,
|
|
212
|
+
label: titleFor(method),
|
|
213
|
+
description: toolDescription(method),
|
|
214
|
+
...inspectionPromptMetadata,
|
|
102
215
|
parameters: ToolParameters[method] as any,
|
|
103
|
-
async execute(_toolCallId, params, signal, onUpdate) {
|
|
216
|
+
async execute(_toolCallId, params, signal, onUpdate, ctx) {
|
|
104
217
|
const response = await executeDirectTool(
|
|
105
218
|
{ method, arguments: params as Record<string, unknown> },
|
|
106
219
|
{
|
|
107
220
|
stateRoot,
|
|
108
221
|
signal,
|
|
222
|
+
supportsOpenAiFormElicitation: true,
|
|
223
|
+
onElicitation: (request) => handleOfficialElicitation(
|
|
224
|
+
request,
|
|
225
|
+
ctx,
|
|
226
|
+
async (url) => {
|
|
227
|
+
const result = await pi.exec("/usr/bin/open", ["--", url], { signal, timeout: 15_000 });
|
|
228
|
+
return result.code === 0;
|
|
229
|
+
},
|
|
230
|
+
),
|
|
109
231
|
onProgress: (message) => onUpdate?.({ content: [{ type: "text", text: message }], details: { status: "running" } }),
|
|
110
232
|
},
|
|
111
233
|
);
|
|
112
234
|
if (response.isError) throw new Error(errorText(response.content));
|
|
235
|
+
if (method === "get_app_state") activateInteractionTools(pi);
|
|
113
236
|
return { content: toPiContent(response.content), details: response.details };
|
|
114
237
|
},
|
|
115
238
|
renderCall(args, theme) {
|
|
@@ -119,4 +242,6 @@ export default function directComputerUse(pi: ExtensionAPI) {
|
|
|
119
242
|
},
|
|
120
243
|
});
|
|
121
244
|
}
|
|
245
|
+
|
|
246
|
+
pi.on("session_start", () => setInitialComputerUseTools(pi));
|
|
122
247
|
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-computer-use-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "codex-computer-use-mcp",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.3.1",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"os": [
|
|
12
12
|
"darwin"
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"codex-computer-use-mcp": "dist/mcp-server.js"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@earendil-works/pi-ai": "0.80.
|
|
25
|
-
"@earendil-works/pi-coding-agent": "0.80.
|
|
26
|
-
"@earendil-works/pi-tui": "0.80.
|
|
24
|
+
"@earendil-works/pi-ai": "0.80.7",
|
|
25
|
+
"@earendil-works/pi-coding-agent": "0.80.7",
|
|
26
|
+
"@earendil-works/pi-tui": "0.80.7",
|
|
27
27
|
"typebox": "1.1.38"
|
|
28
28
|
},
|
|
29
29
|
"engines": {
|
|
@@ -541,9 +541,9 @@
|
|
|
541
541
|
}
|
|
542
542
|
},
|
|
543
543
|
"node_modules/@earendil-works/pi-ai": {
|
|
544
|
-
"version": "0.80.
|
|
545
|
-
"resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.80.
|
|
546
|
-
"integrity": "sha512-
|
|
544
|
+
"version": "0.80.7",
|
|
545
|
+
"resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.80.7.tgz",
|
|
546
|
+
"integrity": "sha512-8RLKLwe5TFM9kKFMNu/lTzveduq4GxZbnlG6ba8FAhLeb5wJP4zbj1eBumKBRvggpFQnW5R/Vo2a8zTlHsV9SQ==",
|
|
547
547
|
"dev": true,
|
|
548
548
|
"license": "MIT",
|
|
549
549
|
"dependencies": {
|
|
@@ -567,16 +567,16 @@
|
|
|
567
567
|
}
|
|
568
568
|
},
|
|
569
569
|
"node_modules/@earendil-works/pi-coding-agent": {
|
|
570
|
-
"version": "0.80.
|
|
571
|
-
"resolved": "https://registry.npmjs.org/@earendil-works/pi-coding-agent/-/pi-coding-agent-0.80.
|
|
572
|
-
"integrity": "sha512-
|
|
570
|
+
"version": "0.80.7",
|
|
571
|
+
"resolved": "https://registry.npmjs.org/@earendil-works/pi-coding-agent/-/pi-coding-agent-0.80.7.tgz",
|
|
572
|
+
"integrity": "sha512-mxq3IClhdgmCrYiKuzKehs4QKCVJgKmlA70nUEzsgeNsGdxriT7o5sKQTCcxzVJkzDRMcHD/8tAP4/eGrV4gKQ==",
|
|
573
573
|
"dev": true,
|
|
574
574
|
"hasShrinkwrap": true,
|
|
575
575
|
"license": "MIT",
|
|
576
576
|
"dependencies": {
|
|
577
|
-
"@earendil-works/pi-agent-core": "^0.80.
|
|
578
|
-
"@earendil-works/pi-ai": "^0.80.
|
|
579
|
-
"@earendil-works/pi-tui": "^0.80.
|
|
577
|
+
"@earendil-works/pi-agent-core": "^0.80.7",
|
|
578
|
+
"@earendil-works/pi-ai": "^0.80.7",
|
|
579
|
+
"@earendil-works/pi-tui": "^0.80.7",
|
|
580
580
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
581
581
|
"chalk": "5.6.2",
|
|
582
582
|
"cross-spawn": "7.0.6",
|
|
@@ -1066,13 +1066,12 @@
|
|
|
1066
1066
|
}
|
|
1067
1067
|
},
|
|
1068
1068
|
"node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-agent-core": {
|
|
1069
|
-
"version": "0.80.
|
|
1070
|
-
"resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.80.
|
|
1071
|
-
"integrity": "sha512-Lvn89ko42h5ETUb6Z0Ku6ldskEqXaTdQBYvSa0+7bdG9V6rUEpXptv5e0OVZ1HDcvi8s6/2lGCQWsxKX+DFHNw==",
|
|
1069
|
+
"version": "0.80.7",
|
|
1070
|
+
"resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.80.7.tgz",
|
|
1072
1071
|
"dev": true,
|
|
1073
1072
|
"license": "MIT",
|
|
1074
1073
|
"dependencies": {
|
|
1075
|
-
"@earendil-works/pi-ai": "^0.80.
|
|
1074
|
+
"@earendil-works/pi-ai": "^0.80.7",
|
|
1076
1075
|
"ignore": "7.0.5",
|
|
1077
1076
|
"typebox": "1.1.38",
|
|
1078
1077
|
"yaml": "2.9.0"
|
|
@@ -1082,9 +1081,8 @@
|
|
|
1082
1081
|
}
|
|
1083
1082
|
},
|
|
1084
1083
|
"node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-ai": {
|
|
1085
|
-
"version": "0.80.
|
|
1086
|
-
"resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.80.
|
|
1087
|
-
"integrity": "sha512-7xfLk8sANBp+bpPEbjoOZTbPxsa+++b1JXAoSJsNa3vbs9AHHEclmvg54XLQcxH+fuwaeti/g2jeIfJ+mVYLpA==",
|
|
1084
|
+
"version": "0.80.7",
|
|
1085
|
+
"resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.80.7.tgz",
|
|
1088
1086
|
"dev": true,
|
|
1089
1087
|
"license": "MIT",
|
|
1090
1088
|
"dependencies": {
|
|
@@ -1108,9 +1106,8 @@
|
|
|
1108
1106
|
}
|
|
1109
1107
|
},
|
|
1110
1108
|
"node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-tui": {
|
|
1111
|
-
"version": "0.80.
|
|
1112
|
-
"resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.80.
|
|
1113
|
-
"integrity": "sha512-bSuzS4EVSqEPj/Qr/p9eqCESfKsGuDNbl77EGci8Iaqqt/C/XCBZL1MjXaxSWW1NsT5afjp/Cb0NTPzOLv/aPA==",
|
|
1109
|
+
"version": "0.80.7",
|
|
1110
|
+
"resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.80.7.tgz",
|
|
1114
1111
|
"dev": true,
|
|
1115
1112
|
"license": "MIT",
|
|
1116
1113
|
"dependencies": {
|
|
@@ -2543,9 +2540,9 @@
|
|
|
2543
2540
|
}
|
|
2544
2541
|
},
|
|
2545
2542
|
"node_modules/@earendil-works/pi-tui": {
|
|
2546
|
-
"version": "0.80.
|
|
2547
|
-
"resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.80.
|
|
2548
|
-
"integrity": "sha512-
|
|
2543
|
+
"version": "0.80.7",
|
|
2544
|
+
"resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.80.7.tgz",
|
|
2545
|
+
"integrity": "sha512-1B2++fLZfgI3XMzW2BTpuDuam2uyHnUUEmsOvi5R0Ne9RAt59WjFV0G8ozX6l1Xafa9P5Y3eT4aDtRr/v/CUTA==",
|
|
2549
2546
|
"dev": true,
|
|
2550
2547
|
"license": "MIT",
|
|
2551
2548
|
"dependencies": {
|
|
@@ -3667,9 +3664,9 @@
|
|
|
3667
3664
|
"license": "MIT"
|
|
3668
3665
|
},
|
|
3669
3666
|
"node_modules/fast-uri": {
|
|
3670
|
-
"version": "3.1.
|
|
3671
|
-
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.
|
|
3672
|
-
"integrity": "sha512-
|
|
3667
|
+
"version": "3.1.4",
|
|
3668
|
+
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz",
|
|
3669
|
+
"integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==",
|
|
3673
3670
|
"funding": [
|
|
3674
3671
|
{
|
|
3675
3672
|
"type": "github",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-computer-use-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Expose the official macOS Computer Use tools directly to Pi and MCP clients without a nested model.",
|
|
5
5
|
"author": "Thomas Mustier",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"ARCHITECTURE.md",
|
|
36
36
|
"MIGRATION.md",
|
|
37
37
|
"SECURITY.md",
|
|
38
|
+
"docs/adr",
|
|
38
39
|
"CONTRIBUTING.md",
|
|
39
40
|
"LICENSE"
|
|
40
41
|
],
|
|
@@ -73,9 +74,9 @@
|
|
|
73
74
|
}
|
|
74
75
|
},
|
|
75
76
|
"devDependencies": {
|
|
76
|
-
"@earendil-works/pi-ai": "0.80.
|
|
77
|
-
"@earendil-works/pi-coding-agent": "0.80.
|
|
78
|
-
"@earendil-works/pi-tui": "0.80.
|
|
77
|
+
"@earendil-works/pi-ai": "0.80.7",
|
|
78
|
+
"@earendil-works/pi-coding-agent": "0.80.7",
|
|
79
|
+
"@earendil-works/pi-tui": "0.80.7",
|
|
79
80
|
"typebox": "1.1.38"
|
|
80
81
|
},
|
|
81
82
|
"engines": {
|