@hypothesi/tauri-mcp-server 0.2.1 → 0.3.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 +18 -46
- package/dist/driver/plugin-commands.js +0 -15
- package/dist/driver/session-manager.js +28 -3
- package/dist/driver/webview-executor.js +35 -10
- package/dist/driver/webview-interactions.js +27 -3
- package/dist/index.js +27 -1
- package/dist/manager/mobile.js +0 -44
- package/dist/monitor/logs.js +15 -3
- package/dist/prompts-registry.js +109 -1
- package/dist/tools-registry.js +31 -170
- package/package.json +1 -1
- package/dist/manager/cli.js +0 -128
- package/dist/manager/config.js +0 -142
- package/dist/manager/docs.js +0 -213
package/dist/tools-registry.js
CHANGED
|
@@ -2,19 +2,15 @@
|
|
|
2
2
|
* Single source of truth for all MCP tool definitions
|
|
3
3
|
* This file defines all available tools and their metadata
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import { readConfig, writeConfig, ReadConfigSchema, WriteConfigSchema } from './manager/config.js';
|
|
7
|
-
import { listDevices, launchEmulator, ListDevicesSchema, LaunchEmulatorSchema } from './manager/mobile.js';
|
|
5
|
+
import { listDevices, ListDevicesSchema } from './manager/mobile.js';
|
|
8
6
|
import { manageDriverSession, ManageDriverSessionSchema, } from './driver/session-manager.js';
|
|
9
7
|
import { readLogs, ReadLogsSchema } from './monitor/logs.js';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { interact, screenshot, keyboard, waitFor, getStyles, executeJavaScript, focusElement, findElement, getConsoleLogs, InteractSchema, ScreenshotSchema, KeyboardSchema, WaitForSchema, GetStylesSchema, ExecuteJavaScriptSchema, FocusElementSchema, FindElementSchema, GetConsoleLogsSchema, } from './driver/webview-interactions.js';
|
|
8
|
+
import { executeIPCCommand, manageIPCMonitoring, getIPCEvents, emitTestEvent, getBackendState, listWindows, ExecuteIPCCommandSchema, ManageIPCMonitoringSchema, GetIPCEventsSchema, EmitTestEventSchema, GetBackendStateSchema, ListWindowsSchema, } from './driver/plugin-commands.js';
|
|
9
|
+
import { interact, screenshot, keyboard, waitFor, getStyles, executeJavaScript, findElement, InteractSchema, ScreenshotSchema, KeyboardSchema, WaitForSchema, GetStylesSchema, ExecuteJavaScriptSchema, FindElementSchema, } from './driver/webview-interactions.js';
|
|
13
10
|
/**
|
|
14
11
|
* Tool categories for organization
|
|
15
12
|
*/
|
|
16
13
|
export const TOOL_CATEGORIES = {
|
|
17
|
-
PROJECT_MANAGEMENT: 'Project Management',
|
|
18
14
|
MOBILE_DEVELOPMENT: 'Mobile Development',
|
|
19
15
|
UI_AUTOMATION: 'UI Automation & WebView Interaction',
|
|
20
16
|
IPC_PLUGIN: 'IPC & Plugin Tools (via MCP Bridge)',
|
|
@@ -24,79 +20,6 @@ export const TOOL_CATEGORIES = {
|
|
|
24
20
|
* This is the single source of truth for tool definitions
|
|
25
21
|
*/
|
|
26
22
|
export const TOOLS = [
|
|
27
|
-
// Project Management Tools
|
|
28
|
-
{
|
|
29
|
-
name: 'tauri_run_command',
|
|
30
|
-
description: '[Tauri Desktop/Mobile Apps Only] Run Tauri CLI commands (dev, build, init, etc.). ' +
|
|
31
|
-
'Use ONLY for projects with a src-tauri/ directory and tauri.conf.json. ' +
|
|
32
|
-
'Do NOT use for regular web apps, Electron apps, or browser-based projects. ' +
|
|
33
|
-
'Check for tauri.conf.json before using this tool.',
|
|
34
|
-
category: TOOL_CATEGORIES.PROJECT_MANAGEMENT,
|
|
35
|
-
schema: RunCommandSchema,
|
|
36
|
-
annotations: {
|
|
37
|
-
title: 'Run Tauri CLI Command',
|
|
38
|
-
readOnlyHint: false,
|
|
39
|
-
destructiveHint: false,
|
|
40
|
-
idempotentHint: false,
|
|
41
|
-
openWorldHint: false,
|
|
42
|
-
},
|
|
43
|
-
handler: async (args) => {
|
|
44
|
-
const parsed = RunCommandSchema.parse(args);
|
|
45
|
-
return await runTauriCommand(parsed.command, parsed.cwd, parsed.args || [], parsed.timeout);
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
name: 'tauri_read_config',
|
|
50
|
-
description: '[Tauri Desktop/Mobile Apps Only] Read tauri.conf.json or platform-specific configs. ' +
|
|
51
|
-
'Use ONLY for Tauri v2 projects (look for src-tauri/ directory). ' +
|
|
52
|
-
'For regular web apps or Electron, use standard file reading tools instead.',
|
|
53
|
-
category: TOOL_CATEGORIES.PROJECT_MANAGEMENT,
|
|
54
|
-
schema: ReadConfigSchema,
|
|
55
|
-
annotations: {
|
|
56
|
-
title: 'Read Tauri Config',
|
|
57
|
-
readOnlyHint: true,
|
|
58
|
-
openWorldHint: false,
|
|
59
|
-
},
|
|
60
|
-
handler: async (args) => {
|
|
61
|
-
const parsed = ReadConfigSchema.parse(args);
|
|
62
|
-
return await readConfig(parsed.projectPath, parsed.file);
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
name: 'tauri_write_config',
|
|
67
|
-
description: '[Tauri Desktop/Mobile Apps Only] Modify tauri.conf.json with validation. ' +
|
|
68
|
-
'Use ONLY for Tauri v2 projects. Validates JSON structure before writing. ' +
|
|
69
|
-
'For other frameworks, use standard file editing tools.',
|
|
70
|
-
category: TOOL_CATEGORIES.PROJECT_MANAGEMENT,
|
|
71
|
-
schema: WriteConfigSchema,
|
|
72
|
-
annotations: {
|
|
73
|
-
title: 'Write Tauri Config',
|
|
74
|
-
readOnlyHint: false,
|
|
75
|
-
destructiveHint: true,
|
|
76
|
-
openWorldHint: false,
|
|
77
|
-
},
|
|
78
|
-
handler: async (args) => {
|
|
79
|
-
const parsed = WriteConfigSchema.parse(args);
|
|
80
|
-
return await writeConfig(parsed.projectPath, parsed.file, parsed.content);
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
name: 'tauri_get_docs',
|
|
85
|
-
description: '[Tauri Desktop/Mobile Apps Only] Fetch Tauri v2 documentation and API reference. ' +
|
|
86
|
-
'Use when working on Tauri projects and need framework-specific guidance. ' +
|
|
87
|
-
'Not useful for Electron, React Native, or web-only projects.',
|
|
88
|
-
category: TOOL_CATEGORIES.PROJECT_MANAGEMENT,
|
|
89
|
-
schema: GetDocsSchema,
|
|
90
|
-
annotations: {
|
|
91
|
-
title: 'Get Tauri Documentation',
|
|
92
|
-
readOnlyHint: true,
|
|
93
|
-
openWorldHint: true,
|
|
94
|
-
},
|
|
95
|
-
handler: async (args) => {
|
|
96
|
-
const parsed = GetDocsSchema.parse(args);
|
|
97
|
-
return await getDocs(parsed.projectPath);
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
23
|
// Mobile Development Tools
|
|
101
24
|
{
|
|
102
25
|
name: 'tauri_list_devices',
|
|
@@ -115,28 +38,11 @@ export const TOOLS = [
|
|
|
115
38
|
return `Android Devices:\n${devices.android.join('\n') || 'None'}\n\niOS Booted Simulators:\n${devices.ios.join('\n') || 'None'}`;
|
|
116
39
|
},
|
|
117
40
|
},
|
|
118
|
-
{
|
|
119
|
-
name: 'tauri_launch_emulator',
|
|
120
|
-
description: '[Tauri Mobile Apps Only] Launch Android AVD or iOS Simulator for Tauri mobile testing. ' +
|
|
121
|
-
'Use when developing Tauri apps for mobile platforms. ' +
|
|
122
|
-
'Not applicable for desktop-only apps or web projects.',
|
|
123
|
-
category: TOOL_CATEGORIES.MOBILE_DEVELOPMENT,
|
|
124
|
-
schema: LaunchEmulatorSchema,
|
|
125
|
-
annotations: {
|
|
126
|
-
title: 'Launch Mobile Emulator',
|
|
127
|
-
readOnlyHint: false,
|
|
128
|
-
destructiveHint: false,
|
|
129
|
-
openWorldHint: false,
|
|
130
|
-
},
|
|
131
|
-
handler: async (args) => {
|
|
132
|
-
const parsed = LaunchEmulatorSchema.parse(args);
|
|
133
|
-
return await launchEmulator(parsed.platform, parsed.name);
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
41
|
// UI Automation Tools
|
|
137
42
|
{
|
|
138
43
|
name: 'tauri_driver_session',
|
|
139
44
|
description: '[Tauri Apps Only] Start/stop automation session to connect to a RUNNING Tauri app. ' +
|
|
45
|
+
'Use action "status" to check current connection state. ' +
|
|
140
46
|
'REQUIRED before using other tauri_webview_* or tauri_plugin_* tools. ' +
|
|
141
47
|
'Connects via WebSocket to the MCP Bridge plugin in the Tauri app. ' +
|
|
142
48
|
'For browser automation, use Chrome DevTools MCP instead. ' +
|
|
@@ -177,47 +83,28 @@ export const TOOLS = [
|
|
|
177
83
|
},
|
|
178
84
|
},
|
|
179
85
|
{
|
|
180
|
-
name: '
|
|
181
|
-
description: '[Tauri Apps Only]
|
|
182
|
-
'
|
|
183
|
-
'
|
|
184
|
-
|
|
185
|
-
schema: GetConsoleLogsSchema,
|
|
186
|
-
annotations: {
|
|
187
|
-
title: 'Get Tauri Console Logs',
|
|
188
|
-
readOnlyHint: true,
|
|
189
|
-
openWorldHint: false,
|
|
190
|
-
},
|
|
191
|
-
handler: async (args) => {
|
|
192
|
-
const parsed = GetConsoleLogsSchema.parse(args);
|
|
193
|
-
return await getConsoleLogs({
|
|
194
|
-
filter: parsed.filter,
|
|
195
|
-
since: parsed.since,
|
|
196
|
-
windowId: parsed.windowId,
|
|
197
|
-
});
|
|
198
|
-
},
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
name: 'tauri_read_platform_logs',
|
|
202
|
-
description: '[Tauri Mobile Apps] Read Android logcat or iOS device logs for Tauri mobile apps. ' +
|
|
203
|
-
'Also reads system logs on desktop. ' +
|
|
204
|
-
'Use for debugging native/platform-level issues in Tauri apps.',
|
|
86
|
+
name: 'tauri_read_logs',
|
|
87
|
+
description: '[Tauri Apps Only] Read logs from various sources: "console" for webview JS logs, ' +
|
|
88
|
+
'"android" for logcat, "ios" for simulator logs, "system" for desktop logs. ' +
|
|
89
|
+
'Requires active tauri_driver_session for console logs. ' +
|
|
90
|
+
'Use for debugging Tauri app issues at any level.',
|
|
205
91
|
category: TOOL_CATEGORIES.UI_AUTOMATION,
|
|
206
92
|
schema: ReadLogsSchema,
|
|
207
93
|
annotations: {
|
|
208
|
-
title: 'Read
|
|
94
|
+
title: 'Read Logs',
|
|
209
95
|
readOnlyHint: true,
|
|
210
96
|
openWorldHint: false,
|
|
211
97
|
},
|
|
212
98
|
handler: async (args) => {
|
|
213
99
|
const parsed = ReadLogsSchema.parse(args);
|
|
214
|
-
return await readLogs(parsed
|
|
100
|
+
return await readLogs(parsed);
|
|
215
101
|
},
|
|
216
102
|
},
|
|
217
103
|
// WebView Interaction Tools
|
|
218
104
|
{
|
|
219
105
|
name: 'tauri_webview_interact',
|
|
220
|
-
description: '[Tauri Apps Only] Click, scroll, swipe, or perform gestures in a Tauri app webview. ' +
|
|
106
|
+
description: '[Tauri Apps Only] Click, scroll, swipe, focus, or perform gestures in a Tauri app webview. ' +
|
|
107
|
+
'Supported actions: click, double-click, long-press, scroll, swipe, focus. ' +
|
|
221
108
|
'Requires active tauri_driver_session. ' +
|
|
222
109
|
'For browser interaction, use Chrome DevTools MCP instead.',
|
|
223
110
|
category: TOOL_CATEGORIES.UI_AUTOMATION,
|
|
@@ -248,11 +135,18 @@ export const TOOLS = [
|
|
|
248
135
|
},
|
|
249
136
|
handler: async (args) => {
|
|
250
137
|
const parsed = ScreenshotSchema.parse(args);
|
|
251
|
-
|
|
138
|
+
const result = await screenshot({
|
|
252
139
|
quality: parsed.quality,
|
|
253
140
|
format: parsed.format,
|
|
254
141
|
windowId: parsed.windowId,
|
|
142
|
+
filePath: parsed.filePath,
|
|
255
143
|
});
|
|
144
|
+
// If saved to file, return text confirmation
|
|
145
|
+
if ('filePath' in result) {
|
|
146
|
+
return `Screenshot saved to: ${result.filePath}`;
|
|
147
|
+
}
|
|
148
|
+
// Return the content array directly for proper image handling
|
|
149
|
+
return result.content;
|
|
256
150
|
},
|
|
257
151
|
},
|
|
258
152
|
{
|
|
@@ -352,27 +246,9 @@ export const TOOLS = [
|
|
|
352
246
|
});
|
|
353
247
|
},
|
|
354
248
|
},
|
|
355
|
-
{
|
|
356
|
-
name: 'tauri_webview_focus_element',
|
|
357
|
-
description: '[Tauri Apps Only] Focus a DOM element in a Tauri app\'s webview. ' +
|
|
358
|
-
'Requires active tauri_driver_session. ' +
|
|
359
|
-
'For browser focus, use Chrome DevTools MCP instead.',
|
|
360
|
-
category: TOOL_CATEGORIES.UI_AUTOMATION,
|
|
361
|
-
schema: FocusElementSchema,
|
|
362
|
-
annotations: {
|
|
363
|
-
title: 'Focus Element in Tauri',
|
|
364
|
-
readOnlyHint: false,
|
|
365
|
-
destructiveHint: false,
|
|
366
|
-
openWorldHint: false,
|
|
367
|
-
},
|
|
368
|
-
handler: async (args) => {
|
|
369
|
-
const parsed = FocusElementSchema.parse(args);
|
|
370
|
-
return await focusElement({ selector: parsed.selector, windowId: parsed.windowId });
|
|
371
|
-
},
|
|
372
|
-
},
|
|
373
249
|
// IPC & Plugin Tools
|
|
374
250
|
{
|
|
375
|
-
name: '
|
|
251
|
+
name: 'tauri_ipc_execute_command',
|
|
376
252
|
description: '[Tauri Apps Only] Execute Tauri IPC commands (invoke Rust backend functions). ' +
|
|
377
253
|
'Requires active tauri_driver_session. This is Tauri-specific IPC, not browser APIs. ' +
|
|
378
254
|
'For Electron IPC or browser APIs, use appropriate tools for those frameworks.',
|
|
@@ -390,23 +266,7 @@ export const TOOLS = [
|
|
|
390
266
|
},
|
|
391
267
|
},
|
|
392
268
|
{
|
|
393
|
-
name: '
|
|
394
|
-
description: '[Tauri Apps Only] Get Tauri window information (size, position, state). ' +
|
|
395
|
-
'Requires active tauri_driver_session. ' +
|
|
396
|
-
'For browser window info, use Chrome DevTools MCP instead.',
|
|
397
|
-
category: TOOL_CATEGORIES.IPC_PLUGIN,
|
|
398
|
-
schema: GetWindowInfoSchema,
|
|
399
|
-
annotations: {
|
|
400
|
-
title: 'Get Tauri Window Info',
|
|
401
|
-
readOnlyHint: true,
|
|
402
|
-
openWorldHint: false,
|
|
403
|
-
},
|
|
404
|
-
handler: async () => {
|
|
405
|
-
return await getWindowInfo();
|
|
406
|
-
},
|
|
407
|
-
},
|
|
408
|
-
{
|
|
409
|
-
name: 'tauri_plugin_ipc_monitor',
|
|
269
|
+
name: 'tauri_ipc_monitor',
|
|
410
270
|
description: '[Tauri Apps Only] Monitor Tauri IPC calls between frontend and Rust backend. ' +
|
|
411
271
|
'Requires active tauri_driver_session. Captures invoke() calls and responses. ' +
|
|
412
272
|
'This is Tauri-specific; for browser network monitoring, use Chrome DevTools MCP.',
|
|
@@ -425,14 +285,14 @@ export const TOOLS = [
|
|
|
425
285
|
},
|
|
426
286
|
},
|
|
427
287
|
{
|
|
428
|
-
name: '
|
|
429
|
-
description: '[Tauri Apps Only] Get captured Tauri IPC
|
|
430
|
-
'Shows
|
|
288
|
+
name: 'tauri_ipc_get_captured',
|
|
289
|
+
description: '[Tauri Apps Only] Get captured Tauri IPC traffic (requires ipc_monitor started). ' +
|
|
290
|
+
'Shows captured commands (invoke calls) and events with arguments and responses. ' +
|
|
431
291
|
'For browser network requests, use Chrome DevTools MCP instead.',
|
|
432
292
|
category: TOOL_CATEGORIES.IPC_PLUGIN,
|
|
433
293
|
schema: GetIPCEventsSchema,
|
|
434
294
|
annotations: {
|
|
435
|
-
title: 'Get
|
|
295
|
+
title: 'Get Captured IPC Traffic',
|
|
436
296
|
readOnlyHint: true,
|
|
437
297
|
openWorldHint: false,
|
|
438
298
|
},
|
|
@@ -442,7 +302,7 @@ export const TOOLS = [
|
|
|
442
302
|
},
|
|
443
303
|
},
|
|
444
304
|
{
|
|
445
|
-
name: '
|
|
305
|
+
name: 'tauri_ipc_emit_event',
|
|
446
306
|
description: '[Tauri Apps Only] Emit a Tauri event to test event handlers. ' +
|
|
447
307
|
'Requires active tauri_driver_session. Events are Tauri-specific (not DOM events). ' +
|
|
448
308
|
'For browser DOM events, use Chrome DevTools MCP instead.',
|
|
@@ -460,7 +320,7 @@ export const TOOLS = [
|
|
|
460
320
|
},
|
|
461
321
|
},
|
|
462
322
|
{
|
|
463
|
-
name: '
|
|
323
|
+
name: 'tauri_ipc_get_backend_state',
|
|
464
324
|
description: '[Tauri Apps Only] Get Tauri backend state: app metadata, Tauri version, environment. ' +
|
|
465
325
|
'Requires active tauri_driver_session. ' +
|
|
466
326
|
'Use to verify you\'re connected to a Tauri app and get app info.',
|
|
@@ -478,7 +338,8 @@ export const TOOLS = [
|
|
|
478
338
|
// Window Management Tools
|
|
479
339
|
{
|
|
480
340
|
name: 'tauri_list_windows',
|
|
481
|
-
description: '[Tauri Apps Only] List all Tauri webview windows
|
|
341
|
+
description: '[Tauri Apps Only] List all Tauri webview windows with details including ' +
|
|
342
|
+
'labels, titles, URLs, and state (focused, visible, isMain). ' +
|
|
482
343
|
'Requires active tauri_driver_session. Use to discover windows before targeting them. ' +
|
|
483
344
|
'For browser tabs/windows, use Chrome DevTools MCP instead.',
|
|
484
345
|
category: TOOL_CATEGORIES.UI_AUTOMATION,
|
package/package.json
CHANGED
package/dist/manager/cli.js
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { execa } from 'execa';
|
|
3
|
-
import fs from 'fs/promises';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
export const RunCommandSchema = z.object({
|
|
6
|
-
command: z.string().describe('Any Tauri CLI command (e.g., "init", "dev", "build", "android dev", "migrate", "plugin add", etc.)'),
|
|
7
|
-
args: z.array(z.string()).optional().describe('Additional arguments to pass to the command'),
|
|
8
|
-
cwd: z.string().describe('The project directory'),
|
|
9
|
-
timeout: z.number().optional().describe('Command timeout in milliseconds (default: 180000)'),
|
|
10
|
-
});
|
|
11
|
-
/**
|
|
12
|
-
* Get available Tauri commands by running 'tauri --help'
|
|
13
|
-
*/
|
|
14
|
-
export async function listTauriCommands(cwd) {
|
|
15
|
-
try {
|
|
16
|
-
const packageJsonPath = path.join(cwd, 'package.json');
|
|
17
|
-
const hasTauriScript = await fs
|
|
18
|
-
.readFile(packageJsonPath, 'utf8')
|
|
19
|
-
.then((content) => {
|
|
20
|
-
try {
|
|
21
|
-
const pkg = JSON.parse(content);
|
|
22
|
-
return Boolean(pkg.scripts && pkg.scripts.tauri);
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
})
|
|
28
|
-
.catch(() => { return false; });
|
|
29
|
-
let result;
|
|
30
|
-
if (hasTauriScript) {
|
|
31
|
-
result = await execa('npm', ['run', 'tauri', '--', '--help'], {
|
|
32
|
-
cwd,
|
|
33
|
-
timeout: 10000,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
result = await execa('tauri', ['--help'], {
|
|
38
|
-
cwd,
|
|
39
|
-
timeout: 10000,
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
return result.stdout;
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
46
|
-
throw new Error(`Failed to get Tauri commands: ${message}`);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
export async function runTauriCommand(command, cwd, args = [], timeout = 180000) {
|
|
50
|
-
try {
|
|
51
|
-
// Split command if it contains spaces (e.g., "android dev" or "plugin add")
|
|
52
|
-
const commandParts = command.split(' ');
|
|
53
|
-
const allArgs = [...commandParts, ...args];
|
|
54
|
-
const packageJsonPath = path.join(cwd, 'package.json');
|
|
55
|
-
const hasTauriScript = await fs
|
|
56
|
-
.readFile(packageJsonPath, 'utf8')
|
|
57
|
-
.then((content) => {
|
|
58
|
-
try {
|
|
59
|
-
const pkg = JSON.parse(content);
|
|
60
|
-
return Boolean(pkg.scripts && pkg.scripts.tauri);
|
|
61
|
-
}
|
|
62
|
-
catch {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
})
|
|
66
|
-
.catch(() => { return false; });
|
|
67
|
-
const isDevLikeCommand = commandParts[0] === 'dev' ||
|
|
68
|
-
command.startsWith('android dev') ||
|
|
69
|
-
command.startsWith('ios dev');
|
|
70
|
-
const spawnTauri = () => {
|
|
71
|
-
if (hasTauriScript) {
|
|
72
|
-
return execa('npm', ['run', 'tauri', '--', ...allArgs], {
|
|
73
|
-
cwd,
|
|
74
|
-
timeout: isDevLikeCommand ? undefined : timeout,
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
return execa('tauri', allArgs, {
|
|
78
|
-
cwd,
|
|
79
|
-
timeout: isDevLikeCommand ? undefined : timeout,
|
|
80
|
-
});
|
|
81
|
-
};
|
|
82
|
-
const child = spawnTauri();
|
|
83
|
-
if (isDevLikeCommand) {
|
|
84
|
-
// For long-running dev commands, start the process and return once the
|
|
85
|
-
// command appears healthy
|
|
86
|
-
child.catch(() => { return; });
|
|
87
|
-
await new Promise((resolve) => {
|
|
88
|
-
setTimeout(resolve, 3000);
|
|
89
|
-
});
|
|
90
|
-
if (child.exitCode !== null) {
|
|
91
|
-
if (child.exitCode === 0) {
|
|
92
|
-
return 'Tauri dev command completed successfully.';
|
|
93
|
-
}
|
|
94
|
-
throw new Error('Tauri dev command exited unexpectedly. Check your project configuration and logs for details.');
|
|
95
|
-
}
|
|
96
|
-
const text = [
|
|
97
|
-
'Tauri dev command started. It may still be initializing; check your terminal',
|
|
98
|
-
'or devtools logs for live output. Use Ctrl+C in the appropriate terminal to',
|
|
99
|
-
'stop it.',
|
|
100
|
-
];
|
|
101
|
-
return text.join(' ');
|
|
102
|
-
}
|
|
103
|
-
const result = await child;
|
|
104
|
-
if (Array.isArray(result.stdout)) {
|
|
105
|
-
return result.stdout.join('\n');
|
|
106
|
-
}
|
|
107
|
-
if (result.stdout instanceof Uint8Array) {
|
|
108
|
-
return new TextDecoder().decode(result.stdout);
|
|
109
|
-
}
|
|
110
|
-
return result.stdout || 'Command completed successfully';
|
|
111
|
-
}
|
|
112
|
-
catch (error) {
|
|
113
|
-
const message = error instanceof Error ? error.message : String(error), stderr = error && typeof error === 'object' && 'stderr' in error ? String(error.stderr) : '';
|
|
114
|
-
// Provide more helpful error messages
|
|
115
|
-
if (message.includes('Unknown command')) {
|
|
116
|
-
throw new Error(`Unknown Tauri command: "${command}". Run 'tauri --help' to see available commands.\n${stderr}`);
|
|
117
|
-
}
|
|
118
|
-
if (message.includes('spawn tauri ENOENT')) {
|
|
119
|
-
const msgParts = [
|
|
120
|
-
'Failed to run the Tauri CLI. Either add a "tauri" script to your',
|
|
121
|
-
'package.json (e.g., "tauri": "tauri") or install the global Tauri CLI',
|
|
122
|
-
'as described in the documentation, then try again.',
|
|
123
|
-
];
|
|
124
|
-
throw new Error(msgParts.join(' '));
|
|
125
|
-
}
|
|
126
|
-
throw new Error(`Tauri command failed: ${message}${stderr ? `\n${stderr}` : ''}`);
|
|
127
|
-
}
|
|
128
|
-
}
|
package/dist/manager/config.js
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import fs from 'fs/promises';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
// Tauri supports multiple configuration files
|
|
5
|
-
const TAURI_CONFIG_FILES = [
|
|
6
|
-
'tauri.conf.json',
|
|
7
|
-
'tauri.conf.json5',
|
|
8
|
-
'Tauri.toml',
|
|
9
|
-
// Platform-specific configs
|
|
10
|
-
'tauri.windows.conf.json',
|
|
11
|
-
'tauri.linux.conf.json',
|
|
12
|
-
'tauri.macos.conf.json',
|
|
13
|
-
'tauri.android.conf.json',
|
|
14
|
-
'tauri.ios.conf.json',
|
|
15
|
-
// Build-specific configs
|
|
16
|
-
'tauri.conf.dev.json',
|
|
17
|
-
'tauri.conf.prod.json',
|
|
18
|
-
// Project files
|
|
19
|
-
'Cargo.toml',
|
|
20
|
-
'package.json',
|
|
21
|
-
// Mobile-specific files
|
|
22
|
-
'Info.plist',
|
|
23
|
-
'AndroidManifest.xml',
|
|
24
|
-
];
|
|
25
|
-
export const ReadConfigSchema = z.object({
|
|
26
|
-
projectPath: z.string(),
|
|
27
|
-
file: z.enum(TAURI_CONFIG_FILES).describe('Tauri configuration file to read'),
|
|
28
|
-
});
|
|
29
|
-
export const WriteConfigSchema = z.object({
|
|
30
|
-
projectPath: z.string(),
|
|
31
|
-
file: z.enum(TAURI_CONFIG_FILES).describe('Tauri configuration file to write'),
|
|
32
|
-
content: z.string().describe('The new content of the file'),
|
|
33
|
-
});
|
|
34
|
-
export async function readConfig(projectPath, file) {
|
|
35
|
-
const filePath = path.join(projectPath, getRelativePath(file));
|
|
36
|
-
try {
|
|
37
|
-
const content = await fs.readFile(filePath, 'utf-8');
|
|
38
|
-
return content;
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
throw new Error(`Failed to read ${file}: ${error}`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* List all available Tauri configuration files in the project
|
|
46
|
-
*/
|
|
47
|
-
export async function listConfigFiles(projectPath) {
|
|
48
|
-
const availableFiles = [];
|
|
49
|
-
for (const file of TAURI_CONFIG_FILES) {
|
|
50
|
-
const filePath = path.join(projectPath, getRelativePath(file));
|
|
51
|
-
try {
|
|
52
|
-
await fs.access(filePath);
|
|
53
|
-
availableFiles.push(file);
|
|
54
|
-
}
|
|
55
|
-
catch (e) {
|
|
56
|
-
// File doesn't exist, skip it
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return availableFiles;
|
|
60
|
-
}
|
|
61
|
-
export async function writeConfig(projectPath, file, content) {
|
|
62
|
-
const filePath = path.join(projectPath, getRelativePath(file));
|
|
63
|
-
// Validate JSON files
|
|
64
|
-
if (file.endsWith('.json')) {
|
|
65
|
-
try {
|
|
66
|
-
JSON.parse(content);
|
|
67
|
-
}
|
|
68
|
-
catch (e) {
|
|
69
|
-
throw new Error(`Invalid JSON content for ${file}`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// Validate JSON5 files
|
|
73
|
-
if (file.endsWith('.json5')) {
|
|
74
|
-
// JSON5 is a superset of JSON, basic validation
|
|
75
|
-
// In production, you'd want to use a json5 parser
|
|
76
|
-
try {
|
|
77
|
-
// At minimum, check for basic syntax
|
|
78
|
-
if (!content.trim()) {
|
|
79
|
-
throw new Error(`Empty content for ${file}`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
catch (e) {
|
|
83
|
-
throw new Error(`Invalid content for ${file}`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// Validate TOML files
|
|
87
|
-
if (file.endsWith('.toml')) {
|
|
88
|
-
// Basic TOML validation - in production use a TOML parser
|
|
89
|
-
if (!content.trim()) {
|
|
90
|
-
throw new Error(`Empty content for ${file}`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
// Validate XML files
|
|
94
|
-
if (file.endsWith('.xml')) {
|
|
95
|
-
// Basic XML validation
|
|
96
|
-
if (!content.includes('<') || !content.includes('>')) {
|
|
97
|
-
throw new Error(`Invalid XML content for ${file}`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
// Validate plist files
|
|
101
|
-
if (file.endsWith('.plist')) {
|
|
102
|
-
// plist files are XML-based
|
|
103
|
-
if (!content.includes('<?xml') || !content.includes('<plist')) {
|
|
104
|
-
throw new Error(`Invalid plist content for ${file}`);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
try {
|
|
108
|
-
await fs.writeFile(filePath, content, 'utf-8');
|
|
109
|
-
return `Successfully wrote to ${file}`;
|
|
110
|
-
}
|
|
111
|
-
catch (error) {
|
|
112
|
-
throw new Error(`Failed to write ${file}: ${error}`);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
function getRelativePath(file) {
|
|
116
|
-
// Main Tauri config files
|
|
117
|
-
if (file === 'tauri.conf.json' || file === 'tauri.conf.json5' || file === 'Tauri.toml') {
|
|
118
|
-
return `src-tauri/${file}`;
|
|
119
|
-
}
|
|
120
|
-
// Platform-specific Tauri configs
|
|
121
|
-
if (file.startsWith('tauri.') && (file.endsWith('.conf.json') || file.endsWith('.conf.json5'))) {
|
|
122
|
-
return `src-tauri/${file}`;
|
|
123
|
-
}
|
|
124
|
-
// Cargo.toml
|
|
125
|
-
if (file === 'Cargo.toml') {
|
|
126
|
-
return 'src-tauri/Cargo.toml';
|
|
127
|
-
}
|
|
128
|
-
// iOS Info.plist
|
|
129
|
-
if (file === 'Info.plist') {
|
|
130
|
-
return 'src-tauri/gen/apple/Runner/Info.plist';
|
|
131
|
-
}
|
|
132
|
-
// Android manifest
|
|
133
|
-
if (file === 'AndroidManifest.xml') {
|
|
134
|
-
return 'src-tauri/gen/android/app/src/main/AndroidManifest.xml';
|
|
135
|
-
}
|
|
136
|
-
// Package.json is at root
|
|
137
|
-
if (file === 'package.json') {
|
|
138
|
-
return 'package.json';
|
|
139
|
-
}
|
|
140
|
-
// Default: assume it's relative to project root
|
|
141
|
-
return file;
|
|
142
|
-
}
|