@rightkit/system-ui 0.0.0-stage → 0.1.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/CHANGELOG.md +5 -0
- package/LICENSE-APACHE +201 -0
- package/LICENSE-MIT +21 -0
- package/README.md +36 -2
- package/dist/activityLease.d.ts +1 -0
- package/dist/activityLease.js +20 -0
- package/dist/api.d.ts +1011 -0
- package/dist/api.js +296 -0
- package/dist/chart.d.ts +14 -0
- package/dist/chart.js +94 -0
- package/dist/components/Chart.d.ts +40 -0
- package/dist/components/Chart.js +109 -0
- package/dist/env.d.ts +60 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +28 -0
- package/dist/kept.d.ts +3 -0
- package/dist/kept.js +21 -0
- package/dist/lib/chatKind.d.ts +4 -0
- package/dist/lib/chatKind.js +15 -0
- package/dist/lib/legal.d.ts +26 -0
- package/dist/lib/legal.js +39 -0
- package/dist/lib/onboardingSettings.d.ts +2 -0
- package/dist/lib/onboardingSettings.js +17 -0
- package/dist/lib/qr.d.ts +9 -0
- package/dist/lib/qr.js +286 -0
- package/dist/lib/rk.d.ts +6 -0
- package/dist/lib/rk.js +30 -0
- package/dist/metrics.d.ts +24 -0
- package/dist/metrics.js +76 -0
- package/dist/onboarding/flow.d.ts +31 -0
- package/dist/onboarding/flow.js +81 -0
- package/dist/onboarding/gate.d.ts +8 -0
- package/dist/onboarding/gate.js +52 -0
- package/dist/styles.css +8 -0
- package/dist/views/Activity.d.ts +3 -0
- package/dist/views/Activity.js +111 -0
- package/dist/views/Apps.d.ts +1 -0
- package/dist/views/Apps.js +478 -0
- package/dist/views/Chat.d.ts +1 -0
- package/dist/views/Chat.js +255 -0
- package/dist/views/ChromeSnapshots.d.ts +6 -0
- package/dist/views/ChromeSnapshots.js +19 -0
- package/dist/views/Cleanup.d.ts +4 -0
- package/dist/views/Cleanup.js +291 -0
- package/dist/views/DriveHealth.d.ts +14 -0
- package/dist/views/DriveHealth.js +81 -0
- package/dist/views/Duplicates.d.ts +2 -0
- package/dist/views/Duplicates.js +99 -0
- package/dist/views/LauncherSettings.d.ts +63 -0
- package/dist/views/LauncherSettings.js +242 -0
- package/dist/views/NearbySettings.d.ts +117 -0
- package/dist/views/NearbySettings.js +237 -0
- package/dist/views/Storage.d.ts +9 -0
- package/dist/views/Storage.js +916 -0
- package/dist/views/activity.css +94 -0
- package/dist/views/apps.css +98 -0
- package/dist/views/chat.css +61 -0
- package/dist/views/cleanup.css +49 -0
- package/dist/views/health.css +17 -0
- package/dist/views/membrane.css +23 -0
- package/dist/views/monitor.css +99 -0
- package/dist/views/settings.css +176 -0
- package/dist/views/settingsKit.d.ts +14 -0
- package/dist/views/settingsKit.js +43 -0
- package/dist/views/storage.css +121 -0
- package/dist/views/storageEstimate.d.ts +6 -0
- package/dist/views/storageEstimate.js +7 -0
- package/dist/visible.d.ts +3 -0
- package/dist/visible.js +42 -0
- package/package.json +110 -3
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,1011 @@
|
|
|
1
|
+
/** True in the Windows webview: the hub runs one page on both systems and a few strings differ. */
|
|
2
|
+
export declare const isWindows: boolean;
|
|
3
|
+
export interface Metric<T> {
|
|
4
|
+
value: T | null;
|
|
5
|
+
capability: string;
|
|
6
|
+
label: string;
|
|
7
|
+
}
|
|
8
|
+
export interface Disk {
|
|
9
|
+
mount_point: string;
|
|
10
|
+
total_bytes: number | null;
|
|
11
|
+
/** Physically free: what the file system would let a write use now. */
|
|
12
|
+
available_bytes: number | null;
|
|
13
|
+
/** macOS only: more space the system could reclaim (snapshots, caches); never added to the free figure. */
|
|
14
|
+
reclaimable_bytes?: number | null;
|
|
15
|
+
removable: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface Status {
|
|
18
|
+
cpu_usage_percent: Metric<number>;
|
|
19
|
+
memory_used_bytes: Metric<number>;
|
|
20
|
+
memory_total_bytes: Metric<number>;
|
|
21
|
+
memory_pressure: Metric<string>;
|
|
22
|
+
swap_used_bytes: Metric<number>;
|
|
23
|
+
swap_total_bytes: Metric<number>;
|
|
24
|
+
disks: Disk[];
|
|
25
|
+
}
|
|
26
|
+
export interface Process {
|
|
27
|
+
identity: {
|
|
28
|
+
pid: number;
|
|
29
|
+
start_time: number;
|
|
30
|
+
};
|
|
31
|
+
name: string;
|
|
32
|
+
cpu_usage_percent: number;
|
|
33
|
+
memory: Metric<number>;
|
|
34
|
+
}
|
|
35
|
+
/** State of one volume's whole-disk index. `partial`: some folders were skipped or unreadable (Full Disk Access). */
|
|
36
|
+
export interface DiskIndexVolume {
|
|
37
|
+
mount_point: string;
|
|
38
|
+
state: "building" | "ready" | "failed";
|
|
39
|
+
entries: number;
|
|
40
|
+
crawl_ms: number;
|
|
41
|
+
resumed_from_snapshot: boolean;
|
|
42
|
+
full_disk_access: boolean;
|
|
43
|
+
partial: boolean;
|
|
44
|
+
unreadable_dirs: number;
|
|
45
|
+
error: string | null;
|
|
46
|
+
health?: DiskIndexHealth | null;
|
|
47
|
+
}
|
|
48
|
+
/** `since` is Unix seconds. Absent until the monitor's first tick and on platforms without the index. */
|
|
49
|
+
export interface DiskIndexHealth {
|
|
50
|
+
state: "healthy" | "unhealthy";
|
|
51
|
+
reasons: string[];
|
|
52
|
+
since: number;
|
|
53
|
+
}
|
|
54
|
+
export interface DiskIndexStatus {
|
|
55
|
+
supported: boolean;
|
|
56
|
+
volumes: DiskIndexVolume[];
|
|
57
|
+
health?: DiskIndexHealth | null;
|
|
58
|
+
}
|
|
59
|
+
/** Image and video compression (the host app #202): the switch, whether a verified FFmpeg is there, and why not. */
|
|
60
|
+
export interface MediaCompressStatus {
|
|
61
|
+
enabled: boolean;
|
|
62
|
+
available: boolean;
|
|
63
|
+
formats: string[];
|
|
64
|
+
note: string | null;
|
|
65
|
+
}
|
|
66
|
+
/** Measured from the written copy, never estimated. */
|
|
67
|
+
export interface MediaCompressOutcome {
|
|
68
|
+
source: string;
|
|
69
|
+
output: string;
|
|
70
|
+
source_bytes: number;
|
|
71
|
+
output_bytes: number;
|
|
72
|
+
saved_bytes: number;
|
|
73
|
+
}
|
|
74
|
+
/** `known: false` means the index does not hold the path yet; the numbers are then meaningless. */
|
|
75
|
+
export interface IndexedSize {
|
|
76
|
+
path: string;
|
|
77
|
+
known: boolean;
|
|
78
|
+
allocated: number;
|
|
79
|
+
allocated_unique: number;
|
|
80
|
+
logical: number;
|
|
81
|
+
files: number;
|
|
82
|
+
}
|
|
83
|
+
export interface Row {
|
|
84
|
+
path: string;
|
|
85
|
+
name: string;
|
|
86
|
+
is_dir: boolean;
|
|
87
|
+
bytes: number;
|
|
88
|
+
/** A "smaller files" total, not a real path. */
|
|
89
|
+
summary?: boolean;
|
|
90
|
+
/** Modified time in Unix seconds (a folder's: the newest below it); 0 or absent when unknown. */
|
|
91
|
+
modified?: number;
|
|
92
|
+
}
|
|
93
|
+
/** A range of modified times in Unix seconds: `since` inclusive, `before` exclusive. */
|
|
94
|
+
export interface ChangedRange {
|
|
95
|
+
since?: number;
|
|
96
|
+
before?: number;
|
|
97
|
+
}
|
|
98
|
+
/** What a search found, with the matches a date range left out for having no date. */
|
|
99
|
+
export interface SearchResult {
|
|
100
|
+
rows: Row[];
|
|
101
|
+
/** Which source answered: Windows Search, the Mac file index, or the saved scan. */
|
|
102
|
+
source?: "windows_search" | "file_index" | "saved_scan";
|
|
103
|
+
undated: number;
|
|
104
|
+
/** The saved scan carries modified times; false until it is scanned again. */
|
|
105
|
+
has_dates: boolean;
|
|
106
|
+
}
|
|
107
|
+
/** An item's identity when the person asked for an action on it (device and inode). */
|
|
108
|
+
export interface FileIdentity {
|
|
109
|
+
dev: number;
|
|
110
|
+
ino: number;
|
|
111
|
+
is_dir: boolean;
|
|
112
|
+
}
|
|
113
|
+
/** What the Storage inspector reads for one item; null means it could not be read. */
|
|
114
|
+
export interface Inspect {
|
|
115
|
+
is_dir: boolean;
|
|
116
|
+
is_link: boolean;
|
|
117
|
+
logical_bytes: number | null;
|
|
118
|
+
created_at: number | null;
|
|
119
|
+
modified_at: number | null;
|
|
120
|
+
files: number | null;
|
|
121
|
+
folders: number | null;
|
|
122
|
+
}
|
|
123
|
+
export interface MovePlan {
|
|
124
|
+
target: string;
|
|
125
|
+
same_volume: boolean;
|
|
126
|
+
}
|
|
127
|
+
export interface MoveResult {
|
|
128
|
+
target: string;
|
|
129
|
+
copied: boolean;
|
|
130
|
+
}
|
|
131
|
+
export interface Folder {
|
|
132
|
+
path: string;
|
|
133
|
+
root: string;
|
|
134
|
+
rows: Row[];
|
|
135
|
+
total_children: number;
|
|
136
|
+
incomplete: boolean;
|
|
137
|
+
needs_access: boolean;
|
|
138
|
+
/** Items the scan could not read (long paths, access denied, entry limit). */
|
|
139
|
+
unread?: number;
|
|
140
|
+
limited: boolean;
|
|
141
|
+
root_label: string;
|
|
142
|
+
/** Unix seconds when this data was scanned. */
|
|
143
|
+
scanned_at: number;
|
|
144
|
+
/** Shown from the last saved scan rather than a scan made this session. */
|
|
145
|
+
from_snapshot: boolean;
|
|
146
|
+
/** Rows carry modified times; false for a scan saved before they were kept. */
|
|
147
|
+
has_dates?: boolean;
|
|
148
|
+
}
|
|
149
|
+
export interface ScanStatus {
|
|
150
|
+
running: boolean;
|
|
151
|
+
running_root: string | null;
|
|
152
|
+
has_index: boolean;
|
|
153
|
+
root: string | null;
|
|
154
|
+
scanned_at: number | null;
|
|
155
|
+
from_snapshot: boolean;
|
|
156
|
+
/** The index is kept current while the hub runs; without it a saved scan only gets older. */
|
|
157
|
+
live_refresh: boolean;
|
|
158
|
+
}
|
|
159
|
+
export interface Volume {
|
|
160
|
+
name: string;
|
|
161
|
+
mount_point: string;
|
|
162
|
+
/** Null for a network volume that did not answer in time (never zero). */
|
|
163
|
+
total_bytes: number | null;
|
|
164
|
+
/** Physically free: what the file system would let a write use now. */
|
|
165
|
+
available_bytes: number | null;
|
|
166
|
+
/** macOS only: more space the system could reclaim (snapshots, caches); never added to the free figure. */
|
|
167
|
+
reclaimable_bytes?: number | null;
|
|
168
|
+
removable: boolean;
|
|
169
|
+
internal: boolean;
|
|
170
|
+
disk_image: boolean;
|
|
171
|
+
/** "network" for a mounted SMB, AFP, NFS or WebDAV share or a mapped network drive. */
|
|
172
|
+
kind: "local" | "network";
|
|
173
|
+
/** The server and share of a network volume, when known. */
|
|
174
|
+
detail: string | null;
|
|
175
|
+
/** "not responding" for a network volume that did not answer in time. */
|
|
176
|
+
state: "ok" | "not responding";
|
|
177
|
+
}
|
|
178
|
+
export interface CleanupFinding {
|
|
179
|
+
id: string;
|
|
180
|
+
rule_id: string;
|
|
181
|
+
rule_name?: string;
|
|
182
|
+
category: string;
|
|
183
|
+
name: string;
|
|
184
|
+
path: string;
|
|
185
|
+
bytes: number;
|
|
186
|
+
apparent_bytes?: number;
|
|
187
|
+
partial: boolean;
|
|
188
|
+
risk: "safe" | "review" | "info";
|
|
189
|
+
eligible: boolean;
|
|
190
|
+
preselected: boolean;
|
|
191
|
+
reason: string;
|
|
192
|
+
action: string;
|
|
193
|
+
dev: string;
|
|
194
|
+
ino: string;
|
|
195
|
+
/** What the item is ("cache", "virtual machine", ...); absent in findings saved before this field. */
|
|
196
|
+
kind?: string;
|
|
197
|
+
/** Plain-words safety note ("old release build"); empty when not described. */
|
|
198
|
+
safety?: string;
|
|
199
|
+
/** Who made the item: the owning app, tool or project; empty when unknown. */
|
|
200
|
+
owner?: string;
|
|
201
|
+
/** Unix seconds the item was last written; 0 when unknown. */
|
|
202
|
+
last_used?: number;
|
|
203
|
+
}
|
|
204
|
+
export interface ChromeSnapshots {
|
|
205
|
+
count: number;
|
|
206
|
+
apparent_bytes: number;
|
|
207
|
+
reclaimable_bytes: number;
|
|
208
|
+
reclaimable_known: boolean;
|
|
209
|
+
running: boolean;
|
|
210
|
+
since_at: number | null;
|
|
211
|
+
since_count: number | null;
|
|
212
|
+
}
|
|
213
|
+
export interface CleanupReport {
|
|
214
|
+
chrome_snapshots?: ChromeSnapshots | null;
|
|
215
|
+
findings: CleanupFinding[];
|
|
216
|
+
safe_bytes: number;
|
|
217
|
+
review_bytes: number;
|
|
218
|
+
scanned_at: number;
|
|
219
|
+
}
|
|
220
|
+
export interface CleanupApplyResult {
|
|
221
|
+
moved_items: number;
|
|
222
|
+
moved_bytes: number;
|
|
223
|
+
skipped: {
|
|
224
|
+
path: string;
|
|
225
|
+
reason: string;
|
|
226
|
+
}[];
|
|
227
|
+
activity_id: string | null;
|
|
228
|
+
}
|
|
229
|
+
export interface AppEntry {
|
|
230
|
+
name: string;
|
|
231
|
+
path: string;
|
|
232
|
+
bundle_id: string | null;
|
|
233
|
+
version: string | null;
|
|
234
|
+
size_bytes: number;
|
|
235
|
+
last_used: number | null;
|
|
236
|
+
running: boolean;
|
|
237
|
+
protected: string | null;
|
|
238
|
+
}
|
|
239
|
+
export interface RelatedItem {
|
|
240
|
+
path: string;
|
|
241
|
+
/** Library folder, or "Application". */
|
|
242
|
+
label: string;
|
|
243
|
+
/** "Application", "User Library", "System Library" or "Installer receipt". */
|
|
244
|
+
location: string;
|
|
245
|
+
exact: boolean;
|
|
246
|
+
/** exact, helper, group, prefix, team, name or receipt. */
|
|
247
|
+
confidence: string;
|
|
248
|
+
reason: string;
|
|
249
|
+
/** Root-owned: Finder asks for an administrator password. */
|
|
250
|
+
admin: boolean;
|
|
251
|
+
size_bytes: number;
|
|
252
|
+
preselected: boolean;
|
|
253
|
+
}
|
|
254
|
+
export interface BackgroundEntry {
|
|
255
|
+
kind: string;
|
|
256
|
+
label: string;
|
|
257
|
+
path: string | null;
|
|
258
|
+
}
|
|
259
|
+
export interface AppDetail {
|
|
260
|
+
app: AppEntry;
|
|
261
|
+
items: RelatedItem[];
|
|
262
|
+
background: BackgroundEntry[];
|
|
263
|
+
receipts: string[];
|
|
264
|
+
}
|
|
265
|
+
export interface UninstallResult {
|
|
266
|
+
moved: {
|
|
267
|
+
path: string;
|
|
268
|
+
bytes: number;
|
|
269
|
+
}[];
|
|
270
|
+
failed: {
|
|
271
|
+
path: string;
|
|
272
|
+
error: string;
|
|
273
|
+
}[];
|
|
274
|
+
/** Same value as moved_bytes. Moved to the Trash or Recycle Bin frees nothing until it is emptied. */
|
|
275
|
+
bytes_moved: number;
|
|
276
|
+
moved_bytes: number;
|
|
277
|
+
}
|
|
278
|
+
/** One listening or bound socket of a process, from `process_inspect`. */
|
|
279
|
+
export interface ListeningPort {
|
|
280
|
+
protocol: string;
|
|
281
|
+
family: string;
|
|
282
|
+
address: string;
|
|
283
|
+
port: number;
|
|
284
|
+
}
|
|
285
|
+
/** On-demand inspection of one process. A null list could not be read; its note says why. */
|
|
286
|
+
export interface ProcessConnection {
|
|
287
|
+
protocol: string;
|
|
288
|
+
family: string;
|
|
289
|
+
/** An address, never a looked-up name: nothing is resolved. */
|
|
290
|
+
remote_address: string;
|
|
291
|
+
remote_port: number;
|
|
292
|
+
}
|
|
293
|
+
export interface ProcessInspection {
|
|
294
|
+
listening: ListeningPort[] | null;
|
|
295
|
+
/** Established connections: the remote ends the process talks to. Null when unreadable; absent from older engines. */
|
|
296
|
+
connections?: ProcessConnection[] | null;
|
|
297
|
+
open_files: string[] | null;
|
|
298
|
+
notes: string[];
|
|
299
|
+
}
|
|
300
|
+
export interface ProcessMember {
|
|
301
|
+
identity: {
|
|
302
|
+
pid: number;
|
|
303
|
+
start_time: number;
|
|
304
|
+
};
|
|
305
|
+
name: string;
|
|
306
|
+
cpu_usage_percent: number;
|
|
307
|
+
/** Memory the process is responsible for: on macOS the physical footprint, including compressed and swapped pages. */
|
|
308
|
+
memory_bytes: number;
|
|
309
|
+
/** Resident size (in RAM now) when it differs from `memory_bytes`; absent when unknown. */
|
|
310
|
+
resident_bytes?: number;
|
|
311
|
+
/** Null when the platform did not report it. */
|
|
312
|
+
threads: number | null;
|
|
313
|
+
/** Windows: share of the busiest GPU engine, 0..100; null when unreadable or switched off. */
|
|
314
|
+
gpu_percent?: number | null;
|
|
315
|
+
/** Unix seconds; null when unreadable. */
|
|
316
|
+
started_at: number | null;
|
|
317
|
+
}
|
|
318
|
+
export interface ProcessRow {
|
|
319
|
+
key: string;
|
|
320
|
+
name: string;
|
|
321
|
+
bundle_id: string | null;
|
|
322
|
+
app_path: string | null;
|
|
323
|
+
lead: {
|
|
324
|
+
pid: number;
|
|
325
|
+
start_time: number;
|
|
326
|
+
};
|
|
327
|
+
cpu_usage_percent: number;
|
|
328
|
+
memory_bytes: number;
|
|
329
|
+
/** Resident size (in RAM now) when it differs from `memory_bytes`; absent when unknown. */
|
|
330
|
+
resident_bytes?: number;
|
|
331
|
+
/** Null when any member's count is unreadable. */
|
|
332
|
+
threads: number | null;
|
|
333
|
+
/** Windows: the members' GPU use added up (of the busiest engine); null when unreadable or switched off. */
|
|
334
|
+
gpu_percent?: number | null;
|
|
335
|
+
/** Bytes read and written since the previous refresh, plus lifetime totals, summed over the group (#324 item 10). Absent from older engines. Windows counts include pipe and network I/O. */
|
|
336
|
+
disk_io?: {
|
|
337
|
+
read_bytes: number;
|
|
338
|
+
written_bytes: number;
|
|
339
|
+
total_read_bytes: number;
|
|
340
|
+
total_written_bytes: number;
|
|
341
|
+
} | null;
|
|
342
|
+
/** Unix seconds the lead started; null when unreadable. */
|
|
343
|
+
started_at: number | null;
|
|
344
|
+
/** The app bundle or the executable; null when unknown. */
|
|
345
|
+
executable: string | null;
|
|
346
|
+
members: ProcessMember[];
|
|
347
|
+
can_act: boolean;
|
|
348
|
+
refusal: string | null;
|
|
349
|
+
}
|
|
350
|
+
export interface Change {
|
|
351
|
+
path: string;
|
|
352
|
+
/** Signed change in bytes. */
|
|
353
|
+
bytes: number;
|
|
354
|
+
}
|
|
355
|
+
export interface Growth {
|
|
356
|
+
available: boolean;
|
|
357
|
+
/** Unix seconds of the scan compared against. */
|
|
358
|
+
since: number | null;
|
|
359
|
+
grown: Change[];
|
|
360
|
+
shrunk: Change[];
|
|
361
|
+
reason: string | null;
|
|
362
|
+
}
|
|
363
|
+
export type QuitOutcome = "quit" | "still_running";
|
|
364
|
+
/** One Activity timeline row. `at` is Unix seconds; `open` names the section that owns it. */
|
|
365
|
+
export interface ActivityRow {
|
|
366
|
+
at: number;
|
|
367
|
+
kind: "Cleanup" | "Undo" | "Uninstall" | "App update" | "Drive health" | "Scan" | "Send" | "Chat" | "Remote" | "File index" | "Hub";
|
|
368
|
+
summary: string;
|
|
369
|
+
open: "cleanup" | "apps" | "storage" | "chat" | null;
|
|
370
|
+
}
|
|
371
|
+
export interface ActivityTimeline {
|
|
372
|
+
rows: ActivityRow[];
|
|
373
|
+
/** Sources that exist but could not be read. */
|
|
374
|
+
unreadable: string[];
|
|
375
|
+
}
|
|
376
|
+
export declare const api: {
|
|
377
|
+
status: () => Promise<Status>;
|
|
378
|
+
processes: () => Promise<Process[]>;
|
|
379
|
+
scan: (path?: string) => Promise<Folder>;
|
|
380
|
+
scanStatus: () => Promise<ScanStatus>;
|
|
381
|
+
lastScan: () => Promise<Folder | null>;
|
|
382
|
+
growth: () => Promise<Growth>;
|
|
383
|
+
children: (path: string) => Promise<Folder>;
|
|
384
|
+
/** `minBytes` keeps only items larger than that many bytes. */
|
|
385
|
+
search: (query: string, limit?: number, extensions?: string[], minBytes?: number) => Promise<Row[]>;
|
|
386
|
+
/** `search` with a modified-time range; says how many matches had no date. */
|
|
387
|
+
searchChanged: (query: string, minBytes?: number, changed?: ChangedRange, limit?: number) => Promise<SearchResult>;
|
|
388
|
+
diskIndexStatus: () => Promise<DiskIndexStatus>;
|
|
389
|
+
diskIndexSizes: (paths: string[]) => Promise<IndexedSize[]>;
|
|
390
|
+
apps: () => Promise<AppEntry[]>;
|
|
391
|
+
appDetail: (path: string) => Promise<AppDetail>;
|
|
392
|
+
uninstall: (path: string, bundleId: string | null, items: string[]) => Promise<UninstallResult>;
|
|
393
|
+
processRows: () => Promise<ProcessRow[]>;
|
|
394
|
+
quit: (r: ProcessRow) => Promise<QuitOutcome>;
|
|
395
|
+
forceQuit: (r: ProcessRow) => Promise<QuitOutcome>;
|
|
396
|
+
/** Listening ports and open files of one process, read now. Nothing is sampled in the background. */
|
|
397
|
+
inspectProcess: (r: ProcessRow) => Promise<ProcessInspection>;
|
|
398
|
+
volumes: () => Promise<Volume[]>;
|
|
399
|
+
eject: (mount: string) => Promise<void>;
|
|
400
|
+
/** Opens the Full Disk Access pane in System Settings. */
|
|
401
|
+
openFullDiskAccess: () => Promise<void>;
|
|
402
|
+
fullDiskAccessStatus: () => Promise<string>;
|
|
403
|
+
cleanupScan: () => Promise<CleanupReport>;
|
|
404
|
+
/** The last saved findings, or null when none were saved. Never scans. */
|
|
405
|
+
cleanupCached: () => Promise<CleanupReport | null>;
|
|
406
|
+
cleanupApply: (items: CleanupFinding[]) => Promise<CleanupApplyResult>;
|
|
407
|
+
cleanupRestore: (id: string) => Promise<unknown>;
|
|
408
|
+
reveal: (path: string) => Promise<void>;
|
|
409
|
+
/** Device and inode of an item now; the file actions check them again before acting. */
|
|
410
|
+
fileIdentity: (path: string) => Promise<FileIdentity>;
|
|
411
|
+
/** Opens a folder, or selects a file, in Finder. Read-only. */
|
|
412
|
+
finderOpen: (path: string) => Promise<void>;
|
|
413
|
+
/** The native folder picker; null when cancelled. */
|
|
414
|
+
fileChooseFolder: () => Promise<string | null>;
|
|
415
|
+
fileMovePlan: (path: string, id: FileIdentity, destination: string) => Promise<MovePlan>;
|
|
416
|
+
/** Renames within one drive; across drives, copies then trashes the original when copyAcrossVolumes is set. */
|
|
417
|
+
fileMove: (path: string, id: FileIdentity, destination: string, copyAcrossVolumes: boolean) => Promise<MoveResult>;
|
|
418
|
+
fileTrash: (path: string, id: FileIdentity) => Promise<void>;
|
|
419
|
+
mediaCompressStatus: () => Promise<MediaCompressStatus>;
|
|
420
|
+
mediaCompress: (path: string, options?: {
|
|
421
|
+
quality?: number;
|
|
422
|
+
max_dimension?: number;
|
|
423
|
+
}) => Promise<MediaCompressOutcome>;
|
|
424
|
+
/** Facts the scan does not hold for one item: read-only, one path, never recursive. */
|
|
425
|
+
storageInspect: (path: string) => Promise<Inspect>;
|
|
426
|
+
/** The raw bytes of one image for the inspector's preview; rejects with the reason when there is no preview. */
|
|
427
|
+
storagePreview: (path: string) => Promise<ArrayBuffer>;
|
|
428
|
+
/** Drive health for these mounts; samples smartctl only when ten minutes have passed. */
|
|
429
|
+
driveHealth: (mounts: string[]) => Promise<HealthReport>;
|
|
430
|
+
/** Read-only merge of the records each feature keeps; newest first, at most `limit` rows older than `before`. */
|
|
431
|
+
activityTimeline: (limit: number, before: number | null) => Promise<ActivityTimeline>;
|
|
432
|
+
homePath: () => Promise<string>;
|
|
433
|
+
duplicatesScan: (path: string) => Promise<DuplicateReport>;
|
|
434
|
+
/** Moves each extra copy to the Trash after re-checking it; the kept copy is never touched. */
|
|
435
|
+
duplicatesTrash: (items: {
|
|
436
|
+
kept: string;
|
|
437
|
+
path: string;
|
|
438
|
+
}[]) => Promise<DuplicatesTrashResult>;
|
|
439
|
+
};
|
|
440
|
+
export interface SelfTest {
|
|
441
|
+
kind: string;
|
|
442
|
+
result: string;
|
|
443
|
+
passed: boolean | null;
|
|
444
|
+
power_on_hours: number | null;
|
|
445
|
+
}
|
|
446
|
+
/** One successful SMART reading. `at` is Unix seconds. */
|
|
447
|
+
export interface HealthReading {
|
|
448
|
+
at: number;
|
|
449
|
+
passed: boolean | null;
|
|
450
|
+
temperature_c: number | null;
|
|
451
|
+
wear_percent: number | null;
|
|
452
|
+
written_bytes: number | null;
|
|
453
|
+
power_on_hours: number | null;
|
|
454
|
+
critical_warning: number | null;
|
|
455
|
+
media_errors: number | null;
|
|
456
|
+
self_tests: SelfTest[];
|
|
457
|
+
}
|
|
458
|
+
export interface HealthAlert {
|
|
459
|
+
id: string;
|
|
460
|
+
at: number;
|
|
461
|
+
disk: string;
|
|
462
|
+
kind: "warning" | "wear" | "media_errors";
|
|
463
|
+
message: string;
|
|
464
|
+
}
|
|
465
|
+
export interface DriveCard {
|
|
466
|
+
mount: string;
|
|
467
|
+
disk: string | null;
|
|
468
|
+
model: string | null;
|
|
469
|
+
status: "ok" | "warning" | "unavailable" | "unknown";
|
|
470
|
+
reachable: boolean;
|
|
471
|
+
/** The latest good reading; when the connection hides SMART, the last one kept, with its date. */
|
|
472
|
+
latest: HealthReading | null;
|
|
473
|
+
history: HealthReading[];
|
|
474
|
+
}
|
|
475
|
+
export interface HealthReport {
|
|
476
|
+
tool_available: boolean;
|
|
477
|
+
sampled_at: number | null;
|
|
478
|
+
drives: DriveCard[];
|
|
479
|
+
/** Newest first. */
|
|
480
|
+
alerts: HealthAlert[];
|
|
481
|
+
}
|
|
482
|
+
export interface DuplicateGroup {
|
|
483
|
+
kept_path: string;
|
|
484
|
+
extras: string[];
|
|
485
|
+
size_bytes: number;
|
|
486
|
+
}
|
|
487
|
+
export interface DuplicateReport {
|
|
488
|
+
groups: DuplicateGroup[];
|
|
489
|
+
skipped: {
|
|
490
|
+
path: string;
|
|
491
|
+
reason: string;
|
|
492
|
+
}[];
|
|
493
|
+
diagnostics: string[];
|
|
494
|
+
truncated: boolean;
|
|
495
|
+
files_considered: number;
|
|
496
|
+
bytes_read: number;
|
|
497
|
+
}
|
|
498
|
+
export interface DuplicatesTrashResult {
|
|
499
|
+
moved: {
|
|
500
|
+
path: string;
|
|
501
|
+
bytes: number;
|
|
502
|
+
}[];
|
|
503
|
+
skipped: {
|
|
504
|
+
path: string;
|
|
505
|
+
reason: string;
|
|
506
|
+
}[];
|
|
507
|
+
moved_bytes: number;
|
|
508
|
+
}
|
|
509
|
+
/** Decimal byte count ("1.5 GB"), or "—" when the value is unknown. */
|
|
510
|
+
export declare function bytes(n: number | null | undefined): string;
|
|
511
|
+
/** "136.3 GB more reclaimable by macOS" when it is at least 1 GB and 2% of the drive, else null. */
|
|
512
|
+
export declare function reclaimableNote(v: {
|
|
513
|
+
total_bytes: number | null;
|
|
514
|
+
reclaimable_bytes?: number | null;
|
|
515
|
+
}): string | null;
|
|
516
|
+
/** True when a saved result (Unix seconds) is old enough to refresh. */
|
|
517
|
+
export declare function isStale(secs: number): boolean;
|
|
518
|
+
/** "just now", "5 min ago", "2 h ago", or the date for anything older. */
|
|
519
|
+
export declare function ago(secs: number): string;
|
|
520
|
+
/** Colour for a 0–1 share, matching the notch rings. */
|
|
521
|
+
export declare function tone(fraction: number): string;
|
|
522
|
+
export declare function signedBytes(n: number): string;
|
|
523
|
+
export interface CachedApps {
|
|
524
|
+
/** Unix seconds when the saved list was written; null when there is none. */
|
|
525
|
+
saved_at: number | null;
|
|
526
|
+
apps: AppEntry[];
|
|
527
|
+
}
|
|
528
|
+
/** One source's share of an app's leftovers (`apps-leftovers` events). */
|
|
529
|
+
export interface LeftoverPart {
|
|
530
|
+
source: "bundle" | "vendor" | "background" | "library" | "receipts";
|
|
531
|
+
items: RelatedItem[];
|
|
532
|
+
background: BackgroundEntry[];
|
|
533
|
+
receipts: string[];
|
|
534
|
+
}
|
|
535
|
+
export type LeftoversEvent = {
|
|
536
|
+
kind: "part";
|
|
537
|
+
path: string;
|
|
538
|
+
part: LeftoverPart;
|
|
539
|
+
} | {
|
|
540
|
+
kind: "done";
|
|
541
|
+
path: string;
|
|
542
|
+
error: string | null;
|
|
543
|
+
};
|
|
544
|
+
/** Update state of one app. Only Sparkle, Homebrew and App Store apps can have one. */
|
|
545
|
+
export interface AppUpdate {
|
|
546
|
+
path: string;
|
|
547
|
+
name: string;
|
|
548
|
+
bundle_id: string | null;
|
|
549
|
+
installed_version: string | null;
|
|
550
|
+
source: "app_store" | "homebrew" | "sparkle" | "winget" | "none";
|
|
551
|
+
state: "available" | "current" | "app_store" | "unknown" | "unavailable";
|
|
552
|
+
latest_version: string | null;
|
|
553
|
+
cask: string | null;
|
|
554
|
+
store_url: string | null;
|
|
555
|
+
reason: string | null;
|
|
556
|
+
/** Unix seconds when this row was checked. */
|
|
557
|
+
checked_at: number;
|
|
558
|
+
}
|
|
559
|
+
export interface UpdateReport {
|
|
560
|
+
/** Unix seconds of the newest check; null before any check. */
|
|
561
|
+
checked_at: number | null;
|
|
562
|
+
apps: AppUpdate[];
|
|
563
|
+
}
|
|
564
|
+
export interface UpdateJob {
|
|
565
|
+
path: string;
|
|
566
|
+
state: "running" | "done" | "failed";
|
|
567
|
+
message: string;
|
|
568
|
+
}
|
|
569
|
+
/** One login or background item that starts by itself (src-tauri/src/startup_items.rs). Read only. */
|
|
570
|
+
export interface StartupItem {
|
|
571
|
+
name: string;
|
|
572
|
+
kind: string;
|
|
573
|
+
scope: "user" | "all users" | "system";
|
|
574
|
+
/** The plist, shortcut or executable; null when there is no file. */
|
|
575
|
+
path: string | null;
|
|
576
|
+
/** What it runs; null when unknown. */
|
|
577
|
+
program: string | null;
|
|
578
|
+
/** null when it cannot be told. */
|
|
579
|
+
enabled: boolean | null;
|
|
580
|
+
vendor: string | null;
|
|
581
|
+
}
|
|
582
|
+
export interface StartupReport {
|
|
583
|
+
rows: StartupItem[];
|
|
584
|
+
/** Plain notes on sources that could not be read or are not listed. */
|
|
585
|
+
notes: string[];
|
|
586
|
+
}
|
|
587
|
+
export declare const appsApi: {
|
|
588
|
+
cached: () => Promise<CachedApps>;
|
|
589
|
+
refresh: () => Promise<void>;
|
|
590
|
+
summary: (path: string) => Promise<AppEntry>;
|
|
591
|
+
leftovers: (path: string) => Promise<void>;
|
|
592
|
+
/** Cached icons by path; the rest arrive as `apps-icon` events. */
|
|
593
|
+
icons: (paths: string[]) => Promise<Record<string, string>>;
|
|
594
|
+
updatesCached: () => Promise<UpdateReport>;
|
|
595
|
+
updatesRefresh: (force: boolean) => Promise<void>;
|
|
596
|
+
/** Returns "running", "opened" or "store". */
|
|
597
|
+
update: (path: string) => Promise<string>;
|
|
598
|
+
/** Startup and login items, read only. Called when the Starts by itself section opens. */
|
|
599
|
+
startupItems: () => Promise<StartupReport>;
|
|
600
|
+
};
|
|
601
|
+
export interface ShareDevice {
|
|
602
|
+
fingerprint: string;
|
|
603
|
+
alias: string;
|
|
604
|
+
deviceModel?: string | null;
|
|
605
|
+
deviceType?: string | null;
|
|
606
|
+
ip: string;
|
|
607
|
+
port: number;
|
|
608
|
+
protocol: string;
|
|
609
|
+
}
|
|
610
|
+
export interface ShareIncoming {
|
|
611
|
+
id: string;
|
|
612
|
+
from: string;
|
|
613
|
+
fingerprint: string;
|
|
614
|
+
fileCount: number;
|
|
615
|
+
totalBytes: number;
|
|
616
|
+
isMessage: boolean;
|
|
617
|
+
preview?: string | null;
|
|
618
|
+
files: {
|
|
619
|
+
name: string;
|
|
620
|
+
size: number;
|
|
621
|
+
}[];
|
|
622
|
+
known: boolean;
|
|
623
|
+
}
|
|
624
|
+
export interface ShareTransfer {
|
|
625
|
+
id: string;
|
|
626
|
+
direction: "send" | "receive";
|
|
627
|
+
peer: string;
|
|
628
|
+
state: "waiting" | "active" | "done" | "failed" | "cancelled" | "declined";
|
|
629
|
+
totalBytes: number;
|
|
630
|
+
doneBytes: number;
|
|
631
|
+
filesTotal: number;
|
|
632
|
+
filesDone: number;
|
|
633
|
+
current?: string | null;
|
|
634
|
+
savedTo?: string | null;
|
|
635
|
+
savedFiles: string[];
|
|
636
|
+
error?: string | null;
|
|
637
|
+
}
|
|
638
|
+
export interface ShareSnapshot {
|
|
639
|
+
running: boolean;
|
|
640
|
+
error: string | null;
|
|
641
|
+
alias?: string;
|
|
642
|
+
saveDir?: string;
|
|
643
|
+
devices: ShareDevice[];
|
|
644
|
+
incoming: ShareIncoming[];
|
|
645
|
+
transfers: ShareTransfer[];
|
|
646
|
+
warnings: string[];
|
|
647
|
+
localNetwork: "unknown" | "granted" | "blocked";
|
|
648
|
+
}
|
|
649
|
+
export declare const shareApi: {
|
|
650
|
+
state: () => Promise<ShareSnapshot>;
|
|
651
|
+
devices: () => Promise<ShareDevice[]>;
|
|
652
|
+
/** Send files and/or text to a device (by fingerprint). Resolves with the transfer id. */
|
|
653
|
+
send: (to: string, paths: string[], text?: string) => Promise<string>;
|
|
654
|
+
accept: (id: string) => Promise<boolean>;
|
|
655
|
+
decline: (id: string) => Promise<boolean>;
|
|
656
|
+
cancel: (id: string) => Promise<boolean>;
|
|
657
|
+
dismiss: (id: string) => Promise<void>;
|
|
658
|
+
};
|
|
659
|
+
/** Effect classes a paired device may request (`agent/effect.rs`, kebab-case). */
|
|
660
|
+
export declare const DEVICE_GRANT_CLASSES: readonly ["reversible", "irreversible-destruction", "spend", "publication"];
|
|
661
|
+
export type DeviceGrantClass = (typeof DEVICE_GRANT_CLASSES)[number];
|
|
662
|
+
/** One device from `device.list` (the answer is `{ devices: DeviceRecord[] }`). */
|
|
663
|
+
export interface DeviceRecord {
|
|
664
|
+
deviceId: string;
|
|
665
|
+
name: string;
|
|
666
|
+
platform: string;
|
|
667
|
+
/** Hex key fingerprint; null until the engine reports it. */
|
|
668
|
+
keyFingerprint: string | null;
|
|
669
|
+
state: string;
|
|
670
|
+
grants: string[];
|
|
671
|
+
grantsExpireAtMs: number | null;
|
|
672
|
+
revision: number;
|
|
673
|
+
/** Null when the engine does not say whether the link is up. */
|
|
674
|
+
linkUp: boolean | null;
|
|
675
|
+
/** The computer may add devices for the circle. */
|
|
676
|
+
admit?: boolean;
|
|
677
|
+
}
|
|
678
|
+
/** The answer to `device.list`. */
|
|
679
|
+
export interface DeviceListResult {
|
|
680
|
+
devices: DeviceRecord[];
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* `code`: only the code is known; the owner types it on the other computer. Name, platform, id and
|
|
684
|
+
* fingerprint are empty and Approve is not offered. `confirm`: the other computer has confirmed and
|
|
685
|
+
* the full card with Approve and Reject is shown.
|
|
686
|
+
*/
|
|
687
|
+
export type PendingPairingStage = "code" | "confirm";
|
|
688
|
+
/** The live pairing awaiting the owner (`device.pair.pending` → `pending`). */
|
|
689
|
+
export interface PendingPairing {
|
|
690
|
+
pairingId: string;
|
|
691
|
+
/** Eight digits, shown as 4+4. */
|
|
692
|
+
code: string;
|
|
693
|
+
stage: PendingPairingStage;
|
|
694
|
+
deviceName: string;
|
|
695
|
+
platform: string;
|
|
696
|
+
deviceId: string;
|
|
697
|
+
keyFingerprint: string;
|
|
698
|
+
expiresAtMs: number;
|
|
699
|
+
}
|
|
700
|
+
/** The answer to `device.pair.pending`: `pending` is set only while `open` is true. */
|
|
701
|
+
export interface PendingPairingResult {
|
|
702
|
+
open: boolean;
|
|
703
|
+
pending: PendingPairing | null;
|
|
704
|
+
}
|
|
705
|
+
/** What `device.pair.start` returns (the code is never in it). */
|
|
706
|
+
export interface PairingStarted {
|
|
707
|
+
pairingId: string;
|
|
708
|
+
expiresAtMs: number;
|
|
709
|
+
/** The single-use join secret (64 hex) the QR carries as `s=`; a phone that proves it joins with one scan. */
|
|
710
|
+
secret?: string | null;
|
|
711
|
+
/** This computer's iroh endpoint id (64 hex); a phone's QR carries it. */
|
|
712
|
+
endpointId?: string;
|
|
713
|
+
/** Our relay, when one is set; null otherwise. */
|
|
714
|
+
relayUrl?: string | null;
|
|
715
|
+
/** This computer's private-network addresses (ip:port); the QR carries them for a phone. */
|
|
716
|
+
addrs?: string[];
|
|
717
|
+
}
|
|
718
|
+
/** What `device.join` returns once this computer joined a host. */
|
|
719
|
+
export interface JoinedHost {
|
|
720
|
+
state: string;
|
|
721
|
+
deviceId: string;
|
|
722
|
+
hostName: string;
|
|
723
|
+
}
|
|
724
|
+
/** What `device.join.create` returns. `token` and `command` are a bearer secret until used or expired: show them to the owner only. */
|
|
725
|
+
export interface JoinCreated {
|
|
726
|
+
/** `pulse-join:1:...` */
|
|
727
|
+
token: string;
|
|
728
|
+
/** `pulse device join <token>`, the one line to run on the computer being added. */
|
|
729
|
+
command: string;
|
|
730
|
+
pairingId: string;
|
|
731
|
+
expiresAtMs: number;
|
|
732
|
+
/** Guest links only (#493): per `uname -m` arch, the pinned artifact and the copyable install command (a bearer secret, it carries the pass). Absent on older engines. */
|
|
733
|
+
linux?: Record<string, {
|
|
734
|
+
url: string;
|
|
735
|
+
sha256: string;
|
|
736
|
+
size: number;
|
|
737
|
+
glibc: string;
|
|
738
|
+
command: string;
|
|
739
|
+
}>;
|
|
740
|
+
/** Why no Linux command was made (no published Linux build, unreadable manifest). */
|
|
741
|
+
linuxUnavailable?: string;
|
|
742
|
+
}
|
|
743
|
+
/** The engine's refusal text is `code: message`; these codes mean the owner check wants a (new) PIN. */
|
|
744
|
+
export declare const OWNER_CHECK_CODES: RegExp;
|
|
745
|
+
/** A Touch ID proof of the owner: the engine's single-use challenge and the signature the Mac notch made over it. The engine verifies it. */
|
|
746
|
+
export interface OwnerProof {
|
|
747
|
+
challenge: string;
|
|
748
|
+
sig: unknown;
|
|
749
|
+
}
|
|
750
|
+
export type PhoneReadMode = "allow" | "deny";
|
|
751
|
+
export type PhoneSendMode = "allow" | "ask" | "deny";
|
|
752
|
+
/** One paired phone from `device.phone.access`; `error` is set when its policy file is unreadable. */
|
|
753
|
+
export interface PhoneAccess {
|
|
754
|
+
deviceId: string;
|
|
755
|
+
name: string;
|
|
756
|
+
read?: PhoneReadMode;
|
|
757
|
+
send?: PhoneSendMode;
|
|
758
|
+
admin?: boolean;
|
|
759
|
+
error?: string;
|
|
760
|
+
}
|
|
761
|
+
export interface PhoneAccessResult {
|
|
762
|
+
enabled: boolean;
|
|
763
|
+
defaults: {
|
|
764
|
+
read: PhoneReadMode;
|
|
765
|
+
send: PhoneSendMode;
|
|
766
|
+
};
|
|
767
|
+
phones: PhoneAccess[];
|
|
768
|
+
}
|
|
769
|
+
/** A phone send held for the owner (`device.phone.asks`); it times out after 60 s. */
|
|
770
|
+
export interface PhoneAsk {
|
|
771
|
+
askId: string;
|
|
772
|
+
deviceId: string;
|
|
773
|
+
deviceName: string;
|
|
774
|
+
chat: string;
|
|
775
|
+
chatName: string;
|
|
776
|
+
preview: string;
|
|
777
|
+
createdAtMs: number;
|
|
778
|
+
}
|
|
779
|
+
/** One guest from `device.guest.list` (#492): a cloud box that redeemed a guest link. */
|
|
780
|
+
export interface GuestRecord {
|
|
781
|
+
deviceId: string;
|
|
782
|
+
name: string;
|
|
783
|
+
platform: string;
|
|
784
|
+
status: "pending" | "approved" | "lapsed";
|
|
785
|
+
/** The three digits the box printed when it joined; compare before approving. */
|
|
786
|
+
checkCode: string;
|
|
787
|
+
/** What the box said about itself; nothing verifies it. */
|
|
788
|
+
reportedSession: string | null;
|
|
789
|
+
mintedBy: string;
|
|
790
|
+
approvedAtMs: number | null;
|
|
791
|
+
leaseExpiresAtMs: number;
|
|
792
|
+
lastSeenMs: number | null;
|
|
793
|
+
/** What it may not do on any computer: add or manage devices, the phone admin path. */
|
|
794
|
+
refused: string[];
|
|
795
|
+
}
|
|
796
|
+
export declare const devicesApi: {
|
|
797
|
+
list: () => Promise<DeviceListResult>;
|
|
798
|
+
pending: () => Promise<PendingPairingResult>;
|
|
799
|
+
/** Opens a phone pairing. The engine checks the owner (`pin`, the the host app PIN) first. */
|
|
800
|
+
pairStart: (pin?: string, proof?: OwnerProof) => Promise<PairingStarted>;
|
|
801
|
+
/** Joins the computer whose owner made `token` (`pulse-join:1:...`); nothing else is asked. */
|
|
802
|
+
joinWith: (token: string) => Promise<JoinedHost>;
|
|
803
|
+
/** The engine checks the owner itself: `pin` is the the host app PIN. Without it the engine refuses `unlock_needs_auth`. */
|
|
804
|
+
pairApprove: (pairingId: string, pin?: string, proof?: OwnerProof) => Promise<unknown>;
|
|
805
|
+
/** Grants or takes away a computer's `admit` (it may add devices for the circle); owner-checked like Add a device. */
|
|
806
|
+
admitSet: (deviceId: string, allowed: boolean, pin?: string, proof?: OwnerProof) => Promise<unknown>;
|
|
807
|
+
/** The enrolled owner-check keys (`remote.owner.key.status`; the Mac notch's and Windows Hello's). */
|
|
808
|
+
ownerKeys: () => Promise<{
|
|
809
|
+
keys: {
|
|
810
|
+
keyId: string;
|
|
811
|
+
device: string;
|
|
812
|
+
dev: boolean;
|
|
813
|
+
bound?: boolean;
|
|
814
|
+
}[];
|
|
815
|
+
/** Where the owner-check keys are kept; `weaker` is Windows without the elevated the host app service (a file any process of this account can rewrite). */
|
|
816
|
+
ownerCheck?: {
|
|
817
|
+
protection?: "service" | "file" | "keychain";
|
|
818
|
+
weaker?: boolean;
|
|
819
|
+
};
|
|
820
|
+
/** True once a day while the owner key needs confirming (the engine remembers the offer), so a recreated web view does not ask again. */
|
|
821
|
+
bindDue?: boolean;
|
|
822
|
+
}>;
|
|
823
|
+
/** Confirms this computer's owner-check key (binds it to this device) with one owner check. Windows signs in the hub; the Mac's notch signs (`notch_command`, `signOwnerChallenge`, op `bind`). */
|
|
824
|
+
ownerKeyBind: () => Promise<unknown>;
|
|
825
|
+
/** Removes one owner-check key; the engine checks `pin`. */
|
|
826
|
+
ownerKeyRevoke: (keyId: string, pin: string) => Promise<unknown>;
|
|
827
|
+
/** "Add a device": the engine checks `pin` (the the host app PIN) first, then makes one join command valid for ten minutes. */
|
|
828
|
+
joinCreate: (pin?: string, proof?: OwnerProof) => Promise<JoinCreated>;
|
|
829
|
+
/** "Make a guest link" (#492): the same owner check as Add a device, then one single-use link for a cloud box. */
|
|
830
|
+
guestCreate: (leaseMs: number, pin?: string, proof?: OwnerProof) => Promise<JoinCreated>;
|
|
831
|
+
guests: () => Promise<{
|
|
832
|
+
guests: GuestRecord[];
|
|
833
|
+
}>;
|
|
834
|
+
/** Owner UI only: makes a pending cloud agent one of your machines until its lease ends. */
|
|
835
|
+
guestApprove: (deviceId: string) => Promise<unknown>;
|
|
836
|
+
/** Voids the open join command. */
|
|
837
|
+
joinCancel: () => Promise<unknown>;
|
|
838
|
+
pairReject: (pairingId: string) => Promise<unknown>;
|
|
839
|
+
revoke: (deviceId: string) => Promise<unknown>;
|
|
840
|
+
phoneAccess: () => Promise<PhoneAccessResult>;
|
|
841
|
+
/** `read` allow|deny|default; `send` allow|ask|deny|default; omit one to leave it. */
|
|
842
|
+
phoneAccessSet: (deviceId: string, change: {
|
|
843
|
+
read?: PhoneReadMode | "default";
|
|
844
|
+
send?: PhoneSendMode | "default";
|
|
845
|
+
}) => Promise<unknown>;
|
|
846
|
+
/** Off revokes the phone's approval key first (system prompt); rejects if cancelled, leaving admin on. */
|
|
847
|
+
phoneAdminSet: (deviceId: string, allow: boolean) => Promise<unknown>;
|
|
848
|
+
phoneAsks: () => Promise<{
|
|
849
|
+
asks: PhoneAsk[];
|
|
850
|
+
}>;
|
|
851
|
+
phoneAnswer: (askId: string, allow: boolean) => Promise<unknown>;
|
|
852
|
+
computerName: () => Promise<string | null>;
|
|
853
|
+
/** `revision` is the one the device was read at; `expiresAtMs` null means no expiry. */
|
|
854
|
+
grantsSet: (deviceId: string, revision: number, classes: DeviceGrantClass[], expiresAtMs: number | null) => Promise<unknown>;
|
|
855
|
+
};
|
|
856
|
+
/** One remote request waiting for the owner's answer (core/src/remote/approvals.rs `Item`, state `pending`). */
|
|
857
|
+
export interface RemoteApproval {
|
|
858
|
+
id: string;
|
|
859
|
+
/** `act` (one change) or `session` (a family's grant). */
|
|
860
|
+
kind: string;
|
|
861
|
+
/** The tool for an act (e.g. `files.patch`), the family (`terminal`) for a session. */
|
|
862
|
+
scope: string;
|
|
863
|
+
/** The door the call came in by: `local` or `gateway`. */
|
|
864
|
+
origin: string;
|
|
865
|
+
/** What the request is bound to; shown to nobody, sent back with the answer so the engine can check it. */
|
|
866
|
+
bind: string;
|
|
867
|
+
/** What it will do and the folder or file name it touches; never file contents or secrets. */
|
|
868
|
+
summary: string;
|
|
869
|
+
/** The external chat's client name (unlock requests). */
|
|
870
|
+
client?: string;
|
|
871
|
+
state: string;
|
|
872
|
+
created: number;
|
|
873
|
+
decided: number;
|
|
874
|
+
lastUsed: number;
|
|
875
|
+
}
|
|
876
|
+
/** The engine answers `remote.approvals.pending` with `{ items: [...] }` (engine/src/contract.rs); a bare list or `{ approvals }` is read too. */
|
|
877
|
+
export declare function pendingApprovals(answer: unknown): RemoteApproval[];
|
|
878
|
+
export declare const remoteApprovalsApi: {
|
|
879
|
+
pending: () => Promise<unknown>;
|
|
880
|
+
/** Approves or denies one pending request, bound to the item as displayed (the engine compares a digest of its fields). Owner UI only: the engine checks that the caller is the the host app hub. */
|
|
881
|
+
decide: (a: RemoteApproval, approve: boolean, pin?: string) => Promise<unknown>;
|
|
882
|
+
};
|
|
883
|
+
/** The per-chat unlock: the the host app PIN and the owner's answer to an unlock request (`scope === "unlock"`). Never log or keep a PIN. */
|
|
884
|
+
export declare const remoteUnlockApi: {
|
|
885
|
+
pinStatus: () => Promise<unknown>;
|
|
886
|
+
/** `current` is needed only when a PIN is already set. */
|
|
887
|
+
pinSet: (pin: string, current?: string) => Promise<unknown>;
|
|
888
|
+
/** Denies, or approves with the the host app PIN (the hub cannot show the system prompt). */
|
|
889
|
+
decide: (a: RemoteApproval, approve: boolean, pin?: string) => Promise<unknown>;
|
|
890
|
+
};
|
|
891
|
+
/** A sign-in request an agent made on a paired computer and that waits for the owner. */
|
|
892
|
+
export interface BrowserRequest {
|
|
893
|
+
id: string;
|
|
894
|
+
sites: string[];
|
|
895
|
+
reason: string;
|
|
896
|
+
chat: string;
|
|
897
|
+
expires_ms?: number;
|
|
898
|
+
}
|
|
899
|
+
/** A sign-in session on a paired computer. `needs-owner` is the state the live view is for. */
|
|
900
|
+
export interface BrowserSession {
|
|
901
|
+
session: string;
|
|
902
|
+
sites: string[];
|
|
903
|
+
chat: string;
|
|
904
|
+
state: string;
|
|
905
|
+
url?: string;
|
|
906
|
+
title?: string;
|
|
907
|
+
}
|
|
908
|
+
/** One frame of a session: JPEG, at most 1280 wide; `seq` rises with each new frame. */
|
|
909
|
+
export interface BrowserFrame {
|
|
910
|
+
seq: number;
|
|
911
|
+
jpeg_b64: string;
|
|
912
|
+
width: number;
|
|
913
|
+
height: number;
|
|
914
|
+
url: string;
|
|
915
|
+
title: string;
|
|
916
|
+
}
|
|
917
|
+
/** An input for the session, with x and y in frame pixels. `text` is never logged or kept. */
|
|
918
|
+
export type BrowserInput = {
|
|
919
|
+
type: "click";
|
|
920
|
+
x: number;
|
|
921
|
+
y: number;
|
|
922
|
+
} | {
|
|
923
|
+
type: "text";
|
|
924
|
+
text: string;
|
|
925
|
+
} | {
|
|
926
|
+
type: "key";
|
|
927
|
+
key: string;
|
|
928
|
+
} | {
|
|
929
|
+
type: "scroll";
|
|
930
|
+
dy: number;
|
|
931
|
+
};
|
|
932
|
+
/** The rows a list call answers: a bare list, or the list under `items` or the given key. */
|
|
933
|
+
export declare function browserRows<T>(answer: unknown, key?: string): T[];
|
|
934
|
+
export declare const browserRemoteApi: {
|
|
935
|
+
pending: (device: string) => Promise<unknown>;
|
|
936
|
+
/** A single-use nonce for one approval (valid for 60 seconds). */
|
|
937
|
+
challenge: (device: string, id: string) => Promise<{
|
|
938
|
+
nonce: string;
|
|
939
|
+
}>;
|
|
940
|
+
approve: (device: string, id: string, nonce: string) => Promise<unknown>;
|
|
941
|
+
deny: (device: string, id: string) => Promise<unknown>;
|
|
942
|
+
sessions: (device: string) => Promise<unknown>;
|
|
943
|
+
frame: (device: string, session: string, afterSeq: number) => Promise<BrowserFrame>;
|
|
944
|
+
input: (device: string, session: string, events: BrowserInput[]) => Promise<unknown>;
|
|
945
|
+
/** Hands the session back to the agent. */
|
|
946
|
+
done: (device: string, session: string) => Promise<unknown>;
|
|
947
|
+
};
|
|
948
|
+
/** One saved item of the agent secure box, as `remote.secure.list` answers: labels, hosts, last four and limits, never a value. */
|
|
949
|
+
export interface SecureItem {
|
|
950
|
+
id: string;
|
|
951
|
+
kind: "login" | "card";
|
|
952
|
+
label: string;
|
|
953
|
+
/** A login's one site. */
|
|
954
|
+
host?: string;
|
|
955
|
+
/** A login has a one-time code saved (never the secret). */
|
|
956
|
+
totp?: boolean;
|
|
957
|
+
/** A card's shops. */
|
|
958
|
+
hosts?: string[];
|
|
959
|
+
last4?: string;
|
|
960
|
+
maxCents?: number;
|
|
961
|
+
autoCents?: number;
|
|
962
|
+
monthCents?: number;
|
|
963
|
+
}
|
|
964
|
+
export interface SecureList {
|
|
965
|
+
items: SecureItem[];
|
|
966
|
+
month?: string;
|
|
967
|
+
spentCents?: Record<string, number>;
|
|
968
|
+
}
|
|
969
|
+
/** `cancelled` when the system dialog was closed; otherwise the saved item's metadata. */
|
|
970
|
+
export type SecureSaved = SecureItem | {
|
|
971
|
+
cancelled: true;
|
|
972
|
+
};
|
|
973
|
+
/**
|
|
974
|
+
* The agent secure box (#345 logins, #346 virtual cards). The renderer sends only non-secret fields and the PIN;
|
|
975
|
+
* the username, password, card number, name, expiry and CVC are typed into a system dialog opened by the command
|
|
976
|
+
* and go straight to the engine, so no secret ever exists in this page.
|
|
977
|
+
*/
|
|
978
|
+
export declare const secureBoxApi: {
|
|
979
|
+
list: () => Promise<SecureList>;
|
|
980
|
+
remove: (id: string) => Promise<unknown>;
|
|
981
|
+
saveLogin: (label: string, host: string, pin: string, withTotp?: boolean) => Promise<SecureSaved>;
|
|
982
|
+
/** Adds or replaces a saved login's one-time code; the secret is typed into the system dialog. */
|
|
983
|
+
setTotp: (id: string, host: string, pin: string) => Promise<SecureSaved>;
|
|
984
|
+
saveCard: (c: {
|
|
985
|
+
label: string;
|
|
986
|
+
hosts: string[];
|
|
987
|
+
zip: string;
|
|
988
|
+
maxCents: number;
|
|
989
|
+
autoCents: number;
|
|
990
|
+
monthCents: number;
|
|
991
|
+
}, pin: string) => Promise<SecureSaved>;
|
|
992
|
+
};
|
|
993
|
+
/** The sentence the Devices page shows when the engine refuses pairing with `listen_off`. */
|
|
994
|
+
export declare const LISTEN_OFF_SENTENCE = "Turn on Settings > Devices > Accept device links (LAN only) on this computer first.";
|
|
995
|
+
/** The engine's `listen_off` refusal (engine/src/devicelink_host.rs, pair_start). The hub's engine link
|
|
996
|
+
* passes only the refusal's message, not its code, so the message text identifies it. */
|
|
997
|
+
export declare function isListenOff(e: unknown): boolean;
|
|
998
|
+
export declare const isProtectedKey: (key: string) => boolean;
|
|
999
|
+
/** A protected change waiting for the the host app PIN (the engine asks for it when a change makes a gate less safe). */
|
|
1000
|
+
export interface PinAsk {
|
|
1001
|
+
key: string;
|
|
1002
|
+
value: unknown;
|
|
1003
|
+
problem: string | null;
|
|
1004
|
+
}
|
|
1005
|
+
export declare function onProtectedPin(fn: ((ask: PinAsk | null) => void) | null): void;
|
|
1006
|
+
/** Sends one protected change to the engine. Without a PIN a change that loosens a gate is refused with
|
|
1007
|
+
* `unlock_needs_auth`; that opens the PIN prompt (`ProtectedPinPrompt`). Never logs or keeps the PIN. */
|
|
1008
|
+
export declare function setProtectedSetting(key: string, value: unknown, pin?: string): Promise<void>;
|
|
1009
|
+
/** Sets one notch setting the way the Settings page does: `notch_command` with a `set` command
|
|
1010
|
+
* (a protected key goes through the engine instead). */
|
|
1011
|
+
export declare function setNotchSetting(key: string, value: unknown): Promise<unknown>;
|