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.
Files changed (128) hide show
  1. package/.agents/skills/tauri-agent-tools/SKILL.md +195 -13
  2. package/.agents/skills/tauri-bridge-setup/SKILL.md +82 -14
  3. package/.agents/skills/tauri-debug-quickstart/SKILL.md +80 -0
  4. package/AGENTS.md +9 -7
  5. package/README.md +119 -11
  6. package/dist/bridge/client.d.ts +21 -2
  7. package/dist/bridge/client.js +119 -3
  8. package/dist/bridge/client.js.map +1 -1
  9. package/dist/cli.js +47 -0
  10. package/dist/cli.js.map +1 -1
  11. package/dist/commands/appPaths.d.ts +2 -0
  12. package/dist/commands/appPaths.js +97 -0
  13. package/dist/commands/appPaths.js.map +1 -0
  14. package/dist/commands/capabilitiesAudit.d.ts +2 -0
  15. package/dist/commands/capabilitiesAudit.js +105 -0
  16. package/dist/commands/capabilitiesAudit.js.map +1 -0
  17. package/dist/commands/capture.d.ts +3 -0
  18. package/dist/commands/capture.js +218 -0
  19. package/dist/commands/capture.js.map +1 -0
  20. package/dist/commands/check.d.ts +5 -0
  21. package/dist/commands/check.js +174 -0
  22. package/dist/commands/check.js.map +1 -0
  23. package/dist/commands/configInspect.d.ts +2 -0
  24. package/dist/commands/configInspect.js +223 -0
  25. package/dist/commands/configInspect.js.map +1 -0
  26. package/dist/commands/diagnose.d.ts +2 -0
  27. package/dist/commands/diagnose.js +311 -0
  28. package/dist/commands/diagnose.js.map +1 -0
  29. package/dist/commands/eval.js +16 -3
  30. package/dist/commands/eval.js.map +1 -1
  31. package/dist/commands/forensics.d.ts +2 -0
  32. package/dist/commands/forensics.js +331 -0
  33. package/dist/commands/forensics.js.map +1 -0
  34. package/dist/commands/health.d.ts +2 -0
  35. package/dist/commands/health.js +39 -0
  36. package/dist/commands/health.js.map +1 -0
  37. package/dist/commands/interact/click.d.ts +6 -0
  38. package/dist/commands/interact/click.js +102 -0
  39. package/dist/commands/interact/click.js.map +1 -0
  40. package/dist/commands/interact/focus.d.ts +3 -0
  41. package/dist/commands/interact/focus.js +40 -0
  42. package/dist/commands/interact/focus.js.map +1 -0
  43. package/dist/commands/interact/navigate.d.ts +3 -0
  44. package/dist/commands/interact/navigate.js +49 -0
  45. package/dist/commands/interact/navigate.js.map +1 -0
  46. package/dist/commands/interact/scroll.d.ts +11 -0
  47. package/dist/commands/interact/scroll.js +110 -0
  48. package/dist/commands/interact/scroll.js.map +1 -0
  49. package/dist/commands/interact/select.d.ts +3 -0
  50. package/dist/commands/interact/select.js +59 -0
  51. package/dist/commands/interact/select.js.map +1 -0
  52. package/dist/commands/interact/shared.d.ts +23 -0
  53. package/dist/commands/interact/shared.js +62 -0
  54. package/dist/commands/interact/shared.js.map +1 -0
  55. package/dist/commands/interact/type.d.ts +6 -0
  56. package/dist/commands/interact/type.js +59 -0
  57. package/dist/commands/interact/type.js.map +1 -0
  58. package/dist/commands/invoke.d.ts +3 -0
  59. package/dist/commands/invoke.js +53 -0
  60. package/dist/commands/invoke.js.map +1 -0
  61. package/dist/commands/osLogs.d.ts +2 -0
  62. package/dist/commands/osLogs.js +130 -0
  63. package/dist/commands/osLogs.js.map +1 -0
  64. package/dist/commands/probe.d.ts +2 -0
  65. package/dist/commands/probe.js +117 -0
  66. package/dist/commands/probe.js.map +1 -0
  67. package/dist/commands/processTree.d.ts +2 -0
  68. package/dist/commands/processTree.js +45 -0
  69. package/dist/commands/processTree.js.map +1 -0
  70. package/dist/commands/shared.d.ts +10 -4
  71. package/dist/commands/shared.js +23 -3
  72. package/dist/commands/shared.js.map +1 -1
  73. package/dist/commands/sidecarReplay.d.ts +7 -0
  74. package/dist/commands/sidecarReplay.js +93 -0
  75. package/dist/commands/sidecarReplay.js.map +1 -0
  76. package/dist/commands/sidecarTap.d.ts +2 -0
  77. package/dist/commands/sidecarTap.js +118 -0
  78. package/dist/commands/sidecarTap.js.map +1 -0
  79. package/dist/commands/storeInspect.d.ts +13 -0
  80. package/dist/commands/storeInspect.js +156 -0
  81. package/dist/commands/storeInspect.js.map +1 -0
  82. package/dist/commands/webviewAttach.d.ts +2 -0
  83. package/dist/commands/webviewAttach.js +64 -0
  84. package/dist/commands/webviewAttach.js.map +1 -0
  85. package/dist/platform/oslog/darwin.d.ts +21 -0
  86. package/dist/platform/oslog/darwin.js +72 -0
  87. package/dist/platform/oslog/darwin.js.map +1 -0
  88. package/dist/platform/oslog/linux.d.ts +16 -0
  89. package/dist/platform/oslog/linux.js +47 -0
  90. package/dist/platform/oslog/linux.js.map +1 -0
  91. package/dist/platform/oslog/windows.d.ts +15 -0
  92. package/dist/platform/oslog/windows.js +16 -0
  93. package/dist/platform/oslog/windows.js.map +1 -0
  94. package/dist/schemas/bridge.d.ts +256 -0
  95. package/dist/schemas/bridge.js +57 -0
  96. package/dist/schemas/bridge.js.map +1 -1
  97. package/dist/schemas/commands.d.ts +126 -0
  98. package/dist/schemas/commands.js +28 -0
  99. package/dist/schemas/commands.js.map +1 -1
  100. package/dist/schemas/index.d.ts +3 -2
  101. package/dist/schemas/index.js +3 -2
  102. package/dist/schemas/index.js.map +1 -1
  103. package/dist/schemas/interact.d.ts +118 -0
  104. package/dist/schemas/interact.js +31 -0
  105. package/dist/schemas/interact.js.map +1 -0
  106. package/dist/schemas/osLog.d.ts +34 -0
  107. package/dist/schemas/osLog.js +18 -0
  108. package/dist/schemas/osLog.js.map +1 -0
  109. package/dist/schemas/sidecar.d.ts +33 -0
  110. package/dist/schemas/sidecar.js +17 -0
  111. package/dist/schemas/sidecar.js.map +1 -0
  112. package/dist/schemas/tauriConfig.d.ts +825 -0
  113. package/dist/schemas/tauriConfig.js +102 -0
  114. package/dist/schemas/tauriConfig.js.map +1 -0
  115. package/dist/util/ndjson.d.ts +37 -0
  116. package/dist/util/ndjson.js +82 -0
  117. package/dist/util/ndjson.js.map +1 -0
  118. package/dist/util/tauriConfig.d.ts +63 -0
  119. package/dist/util/tauriConfig.js +235 -0
  120. package/dist/util/tauriConfig.js.map +1 -0
  121. package/examples/frontend-stub/index.html +1 -0
  122. package/examples/tauri-bridge/Cargo.toml +6 -0
  123. package/examples/tauri-bridge/build.rs +3 -0
  124. package/examples/tauri-bridge/icons/icon.png +0 -0
  125. package/examples/tauri-bridge/src/dev_bridge.rs +509 -10
  126. package/examples/tauri-bridge/tauri.conf.json +25 -0
  127. package/package.json +3 -1
  128. package/rust-bridge/README.md +7 -5
