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,117 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { detectDisplayServer } from '../platform/detect.js';
|
|
3
|
+
import { addBridgeOptions, resolveBridge } from './shared.js';
|
|
4
|
+
import { discoverBridgesByPid, discoverBridge } from '../bridge/tokenDiscovery.js';
|
|
5
|
+
export function registerProbe(program) {
|
|
6
|
+
const cmd = new Command('probe')
|
|
7
|
+
.description('Discover and report Tauri app targets and bridge health')
|
|
8
|
+
.option('--json', 'Output as JSON');
|
|
9
|
+
addBridgeOptions(cmd);
|
|
10
|
+
cmd.action(async (opts) => {
|
|
11
|
+
// 1. Discover all bridges by PID
|
|
12
|
+
const bridgesByPid = await discoverBridgesByPid();
|
|
13
|
+
const allBridges = [...bridgesByPid.entries()].map(([pid, cfg]) => ({
|
|
14
|
+
pid,
|
|
15
|
+
port: cfg.port,
|
|
16
|
+
}));
|
|
17
|
+
// 2. Resolve specific bridge (may throw if none found)
|
|
18
|
+
const bridge = await resolveBridge(opts);
|
|
19
|
+
// 3. Ping
|
|
20
|
+
const alive = await bridge.ping();
|
|
21
|
+
// 4. Get version (graceful null on 404)
|
|
22
|
+
const versionInfo = await bridge.version();
|
|
23
|
+
// 5. Get describe (graceful null on 404)
|
|
24
|
+
const describeInfo = await bridge.describe();
|
|
25
|
+
// 6. Get page info via eval (try/catch each independently)
|
|
26
|
+
let url = null;
|
|
27
|
+
let title = null;
|
|
28
|
+
let viewport = null;
|
|
29
|
+
try {
|
|
30
|
+
url = String(await bridge.eval('window.location.href'));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// bridge may be unreachable or page not loaded
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
title = String(await bridge.eval('document.title'));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// ignore
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
viewport = await bridge.getViewportSize();
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// ignore
|
|
46
|
+
}
|
|
47
|
+
// 7. Detect platform
|
|
48
|
+
const platform = detectDisplayServer();
|
|
49
|
+
// Determine the port for the target by checking opts or discovered bridge
|
|
50
|
+
let targetPort = opts.port;
|
|
51
|
+
if (targetPort === undefined) {
|
|
52
|
+
if (opts.pid !== undefined) {
|
|
53
|
+
const pidEntry = bridgesByPid.get(opts.pid);
|
|
54
|
+
targetPort = pidEntry?.port;
|
|
55
|
+
}
|
|
56
|
+
if (targetPort === undefined) {
|
|
57
|
+
const first = await discoverBridge();
|
|
58
|
+
targetPort = first?.port;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const result = {
|
|
62
|
+
bridges: allBridges,
|
|
63
|
+
target: {
|
|
64
|
+
alive,
|
|
65
|
+
version: versionInfo,
|
|
66
|
+
describe: describeInfo,
|
|
67
|
+
page: { url, title, viewport },
|
|
68
|
+
},
|
|
69
|
+
platform,
|
|
70
|
+
};
|
|
71
|
+
if (opts.json) {
|
|
72
|
+
console.log(JSON.stringify(result, null, 2));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Human-readable output
|
|
76
|
+
console.log('=== Tauri Bridge Probe ===');
|
|
77
|
+
console.log('');
|
|
78
|
+
if (allBridges.length === 0) {
|
|
79
|
+
console.log('Running bridges: none');
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
console.log(`Running bridges: ${allBridges.length}`);
|
|
83
|
+
for (const b of allBridges) {
|
|
84
|
+
console.log(` PID ${b.pid} port ${b.port}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
console.log('');
|
|
88
|
+
console.log(`Platform: ${platform}`);
|
|
89
|
+
console.log(`Bridge alive: ${alive ? 'yes' : 'no'}`);
|
|
90
|
+
if (versionInfo) {
|
|
91
|
+
console.log(`Bridge version: ${versionInfo.version}`);
|
|
92
|
+
console.log(`Endpoints: ${versionInfo.endpoints.join(', ')}`);
|
|
93
|
+
}
|
|
94
|
+
if (describeInfo) {
|
|
95
|
+
if (describeInfo.app !== undefined)
|
|
96
|
+
console.log(`App: ${describeInfo.app}`);
|
|
97
|
+
if (describeInfo.pid !== undefined)
|
|
98
|
+
console.log(`App PID: ${describeInfo.pid}`);
|
|
99
|
+
if (describeInfo.windows !== undefined)
|
|
100
|
+
console.log(`Windows: ${describeInfo.windows.join(', ')}`);
|
|
101
|
+
if (describeInfo.capabilities !== undefined)
|
|
102
|
+
console.log(`Capabilities: ${describeInfo.capabilities.join(', ')}`);
|
|
103
|
+
}
|
|
104
|
+
console.log('');
|
|
105
|
+
console.log('Page:');
|
|
106
|
+
console.log(` URL: ${url ?? '(unavailable)'}`);
|
|
107
|
+
console.log(` Title: ${title ?? '(unavailable)'}`);
|
|
108
|
+
if (viewport) {
|
|
109
|
+
console.log(` Viewport: ${viewport.width}x${viewport.height}`);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
console.log(' Viewport: (unavailable)');
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
program.addCommand(cmd);
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../../src/commands/probe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { addBridgeOptions, resolveBridge } from './shared.js';
|
|
3
|
+
export function registerProcessTree(program) {
|
|
4
|
+
const cmd = new Command('process-tree')
|
|
5
|
+
.description('Show the Tauri PID and its registered sidecar processes (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 proc = await bridge.process();
|
|
11
|
+
if (opts.json) {
|
|
12
|
+
console.log(JSON.stringify(proc, null, 2));
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
renderHuman(proc);
|
|
16
|
+
});
|
|
17
|
+
program.addCommand(cmd);
|
|
18
|
+
}
|
|
19
|
+
function renderHuman(p) {
|
|
20
|
+
const uptimeSec = Math.floor(p.tauri.uptime_ms / 1000);
|
|
21
|
+
console.log(`tauri pid=${p.tauri.pid} uptime=${uptimeSec}s`);
|
|
22
|
+
if (p.tauri.exe)
|
|
23
|
+
console.log(` exe=${p.tauri.exe}`);
|
|
24
|
+
if (p.tauri.args.length > 0)
|
|
25
|
+
console.log(` args=[${p.tauri.args.join(', ')}]`);
|
|
26
|
+
if (p.sidecars.length === 0) {
|
|
27
|
+
console.log(`└── (no sidecars registered)`);
|
|
28
|
+
console.log(` Tip: use \`dev_bridge::spawn_sidecar_monitored(name, cmd, args, &buf, Some(®istry))\``);
|
|
29
|
+
console.log(` or call \`dev_bridge::register_sidecar(®istry, ...)\` after spawning your own.`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
for (let i = 0; i < p.sidecars.length; i++) {
|
|
33
|
+
const s = p.sidecars[i];
|
|
34
|
+
const last = i === p.sidecars.length - 1;
|
|
35
|
+
const connector = last ? '└──' : '├──';
|
|
36
|
+
const alive = s.alive === null || s.alive === undefined ? '?' : s.alive ? 'alive' : 'DEAD';
|
|
37
|
+
console.log(`${connector} ${s.name} pid=${s.pid} ${alive}`);
|
|
38
|
+
const indent = last ? ' ' : '│ ';
|
|
39
|
+
if (s.exe)
|
|
40
|
+
console.log(`${indent}exe=${s.exe}`);
|
|
41
|
+
if (s.args.length > 0)
|
|
42
|
+
console.log(`${indent}args=[${s.args.join(', ')}]`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=processTree.js.map
|
|
@@ -0,0 +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,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI9D,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,cAAc,CAAC;SACpC,WAAW,CAAC,mFAAmF,CAAC;SAChG,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,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,WAAW,CAAC,CAAkB;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,GAAG,YAAY,SAAS,GAAG,CAAC,CAAC;IAC/D,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG;QAAE,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IAC1D,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrF,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,+FAA+F,CAAC,CAAC;QAC7G,OAAO,CAAC,GAAG,CAAC,wFAAwF,CAAC,CAAC;QACtG,OAAO;IACT,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QACzC,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QACvC,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,GAAG,SAAS,IAAI,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC;QAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QACtC,IAAI,CAAC,CAAC,GAAG;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC"}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
2
|
import type { z } from 'zod';
|
|
3
3
|
import { BridgeClient } from '../bridge/client.js';
|
|
4
|
+
/**
|
|
5
|
+
* Options parsed from the bridge-related CLI flags.
|
|
6
|
+
*/
|
|
7
|
+
export interface BridgeOpts {
|
|
8
|
+
port?: number;
|
|
9
|
+
token?: string;
|
|
10
|
+
pid?: number;
|
|
11
|
+
windowLabel?: string;
|
|
12
|
+
}
|
|
4
13
|
/**
|
|
5
14
|
* Parse a value with a Zod enum schema, throwing a human-readable error on failure.
|
|
6
15
|
* Replaces raw `.parse()` calls that would surface cryptic ZodError messages.
|
|
7
16
|
*/
|
|
8
17
|
export declare function parseEnum<T extends [string, ...string[]]>(schema: z.ZodEnum<T>, value: string, label: string): T[number];
|
|
9
18
|
export declare function addBridgeOptions(cmd: Command): Command;
|
|
10
|
-
export declare function resolveBridge(opts:
|
|
11
|
-
port?: number;
|
|
12
|
-
token?: string;
|
|
13
|
-
}): Promise<BridgeClient>;
|
|
19
|
+
export declare function resolveBridge(opts: BridgeOpts): Promise<BridgeClient>;
|
package/dist/commands/shared.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BridgeClient } from '../bridge/client.js';
|
|
2
|
-
import { discoverBridge } from '../bridge/tokenDiscovery.js';
|
|
2
|
+
import { discoverBridge, discoverBridgesByPid } from '../bridge/tokenDiscovery.js';
|
|
3
3
|
/**
|
|
4
4
|
* Parse a value with a Zod enum schema, throwing a human-readable error on failure.
|
|
5
5
|
* Replaces raw `.parse()` calls that would surface cryptic ZodError messages.
|
|
@@ -14,14 +14,34 @@ export function parseEnum(schema, value, label) {
|
|
|
14
14
|
export function addBridgeOptions(cmd) {
|
|
15
15
|
return cmd
|
|
16
16
|
.option('--port <number>', 'Bridge port (auto-discover if omitted)', parseInt)
|
|
17
|
-
.option('--token <string>', 'Bridge token (auto-discover if omitted)')
|
|
17
|
+
.option('--token <string>', 'Bridge token (auto-discover if omitted)')
|
|
18
|
+
.option('--pid <number>', 'Target app PID (auto-discover if omitted)', parseInt)
|
|
19
|
+
.option('--window-label <label>', 'Target window label (default: main)');
|
|
18
20
|
}
|
|
19
21
|
export async function resolveBridge(opts) {
|
|
20
22
|
let config;
|
|
21
23
|
if (opts.port && opts.token) {
|
|
24
|
+
// Explicit port + token: skip discovery entirely
|
|
22
25
|
config = { port: opts.port, token: opts.token };
|
|
23
26
|
}
|
|
27
|
+
else if (opts.pid !== undefined) {
|
|
28
|
+
// PID-targeted discovery
|
|
29
|
+
const bridges = await discoverBridgesByPid();
|
|
30
|
+
const match = bridges.get(opts.pid);
|
|
31
|
+
if (!match) {
|
|
32
|
+
const pids = [...bridges.keys()];
|
|
33
|
+
const listing = pids.length > 0
|
|
34
|
+
? `Running bridges:\n${pids.map((p) => ` PID ${p}`).join('\n')}`
|
|
35
|
+
: 'No running bridges found.';
|
|
36
|
+
throw new Error(`No bridge found for PID ${opts.pid}.\n${listing}`);
|
|
37
|
+
}
|
|
38
|
+
config = {
|
|
39
|
+
port: opts.port ?? match.port,
|
|
40
|
+
token: opts.token ?? match.token,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
24
43
|
else {
|
|
44
|
+
// First-match discovery
|
|
25
45
|
const discovered = await discoverBridge();
|
|
26
46
|
if (!discovered) {
|
|
27
47
|
throw new Error('No bridge found. Either:\n' +
|
|
@@ -33,6 +53,6 @@ export async function resolveBridge(opts) {
|
|
|
33
53
|
token: opts.token ?? discovered.token,
|
|
34
54
|
};
|
|
35
55
|
}
|
|
36
|
-
return new BridgeClient(config);
|
|
56
|
+
return new BridgeClient(config, opts.windowLabel);
|
|
37
57
|
}
|
|
38
58
|
//# sourceMappingURL=shared.js.map
|
|
@@ -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,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;AAYnF;;;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,CAAC;AAC7E,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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Register the `sidecar` parent command's `replay` subcommand alongside `tap`.
|
|
4
|
+
* Note: this file does NOT define a top-level "sidecar" parent — that lives in
|
|
5
|
+
* sidecarTap.ts. Instead we expose a helper that the CLI bootstrap composes.
|
|
6
|
+
*/
|
|
7
|
+
export declare function registerSidecarReplay(program: Command): void;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
/**
|
|
5
|
+
* Register the `sidecar` parent command's `replay` subcommand alongside `tap`.
|
|
6
|
+
* Note: this file does NOT define a top-level "sidecar" parent — that lives in
|
|
7
|
+
* sidecarTap.ts. Instead we expose a helper that the CLI bootstrap composes.
|
|
8
|
+
*/
|
|
9
|
+
export function registerSidecarReplay(program) {
|
|
10
|
+
// Find the existing "sidecar" parent command registered by sidecarTap.
|
|
11
|
+
const sidecar = program.commands.find((c) => c.name() === 'sidecar');
|
|
12
|
+
if (!sidecar) {
|
|
13
|
+
throw new Error('registerSidecarReplay must run after registerSidecarTap');
|
|
14
|
+
}
|
|
15
|
+
sidecar
|
|
16
|
+
.command('replay')
|
|
17
|
+
.description('Replay a recorded NDJSON stream (from `sidecar tap --record`)')
|
|
18
|
+
.argument('<file>', 'Path to NDJSON file produced by `sidecar tap --record`')
|
|
19
|
+
.option('--to-stdout', 'Emit lines verbatim to stdout (default)')
|
|
20
|
+
.option('--to-exec <cmd>', 'Pipe lines into the stdin of this command (split with spaces for args)')
|
|
21
|
+
.option('--rate <lps>', 'Lines per second (default: unlimited — emit as fast as possible)')
|
|
22
|
+
.option('--loop', 'After EOF, restart the file from the top until interrupted')
|
|
23
|
+
.action(async (file, opts) => {
|
|
24
|
+
if (!existsSync(file)) {
|
|
25
|
+
throw new Error(`Recording file not found: ${file}`);
|
|
26
|
+
}
|
|
27
|
+
const rate = opts.rate ? parseRate(opts.rate) : Number.POSITIVE_INFINITY;
|
|
28
|
+
const delayMs = Number.isFinite(rate) ? Math.round(1000 / rate) : 0;
|
|
29
|
+
const lines = (await readFile(file, 'utf-8'))
|
|
30
|
+
.split(/\r?\n/)
|
|
31
|
+
.filter((l) => l.length > 0);
|
|
32
|
+
if (lines.length === 0) {
|
|
33
|
+
process.stderr.write(`[sidecar-replay] recording is empty: ${file}\n`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (opts.toExec) {
|
|
37
|
+
await replayToExec(lines, opts.toExec, delayMs, opts.loop ?? false);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
await replayToStdout(lines, delayMs, opts.loop ?? false);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function parseRate(input) {
|
|
45
|
+
const n = Number(input);
|
|
46
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
47
|
+
throw new Error(`--rate must be a positive number (lines per second), got: ${input}`);
|
|
48
|
+
}
|
|
49
|
+
return n;
|
|
50
|
+
}
|
|
51
|
+
async function replayToStdout(lines, delayMs, loop) {
|
|
52
|
+
do {
|
|
53
|
+
for (const line of lines) {
|
|
54
|
+
process.stdout.write(line + '\n');
|
|
55
|
+
if (delayMs > 0)
|
|
56
|
+
await sleep(delayMs);
|
|
57
|
+
}
|
|
58
|
+
} while (loop);
|
|
59
|
+
}
|
|
60
|
+
async function replayToExec(lines, cmdLine, delayMs, loop) {
|
|
61
|
+
// Naive whitespace split. Users with quoted args should pre-tokenize via shell.
|
|
62
|
+
const [exec, ...args] = cmdLine.split(/\s+/);
|
|
63
|
+
if (!exec)
|
|
64
|
+
throw new Error('--to-exec must include a command');
|
|
65
|
+
const child = spawn(exec, args, { stdio: ['pipe', 'inherit', 'inherit'] });
|
|
66
|
+
const closed = new Promise((resolve, reject) => {
|
|
67
|
+
child.on('error', (err) => reject(err));
|
|
68
|
+
child.on('close', (code) => resolve(code ?? 0));
|
|
69
|
+
});
|
|
70
|
+
try {
|
|
71
|
+
do {
|
|
72
|
+
for (const line of lines) {
|
|
73
|
+
if (!child.stdin.write(line + '\n')) {
|
|
74
|
+
await new Promise((r) => child.stdin.once('drain', r));
|
|
75
|
+
}
|
|
76
|
+
if (delayMs > 0)
|
|
77
|
+
await sleep(delayMs);
|
|
78
|
+
}
|
|
79
|
+
} while (loop);
|
|
80
|
+
child.stdin.end();
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
child.kill('SIGTERM');
|
|
84
|
+
throw err;
|
|
85
|
+
}
|
|
86
|
+
const exitCode = await closed;
|
|
87
|
+
if (exitCode !== 0)
|
|
88
|
+
process.exitCode = exitCode;
|
|
89
|
+
}
|
|
90
|
+
function sleep(ms) {
|
|
91
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=sidecarReplay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidecarReplay.js","sourceRoot":"","sources":["../../src/commands/sidecarReplay.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { readFile, appendFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
5
|
+
import { LineFramer, NdjsonValidator } from '../util/ndjson.js';
|
|
6
|
+
export function registerSidecarTap(program) {
|
|
7
|
+
const cmd = new Command('sidecar')
|
|
8
|
+
.description('Sidecar process tools (wrap-and-run NDJSON tap, recorded replay)');
|
|
9
|
+
cmd
|
|
10
|
+
.command('tap')
|
|
11
|
+
.description('Spawn a sidecar via its exec command, frame stdout as NDJSON, optionally validate + record')
|
|
12
|
+
.argument('<command...>', 'Sidecar command and args (use -- to delimit)')
|
|
13
|
+
.option('--schema <path>', 'JSON Schema (file path) to validate each envelope against')
|
|
14
|
+
.option('--record <path>', 'Append the raw NDJSON stream to this file as it arrives')
|
|
15
|
+
.option('--raw', 'Echo the original sidecar stdout to our stdout (alongside structured envelopes on stderr)')
|
|
16
|
+
.option('--json', 'Emit structured envelopes as JSON (default)')
|
|
17
|
+
.action(async (commandTokens, opts) => {
|
|
18
|
+
if (commandTokens.length === 0) {
|
|
19
|
+
throw new Error('sidecar tap requires a command. Example: sidecar tap -- node my-sidecar.js');
|
|
20
|
+
}
|
|
21
|
+
const [exec, ...args] = commandTokens;
|
|
22
|
+
let validator;
|
|
23
|
+
if (opts.schema) {
|
|
24
|
+
if (!existsSync(opts.schema)) {
|
|
25
|
+
throw new Error(`Schema file not found: ${opts.schema}`);
|
|
26
|
+
}
|
|
27
|
+
const text = await readFile(opts.schema, 'utf-8');
|
|
28
|
+
let schemaJson;
|
|
29
|
+
try {
|
|
30
|
+
schemaJson = JSON.parse(text);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
throw new Error(`Failed to parse schema ${opts.schema}: ${err instanceof Error ? err.message : String(err)}`);
|
|
34
|
+
}
|
|
35
|
+
validator = new NdjsonValidator(schemaJson);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
validator = new NdjsonValidator();
|
|
39
|
+
}
|
|
40
|
+
if (opts.record) {
|
|
41
|
+
// Reset the recording file at the start of a tap session.
|
|
42
|
+
await writeFile(opts.record, '');
|
|
43
|
+
}
|
|
44
|
+
const child = spawn(exec, args, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
45
|
+
const framer = new LineFramer();
|
|
46
|
+
child.stdout.setEncoding('utf-8');
|
|
47
|
+
let envelopesEmitted = 0;
|
|
48
|
+
let invalidCount = 0;
|
|
49
|
+
child.stdout.on('data', async (chunk) => {
|
|
50
|
+
const lines = framer.push(chunk);
|
|
51
|
+
for (const line of lines) {
|
|
52
|
+
if (line.length === 0)
|
|
53
|
+
continue;
|
|
54
|
+
await processLine(line, validator, opts);
|
|
55
|
+
envelopesEmitted++;
|
|
56
|
+
if (!validator.parse(line).ok)
|
|
57
|
+
invalidCount++;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
let stderrBuf = '';
|
|
61
|
+
child.stderr.setEncoding('utf-8');
|
|
62
|
+
child.stderr.on('data', (chunk) => {
|
|
63
|
+
// Forward sidecar stderr to ours, prefixed so it's distinguishable.
|
|
64
|
+
stderrBuf += chunk;
|
|
65
|
+
process.stderr.write(`[sidecar-stderr] ${chunk}`);
|
|
66
|
+
});
|
|
67
|
+
const exitCode = await new Promise((resolve, reject) => {
|
|
68
|
+
child.on('error', (err) => {
|
|
69
|
+
if (err.code === 'ENOENT') {
|
|
70
|
+
reject(new Error(`sidecar exec not found: ${exec}`));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
reject(err);
|
|
74
|
+
});
|
|
75
|
+
child.on('close', async (code) => {
|
|
76
|
+
const trailing = framer.flush();
|
|
77
|
+
if (trailing) {
|
|
78
|
+
await processLine(trailing, validator, opts);
|
|
79
|
+
envelopesEmitted++;
|
|
80
|
+
}
|
|
81
|
+
resolve(code ?? 0);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
// Final summary on stderr so it doesn't pollute the NDJSON stream on stdout.
|
|
85
|
+
process.stderr.write(`[sidecar-tap] exited code=${exitCode} envelopes=${envelopesEmitted} invalid=${invalidCount}${stderrBuf.length > 0 ? ' stderr_bytes=' + stderrBuf.length : ''}\n`);
|
|
86
|
+
if (exitCode !== 0)
|
|
87
|
+
process.exitCode = exitCode;
|
|
88
|
+
});
|
|
89
|
+
program.addCommand(cmd);
|
|
90
|
+
}
|
|
91
|
+
async function processLine(line, validator, opts) {
|
|
92
|
+
if (opts.record) {
|
|
93
|
+
await appendFile(opts.record, line + '\n');
|
|
94
|
+
}
|
|
95
|
+
if (opts.raw) {
|
|
96
|
+
// Echo original line verbatim
|
|
97
|
+
process.stdout.write(line + '\n');
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const result = validator.parse(line);
|
|
101
|
+
const envelope = result.ok
|
|
102
|
+
? {
|
|
103
|
+
ts: new Date().toISOString(),
|
|
104
|
+
direction: 'sidecar→',
|
|
105
|
+
valid: result.valid,
|
|
106
|
+
payload: result.value,
|
|
107
|
+
...(result.errors.length > 0 ? { schemaErrors: result.errors } : {}),
|
|
108
|
+
}
|
|
109
|
+
: {
|
|
110
|
+
ts: new Date().toISOString(),
|
|
111
|
+
direction: 'sidecar→',
|
|
112
|
+
valid: false,
|
|
113
|
+
rawLine: line,
|
|
114
|
+
parseError: result.error,
|
|
115
|
+
};
|
|
116
|
+
console.log(JSON.stringify(envelope));
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=sidecarTap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidecarTap.js","sourceRoot":"","sources":["../../src/commands/sidecarTap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAUhE,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;SAC/B,WAAW,CAAC,kEAAkE,CAAC,CAAC;IACnF,GAAG;SACA,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,4FAA4F,CAAC;SACzG,QAAQ,CAAC,cAAc,EAAE,8CAA8C,CAAC;SACxE,MAAM,CAAC,iBAAiB,EAAE,2DAA2D,CAAC;SACtF,MAAM,CAAC,iBAAiB,EAAE,yDAAyD,CAAC;SACpF,MAAM,CAAC,OAAO,EAAE,2FAA2F,CAAC;SAC5G,MAAM,CAAC,QAAQ,EAAE,6CAA6C,CAAC;SAC/D,MAAM,CAAC,KAAK,EAAE,aAAuB,EAAE,IAAoB,EAAE,EAAE;QAC9D,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;QAChG,CAAC;QACD,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,aAAsC,CAAC;QAE/D,IAAI,SAA0B,CAAC;QAC/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3D,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAClD,IAAI,UAAmB,CAAC;YACxB,IAAI,CAAC;gBACH,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAChC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CACb,0BAA0B,IAAI,CAAC,MAAM,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC7F,CAAC;YACJ,CAAC;YACD,SAAS,GAAG,IAAI,eAAe,CAAC,UAAU,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC;QACpC,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,0DAA0D;YAC1D,MAAM,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAEvE,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAChC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAElC,IAAI,gBAAgB,GAAG,CAAC,CAAC;QACzB,IAAI,YAAY,GAAG,CAAC,CAAC;QAErB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE;YAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;oBAAE,SAAS;gBAChC,MAAM,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;gBACzC,gBAAgB,EAAE,CAAC;gBACnB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE;oBAAE,YAAY,EAAE,CAAC;YAChD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,SAAS,GAAG,EAAE,CAAC;QACnB,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAClC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACxC,oEAAoE;YACpE,SAAS,IAAI,KAAK,CAAC;YACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,KAAK,EAAE,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC7D,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACxB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACrD,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC,CAAC;oBACrD,OAAO;gBACT,CAAC;gBACD,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;gBAChC,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,WAAW,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;oBAC7C,gBAAgB,EAAE,CAAC;gBACrB,CAAC;gBACD,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;YACrB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,6EAA6E;QAC7E,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6BAA6B,QAAQ,cAAc,gBAAgB,YAAY,YAAY,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAClK,CAAC;QACF,IAAI,QAAQ,KAAK,CAAC;YAAE,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAClD,CAAC,CAAC,CAAC;IAEL,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,IAAY,EACZ,SAA0B,EAC1B,IAAoB;IAEpB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,8BAA8B;QAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAoB,MAAM,CAAC,EAAE;QACzC,CAAC,CAAC;YACE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,SAAS,EAAE,UAAU;YACrB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,MAAM,CAAC,KAAK;YACrB,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE;QACH,CAAC,CAAC;YACE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,SAAS,EAAE,UAAU;YACrB,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,MAAM,CAAC,KAAK;SACzB,CAAC;IAEN,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a JavaScript IIFE that detects and serializes reactive stores
|
|
4
|
+
* from the target framework running in the Tauri webview.
|
|
5
|
+
*
|
|
6
|
+
* Detection priority:
|
|
7
|
+
* 1. window.__DEBUG_STORES__ (app-registered hook)
|
|
8
|
+
* 2. window.__pinia (Pinia store)
|
|
9
|
+
* 3. window.__VUE_DEVTOOLS_GLOBAL_HOOK__ (Vue devtools hook)
|
|
10
|
+
* 4. Fallback: unknown with empty stores
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildStoreDetectionScript(framework: string, storeName?: string, depth?: number): string;
|
|
13
|
+
export declare function registerStoreInspect(program: Command): void;
|