tauri-agent-tools 0.7.1 → 0.8.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 +50 -13
- package/.agents/skills/tauri-bridge-setup/SKILL.md +5 -3
- package/.agents/skills/tauri-debug-quickstart/SKILL.md +9 -6
- package/AGENTS.md +13 -3
- package/README.md +25 -4
- package/dist/bridge/client.d.ts +8 -0
- package/dist/bridge/client.js +20 -0
- package/dist/bridge/client.js.map +1 -1
- package/dist/cli.js +5 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/bundle.d.ts +2 -0
- package/dist/commands/bundle.js +251 -0
- package/dist/commands/bundle.js.map +1 -0
- package/dist/commands/capabilitiesAudit.js +14 -1
- package/dist/commands/capabilitiesAudit.js.map +1 -1
- package/dist/commands/health.js +19 -1
- package/dist/commands/health.js.map +1 -1
- package/dist/commands/ipcMonitor.js +38 -4
- package/dist/commands/ipcMonitor.js.map +1 -1
- package/dist/commands/logs.d.ts +2 -0
- package/dist/commands/logs.js +193 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/processTree.js +116 -4
- package/dist/commands/processTree.js.map +1 -1
- package/dist/commands/shared.d.ts +31 -0
- package/dist/commands/shared.js +52 -1
- package/dist/commands/shared.js.map +1 -1
- package/dist/commands/webviewAttach.js +17 -1
- package/dist/commands/webviewAttach.js.map +1 -1
- package/dist/platform/macos.js +35 -15
- package/dist/platform/macos.js.map +1 -1
- package/dist/util/logMerge.d.ts +42 -0
- package/dist/util/logMerge.js +133 -0
- package/dist/util/logMerge.js.map +1 -0
- package/dist/util/mergeByTimestamp.d.ts +18 -0
- package/dist/util/mergeByTimestamp.js +30 -0
- package/dist/util/mergeByTimestamp.js.map +1 -0
- package/dist/util/psTree.d.ts +28 -0
- package/dist/util/psTree.js +76 -0
- package/dist/util/psTree.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { readFile, readdir } from 'node:fs/promises';
|
|
3
|
+
import { basename, join, resolve } from 'node:path';
|
|
4
|
+
import { addBridgeOptions, tryResolveBridgeConfig } from './shared.js';
|
|
5
|
+
import { BridgeClient } from '../bridge/client.js';
|
|
6
|
+
import { resolveTauriProject, resolveTauriPaths, currentPlatform } from '../util/tauriConfig.js';
|
|
7
|
+
import { mergeByTimestamp } from '../util/mergeByTimestamp.js';
|
|
8
|
+
import { parseLogLine, normalizeRustLog, inferCorrelation, LEVEL_RANK, } from '../util/logMerge.js';
|
|
9
|
+
function collect(value, prev) {
|
|
10
|
+
return [...prev, value];
|
|
11
|
+
}
|
|
12
|
+
export function registerLogs(program) {
|
|
13
|
+
const cmd = new Command('logs')
|
|
14
|
+
.description("Merge a Tauri app's scattered logs (on-disk log files + bridge ring buffer) into one timestamp-ordered stream")
|
|
15
|
+
.option('--config <path>', 'Path to tauri.conf.json (or its dir). Auto-detected if omitted.')
|
|
16
|
+
.option('--identifier <id>', 'Bundle identifier override (locates the OS log dir without a config)')
|
|
17
|
+
.option('--log-dir <path>', 'Override the directory scanned for *.log files')
|
|
18
|
+
.option('--log-file <path>', 'Add an explicit log file (repeatable)', collect, [])
|
|
19
|
+
.option('--no-bridge', 'Skip the live bridge /logs source')
|
|
20
|
+
.option('--no-files', 'Skip on-disk log file sources')
|
|
21
|
+
.option('--level <level>', 'Minimum level: debug | info | warn | error')
|
|
22
|
+
.option('--source <regex>', 'Filter by normalized source (regex), e.g. "sidecar:" or "file:"')
|
|
23
|
+
.option('--filter <regex>', 'Filter messages by regex')
|
|
24
|
+
.option('--correlate', 'Infer correlation ids (run_id, requestId, …) into a correlation field')
|
|
25
|
+
.option('--raw', 'Include the raw source payload/line in NDJSON output')
|
|
26
|
+
.option('--json', 'Emit NDJSON, one object per line (this is the default; accepted for consistency)')
|
|
27
|
+
.option('--pretty', 'Human-readable output (overrides --json)');
|
|
28
|
+
addBridgeOptions(cmd);
|
|
29
|
+
cmd.action(async (opts) => {
|
|
30
|
+
const minLevel = opts.level ? validateLevel(opts.level) : null;
|
|
31
|
+
const sourceRe = opts.source ? compileRegex(opts.source, 'source') : null;
|
|
32
|
+
const filterRe = opts.filter ? compileRegex(opts.filter, 'filter') : null;
|
|
33
|
+
const notes = [];
|
|
34
|
+
// ── On-disk file sources ────────────────────────────────────────────────
|
|
35
|
+
let fileEntries = [];
|
|
36
|
+
if (opts.files !== false) {
|
|
37
|
+
const files = await resolveFiles(opts, notes);
|
|
38
|
+
const perFile = await Promise.all(files.map((f) => readLogFile(f)));
|
|
39
|
+
fileEntries = perFile.flat();
|
|
40
|
+
notes.push(`files: ${fileEntries.length} line(s) from ${files.length} file(s)`);
|
|
41
|
+
}
|
|
42
|
+
// ── Live bridge ring buffer ─────────────────────────────────────────────
|
|
43
|
+
let bridgeEntries = [];
|
|
44
|
+
if (opts.bridge !== false) {
|
|
45
|
+
const cfg = await tryResolveBridgeConfig(opts);
|
|
46
|
+
if (!cfg) {
|
|
47
|
+
notes.push('bridge: no live bridge discovered (skipped)');
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
try {
|
|
51
|
+
const client = new BridgeClient(cfg, opts.windowLabel);
|
|
52
|
+
const logs = await client.fetchLogs();
|
|
53
|
+
bridgeEntries = logs.map(normalizeRustLog);
|
|
54
|
+
notes.push(`bridge: ${bridgeEntries.length} entry(ies) from /logs`);
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
notes.push(`bridge: ${e instanceof Error ? e.message : String(e)} (skipped)`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (fileEntries.length === 0 && bridgeEntries.length === 0) {
|
|
62
|
+
console.error(`note: no log entries available. ${notes.join('; ')}`);
|
|
63
|
+
console.error('Hint: pass --log-file <path>, --log-dir <dir>, --config <path>, or start the app with the dev bridge.');
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// ── Merge + filter ──────────────────────────────────────────────────────
|
|
67
|
+
let merged = mergeByTimestamp([fileEntries, bridgeEntries]);
|
|
68
|
+
merged = merged.filter((e) => {
|
|
69
|
+
if (minLevel && LEVEL_RANK[e.level] < LEVEL_RANK[minLevel])
|
|
70
|
+
return false;
|
|
71
|
+
if (sourceRe && !sourceRe.test(e.source))
|
|
72
|
+
return false;
|
|
73
|
+
if (filterRe && !filterRe.test(e.message))
|
|
74
|
+
return false;
|
|
75
|
+
return true;
|
|
76
|
+
});
|
|
77
|
+
if (opts.correlate) {
|
|
78
|
+
merged = merged.map((e) => {
|
|
79
|
+
const correlation = inferCorrelation(e.message);
|
|
80
|
+
return correlation ? { ...e, correlation } : e;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
// ── Emit ────────────────────────────────────────────────────────────────
|
|
84
|
+
console.error(`# ${notes.join(' | ')} → ${merged.length} entries`);
|
|
85
|
+
if (opts.pretty) {
|
|
86
|
+
for (const e of merged)
|
|
87
|
+
console.log(formatPretty(e));
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
for (const e of merged) {
|
|
91
|
+
if (opts.raw) {
|
|
92
|
+
console.log(JSON.stringify(e));
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
const rest = { ...e };
|
|
96
|
+
delete rest.raw;
|
|
97
|
+
console.log(JSON.stringify(rest));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
program.addCommand(cmd);
|
|
103
|
+
}
|
|
104
|
+
async function resolveFiles(opts, notes) {
|
|
105
|
+
const set = new Set();
|
|
106
|
+
for (const f of opts.logFile ?? [])
|
|
107
|
+
set.add(resolve(f));
|
|
108
|
+
const dir = await resolveLogDir(opts, notes);
|
|
109
|
+
if (dir) {
|
|
110
|
+
for (const name of await listLogFiles(dir))
|
|
111
|
+
set.add(join(dir, name));
|
|
112
|
+
}
|
|
113
|
+
return [...set];
|
|
114
|
+
}
|
|
115
|
+
async function resolveLogDir(opts, notes) {
|
|
116
|
+
if (opts.logDir)
|
|
117
|
+
return resolve(opts.logDir);
|
|
118
|
+
try {
|
|
119
|
+
let identifier;
|
|
120
|
+
if (opts.identifier && !opts.config) {
|
|
121
|
+
identifier = opts.identifier;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
const r = await resolveTauriProject({ configPath: opts.config, identifierOverride: opts.identifier });
|
|
125
|
+
identifier = r.identifier;
|
|
126
|
+
}
|
|
127
|
+
return resolveTauriPaths(identifier)[currentPlatform()].appLogDir;
|
|
128
|
+
}
|
|
129
|
+
catch (e) {
|
|
130
|
+
notes.push(`log-dir: unresolved (${e instanceof Error ? e.message : String(e)})`);
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async function listLogFiles(dir) {
|
|
135
|
+
try {
|
|
136
|
+
const entries = await readdir(dir);
|
|
137
|
+
return entries.filter((f) => /\.log(\.\d+|\.prev)?$/i.test(f));
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async function readLogFile(path) {
|
|
144
|
+
let content;
|
|
145
|
+
try {
|
|
146
|
+
content = await readFile(path, 'utf-8');
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
const base = basename(path);
|
|
152
|
+
const out = [];
|
|
153
|
+
let lastTs = '';
|
|
154
|
+
for (const rawLine of content.split('\n')) {
|
|
155
|
+
const line = rawLine.endsWith('\r') ? rawLine.slice(0, -1) : rawLine;
|
|
156
|
+
if (line.trim() === '')
|
|
157
|
+
continue;
|
|
158
|
+
const p = parseLogLine(line);
|
|
159
|
+
if (p.ts)
|
|
160
|
+
lastTs = p.ts;
|
|
161
|
+
out.push({
|
|
162
|
+
ts: p.ts || lastTs,
|
|
163
|
+
level: p.level,
|
|
164
|
+
source: `file:${base}`,
|
|
165
|
+
subsystem: p.subsystem,
|
|
166
|
+
message: p.message,
|
|
167
|
+
origin: 'file',
|
|
168
|
+
raw: line,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return out;
|
|
172
|
+
}
|
|
173
|
+
function formatPretty(e) {
|
|
174
|
+
const time = e.ts ? new Date(e.ts).toISOString().slice(11, 23) : '--:--:--.---';
|
|
175
|
+
const lvl = e.level.toUpperCase().padEnd(5);
|
|
176
|
+
const sub = e.subsystem ? ` ${e.subsystem}:` : '';
|
|
177
|
+
const corr = e.correlation ? ` ${JSON.stringify(e.correlation)}` : '';
|
|
178
|
+
return `[${time}] ${lvl} [${e.source}]${sub} ${e.message}${corr}`;
|
|
179
|
+
}
|
|
180
|
+
function validateLevel(input) {
|
|
181
|
+
if (input === 'debug' || input === 'info' || input === 'warn' || input === 'error')
|
|
182
|
+
return input;
|
|
183
|
+
throw new Error(`Invalid --level: ${input}. Expected one of: debug, info, warn, error.`);
|
|
184
|
+
}
|
|
185
|
+
function compileRegex(pattern, label) {
|
|
186
|
+
try {
|
|
187
|
+
return new RegExp(pattern);
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
throw new Error(`Invalid ${label} regex: ${pattern}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,44 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { addBridgeOptions, resolveBridge } from './shared.js';
|
|
2
|
+
import { addBridgeOptions, resolveBridge, endpointAvailable, endpointUnavailableNote, } from './shared.js';
|
|
3
|
+
import { discoverBridge, discoverBridgesByPid } from '../bridge/tokenDiscovery.js';
|
|
4
|
+
import { snapshotProcesses, buildDescendantTree, countDescendants } from '../util/psTree.js';
|
|
3
5
|
export function registerProcessTree(program) {
|
|
4
6
|
const cmd = new Command('process-tree')
|
|
5
|
-
.description('Show the Tauri PID and its
|
|
7
|
+
.description('Show the Tauri PID and its sidecars. Uses bridge /process (v0.7+); ' +
|
|
8
|
+
'--deep walks the real OS descendant tree (sidecar grandchildren, workers) without the bridge.')
|
|
9
|
+
.option('--deep', 'Walk the full OS process descendant tree via `ps` (includes unregistered grandchildren); works without bridge /process')
|
|
6
10
|
.option('--json', 'Output as JSON');
|
|
7
11
|
addBridgeOptions(cmd);
|
|
8
12
|
cmd.action(async (opts) => {
|
|
13
|
+
// --deep: OS-level descendant walk, independent of the bridge entirely.
|
|
14
|
+
// With an explicit --pid it needs no bridge at all; otherwise it resolves
|
|
15
|
+
// the app PID from a discoverable bridge token file.
|
|
16
|
+
if (opts.deep) {
|
|
17
|
+
const appPid = await resolveAppPid(opts);
|
|
18
|
+
if (appPid === null) {
|
|
19
|
+
throw new Error('process-tree --deep needs the app PID. Pass --pid <n>, or run it where a bridge token file is discoverable.');
|
|
20
|
+
}
|
|
21
|
+
await renderDeep(appPid, opts);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
9
24
|
const bridge = await resolveBridge(opts);
|
|
25
|
+
// Default path: bridge /process. On older bridges this endpoint is absent.
|
|
26
|
+
if (!(await endpointAvailable(bridge, '/process', opts))) {
|
|
27
|
+
// Degrade where we can: fall back to the OS walk if the app PID is
|
|
28
|
+
// resolvable; otherwise re-raise the actionable "needs v0.7" error so the
|
|
29
|
+
// upgrade hint is preserved.
|
|
30
|
+
const appPid = await resolveAppPid(opts);
|
|
31
|
+
if (appPid === null) {
|
|
32
|
+
await bridge.process(); // throws requireEndpoint('/process') with upgrade hint
|
|
33
|
+
return; // unreachable
|
|
34
|
+
}
|
|
35
|
+
if (!opts.json) {
|
|
36
|
+
const v = (await bridge.version())?.version;
|
|
37
|
+
console.error(`note: ${endpointUnavailableNote('/process', v)} Falling back to the OS process walk (as --deep).`);
|
|
38
|
+
}
|
|
39
|
+
await renderDeep(appPid, opts);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
10
42
|
const proc = await bridge.process();
|
|
11
43
|
if (opts.json) {
|
|
12
44
|
console.log(JSON.stringify(proc, null, 2));
|
|
@@ -16,6 +48,86 @@ export function registerProcessTree(program) {
|
|
|
16
48
|
});
|
|
17
49
|
program.addCommand(cmd);
|
|
18
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Resolve the target app PID for the OS-level walk:
|
|
53
|
+
* - explicit `--pid` wins;
|
|
54
|
+
* - explicit `--port` matches a discovered bridge token by port (strictly — no
|
|
55
|
+
* silent first-bridge fallback, so an unknown port resolves to null);
|
|
56
|
+
* - otherwise the first/only discoverable bridge.
|
|
57
|
+
*/
|
|
58
|
+
async function resolveAppPid(opts) {
|
|
59
|
+
if (opts.pid !== undefined)
|
|
60
|
+
return opts.pid;
|
|
61
|
+
const byPid = await discoverBridgesByPid();
|
|
62
|
+
if (opts.port !== undefined) {
|
|
63
|
+
for (const [pid, cfg] of byPid) {
|
|
64
|
+
if (cfg.port === opts.port)
|
|
65
|
+
return pid;
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const first = await discoverBridge();
|
|
70
|
+
if (first) {
|
|
71
|
+
for (const [pid, cfg] of byPid) {
|
|
72
|
+
if (cfg.port === first.port)
|
|
73
|
+
return pid;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Single unambiguous bridge: use it even if the port match above missed.
|
|
77
|
+
if (byPid.size === 1)
|
|
78
|
+
return [...byPid.keys()][0];
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
function toJson(n) {
|
|
82
|
+
return { pid: n.pid, ppid: n.ppid, command: n.command, children: n.children.map(toJson) };
|
|
83
|
+
}
|
|
84
|
+
async function renderDeep(appPid, opts) {
|
|
85
|
+
if (process.platform === 'win32') {
|
|
86
|
+
const msg = 'process-tree --deep is Unix-only (macOS/Linux) in this release.';
|
|
87
|
+
if (opts.json) {
|
|
88
|
+
console.log(JSON.stringify({ pid: appPid, found: false, source: 'os', error: msg }, null, 2));
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
console.error(`note: ${msg}`);
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const procs = await snapshotProcesses();
|
|
96
|
+
const tree = buildDescendantTree(procs, appPid);
|
|
97
|
+
if (opts.json) {
|
|
98
|
+
const payload = {
|
|
99
|
+
pid: appPid,
|
|
100
|
+
found: tree !== null,
|
|
101
|
+
source: 'os',
|
|
102
|
+
descendants: tree ? countDescendants(tree) : 0,
|
|
103
|
+
tree: tree ? toJson(tree) : null,
|
|
104
|
+
};
|
|
105
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (!tree) {
|
|
109
|
+
console.log(`No process found with pid=${appPid} (it may have exited).`);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
console.log(`app pid=${tree.pid} ${shortCommand(tree.command)}`);
|
|
113
|
+
renderChildren(tree.children, '');
|
|
114
|
+
console.log(`\n${countDescendants(tree)} descendant process(es) [source: os]`);
|
|
115
|
+
}
|
|
116
|
+
function renderChildren(nodes, indent) {
|
|
117
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
118
|
+
const node = nodes[i];
|
|
119
|
+
const last = i === nodes.length - 1;
|
|
120
|
+
const connector = last ? '└──' : '├──';
|
|
121
|
+
console.log(`${indent}${connector} pid=${node.pid} ${shortCommand(node.command)}`);
|
|
122
|
+
const childIndent = indent + (last ? ' ' : '│ ');
|
|
123
|
+
renderChildren(node.children, childIndent);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** Trim a full command line to a readable single-line label. */
|
|
127
|
+
function shortCommand(command) {
|
|
128
|
+
const trimmed = command.length > 100 ? command.slice(0, 97) + '…' : command;
|
|
129
|
+
return trimmed || '(unknown)';
|
|
130
|
+
}
|
|
19
131
|
function renderHuman(p) {
|
|
20
132
|
const uptimeSec = Math.floor(p.tauri.uptime_ms / 1000);
|
|
21
133
|
console.log(`tauri pid=${p.tauri.pid} uptime=${uptimeSec}s`);
|
|
@@ -25,8 +137,8 @@ function renderHuman(p) {
|
|
|
25
137
|
console.log(` args=[${p.tauri.args.join(', ')}]`);
|
|
26
138
|
if (p.sidecars.length === 0) {
|
|
27
139
|
console.log(`└── (no sidecars registered)`);
|
|
28
|
-
console.log(` Tip:
|
|
29
|
-
console.log(` or
|
|
140
|
+
console.log(` Tip: re-run with \`--deep\` to walk the real OS process tree (unregistered children included),`);
|
|
141
|
+
console.log(` or register sidecars via \`dev_bridge::spawn_sidecar_monitored(.., Some(®istry))\`.`);
|
|
30
142
|
return;
|
|
31
143
|
}
|
|
32
144
|
for (let i = 0; i < p.sidecars.length; i++) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processTree.js","sourceRoot":"","sources":["../../src/commands/processTree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,
|
|
1
|
+
{"version":3,"file":"processTree.js","sourceRoot":"","sources":["../../src/commands/processTree.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
2
|
import type { z } from 'zod';
|
|
3
|
+
import type { BridgeConfig } from '../schemas/bridge.js';
|
|
3
4
|
import { BridgeClient } from '../bridge/client.js';
|
|
4
5
|
/**
|
|
5
6
|
* Options parsed from the bridge-related CLI flags.
|
|
@@ -9,6 +10,12 @@ export interface BridgeOpts {
|
|
|
9
10
|
token?: string;
|
|
10
11
|
pid?: number;
|
|
11
12
|
windowLabel?: string;
|
|
13
|
+
/**
|
|
14
|
+
* When true, commands that depend on a v0.7+ bridge endpoint throw the
|
|
15
|
+
* actionable "requires bridge vX" error instead of degrading. Default
|
|
16
|
+
* (false) = degrade gracefully. See {@link endpointAvailable}.
|
|
17
|
+
*/
|
|
18
|
+
strict?: boolean;
|
|
12
19
|
}
|
|
13
20
|
/**
|
|
14
21
|
* Parse a value with a Zod enum schema, throwing a human-readable error on failure.
|
|
@@ -16,4 +23,28 @@ export interface BridgeOpts {
|
|
|
16
23
|
*/
|
|
17
24
|
export declare function parseEnum<T extends [string, ...string[]]>(schema: z.ZodEnum<T>, value: string, label: string): T[number];
|
|
18
25
|
export declare function addBridgeOptions(cmd: Command): Command;
|
|
26
|
+
/**
|
|
27
|
+
* Non-throwing gate for a v0.7+ bridge endpoint. Returns true when the caller
|
|
28
|
+
* should proceed to use the endpoint, false when it should degrade.
|
|
29
|
+
*
|
|
30
|
+
* - In `--strict` mode it always returns true, so the subsequent throwing call
|
|
31
|
+
* (e.g. `bridge.process()`) surfaces the actionable "requires bridge vX" error
|
|
32
|
+
* — preserving the pre-v0.8 behavior for callers that opt in.
|
|
33
|
+
* - Otherwise it feature-detects via `/version` (cached) and returns whether the
|
|
34
|
+
* endpoint is advertised, letting the command fall back instead of throwing.
|
|
35
|
+
*/
|
|
36
|
+
export declare function endpointAvailable(bridge: BridgeClient, path: string, opts: {
|
|
37
|
+
strict?: boolean;
|
|
38
|
+
}): Promise<boolean>;
|
|
39
|
+
/**
|
|
40
|
+
* Standard one-line note explaining that a v0.7+ endpoint is absent on the
|
|
41
|
+
* running bridge, with the same remediation hint `requireEndpoint` uses.
|
|
42
|
+
*/
|
|
43
|
+
export declare function endpointUnavailableNote(path: string, version?: string | null): string;
|
|
44
|
+
/**
|
|
45
|
+
* Resolve a bridge config WITHOUT throwing — returns null when no bridge is
|
|
46
|
+
* reachable. Use this in best-effort, bridge-optional commands (`logs`,
|
|
47
|
+
* `bundle`) that should still produce output when no app is running.
|
|
48
|
+
*/
|
|
49
|
+
export declare function tryResolveBridgeConfig(opts: BridgeOpts): Promise<BridgeConfig | null>;
|
|
19
50
|
export declare function resolveBridge(opts: BridgeOpts): Promise<BridgeClient>;
|
package/dist/commands/shared.js
CHANGED
|
@@ -16,7 +16,58 @@ export function addBridgeOptions(cmd) {
|
|
|
16
16
|
.option('--port <number>', 'Bridge port (auto-discover if omitted)', parseInt)
|
|
17
17
|
.option('--token <string>', 'Bridge token (auto-discover if omitted)')
|
|
18
18
|
.option('--pid <number>', 'Target app PID (auto-discover if omitted)', parseInt)
|
|
19
|
-
.option('--window-label <label>', 'Target window label (default: main)')
|
|
19
|
+
.option('--window-label <label>', 'Target window label (default: main)')
|
|
20
|
+
.option('--strict', 'Fail (instead of degrading) when the bridge lacks a required v0.7+ endpoint');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Non-throwing gate for a v0.7+ bridge endpoint. Returns true when the caller
|
|
24
|
+
* should proceed to use the endpoint, false when it should degrade.
|
|
25
|
+
*
|
|
26
|
+
* - In `--strict` mode it always returns true, so the subsequent throwing call
|
|
27
|
+
* (e.g. `bridge.process()`) surfaces the actionable "requires bridge vX" error
|
|
28
|
+
* — preserving the pre-v0.8 behavior for callers that opt in.
|
|
29
|
+
* - Otherwise it feature-detects via `/version` (cached) and returns whether the
|
|
30
|
+
* endpoint is advertised, letting the command fall back instead of throwing.
|
|
31
|
+
*/
|
|
32
|
+
export async function endpointAvailable(bridge, path, opts) {
|
|
33
|
+
if (opts.strict)
|
|
34
|
+
return true;
|
|
35
|
+
return bridge.hasEndpoint(path);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Standard one-line note explaining that a v0.7+ endpoint is absent on the
|
|
39
|
+
* running bridge, with the same remediation hint `requireEndpoint` uses.
|
|
40
|
+
*/
|
|
41
|
+
export function endpointUnavailableNote(path, version) {
|
|
42
|
+
const v = version ? ` (this app reports bridge v${version})` : '';
|
|
43
|
+
return (`${path} is not available on the running bridge${v}. ` +
|
|
44
|
+
`Re-copy examples/tauri-bridge/src/dev_bridge.rs and rebuild to enable it — ` +
|
|
45
|
+
`or pass --strict to fail instead of degrading.`);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Resolve a bridge config WITHOUT throwing — returns null when no bridge is
|
|
49
|
+
* reachable. Use this in best-effort, bridge-optional commands (`logs`,
|
|
50
|
+
* `bundle`) that should still produce output when no app is running.
|
|
51
|
+
*/
|
|
52
|
+
export async function tryResolveBridgeConfig(opts) {
|
|
53
|
+
try {
|
|
54
|
+
if (opts.port && opts.token)
|
|
55
|
+
return { port: opts.port, token: opts.token };
|
|
56
|
+
if (opts.pid !== undefined) {
|
|
57
|
+
const bridges = await discoverBridgesByPid();
|
|
58
|
+
const match = bridges.get(opts.pid);
|
|
59
|
+
if (!match)
|
|
60
|
+
return null;
|
|
61
|
+
return { port: opts.port ?? match.port, token: opts.token ?? match.token };
|
|
62
|
+
}
|
|
63
|
+
const discovered = await discoverBridge();
|
|
64
|
+
if (!discovered)
|
|
65
|
+
return null;
|
|
66
|
+
return { port: opts.port ?? discovered.port, token: opts.token ?? discovered.token };
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
20
71
|
}
|
|
21
72
|
export async function resolveBridge(opts) {
|
|
22
73
|
let config;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/commands/shared.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/commands/shared.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAkBnF;;;GAGG;AACH,MAAM,UAAU,SAAS,CACvB,MAAoB,EACpB,KAAa,EACb,KAAa;IAEb,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,KAAK,qBAAqB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,OAAO,GAAG;SACP,MAAM,CAAC,iBAAiB,EAAE,wCAAwC,EAAE,QAAQ,CAAC;SAC7E,MAAM,CAAC,kBAAkB,EAAE,yCAAyC,CAAC;SACrE,MAAM,CAAC,gBAAgB,EAAE,2CAA2C,EAAE,QAAQ,CAAC;SAC/E,MAAM,CAAC,wBAAwB,EAAE,qCAAqC,CAAC;SACvE,MAAM,CACL,UAAU,EACV,6EAA6E,CAC9E,CAAC;AACN,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAoB,EACpB,IAAY,EACZ,IAA0B;IAE1B,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAC7B,OAAO,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,OAAuB;IAC3E,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,8BAA8B,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,OAAO,CACL,GAAG,IAAI,0CAA0C,CAAC,IAAI;QACtD,6EAA6E;QAC7E,gDAAgD,CACjD,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAAgB;IAC3D,IAAI,CAAC;QACH,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3E,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,MAAM,oBAAoB,EAAE,CAAC;YAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,CAAC,KAAK;gBAAE,OAAO,IAAI,CAAC;YACxB,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC7E,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,cAAc,EAAE,CAAC;QAC1C,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;IACvF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAgB;IAClD,IAAI,MAAoB,CAAC;IAEzB,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC5B,iDAAiD;QACjD,MAAM,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IAClD,CAAC;SAAM,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAClC,yBAAyB;QACzB,MAAM,OAAO,GAAG,MAAM,oBAAoB,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YACjC,MAAM,OAAO,GACX,IAAI,CAAC,MAAM,GAAG,CAAC;gBACb,CAAC,CAAC,qBAAqB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACjE,CAAC,CAAC,2BAA2B,CAAC;YAClC,MAAM,IAAI,KAAK,CACb,2BAA2B,IAAI,CAAC,GAAG,MAAM,OAAO,EAAE,CACnD,CAAC;QACJ,CAAC;QACD,MAAM,GAAG;YACP,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;YAC7B,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK;SACjC,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,wBAAwB;QACxB,MAAM,UAAU,GAAG,MAAM,cAAc,EAAE,CAAC;QAC1C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,4BAA4B;gBAC1B,mDAAmD;gBACnD,0CAA0C,CAC7C,CAAC;QACJ,CAAC;QACD,MAAM,GAAG;YACP,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,UAAU,CAAC,IAAI;YAClC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK;SACtC,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { exec } from '../util/exec.js';
|
|
3
|
-
import { addBridgeOptions, resolveBridge } from './shared.js';
|
|
3
|
+
import { addBridgeOptions, resolveBridge, endpointAvailable, endpointUnavailableNote, } from './shared.js';
|
|
4
4
|
export function registerWebviewAttach(program) {
|
|
5
5
|
const cmd = new Command('webview')
|
|
6
6
|
.description('Webview/devtools introspection (requires bridge v0.7.0+)');
|
|
@@ -13,6 +13,22 @@ export function registerWebviewAttach(program) {
|
|
|
13
13
|
addBridgeOptions(sub);
|
|
14
14
|
sub.action(async (opts) => {
|
|
15
15
|
const bridge = await resolveBridge(opts);
|
|
16
|
+
// Graceful degradation: older bridges (pre-v0.7) have no /devtools endpoint.
|
|
17
|
+
if (!(await endpointAvailable(bridge, '/devtools', opts))) {
|
|
18
|
+
const note = endpointUnavailableNote('/devtools', (await bridge.version())?.version);
|
|
19
|
+
if (opts.json) {
|
|
20
|
+
console.log(JSON.stringify({ endpoint: '/devtools', available: false, note }, null, 2));
|
|
21
|
+
}
|
|
22
|
+
else if (opts.printUrl) {
|
|
23
|
+
// Keep --print-url contract: emit an empty line when no URL is available.
|
|
24
|
+
console.log('');
|
|
25
|
+
console.error(`note: ${note}`);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.error(`note: ${note}`);
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
16
32
|
const dt = await bridge.devtools();
|
|
17
33
|
if (opts.json) {
|
|
18
34
|
console.log(JSON.stringify(dt, null, 2));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webviewAttach.js","sourceRoot":"","sources":["../../src/commands/webviewAttach.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,
|
|
1
|
+
{"version":3,"file":"webviewAttach.js","sourceRoot":"","sources":["../../src/commands/webviewAttach.ts"],"names":[],"mappings":"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"}
|
package/dist/platform/macos.js
CHANGED
|
@@ -8,22 +8,42 @@ async function runJxa(script) {
|
|
|
8
8
|
const { stdout } = await exec('osascript', ['-l', 'JavaScript', '-e', script]);
|
|
9
9
|
return stdout.toString().trim();
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
// JXA reads window info by iterating the CFArray element-by-element. We avoid
|
|
12
|
+
// ObjC.deepUnwrap (and ObjC.unwrap on the CFDictionary elements) because both
|
|
13
|
+
// are broken on recent macOS for CGWindowListCopyWindowInfo's CFArray result —
|
|
14
|
+
// deepUnwrap returns a non-array ("list.map is not a function") and unwrap loses
|
|
15
|
+
// all keys. Iterating with CFArrayGetCount/CFArrayGetValueAtIndex and reading
|
|
16
|
+
// each key via objectForKey().js works on every supported macOS version and
|
|
17
|
+
// keeps this path 100% dependency-free (osascript is built in).
|
|
18
|
+
const WINDOW_LIST_SCRIPT = `
|
|
13
19
|
ObjC.import('CoreGraphics');
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
ObjC.import('Foundation');
|
|
21
|
+
function val(dict, key) {
|
|
22
|
+
var ref = dict.objectForKey(key);
|
|
23
|
+
return ref ? ref.js : null;
|
|
24
|
+
}
|
|
25
|
+
var cfList = $.CGWindowListCopyWindowInfo($.kCGWindowListOptionOnScreenOnly, 0);
|
|
26
|
+
var count = $.CFArrayGetCount(cfList);
|
|
27
|
+
var out = [];
|
|
28
|
+
for (var i = 0; i < count; i++) {
|
|
29
|
+
var w = ObjC.castRefToObject($.CFArrayGetValueAtIndex(cfList, i));
|
|
30
|
+
var bounds = w.objectForKey('kCGWindowBounds');
|
|
31
|
+
out.push({
|
|
32
|
+
kCGWindowNumber: val(w, 'kCGWindowNumber') || 0,
|
|
33
|
+
kCGWindowOwnerPID: val(w, 'kCGWindowOwnerPID') || 0,
|
|
34
|
+
kCGWindowName: val(w, 'kCGWindowName') || '',
|
|
35
|
+
kCGWindowOwnerName: val(w, 'kCGWindowOwnerName') || '',
|
|
36
|
+
kCGWindowBounds: {
|
|
37
|
+
X: (bounds ? val(bounds, 'X') : 0) || 0,
|
|
38
|
+
Y: (bounds ? val(bounds, 'Y') : 0) || 0,
|
|
39
|
+
Width: (bounds ? val(bounds, 'Width') : 0) || 0,
|
|
40
|
+
Height: (bounds ? val(bounds, 'Height') : 0) || 0,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
JSON.stringify(out);`;
|
|
45
|
+
async function getWindowList() {
|
|
46
|
+
const raw = await runJxa(WINDOW_LIST_SCRIPT);
|
|
27
47
|
const windows = z.array(CGWindowInfoSchema).parse(JSON.parse(raw));
|
|
28
48
|
// Detect Screen Recording permission issue: all names empty
|
|
29
49
|
const hasAnyName = windows.some((w) => (w.kCGWindowName && w.kCGWindowName.length > 0) ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"macos.js","sourceRoot":"","sources":["../../src/platform/macos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,KAAK,UAAU,MAAM,CAAC,MAAc;IAClC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/E,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;AAClC,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"macos.js","sourceRoot":"","sources":["../../src/platform/macos.ts"],"names":[],"mappings":"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"}
|