@@ -0,0 +1,156 @@
1
+ import { Command } from 'commander';
2
+ import { addBridgeOptions, resolveBridge } from './shared.js';
3
+ import { StoreInspectResultSchema } from '../schemas/commands.js';
4
+ /**
5
+ * Builds a JavaScript IIFE that detects and serializes reactive stores
6
+ * from the target framework running in the Tauri webview.
7
+ *
8
+ * Detection priority:
9
+ * 1. window.__DEBUG_STORES__ (app-registered hook)
10
+ * 2. window.__pinia (Pinia store)
11
+ * 3. window.__VUE_DEVTOOLS_GLOBAL_HOOK__ (Vue devtools hook)
12
+ * 4. Fallback: unknown with empty stores
13
+ */
14
+ export function buildStoreDetectionScript(framework, storeName, depth = 3) {
15
+ const storeNameFilter = storeName ? JSON.stringify(storeName) : 'null';
16
+ return `(function() {
17
+ var maxDepth = ${depth};
18
+ var storeNameFilter = ${storeNameFilter};
19
+
20
+ function serialize(obj, maxD, currentD) {
21
+ if (currentD === undefined) currentD = 0;
22
+ try {
23
+ if (obj === null || obj === undefined) return obj;
24
+ if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean') return obj;
25
+ if (currentD >= maxD) return '[max depth]';
26
+ if (Array.isArray(obj)) {
27
+ var arr = obj.slice(0, 100).map(function(item) { return serialize(item, maxD, currentD + 1); });
28
+ if (obj.length > 100) arr.push('[truncated, ' + (obj.length - 100) + ' more]');
29
+ return arr;
30
+ }
31
+ if (typeof obj === 'object') {
32
+ var keys = Object.keys(obj).slice(0, 50);
33
+ var result = {};
34
+ for (var i = 0; i < keys.length; i++) {
35
+ var k = keys[i];
36
+ try { result[k] = serialize(obj[k], maxD, currentD + 1); } catch(e) { result[k] = '[error]'; }
37
+ }
38
+ if (Object.keys(obj).length > 50) result['__truncated__'] = true;
39
+ return result;
40
+ }
41
+ return String(obj);
42
+ } catch(e) {
43
+ return '[error]';
44
+ }
45
+ }
46
+
47
+ // Check for app-registered debug hook first
48
+ if (typeof window.__DEBUG_STORES__ === 'function') {
49
+ try {
50
+ var hookResult = window.__DEBUG_STORES__();
51
+ var hookStores = {};
52
+ if (hookResult && typeof hookResult === 'object') {
53
+ var hookKeys = Object.keys(hookResult);
54
+ for (var i = 0; i < hookKeys.length; i++) {
55
+ var key = hookKeys[i];
56
+ if (storeNameFilter === null || key === storeNameFilter) {
57
+ hookStores[key] = serialize(hookResult[key], maxDepth, 0);
58
+ }
59
+ }
60
+ }
61
+ return JSON.stringify({ framework: 'custom', stores: hookStores });
62
+ } catch(e) {
63
+ // fall through to framework detection
64
+ }
65
+ }
66
+
67
+ var stores = {};
68
+ var detectedFramework = 'unknown';
69
+
70
+ // Pinia detection
71
+ if ((${framework === 'auto' || framework === 'pinia' ? 'true' : 'false'}) && window.__pinia) {
72
+ try {
73
+ var pinia = window.__pinia;
74
+ if (pinia._s && typeof pinia._s.forEach === 'function') {
75
+ pinia._s.forEach(function(store, id) {
76
+ if (storeNameFilter === null || id === storeNameFilter) {
77
+ try {
78
+ var state = store.$state;
79
+ stores[id] = serialize(state, maxDepth, 0);
80
+ } catch(e) {
81
+ stores[id] = '[error]';
82
+ }
83
+ }
84
+ });
85
+ detectedFramework = 'pinia';
86
+ }
87
+ } catch(e) {
88
+ // continue to next detection
89
+ }
90
+ }
91
+
92
+ // Vue devtools hook detection
93
+ if ((${framework === 'auto' || framework === 'vue' ? 'true' : 'false'}) && detectedFramework === 'unknown' && window.__VUE_DEVTOOLS_GLOBAL_HOOK__) {
94
+ try {
95
+ var hook = window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
96
+ if (hook.store) {
97
+ var vueStoreId = storeNameFilter || 'vuex';
98
+ if (storeNameFilter === null || storeNameFilter === 'vuex') {
99
+ stores[vueStoreId] = serialize(hook.store.state, maxDepth, 0);
100
+ }
101
+ detectedFramework = 'vue';
102
+ } else if (hook.stores && typeof hook.stores.forEach === 'function') {
103
+ hook.stores.forEach(function(store) {
104
+ var sid = (store.$id || store.id || 'store');
105
+ if (storeNameFilter === null || sid === storeNameFilter) {
106
+ stores[sid] = serialize(store.$state || store.state, maxDepth, 0);
107
+ }
108
+ });
109
+ detectedFramework = 'vue';
110
+ }
111
+ } catch(e) {
112
+ // continue to fallback
113
+ }
114
+ }
115
+
116
+ return JSON.stringify({ framework: detectedFramework, stores: stores });
117
+ })()`;
118
+ }
119
+ function formatStoreInspectResult(result) {
120
+ const storeKeys = Object.keys(result.stores);
121
+ const lines = [`Framework: ${result.framework}`];
122
+ if (storeKeys.length === 0) {
123
+ lines.push('Stores: (none detected)');
124
+ }
125
+ else {
126
+ lines.push(`Stores (${storeKeys.length}):`);
127
+ for (const key of storeKeys) {
128
+ lines.push(` ${key}:`);
129
+ lines.push(` ${JSON.stringify(result.stores[key], null, 2).replace(/\n/g, '\n ')}`);
130
+ }
131
+ }
132
+ return lines.join('\n');
133
+ }
134
+ export function registerStoreInspect(program) {
135
+ const cmd = new Command('store-inspect')
136
+ .description('Inspect reactive stores (Pinia, Vue, or custom app-registered hook)')
137
+ .option('--framework <name>', 'Framework to inspect: auto, pinia, vue', 'auto')
138
+ .option('--store <name>', 'Filter to a specific store by name')
139
+ .option('--depth <n>', 'Serialization depth', parseInt, 3)
140
+ .option('--json', 'Output as JSON');
141
+ addBridgeOptions(cmd);
142
+ cmd.action(async (opts) => {
143
+ const bridge = await resolveBridge(opts);
144
+ const script = buildStoreDetectionScript(opts.framework, opts.store, opts.depth);
145
+ const raw = await bridge.eval(script);
146
+ const result = StoreInspectResultSchema.parse(JSON.parse(String(raw)));
147
+ if (opts.json) {
148
+ console.log(JSON.stringify(result, null, 2));
149
+ }
150
+ else {
151
+ console.log(formatStoreInspectResult(result));
152
+ }
153
+ });
154
+ program.addCommand(cmd);
155
+ }
156
+ //# sourceMappingURL=storeInspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storeInspect.js","sourceRoot":"","sources":["../../src/commands/storeInspect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerWebviewAttach(program: Command): void;
@@ -0,0 +1,64 @@
1
+ import { Command } from 'commander';
2
+ import { exec } from '../util/exec.js';
3
+ import { addBridgeOptions, resolveBridge } from './shared.js';
4
+ export function registerWebviewAttach(program) {
5
+ const cmd = new Command('webview')
6
+ .description('Webview/devtools introspection (requires bridge v0.7.0+)');
7
+ const sub = cmd
8
+ .command('attach')
9
+ .description('Print the platform devtools URL or hint, optionally open in a browser')
10
+ .option('--print-url', 'Print only the inspector URL (or empty string if none)')
11
+ .option('--open', 'Open the inspector URL in the default browser (if available)')
12
+ .option('--json', 'Output as JSON');
13
+ addBridgeOptions(sub);
14
+ sub.action(async (opts) => {
15
+ const bridge = await resolveBridge(opts);
16
+ const dt = await bridge.devtools();
17
+ if (opts.json) {
18
+ console.log(JSON.stringify(dt, null, 2));
19
+ return;
20
+ }
21
+ if (opts.printUrl) {
22
+ console.log(dt.url ?? '');
23
+ return;
24
+ }
25
+ renderHuman(dt);
26
+ if (opts.open) {
27
+ if (!dt.url) {
28
+ console.error('--open requested but no inspector URL is available on this platform.');
29
+ process.exitCode = 2;
30
+ return;
31
+ }
32
+ await openInBrowser(dt.url);
33
+ }
34
+ });
35
+ program.addCommand(cmd);
36
+ }
37
+ function renderHuman(dt) {
38
+ console.log(`Webview platform: ${dt.platform}`);
39
+ console.log(`Inspectable: ${dt.inspectable ? 'yes' : 'no'}`);
40
+ if (dt.url) {
41
+ console.log(`Inspector URL: ${dt.url}`);
42
+ }
43
+ else {
44
+ console.log(`Inspector URL: (not exposed)`);
45
+ }
46
+ console.log(`Hint: ${dt.hint}`);
47
+ }
48
+ async function openInBrowser(url) {
49
+ // Cross-platform default-browser open via the host's standard tool.
50
+ const bin = process.platform === 'darwin'
51
+ ? 'open'
52
+ : process.platform === 'win32'
53
+ ? 'cmd'
54
+ : 'xdg-open';
55
+ const args = process.platform === 'win32' ? ['/c', 'start', '', url] : [url];
56
+ try {
57
+ await exec(bin, args, { timeout: 5000 });
58
+ }
59
+ catch (err) {
60
+ console.error(`Failed to launch browser: ${err instanceof Error ? err.message : String(err)}`);
61
+ process.exitCode = 2;
62
+ }
63
+ }
64
+ //# sourceMappingURL=webviewAttach.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webviewAttach.js","sourceRoot":"","sources":["../../src/commands/webviewAttach.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { NormalizedLogEntry } from '../../schemas/osLog.js';
2
+ export interface DarwinSpawnArgs {
3
+ identifier: string;
4
+ productName: string;
5
+ since?: string;
6
+ }
7
+ /**
8
+ * Build `log stream` args for the macOS unified log. We filter by either the
9
+ * subsystem (matches `OSLog.Logger`/Rust `tracing` subsystem when configured)
10
+ * or by sender image path (catches everything the app process emits even when
11
+ * the subsystem isn't set). Returns argv suitable for execFile.
12
+ */
13
+ export declare function buildArgs({ identifier, productName, since }: DarwinSpawnArgs): string[];
14
+ /**
15
+ * Parse a single `log stream --style ndjson` line into our normalized shape.
16
+ * Returns null when the line is metadata (e.g., the initial "Filtering the
17
+ * log data using…" line which is not valid JSON).
18
+ */
19
+ export declare function parseLine(line: string): NormalizedLogEntry | null;
20
+ /** The actual command binary the adapter shells out to. */
21
+ export declare const COMMAND = "log";
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Build `log stream` args for the macOS unified log. We filter by either the
3
+ * subsystem (matches `OSLog.Logger`/Rust `tracing` subsystem when configured)
4
+ * or by sender image path (catches everything the app process emits even when
5
+ * the subsystem isn't set). Returns argv suitable for execFile.
6
+ */
7
+ export function buildArgs({ identifier, productName, since }) {
8
+ const predicate = `subsystem == "${identifier}" OR senderImagePath CONTAINS[c] "${productName}"`;
9
+ const args = ['stream', '--predicate', predicate, '--style', 'ndjson'];
10
+ if (since) {
11
+ // `log stream` doesn't support --start directly; we accept the flag and
12
+ // surface it to the caller, but the actual time-based filter must be done
13
+ // client-side via `--last`/`show`. For `stream`, --since is informational.
14
+ // Callers wanting historical logs should use a separate `log show` variant.
15
+ }
16
+ return args;
17
+ }
18
+ /**
19
+ * Parse a single `log stream --style ndjson` line into our normalized shape.
20
+ * Returns null when the line is metadata (e.g., the initial "Filtering the
21
+ * log data using…" line which is not valid JSON).
22
+ */
23
+ export function parseLine(line) {
24
+ if (!line.trim().startsWith('{'))
25
+ return null;
26
+ let raw;
27
+ try {
28
+ raw = JSON.parse(line);
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ const ts = typeof raw['timestamp'] === 'string'
34
+ ? raw['timestamp']
35
+ : new Date().toISOString();
36
+ // macOS log levels: Default, Info, Debug, Error, Fault. Coerce to our 4-level
37
+ // taxonomy.
38
+ const typeRaw = String(raw['messageType'] ?? raw['eventMessage'] ?? 'Default');
39
+ const level = mapDarwinLevel(typeRaw);
40
+ const subsystem = String(raw['subsystem'] ?? '');
41
+ const senderImage = String(raw['senderImagePath'] ?? '');
42
+ const source = inferSource(senderImage);
43
+ const message = String(raw['eventMessage'] ?? raw['message'] ?? '');
44
+ return { ts, level, source, subsystem, message, raw };
45
+ }
46
+ function mapDarwinLevel(typeRaw) {
47
+ // macOS log emits canonical types: Default, Info, Debug, Error, Fault.
48
+ // Match the exact token (case-insensitive) rather than substring, otherwise
49
+ // "Default" gets misclassified as an error because it contains "fault".
50
+ switch (typeRaw.toLowerCase()) {
51
+ case 'fault':
52
+ case 'error':
53
+ return 'error';
54
+ case 'debug':
55
+ return 'debug';
56
+ case 'info':
57
+ return 'info';
58
+ case 'default':
59
+ default:
60
+ return 'info';
61
+ }
62
+ }
63
+ function inferSource(senderImagePath) {
64
+ // Apple's WebKit lives at /System/Library/Frameworks/WebKit.framework/…
65
+ if (/WebKit|com\.apple\.WebKit/i.test(senderImagePath))
66
+ return 'webview';
67
+ // App's main binary path will end with the executable name; everything else is "main".
68
+ return 'main';
69
+ }
70
+ /** The actual command binary the adapter shells out to. */
71
+ export const COMMAND = 'log';
72
+ //# sourceMappingURL=darwin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"darwin.js","sourceRoot":"","sources":["../../../src/platform/oslog/darwin.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAmB;IAC3E,MAAM,SAAS,GAAG,iBAAiB,UAAU,qCAAqC,WAAW,GAAG,CAAC;IACjG,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IACvE,IAAI,KAAK,EAAE,CAAC;QACV,wEAAwE;QACxE,0EAA0E;QAC1E,2EAA2E;QAC3E,4EAA4E;IAC9E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,GAA4B,CAAC;IACjC,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,EAAE,GACN,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,QAAQ;QAClC,CAAC,CAAE,GAAG,CAAC,WAAW,CAAY;QAC9B,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE/B,8EAA8E;IAC9E,YAAY;IACZ,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC,CAAC;IAC/E,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAEtC,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IACjD,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAEpE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AACxD,CAAC;AAED,SAAS,cAAc,CAAC,OAAe;IACrC,uEAAuE;IACvE,4EAA4E;IAC5E,wEAAwE;IACxE,QAAQ,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QAC9B,KAAK,OAAO,CAAC;QACb,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,KAAK,MAAM;YACT,OAAO,MAAM,CAAC;QAChB,KAAK,SAAS,CAAC;QACf;YACE,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,eAAuB;IAC1C,wEAAwE;IACxE,IAAI,4BAA4B,CAAC,IAAI,CAAC,eAAe,CAAC;QAAE,OAAO,SAAS,CAAC;IACzE,uFAAuF;IACvF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,2DAA2D;AAC3D,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { NormalizedLogEntry } from '../../schemas/osLog.js';
2
+ export interface LinuxSpawnArgs {
3
+ identifier: string;
4
+ productName: string;
5
+ since?: string;
6
+ }
7
+ /**
8
+ * Build `journalctl` args. We use `--user` (current user's systemd journal),
9
+ * `-f` to follow, `-o json` for structured output, and `-t` to filter by
10
+ * SYSLOG_IDENTIFIER. The product name is the most reliable identifier here
11
+ * because that's what Rust's `env_logger`/`log` typically uses, but we also
12
+ * accept the bundle id as a fallback subsystem match.
13
+ */
14
+ export declare function buildArgs({ identifier, productName, since }: LinuxSpawnArgs): string[];
15
+ export declare function parseLine(line: string): NormalizedLogEntry | null;
16
+ export declare const COMMAND = "journalctl";
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Build `journalctl` args. We use `--user` (current user's systemd journal),
3
+ * `-f` to follow, `-o json` for structured output, and `-t` to filter by
4
+ * SYSLOG_IDENTIFIER. The product name is the most reliable identifier here
5
+ * because that's what Rust's `env_logger`/`log` typically uses, but we also
6
+ * accept the bundle id as a fallback subsystem match.
7
+ */
8
+ export function buildArgs({ identifier, productName, since }) {
9
+ const args = ['--user', '-f', '-o', 'json', '-t', productName, '-t', identifier];
10
+ if (since)
11
+ args.push('--since', since);
12
+ return args;
13
+ }
14
+ export function parseLine(line) {
15
+ if (!line.trim().startsWith('{'))
16
+ return null;
17
+ let raw;
18
+ try {
19
+ raw = JSON.parse(line);
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ // journalctl `__REALTIME_TIMESTAMP` is microseconds since epoch as a string.
25
+ const tsMicros = raw['__REALTIME_TIMESTAMP'];
26
+ const ts = typeof tsMicros === 'string' && /^\d+$/.test(tsMicros)
27
+ ? new Date(Math.floor(Number(tsMicros) / 1000)).toISOString()
28
+ : new Date().toISOString();
29
+ // syslog priorities: 0=emerg .. 7=debug. journalctl exposes PRIORITY as a string.
30
+ const priorityRaw = raw['PRIORITY'];
31
+ const level = mapJournalPriority(typeof priorityRaw === 'string' ? Number(priorityRaw) : Number(priorityRaw ?? 6));
32
+ const subsystem = String(raw['SYSLOG_IDENTIFIER'] ?? '');
33
+ const message = String(raw['MESSAGE'] ?? '');
34
+ const source = 'main';
35
+ return { ts, level, source, subsystem, message, raw };
36
+ }
37
+ function mapJournalPriority(priority) {
38
+ if (priority <= 3)
39
+ return 'error'; // emerg/alert/crit/err
40
+ if (priority === 4)
41
+ return 'warn';
42
+ if (priority === 5 || priority === 6)
43
+ return 'info';
44
+ return 'debug';
45
+ }
46
+ export const COMMAND = 'journalctl';
47
+ //# sourceMappingURL=linux.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linux.js","sourceRoot":"","sources":["../../../src/platform/oslog/linux.ts"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAkB;IAC1E,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IACjF,IAAI,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACvC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,GAA4B,CAAC;IACjC,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6EAA6E;IAC7E,MAAM,QAAQ,GAAG,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAC7C,MAAM,EAAE,GACN,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;QACpD,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE;QAC7D,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE/B,kFAAkF;IAClF,MAAM,WAAW,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,kBAAkB,CAC9B,OAAO,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC,CACjF,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,CAAC;IAEtB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AACxD,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAgB;IAC1C,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC,CAAC,uBAAuB;IAC1D,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,QAAQ,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IACpD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,YAAY,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { NormalizedLogEntry } from '../../schemas/osLog.js';
2
+ export interface WindowsSpawnArgs {
3
+ identifier: string;
4
+ productName: string;
5
+ since?: string;
6
+ }
7
+ /**
8
+ * Windows os-logs support is not implemented in v0.7. The plan is to wrap
9
+ * `wevtutil qe Application` and `Get-WinEvent -FilterHashtable` once we have
10
+ * a Windows test target. Until then, callers receive a clear error rather
11
+ * than silent zero output.
12
+ */
13
+ export declare function buildArgs(_args: WindowsSpawnArgs): string[];
14
+ export declare function parseLine(_line: string): NormalizedLogEntry | null;
15
+ export declare const COMMAND = "wevtutil";
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Windows os-logs support is not implemented in v0.7. The plan is to wrap
3
+ * `wevtutil qe Application` and `Get-WinEvent -FilterHashtable` once we have
4
+ * a Windows test target. Until then, callers receive a clear error rather
5
+ * than silent zero output.
6
+ */
7
+ export function buildArgs(_args) {
8
+ throw new Error('os-logs is not yet implemented on Windows. ' +
9
+ 'Track the gap in the CHANGELOG or use `tauri-agent-tools forensics --since <duration>` ' +
10
+ 'against the app log directory directly.');
11
+ }
12
+ export function parseLine(_line) {
13
+ return null;
14
+ }
15
+ export const COMMAND = 'wevtutil';
16
+ //# sourceMappingURL=windows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windows.js","sourceRoot":"","sources":["../../../src/platform/oslog/windows.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,KAAuB;IAC/C,MAAM,IAAI,KAAK,CACb,6CAA6C;QAC3C,yFAAyF;QACzF,yCAAyC,CAC5C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,CAAC"}