tauri-agent-tools 0.5.1 → 0.7.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/.agents/skills/tauri-agent-tools/SKILL.md +195 -13
- package/.agents/skills/tauri-bridge-setup/SKILL.md +82 -14
- package/.agents/skills/tauri-debug-quickstart/SKILL.md +80 -0
- package/AGENTS.md +9 -7
- package/README.md +119 -11
- package/dist/bridge/client.d.ts +21 -2
- package/dist/bridge/client.js +119 -3
- package/dist/bridge/client.js.map +1 -1
- package/dist/cli.js +47 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/appPaths.d.ts +2 -0
- package/dist/commands/appPaths.js +97 -0
- package/dist/commands/appPaths.js.map +1 -0
- package/dist/commands/capabilitiesAudit.d.ts +2 -0
- package/dist/commands/capabilitiesAudit.js +105 -0
- package/dist/commands/capabilitiesAudit.js.map +1 -0
- package/dist/commands/capture.d.ts +3 -0
- package/dist/commands/capture.js +218 -0
- package/dist/commands/capture.js.map +1 -0
- package/dist/commands/check.d.ts +5 -0
- package/dist/commands/check.js +174 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/configInspect.d.ts +2 -0
- package/dist/commands/configInspect.js +223 -0
- package/dist/commands/configInspect.js.map +1 -0
- package/dist/commands/diagnose.d.ts +2 -0
- package/dist/commands/diagnose.js +311 -0
- package/dist/commands/diagnose.js.map +1 -0
- package/dist/commands/eval.js +16 -3
- package/dist/commands/eval.js.map +1 -1
- package/dist/commands/forensics.d.ts +2 -0
- package/dist/commands/forensics.js +331 -0
- package/dist/commands/forensics.js.map +1 -0
- package/dist/commands/health.d.ts +2 -0
- package/dist/commands/health.js +39 -0
- package/dist/commands/health.js.map +1 -0
- package/dist/commands/interact/click.d.ts +6 -0
- package/dist/commands/interact/click.js +102 -0
- package/dist/commands/interact/click.js.map +1 -0
- package/dist/commands/interact/focus.d.ts +3 -0
- package/dist/commands/interact/focus.js +40 -0
- package/dist/commands/interact/focus.js.map +1 -0
- package/dist/commands/interact/navigate.d.ts +3 -0
- package/dist/commands/interact/navigate.js +49 -0
- package/dist/commands/interact/navigate.js.map +1 -0
- package/dist/commands/interact/scroll.d.ts +11 -0
- package/dist/commands/interact/scroll.js +110 -0
- package/dist/commands/interact/scroll.js.map +1 -0
- package/dist/commands/interact/select.d.ts +3 -0
- package/dist/commands/interact/select.js +59 -0
- package/dist/commands/interact/select.js.map +1 -0
- package/dist/commands/interact/shared.d.ts +23 -0
- package/dist/commands/interact/shared.js +62 -0
- package/dist/commands/interact/shared.js.map +1 -0
- package/dist/commands/interact/type.d.ts +6 -0
- package/dist/commands/interact/type.js +59 -0
- package/dist/commands/interact/type.js.map +1 -0
- package/dist/commands/invoke.d.ts +3 -0
- package/dist/commands/invoke.js +53 -0
- package/dist/commands/invoke.js.map +1 -0
- package/dist/commands/osLogs.d.ts +2 -0
- package/dist/commands/osLogs.js +130 -0
- package/dist/commands/osLogs.js.map +1 -0
- package/dist/commands/probe.d.ts +2 -0
- package/dist/commands/probe.js +117 -0
- package/dist/commands/probe.js.map +1 -0
- package/dist/commands/processTree.d.ts +2 -0
- package/dist/commands/processTree.js +45 -0
- package/dist/commands/processTree.js.map +1 -0
- package/dist/commands/shared.d.ts +10 -4
- package/dist/commands/shared.js +23 -3
- package/dist/commands/shared.js.map +1 -1
- package/dist/commands/sidecarReplay.d.ts +7 -0
- package/dist/commands/sidecarReplay.js +93 -0
- package/dist/commands/sidecarReplay.js.map +1 -0
- package/dist/commands/sidecarTap.d.ts +2 -0
- package/dist/commands/sidecarTap.js +118 -0
- package/dist/commands/sidecarTap.js.map +1 -0
- package/dist/commands/storeInspect.d.ts +13 -0
- package/dist/commands/storeInspect.js +156 -0
- package/dist/commands/storeInspect.js.map +1 -0
- package/dist/commands/webviewAttach.d.ts +2 -0
- package/dist/commands/webviewAttach.js +64 -0
- package/dist/commands/webviewAttach.js.map +1 -0
- package/dist/platform/oslog/darwin.d.ts +21 -0
- package/dist/platform/oslog/darwin.js +72 -0
- package/dist/platform/oslog/darwin.js.map +1 -0
- package/dist/platform/oslog/linux.d.ts +16 -0
- package/dist/platform/oslog/linux.js +47 -0
- package/dist/platform/oslog/linux.js.map +1 -0
- package/dist/platform/oslog/windows.d.ts +15 -0
- package/dist/platform/oslog/windows.js +16 -0
- package/dist/platform/oslog/windows.js.map +1 -0
- package/dist/schemas/bridge.d.ts +256 -0
- package/dist/schemas/bridge.js +57 -0
- package/dist/schemas/bridge.js.map +1 -1
- package/dist/schemas/commands.d.ts +126 -0
- package/dist/schemas/commands.js +28 -0
- package/dist/schemas/commands.js.map +1 -1
- package/dist/schemas/index.d.ts +3 -2
- package/dist/schemas/index.js +3 -2
- package/dist/schemas/index.js.map +1 -1
- package/dist/schemas/interact.d.ts +118 -0
- package/dist/schemas/interact.js +31 -0
- package/dist/schemas/interact.js.map +1 -0
- package/dist/schemas/osLog.d.ts +34 -0
- package/dist/schemas/osLog.js +18 -0
- package/dist/schemas/osLog.js.map +1 -0
- package/dist/schemas/sidecar.d.ts +33 -0
- package/dist/schemas/sidecar.js +17 -0
- package/dist/schemas/sidecar.js.map +1 -0
- package/dist/schemas/tauriConfig.d.ts +825 -0
- package/dist/schemas/tauriConfig.js +102 -0
- package/dist/schemas/tauriConfig.js.map +1 -0
- package/dist/util/ndjson.d.ts +37 -0
- package/dist/util/ndjson.js +82 -0
- package/dist/util/ndjson.js.map +1 -0
- package/dist/util/tauriConfig.d.ts +63 -0
- package/dist/util/tauriConfig.js +235 -0
- package/dist/util/tauriConfig.js.map +1 -0
- package/examples/frontend-stub/index.html +1 -0
- package/examples/tauri-bridge/Cargo.toml +6 -0
- package/examples/tauri-bridge/build.rs +3 -0
- package/examples/tauri-bridge/icons/icon.png +0 -0
- package/examples/tauri-bridge/src/dev_bridge.rs +509 -10
- package/examples/tauri-bridge/tauri.conf.json +25 -0
- package/package.json +3 -1
- package/rust-bridge/README.md +7 -5
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { mkdir, readdir, stat, writeFile, readFile } from 'node:fs/promises';
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
5
|
+
import { homedir } from 'node:os';
|
|
6
|
+
import { join, basename } from 'node:path';
|
|
7
|
+
import { LineFramer } from '../util/ndjson.js';
|
|
8
|
+
import { resolveTauriProject } from '../util/tauriConfig.js';
|
|
9
|
+
import { buildArgs as buildDarwinArgs, parseLine as parseDarwinLine } from '../platform/oslog/darwin.js';
|
|
10
|
+
import { buildArgs as buildLinuxArgs, parseLine as parseLinuxLine } from '../platform/oslog/linux.js';
|
|
11
|
+
const PANIC_MARKERS = [
|
|
12
|
+
'panicked at',
|
|
13
|
+
'panic occurred',
|
|
14
|
+
'SIGSEGV',
|
|
15
|
+
'SIGABRT',
|
|
16
|
+
'fatal runtime error',
|
|
17
|
+
'thread \'main\' panicked',
|
|
18
|
+
'Uncaught',
|
|
19
|
+
'unhandledRejection',
|
|
20
|
+
];
|
|
21
|
+
export function registerForensics(program) {
|
|
22
|
+
const cmd = new Command('forensics')
|
|
23
|
+
.description("Bundle a forensic snapshot of a Tauri app (paths, logs, crash reports). Works on dead apps.")
|
|
24
|
+
.option('--config <path>', 'Path to tauri.conf.json (or its directory). Auto-detected if omitted.')
|
|
25
|
+
.option('--identifier <id>', 'Bundle identifier override')
|
|
26
|
+
.option('-o, --out <dir>', 'Output directory (default: ./forensics-<timestamp>)')
|
|
27
|
+
.option('--since <duration>', 'How far back to pull from app log files (default: 10m)')
|
|
28
|
+
.option('--logs-duration <ms>', 'Time budget for the live OS-log tail in milliseconds (default: 3000)', parsePositiveInt)
|
|
29
|
+
.option('--json', 'Print the summary as JSON to stdout in addition to writing to disk')
|
|
30
|
+
.action(async (opts) => {
|
|
31
|
+
const outDir = opts.out ?? `./forensics-${timestampSlug()}`;
|
|
32
|
+
await mkdir(outDir, { recursive: true });
|
|
33
|
+
const outcomes = [];
|
|
34
|
+
const summary = { phases: outcomes };
|
|
35
|
+
// ── Phase 1: Resolve project + paths ─────────────────────────────────
|
|
36
|
+
const resolved = await safe(async () => resolveTauriProject({ configPath: opts.config, identifierOverride: opts.identifier }));
|
|
37
|
+
if (!resolved.ok) {
|
|
38
|
+
outcomes.push({ phase: 'resolve-config', ok: false, detail: resolved.error });
|
|
39
|
+
await writeSummary(outDir, summary, opts.json);
|
|
40
|
+
throw new Error(`Could not resolve Tauri config: ${resolved.error}`);
|
|
41
|
+
}
|
|
42
|
+
const project = resolved.value;
|
|
43
|
+
outcomes.push({
|
|
44
|
+
phase: 'resolve-config',
|
|
45
|
+
ok: true,
|
|
46
|
+
detail: `identifier=${project.identifier} productName=${project.productName}`,
|
|
47
|
+
});
|
|
48
|
+
summary['identifier'] = project.identifier;
|
|
49
|
+
summary['productName'] = project.productName;
|
|
50
|
+
summary['configPath'] = project.configPath;
|
|
51
|
+
summary['platform'] = project.platform;
|
|
52
|
+
summary['paths'] = project.paths[project.platform];
|
|
53
|
+
// ── Phase 2: List files in app-data + app-log directories ────────────
|
|
54
|
+
const dataFiles = await safeListDir(project.paths[project.platform].appDataDir);
|
|
55
|
+
const logFiles = await safeListDir(project.paths[project.platform].appLogDir);
|
|
56
|
+
summary['appDataFiles'] = dataFiles.files;
|
|
57
|
+
summary['appLogFiles'] = logFiles.files;
|
|
58
|
+
outcomes.push({
|
|
59
|
+
phase: 'list-app-data',
|
|
60
|
+
ok: dataFiles.ok,
|
|
61
|
+
detail: dataFiles.ok ? `${dataFiles.files.length} files` : dataFiles.detail,
|
|
62
|
+
});
|
|
63
|
+
outcomes.push({
|
|
64
|
+
phase: 'list-app-log',
|
|
65
|
+
ok: logFiles.ok,
|
|
66
|
+
detail: logFiles.ok ? `${logFiles.files.length} files` : logFiles.detail,
|
|
67
|
+
});
|
|
68
|
+
// ── Phase 3: Tail the most-recently-modified app log file ────────────
|
|
69
|
+
const newestLog = pickNewest(logFiles.files);
|
|
70
|
+
let logTail = [];
|
|
71
|
+
let panicLines = [];
|
|
72
|
+
if (newestLog) {
|
|
73
|
+
const tailResult = await safe(async () => tailFile(newestLog.path, 200));
|
|
74
|
+
if (tailResult.ok) {
|
|
75
|
+
logTail = tailResult.value;
|
|
76
|
+
panicLines = logTail.filter((l) => PANIC_MARKERS.some((m) => l.includes(m)));
|
|
77
|
+
outcomes.push({
|
|
78
|
+
phase: 'tail-app-log',
|
|
79
|
+
ok: true,
|
|
80
|
+
detail: `${logTail.length} lines, ${panicLines.length} panic marker(s)`,
|
|
81
|
+
});
|
|
82
|
+
await writeFile(join(outDir, 'app-log-tail.txt'), logTail.join('\n'));
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
outcomes.push({ phase: 'tail-app-log', ok: false, detail: tailResult.error });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
outcomes.push({ phase: 'tail-app-log', ok: false, detail: 'no app log files found' });
|
|
90
|
+
}
|
|
91
|
+
summary['logTailLineCount'] = logTail.length;
|
|
92
|
+
summary['panicLines'] = panicLines;
|
|
93
|
+
// ── Phase 4: macOS DiagnosticReports (skip on other platforms) ───────
|
|
94
|
+
let diagnosticReports = [];
|
|
95
|
+
if (project.platform === 'darwin') {
|
|
96
|
+
const drDir = `${homedir()}/Library/Logs/DiagnosticReports`;
|
|
97
|
+
if (existsSync(drDir)) {
|
|
98
|
+
const all = await safeListDir(drDir);
|
|
99
|
+
// Filter to entries whose name starts with productName (macOS naming convention).
|
|
100
|
+
diagnosticReports = all.files
|
|
101
|
+
.filter((f) => basename(f.path).startsWith(project.productName))
|
|
102
|
+
.sort((a, b) => (a.mtime < b.mtime ? 1 : -1))
|
|
103
|
+
.slice(0, 5);
|
|
104
|
+
outcomes.push({
|
|
105
|
+
phase: 'macos-diagnostic-reports',
|
|
106
|
+
ok: true,
|
|
107
|
+
detail: `${diagnosticReports.length} report(s) matching productName`,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
outcomes.push({
|
|
112
|
+
phase: 'macos-diagnostic-reports',
|
|
113
|
+
ok: false,
|
|
114
|
+
detail: `${drDir} not accessible`,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
summary['diagnosticReports'] = diagnosticReports;
|
|
119
|
+
// ── Phase 5: Live OS-log tail (best-effort) ──────────────────────────
|
|
120
|
+
const liveLogs = [];
|
|
121
|
+
const budgetMs = opts.logsDuration ?? 3000;
|
|
122
|
+
if (project.platform === 'darwin' || project.platform === 'linux') {
|
|
123
|
+
const livRes = await safe(async () => collectLiveLogs(project.identifier, project.productName, budgetMs, project.platform));
|
|
124
|
+
if (livRes.ok) {
|
|
125
|
+
liveLogs.push(...livRes.value);
|
|
126
|
+
outcomes.push({
|
|
127
|
+
phase: 'live-os-log-tail',
|
|
128
|
+
ok: true,
|
|
129
|
+
detail: `${liveLogs.length} entries in ${budgetMs}ms`,
|
|
130
|
+
});
|
|
131
|
+
await writeFile(join(outDir, 'live-os-log.ndjson'), liveLogs.map((e) => JSON.stringify(e)).join('\n'));
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
outcomes.push({ phase: 'live-os-log-tail', ok: false, detail: livRes.error });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
outcomes.push({
|
|
139
|
+
phase: 'live-os-log-tail',
|
|
140
|
+
ok: false,
|
|
141
|
+
detail: `not implemented on ${project.platform}`,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
summary['liveLogEntries'] = liveLogs.length;
|
|
145
|
+
// ── Phase 6: Write artifacts to outDir ───────────────────────────────
|
|
146
|
+
await writeFile(join(outDir, 'project.json'), JSON.stringify(project, null, 2));
|
|
147
|
+
await writeFile(join(outDir, 'summary.json'), JSON.stringify(summary, null, 2));
|
|
148
|
+
await writeFile(join(outDir, 'summary.md'), renderMarkdown(summary, outcomes, project, panicLines, logTail));
|
|
149
|
+
summary['outDir'] = outDir;
|
|
150
|
+
if (opts.json) {
|
|
151
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
console.log(`✓ Forensic bundle written to ${outDir}`);
|
|
155
|
+
console.log(` ${outcomes.filter((o) => o.ok).length}/${outcomes.length} phases succeeded`);
|
|
156
|
+
if (panicLines.length > 0) {
|
|
157
|
+
console.log(` ⚠ ${panicLines.length} panic marker(s) in the most-recent log`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
program.addCommand(cmd);
|
|
162
|
+
}
|
|
163
|
+
function timestampSlug() {
|
|
164
|
+
return new Date().toISOString().replace(/[:.]/g, '-');
|
|
165
|
+
}
|
|
166
|
+
async function safe(fn) {
|
|
167
|
+
try {
|
|
168
|
+
return { ok: true, value: await fn() };
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async function safeListDir(dir) {
|
|
175
|
+
if (!existsSync(dir)) {
|
|
176
|
+
return { ok: false, files: [], detail: `${dir} does not exist` };
|
|
177
|
+
}
|
|
178
|
+
try {
|
|
179
|
+
const entries = await readdir(dir);
|
|
180
|
+
const files = [];
|
|
181
|
+
for (const name of entries) {
|
|
182
|
+
const path = join(dir, name);
|
|
183
|
+
try {
|
|
184
|
+
const st = await stat(path);
|
|
185
|
+
if (!st.isFile())
|
|
186
|
+
continue;
|
|
187
|
+
files.push({ path, size: st.size, mtime: st.mtime.toISOString() });
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
// Skip unreadable entries (permission denied, etc.)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return { ok: true, files, detail: `${files.length} files` };
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
return {
|
|
197
|
+
ok: false,
|
|
198
|
+
files: [],
|
|
199
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function pickNewest(files) {
|
|
204
|
+
if (files.length === 0)
|
|
205
|
+
return null;
|
|
206
|
+
return [...files].sort((a, b) => (a.mtime < b.mtime ? 1 : -1))[0] ?? null;
|
|
207
|
+
}
|
|
208
|
+
async function tailFile(path, lines) {
|
|
209
|
+
// Naive impl: read whole file, slice last N. Good enough for "tail the most
|
|
210
|
+
// recent app log" since these files are typically rotated/small.
|
|
211
|
+
const text = await readFile(path, 'utf-8');
|
|
212
|
+
return text.split(/\r?\n/).slice(-lines).filter((l) => l.length > 0);
|
|
213
|
+
}
|
|
214
|
+
async function collectLiveLogs(identifier, productName, budgetMs, platform) {
|
|
215
|
+
if (platform === 'win32')
|
|
216
|
+
return [];
|
|
217
|
+
const args = platform === 'darwin'
|
|
218
|
+
? buildDarwinArgs({ identifier, productName })
|
|
219
|
+
: buildLinuxArgs({ identifier, productName, since: `${Math.ceil(budgetMs / 1000)}s ago` });
|
|
220
|
+
const cmdBin = platform === 'darwin' ? 'log' : 'journalctl';
|
|
221
|
+
const parser = platform === 'darwin' ? parseDarwinLine : parseLinuxLine;
|
|
222
|
+
const child = spawn(cmdBin, args, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
223
|
+
const framer = new LineFramer();
|
|
224
|
+
const entries = [];
|
|
225
|
+
child.stdout.setEncoding('utf-8');
|
|
226
|
+
child.stdout.on('data', (chunk) => {
|
|
227
|
+
for (const line of framer.push(chunk)) {
|
|
228
|
+
const e = parser(line);
|
|
229
|
+
if (e)
|
|
230
|
+
entries.push(e);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
const timer = setTimeout(() => child.kill('SIGTERM'), budgetMs);
|
|
234
|
+
await new Promise((resolve) => {
|
|
235
|
+
child.on('close', () => {
|
|
236
|
+
clearTimeout(timer);
|
|
237
|
+
resolve();
|
|
238
|
+
});
|
|
239
|
+
child.on('error', () => {
|
|
240
|
+
clearTimeout(timer);
|
|
241
|
+
resolve(); // swallow — forensics is best-effort
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
return entries;
|
|
245
|
+
}
|
|
246
|
+
async function writeSummary(outDir, summary, alsoStdout) {
|
|
247
|
+
await writeFile(join(outDir, 'summary.json'), JSON.stringify(summary, null, 2));
|
|
248
|
+
if (alsoStdout)
|
|
249
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
250
|
+
}
|
|
251
|
+
function renderMarkdown(summary, outcomes, project, panicLines, logTail) {
|
|
252
|
+
const phases = outcomes
|
|
253
|
+
.map((o) => `- ${o.ok ? '✓' : '✗'} **${o.phase}** — ${o.detail}`)
|
|
254
|
+
.join('\n');
|
|
255
|
+
const dataFiles = summary['appDataFiles'] ?? [];
|
|
256
|
+
const logFiles = summary['appLogFiles'] ?? [];
|
|
257
|
+
const dataList = dataFiles.length === 0
|
|
258
|
+
? '_no files_'
|
|
259
|
+
: dataFiles.map((f) => `- \`${f.path}\` (${f.size} bytes, ${f.mtime})`).join('\n');
|
|
260
|
+
const logList = logFiles.length === 0
|
|
261
|
+
? '_no files_'
|
|
262
|
+
: logFiles.map((f) => `- \`${f.path}\` (${f.size} bytes, ${f.mtime})`).join('\n');
|
|
263
|
+
const panicBlock = panicLines.length === 0
|
|
264
|
+
? '_none_'
|
|
265
|
+
: panicLines.map((l) => ' ' + l).join('\n');
|
|
266
|
+
const tailBlock = logTail.length === 0
|
|
267
|
+
? '_no log file to tail_'
|
|
268
|
+
: '```\n' + logTail.slice(-20).join('\n') + '\n```';
|
|
269
|
+
return `# Forensics: ${project.productName}
|
|
270
|
+
|
|
271
|
+
- **Identifier:** \`${project.identifier}\`
|
|
272
|
+
- **Platform:** ${project.platform}
|
|
273
|
+
- **Config:** \`${project.configPath}\`
|
|
274
|
+
|
|
275
|
+
## Phases
|
|
276
|
+
|
|
277
|
+
${phases}
|
|
278
|
+
|
|
279
|
+
## Resolved paths (current platform)
|
|
280
|
+
|
|
281
|
+
\`\`\`json
|
|
282
|
+
${JSON.stringify(project.paths[project.platform], null, 2)}
|
|
283
|
+
\`\`\`
|
|
284
|
+
|
|
285
|
+
## App data files
|
|
286
|
+
|
|
287
|
+
${dataList}
|
|
288
|
+
|
|
289
|
+
## App log files
|
|
290
|
+
|
|
291
|
+
${logList}
|
|
292
|
+
|
|
293
|
+
## Panic markers in most-recent log
|
|
294
|
+
|
|
295
|
+
\`\`\`
|
|
296
|
+
${panicBlock}
|
|
297
|
+
\`\`\`
|
|
298
|
+
|
|
299
|
+
## Tail of most-recent log (last 20 lines)
|
|
300
|
+
|
|
301
|
+
${tailBlock}
|
|
302
|
+
|
|
303
|
+
## Suggested next steps
|
|
304
|
+
|
|
305
|
+
${suggestNextSteps(project, panicLines, logTail, outcomes)}
|
|
306
|
+
`;
|
|
307
|
+
}
|
|
308
|
+
function suggestNextSteps(project, panicLines, logTail, outcomes) {
|
|
309
|
+
const tips = [];
|
|
310
|
+
if (panicLines.length > 0) {
|
|
311
|
+
tips.push(`- A panic was detected. Run \`tauri-agent-tools os-logs --identifier ${project.identifier} --level error --since 30m --json\` to fetch surrounding error-level entries.`);
|
|
312
|
+
}
|
|
313
|
+
if (logTail.length === 0) {
|
|
314
|
+
tips.push(`- No app log file found. Verify the app actually writes to \`appLogDir\` (default for Tauri is via \`tauri-plugin-log\`).`);
|
|
315
|
+
}
|
|
316
|
+
if (outcomes.some((o) => o.phase === 'live-os-log-tail' && !o.ok)) {
|
|
317
|
+
tips.push(`- Live OS-log tail failed. Check that \`${project.platform === 'darwin' ? 'log' : 'journalctl'}\` is on PATH.`);
|
|
318
|
+
}
|
|
319
|
+
if (tips.length === 0) {
|
|
320
|
+
tips.push(`- No specific anomalies detected. Inspect the artifacts in this folder for context.`);
|
|
321
|
+
}
|
|
322
|
+
return tips.join('\n');
|
|
323
|
+
}
|
|
324
|
+
function parsePositiveInt(value) {
|
|
325
|
+
const n = parseInt(value, 10);
|
|
326
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
327
|
+
throw new Error(`Expected a positive integer, got: ${value}`);
|
|
328
|
+
}
|
|
329
|
+
return n;
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=forensics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forensics.js","sourceRoot":"","sources":["../../src/commands/forensics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { addBridgeOptions, resolveBridge } from './shared.js';
|
|
3
|
+
export function registerHealth(program) {
|
|
4
|
+
const cmd = new Command('health')
|
|
5
|
+
.description('Quick "is this Tauri app sick" check (requires bridge v0.7.0+)')
|
|
6
|
+
.option('--json', 'Output as JSON');
|
|
7
|
+
addBridgeOptions(cmd);
|
|
8
|
+
cmd.action(async (opts) => {
|
|
9
|
+
const bridge = await resolveBridge(opts);
|
|
10
|
+
const h = await bridge.health();
|
|
11
|
+
if (opts.json) {
|
|
12
|
+
console.log(JSON.stringify(h, null, 2));
|
|
13
|
+
// Exit non-zero on detected issues so this can drive CI gates.
|
|
14
|
+
if (!h.webview_ready || !h.sidecars_alive)
|
|
15
|
+
process.exitCode = 1;
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
renderHuman(h);
|
|
19
|
+
if (!h.webview_ready || !h.sidecars_alive)
|
|
20
|
+
process.exitCode = 1;
|
|
21
|
+
});
|
|
22
|
+
program.addCommand(cmd);
|
|
23
|
+
}
|
|
24
|
+
function renderHuman(h) {
|
|
25
|
+
const uptimeSec = Math.floor(h.uptime_ms / 1000);
|
|
26
|
+
console.log(`Uptime: ${uptimeSec}s`);
|
|
27
|
+
console.log(`Webview ready: ${h.webview_ready ? 'yes' : 'NO'}`);
|
|
28
|
+
console.log(`Sidecars alive: ${h.sidecars_alive ? 'yes' : 'NO'}`);
|
|
29
|
+
if (h.sidecars.length === 0) {
|
|
30
|
+
console.log(`Sidecars: (none registered)`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
console.log(`Sidecars (${h.sidecars.length}):`);
|
|
34
|
+
for (const s of h.sidecars) {
|
|
35
|
+
const alive = s.alive === null || s.alive === undefined ? '?' : s.alive ? 'alive' : 'DEAD';
|
|
36
|
+
console.log(` ${s.name.padEnd(20)} pid=${s.pid} ${alive}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/commands/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI9D,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;SAC9B,WAAW,CAAC,gEAAgE,CAAC;SAC7E,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IAEtC,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAEtB,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,IAAqC,EAAE,EAAE;QACzD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACxC,+DAA+D;YAC/D,IAAI,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,cAAc;gBAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YAChE,OAAO;QACT,CAAC;QACD,WAAW,CAAC,CAAC,CAAC,CAAC;QACf,IAAI,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,cAAc;YAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,WAAW,CAAC,CAAiB;IACpC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,mBAAmB,SAAS,GAAG,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAClE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QAC3F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { resolveBridge } from '../shared.js';
|
|
3
|
+
import { addInteractOptions, escapeSelector } from './shared.js';
|
|
4
|
+
import { ClickResultSchema } from '../../schemas/interact.js';
|
|
5
|
+
export function buildClickScript(selector, opts) {
|
|
6
|
+
const escaped = escapeSelector(selector);
|
|
7
|
+
const button = opts.right ? 2 : 0;
|
|
8
|
+
return `(() => {
|
|
9
|
+
var el = document.querySelector('${escaped}');
|
|
10
|
+
if (!el) return JSON.stringify({ success: false, selector: '${escaped}', error: 'Element not found' });
|
|
11
|
+
var r = el.getBoundingClientRect();
|
|
12
|
+
var clientX = r.left + r.width / 2;
|
|
13
|
+
var clientY = r.top + r.height / 2;
|
|
14
|
+
var eventOpts = { bubbles: true, cancelable: true, clientX: clientX, clientY: clientY, button: ${button} };
|
|
15
|
+
el.dispatchEvent(new MouseEvent('mousedown', eventOpts));
|
|
16
|
+
el.dispatchEvent(new MouseEvent('mouseup', eventOpts));
|
|
17
|
+
${opts.right
|
|
18
|
+
? `el.dispatchEvent(new MouseEvent('contextmenu', eventOpts));`
|
|
19
|
+
: opts.double
|
|
20
|
+
? `el.dispatchEvent(new MouseEvent('click', eventOpts));
|
|
21
|
+
el.dispatchEvent(new MouseEvent('dblclick', eventOpts));`
|
|
22
|
+
: `el.dispatchEvent(new MouseEvent('click', eventOpts));`}
|
|
23
|
+
var text = (el.textContent || '').trim().slice(0, 100);
|
|
24
|
+
return JSON.stringify({ success: true, selector: '${escaped}', tagName: el.tagName.toLowerCase(), text: text });
|
|
25
|
+
})()`;
|
|
26
|
+
}
|
|
27
|
+
function buildWaitAndClickScript(selector, opts, waitMs) {
|
|
28
|
+
const escaped = escapeSelector(selector);
|
|
29
|
+
const button = opts.right ? 2 : 0;
|
|
30
|
+
const clickEvents = opts.right
|
|
31
|
+
? `el.dispatchEvent(new MouseEvent('contextmenu', eventOpts));`
|
|
32
|
+
: opts.double
|
|
33
|
+
? `el.dispatchEvent(new MouseEvent('click', eventOpts));
|
|
34
|
+
el.dispatchEvent(new MouseEvent('dblclick', eventOpts));`
|
|
35
|
+
: `el.dispatchEvent(new MouseEvent('click', eventOpts));`;
|
|
36
|
+
return `(() => {
|
|
37
|
+
var deadline = Date.now() + ${waitMs};
|
|
38
|
+
function attempt() {
|
|
39
|
+
var el = document.querySelector('${escaped}');
|
|
40
|
+
if (el) {
|
|
41
|
+
var r = el.getBoundingClientRect();
|
|
42
|
+
var clientX = r.left + r.width / 2;
|
|
43
|
+
var clientY = r.top + r.height / 2;
|
|
44
|
+
var eventOpts = { bubbles: true, cancelable: true, clientX: clientX, clientY: clientY, button: ${button} };
|
|
45
|
+
el.dispatchEvent(new MouseEvent('mousedown', eventOpts));
|
|
46
|
+
el.dispatchEvent(new MouseEvent('mouseup', eventOpts));
|
|
47
|
+
${clickEvents}
|
|
48
|
+
var text = (el.textContent || '').trim().slice(0, 100);
|
|
49
|
+
return JSON.stringify({ success: true, selector: '${escaped}', tagName: el.tagName.toLowerCase(), text: text });
|
|
50
|
+
}
|
|
51
|
+
if (Date.now() >= deadline) {
|
|
52
|
+
return JSON.stringify({ success: false, selector: '${escaped}', error: 'Element not found' });
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
return new Promise(function(resolve) {
|
|
57
|
+
function poll() {
|
|
58
|
+
var result = attempt();
|
|
59
|
+
if (result !== null) { resolve(result); return; }
|
|
60
|
+
setTimeout(poll, 100);
|
|
61
|
+
}
|
|
62
|
+
poll();
|
|
63
|
+
});
|
|
64
|
+
})()`;
|
|
65
|
+
}
|
|
66
|
+
export function registerClick(program) {
|
|
67
|
+
const cmd = new Command('click')
|
|
68
|
+
.description('Dispatch mouse click events on a DOM element')
|
|
69
|
+
.argument('<selector>', 'CSS selector of the element to click')
|
|
70
|
+
.option('--double', 'Dispatch a double-click (dblclick) instead of a single click')
|
|
71
|
+
.option('--right', 'Dispatch a right-click (contextmenu) instead of a left click')
|
|
72
|
+
.option('--wait <ms>', 'Wait up to <ms> milliseconds for element to appear', parseInt, 0)
|
|
73
|
+
.addHelpText('after', `
|
|
74
|
+
Examples:
|
|
75
|
+
$ tauri-agent-tools click "button.submit"
|
|
76
|
+
$ tauri-agent-tools click "#menu-toggle" --double
|
|
77
|
+
$ tauri-agent-tools click ".context-target" --right
|
|
78
|
+
$ tauri-agent-tools click ".lazy-item" --wait 3000 --json`);
|
|
79
|
+
addInteractOptions(cmd);
|
|
80
|
+
cmd.action(async (selector, opts) => {
|
|
81
|
+
const bridge = await resolveBridge(opts);
|
|
82
|
+
const clickOpts = { double: !!opts.double, right: !!opts.right };
|
|
83
|
+
const script = opts.wait > 0
|
|
84
|
+
? buildWaitAndClickScript(selector, clickOpts, opts.wait)
|
|
85
|
+
: buildClickScript(selector, clickOpts);
|
|
86
|
+
const raw = await bridge.eval(script);
|
|
87
|
+
const result = ClickResultSchema.parse(JSON.parse(String(raw)));
|
|
88
|
+
if (!result.success) {
|
|
89
|
+
throw new Error(`Click failed: ${result.error} (selector: ${result.selector})`);
|
|
90
|
+
}
|
|
91
|
+
if (opts.json) {
|
|
92
|
+
console.log(JSON.stringify(result, null, 2));
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
const actionLabel = opts.right ? 'right-clicked' : opts.double ? 'double-clicked' : 'clicked';
|
|
96
|
+
const textHint = result.text ? ` "${result.text.slice(0, 40)}"` : '';
|
|
97
|
+
console.log(`${actionLabel} <${result.tagName}${textHint}> (${result.selector})`);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
program.addCommand(cmd);
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=click.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"click.js","sourceRoot":"","sources":["../../../src/commands/interact/click.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { resolveBridge } from '../shared.js';
|
|
3
|
+
import { addInteractOptions, escapeSelector } from './shared.js';
|
|
4
|
+
import { InteractionResultSchema } from '../../schemas/interact.js';
|
|
5
|
+
export function buildFocusScript(selector) {
|
|
6
|
+
const escaped = escapeSelector(selector);
|
|
7
|
+
return `(function() {
|
|
8
|
+
try {
|
|
9
|
+
var el = document.querySelector('${escaped}');
|
|
10
|
+
if (!el) return JSON.stringify({ success: false, error: 'Element not found: ${escaped}' });
|
|
11
|
+
el.focus();
|
|
12
|
+
return JSON.stringify({ success: true, selector: '${escaped}', tagName: el.tagName.toLowerCase() });
|
|
13
|
+
} catch (e) {
|
|
14
|
+
return JSON.stringify({ success: false, error: String(e) });
|
|
15
|
+
}
|
|
16
|
+
})()`;
|
|
17
|
+
}
|
|
18
|
+
export function registerFocus(program) {
|
|
19
|
+
const cmd = new Command('focus')
|
|
20
|
+
.description('Focus a DOM element by CSS selector')
|
|
21
|
+
.argument('<selector>', 'CSS selector of the element to focus')
|
|
22
|
+
.addHelpText('after', `
|
|
23
|
+
Examples:
|
|
24
|
+
$ tauri-agent-tools focus "input[name='email']"
|
|
25
|
+
$ tauri-agent-tools focus "#submit-button"
|
|
26
|
+
$ tauri-agent-tools focus ".search-field"`);
|
|
27
|
+
addInteractOptions(cmd);
|
|
28
|
+
cmd.action(async (selector, opts) => {
|
|
29
|
+
const bridge = await resolveBridge(opts);
|
|
30
|
+
const script = buildFocusScript(selector);
|
|
31
|
+
const raw = await bridge.eval(script);
|
|
32
|
+
const result = InteractionResultSchema.parse(JSON.parse(String(raw)));
|
|
33
|
+
if (!result.success) {
|
|
34
|
+
throw new Error(result.error ?? 'Focus failed');
|
|
35
|
+
}
|
|
36
|
+
console.log(JSON.stringify(result, null, 2));
|
|
37
|
+
});
|
|
38
|
+
program.addCommand(cmd);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=focus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus.js","sourceRoot":"","sources":["../../../src/commands/interact/focus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IACzC,OAAO;;uCAE8B,OAAO;kFACoC,OAAO;;wDAEjC,OAAO;;;;KAI1D,CAAC;AACN,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;SAC7B,WAAW,CAAC,qCAAqC,CAAC;SAClD,QAAQ,CAAC,YAAY,EAAE,sCAAsC,CAAC;SAC9D,WAAW,CAAC,OAAO,EAAE;;;;4CAIkB,CAAC,CAAC;IAE5C,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAExB,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,IAAgB,EAAE,EAAE;QACtD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,cAAc,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { resolveBridge } from '../shared.js';
|
|
3
|
+
import { addInteractOptions, escapeSelector } from './shared.js';
|
|
4
|
+
import { InteractionResultSchema } from '../../schemas/interact.js';
|
|
5
|
+
export function buildNavigateScript(target) {
|
|
6
|
+
const escaped = escapeSelector(target);
|
|
7
|
+
if (target.startsWith('/')) {
|
|
8
|
+
return `(function() {
|
|
9
|
+
try {
|
|
10
|
+
window.history.pushState({}, '', '${escaped}');
|
|
11
|
+
window.dispatchEvent(new PopStateEvent('popstate', { state: {} }));
|
|
12
|
+
return JSON.stringify({ success: true, tagName: 'window', selector: '${escaped}' });
|
|
13
|
+
} catch (e) {
|
|
14
|
+
return JSON.stringify({ success: false, error: String(e) });
|
|
15
|
+
}
|
|
16
|
+
})()`;
|
|
17
|
+
}
|
|
18
|
+
return `(function() {
|
|
19
|
+
try {
|
|
20
|
+
window.location.href = '${escaped}';
|
|
21
|
+
return JSON.stringify({ success: true, tagName: 'window', selector: '${escaped}' });
|
|
22
|
+
} catch (e) {
|
|
23
|
+
return JSON.stringify({ success: false, error: String(e) });
|
|
24
|
+
}
|
|
25
|
+
})()`;
|
|
26
|
+
}
|
|
27
|
+
export function registerNavigate(program) {
|
|
28
|
+
const cmd = new Command('navigate')
|
|
29
|
+
.description('Navigate to a URL or path')
|
|
30
|
+
.argument('<target>', 'URL or path to navigate to (paths starting with / use pushState)')
|
|
31
|
+
.addHelpText('after', `
|
|
32
|
+
Examples:
|
|
33
|
+
$ tauri-agent-tools navigate /dashboard
|
|
34
|
+
$ tauri-agent-tools navigate /settings/profile
|
|
35
|
+
$ tauri-agent-tools navigate https://example.com`);
|
|
36
|
+
addInteractOptions(cmd);
|
|
37
|
+
cmd.action(async (target, opts) => {
|
|
38
|
+
const bridge = await resolveBridge(opts);
|
|
39
|
+
const script = buildNavigateScript(target);
|
|
40
|
+
const raw = await bridge.eval(script);
|
|
41
|
+
const result = InteractionResultSchema.parse(JSON.parse(String(raw)));
|
|
42
|
+
if (!result.success) {
|
|
43
|
+
throw new Error(result.error ?? 'Navigate failed');
|
|
44
|
+
}
|
|
45
|
+
console.log(JSON.stringify(result, null, 2));
|
|
46
|
+
});
|
|
47
|
+
program.addCommand(cmd);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=navigate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigate.js","sourceRoot":"","sources":["../../../src/commands/interact/navigate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO;;wCAE6B,OAAO;;2EAE4B,OAAO;;;;KAI7E,CAAC;IACJ,CAAC;IAED,OAAO;;8BAEqB,OAAO;2EACsC,OAAO;;;;KAI7E,CAAC;AACN,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;SAChC,WAAW,CAAC,2BAA2B,CAAC;SACxC,QAAQ,CAAC,UAAU,EAAE,kEAAkE,CAAC;SACxF,WAAW,CAAC,OAAO,EAAE;;;;mDAIyB,CAAC,CAAC;IAEnD,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAExB,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAgB,EAAE,EAAE;QACpD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,iBAAiB,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export interface ScrollOpts {
|
|
3
|
+
selector?: string;
|
|
4
|
+
by?: number;
|
|
5
|
+
to?: number;
|
|
6
|
+
toTop?: boolean;
|
|
7
|
+
toBottom?: boolean;
|
|
8
|
+
intoView?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildScrollScript(opts: ScrollOpts): string;
|
|
11
|
+
export declare function registerScroll(program: Command): void;
|