@zogien/native-sdk 0.11.0-fork.3 → 0.11.0-fork.5
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/README.md +1 -1
- package/build/app.zig +53 -34
- package/build/cli.zig +22 -0
- package/package.json +10 -10
- package/packages/core/package-lock.json +2 -2
- package/packages/core/package.json +1 -1
- package/schemas/app.schema.json +9 -1
- package/skill-data/core/references/bridge-security-native-capabilities.md +4 -0
- package/skill-data/ts-core/SKILL.md +2 -0
- package/src/app_runner/app_assets.zig +85 -1
- package/src/app_runner/root.zig +63 -3
- package/src/app_runner/ts_core_main.zig +8 -0
- package/src/platform/linux/cef_host.cpp +22 -0
- package/src/platform/linux/gtk_host.c +317 -34
- package/src/platform/linux/gtk_host.h +37 -0
- package/src/platform/linux/root.zig +114 -20
- package/src/platform/macos/appkit_host.h +53 -0
- package/src/platform/macos/appkit_host.m +667 -67
- package/src/platform/macos/cef_host.mm +21 -0
- package/src/platform/macos/root.zig +146 -29
- package/src/platform/null_platform.zig +136 -0
- package/src/platform/root.zig +7 -0
- package/src/platform/types.zig +90 -0
- package/src/platform/windows/dialog_test.cpp +303 -0
- package/src/platform/windows/host_loop_test.cpp +169 -0
- package/src/platform/windows/root.zig +262 -39
- package/src/platform/windows/session_end_test.cpp +303 -0
- package/src/platform/windows/webview2_host.cpp +1435 -306
- package/src/primitives/app_manifest/root.zig +1 -0
- package/src/primitives/app_manifest/tests.zig +35 -0
- package/src/primitives/app_manifest/types.zig +12 -0
- package/src/primitives/app_manifest/validation.zig +44 -6
- package/src/root.zig +8 -0
- package/src/runtime/builtin_bridge.zig +108 -13
- package/src/runtime/channel_sources.zig +49 -1
- package/src/runtime/core.zig +24 -3
- package/src/runtime/dialog_tests.zig +367 -0
- package/src/runtime/dialogs.zig +385 -0
- package/src/runtime/effects.zig +83 -3
- package/src/runtime/effects_host_tests.zig +69 -1
- package/src/runtime/flow.zig +20 -6
- package/src/runtime/flow_reference.zig +20 -6
- package/src/runtime/platform_bridge_tests.zig +1 -0
- package/src/runtime/root.zig +9 -0
- package/src/runtime/single_instance.zig +893 -0
- package/src/runtime/system_services.zig +64 -82
- package/src/runtime/ui_app.zig +67 -0
- package/src/tooling/manifest.zig +111 -3
- package/src/tooling/package.zig +98 -8
- package/src/tooling/raw_manifest.zig +7 -0
- package/src/tooling/root.zig +2 -0
- package/src/tooling/templates.zig +44 -2
- package/src/tooling/update.zig +228 -10
- package/src/tooling/windows_installer.zig +245 -0
- package/src/tooling/zip_writer.zig +211 -0
- package/src/updater/engine.zig +936 -0
- package/src/updater/feed.zig +261 -12
- package/src/updater/macos.zig +187 -0
- package/src/updater/root.zig +41 -0
- package/src/updater/windows.zig +470 -0
- package/src/windows_install/config.zig +247 -0
- package/src/windows_install/main.zig +690 -0
- package/src/windows_install/payload.zig +146 -0
- package/src/windows_install/switch.zig +184 -0
- package/src/windows_install/tests.zig +11 -0
- package/src/windows_install/win32.zig +248 -0
- package/tools/native-sdk/main.zig +10 -9
package/src/runtime/flow.zig
CHANGED
|
@@ -30,6 +30,7 @@ const app_manifest = @import("app_manifest");
|
|
|
30
30
|
const platform = @import("../platform/root.zig");
|
|
31
31
|
const host_flow = @import("host_flow_policy.zig");
|
|
32
32
|
const native_reference = @import("flow_reference.zig");
|
|
33
|
+
const update_engine = @import("../updater/engine.zig");
|
|
33
34
|
const HostEventPump = @import("host_event_pump.zig").HostEventPump;
|
|
34
35
|
const security = @import("../security/root.zig");
|
|
35
36
|
|
|
@@ -381,6 +382,7 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
381
382
|
const state = event_value.window_frame_changed;
|
|
382
383
|
if (host_flow.gate(policy, 1, @intFromBool(was_open), @intFromBool(state.open)) != 0) {
|
|
383
384
|
const label = if (WindowViewMethods().findWindowIndexById(self, state.id)) |index| self.windows[index].info.label else state.label;
|
|
385
|
+
self.cancelDialogsForWindow(state.id);
|
|
384
386
|
try dispatchEvent(self, app, .{ .window_closed = .{ .window_id = state.id, .label = label } });
|
|
385
387
|
}
|
|
386
388
|
},
|
|
@@ -448,6 +450,7 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
448
450
|
emitFileDropEvent(self, drop) catch |err| log(self, "drop.files.emit_failed", @errorName(err), &.{trace.uint("window_id", drop.window_id)});
|
|
449
451
|
},
|
|
450
452
|
.lifecycle_stop => {
|
|
453
|
+
self.abandonDialogs();
|
|
451
454
|
try dispatchEvent(self, app, .{ .lifecycle = .stop });
|
|
452
455
|
},
|
|
453
456
|
.extensions_stop => {
|
|
@@ -455,6 +458,11 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
455
458
|
},
|
|
456
459
|
.mark_stop => {
|
|
457
460
|
self.app_stop_delivered = true;
|
|
461
|
+
// A release the app staged but did not restart into
|
|
462
|
+
// installs as the app quits, where the platform
|
|
463
|
+
// installs on exit (macOS); hosts may exit the process
|
|
464
|
+
// right after this event, so it cannot wait for run().
|
|
465
|
+
update_engine.finish();
|
|
458
466
|
},
|
|
459
467
|
.stop => {
|
|
460
468
|
try app.stop(self);
|
|
@@ -523,6 +531,10 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
523
531
|
try dispatchEvent(self, app, .{ .video = event_value.video });
|
|
524
532
|
},
|
|
525
533
|
.event_wake => {
|
|
534
|
+
// Finished dialogs ride the same nudge the effects
|
|
535
|
+
// channel uses; their completions run before the app
|
|
536
|
+
// drains its own work.
|
|
537
|
+
self.adoptDialogResults();
|
|
526
538
|
try dispatchEvent(self, app, .effects_wake);
|
|
527
539
|
},
|
|
528
540
|
.capability_gpu_surface_frame => {
|
|
@@ -1200,19 +1212,20 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
1200
1212
|
self.invalidateFor(.command, null);
|
|
1201
1213
|
return true;
|
|
1202
1214
|
}
|
|
1203
|
-
const response = switch (plan.family()) {
|
|
1215
|
+
const response: ?[]const u8 = switch (plan.family()) {
|
|
1204
1216
|
.none => unreachable,
|
|
1205
1217
|
.command => dispatchCommandBridgeCommand(self, app, request, message.window_id, message.webview_label, &result_buffer, &response_buffer),
|
|
1206
1218
|
.window => dispatchWindowBridgeCommand(self, request, &result_buffer, &response_buffer),
|
|
1207
1219
|
.view => dispatchViewBridgeCommand(self, request, message.window_id, &result_buffer, &response_buffer),
|
|
1208
1220
|
.webview => dispatchWebViewBridgeCommand(self, request, message.window_id, &result_buffer, &response_buffer),
|
|
1209
1221
|
.platform => dispatchPlatformBridgeCommand(self, request, &result_buffer, &response_buffer),
|
|
1210
|
-
.dialog => dispatchDialogBridgeCommand(self, request, &result_buffer, &response_buffer),
|
|
1222
|
+
.dialog => dispatchDialogBridgeCommand(self, request, message, &result_buffer, &response_buffer),
|
|
1211
1223
|
.os => dispatchOsBridgeCommand(self, request, message.origin, &result_buffer, &response_buffer),
|
|
1212
1224
|
.clipboard => dispatchClipboardBridgeCommand(self, request, &result_buffer, &response_buffer),
|
|
1213
1225
|
.credentials => dispatchCredentialBridgeCommand(self, request, &result_buffer, &response_buffer),
|
|
1214
1226
|
};
|
|
1215
|
-
|
|
1227
|
+
// Dialogs answer later, when they finish.
|
|
1228
|
+
if (response) |bytes| try completeBridgeResponse(self, message.window_id, message.webview_label, bytes);
|
|
1216
1229
|
self.invalidateFor(.command, null);
|
|
1217
1230
|
return true;
|
|
1218
1231
|
}
|
|
@@ -1265,7 +1278,7 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
1265
1278
|
self.invalidateFor(.command, null);
|
|
1266
1279
|
return true;
|
|
1267
1280
|
}
|
|
1268
|
-
const result = if (is_command)
|
|
1281
|
+
const result: ?[]const u8 = if (is_command)
|
|
1269
1282
|
dispatchCommandBridgeCommand(self, app, request, message.window_id, message.webview_label, &result_buffer, &response_buffer)
|
|
1270
1283
|
else if (is_window)
|
|
1271
1284
|
dispatchWindowBridgeCommand(self, request, &result_buffer, &response_buffer)
|
|
@@ -1276,7 +1289,7 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
1276
1289
|
else if (is_platform)
|
|
1277
1290
|
dispatchPlatformBridgeCommand(self, request, &result_buffer, &response_buffer)
|
|
1278
1291
|
else if (is_dialog)
|
|
1279
|
-
dispatchDialogBridgeCommand(self, request, &result_buffer, &response_buffer)
|
|
1292
|
+
dispatchDialogBridgeCommand(self, request, message, &result_buffer, &response_buffer)
|
|
1280
1293
|
else if (is_clipboard)
|
|
1281
1294
|
dispatchClipboardBridgeCommand(self, request, &result_buffer, &response_buffer)
|
|
1282
1295
|
else if (is_credentials)
|
|
@@ -1284,7 +1297,8 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
1284
1297
|
else
|
|
1285
1298
|
dispatchOsBridgeCommand(self, request, message.origin, &result_buffer, &response_buffer);
|
|
1286
1299
|
|
|
1287
|
-
|
|
1300
|
+
// Dialogs answer later, when they finish.
|
|
1301
|
+
if (result) |bytes| try completeBridgeResponse(self, message.window_id, message.webview_label, bytes);
|
|
1288
1302
|
self.invalidateFor(.command, null);
|
|
1289
1303
|
return true;
|
|
1290
1304
|
}
|
|
@@ -12,6 +12,7 @@ const runtime_automation_snapshot = @import("automation_snapshot.zig");
|
|
|
12
12
|
const runtime_automation_widget_dispatch = @import("automation_widget_dispatch.zig");
|
|
13
13
|
const automation_commands = @import("automation_command_policy.zig");
|
|
14
14
|
const launch_timing = @import("launch_timing.zig");
|
|
15
|
+
const update_engine = @import("../updater/engine.zig");
|
|
15
16
|
const runtime_clock = @import("clock.zig");
|
|
16
17
|
const runtime_state = @import("state.zig");
|
|
17
18
|
const shell_layout = @import("shell_layout.zig");
|
|
@@ -368,6 +369,7 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
368
369
|
// comes from runtime storage, which outlives the
|
|
369
370
|
// event's transient slices.
|
|
370
371
|
const label = if (WindowViewMethods().findWindowIndexById(self, state.id)) |index| self.windows[index].info.label else state.label;
|
|
372
|
+
self.cancelDialogsForWindow(state.id);
|
|
371
373
|
try dispatchEvent(self, app, .{ .window_closed = .{ .window_id = state.id, .label = label } });
|
|
372
374
|
}
|
|
373
375
|
},
|
|
@@ -504,6 +506,10 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
504
506
|
try dispatchEvent(self, app, .{ .video = video_event });
|
|
505
507
|
},
|
|
506
508
|
.wake => {
|
|
509
|
+
// Finished dialogs ride the same nudge the effects
|
|
510
|
+
// channel uses; their completions run before the app
|
|
511
|
+
// drains its own work.
|
|
512
|
+
self.adoptDialogResults();
|
|
507
513
|
try dispatchEvent(self, app, .effects_wake);
|
|
508
514
|
},
|
|
509
515
|
.files_dropped => |drop| {
|
|
@@ -522,8 +528,14 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
522
528
|
self.invalidateFor(.command, null);
|
|
523
529
|
},
|
|
524
530
|
.app_shutdown => {
|
|
531
|
+
self.abandonDialogs();
|
|
525
532
|
try dispatchEvent(self, app, .{ .lifecycle = .stop });
|
|
526
533
|
if (self.options.extensions) |registry| try registry.stopAll(extensionContext(self));
|
|
534
|
+
// A release the app staged but did not restart into
|
|
535
|
+
// installs as the app quits, where the platform
|
|
536
|
+
// installs on exit (macOS); hosts may exit the process
|
|
537
|
+
// right after this event, so it cannot wait for run().
|
|
538
|
+
update_engine.finish();
|
|
527
539
|
// Marked delivered BEFORE the call: if the hook itself
|
|
528
540
|
// errors, the run loop's exit path must not invoke it a
|
|
529
541
|
// second time (the hook contract is exactly-once).
|
|
@@ -1208,19 +1220,20 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
1208
1220
|
self.invalidateFor(.command, null);
|
|
1209
1221
|
return true;
|
|
1210
1222
|
}
|
|
1211
|
-
const response = switch (plan.family()) {
|
|
1223
|
+
const response: ?[]const u8 = switch (plan.family()) {
|
|
1212
1224
|
.none => unreachable,
|
|
1213
1225
|
.command => dispatchCommandBridgeCommand(self, app, request, message.window_id, message.webview_label, &result_buffer, &response_buffer),
|
|
1214
1226
|
.window => dispatchWindowBridgeCommand(self, request, &result_buffer, &response_buffer),
|
|
1215
1227
|
.view => dispatchViewBridgeCommand(self, request, message.window_id, &result_buffer, &response_buffer),
|
|
1216
1228
|
.webview => dispatchWebViewBridgeCommand(self, request, message.window_id, &result_buffer, &response_buffer),
|
|
1217
1229
|
.platform => dispatchPlatformBridgeCommand(self, request, &result_buffer, &response_buffer),
|
|
1218
|
-
.dialog => dispatchDialogBridgeCommand(self, request, &result_buffer, &response_buffer),
|
|
1230
|
+
.dialog => dispatchDialogBridgeCommand(self, request, message, &result_buffer, &response_buffer),
|
|
1219
1231
|
.os => dispatchOsBridgeCommand(self, request, message.origin, &result_buffer, &response_buffer),
|
|
1220
1232
|
.clipboard => dispatchClipboardBridgeCommand(self, request, &result_buffer, &response_buffer),
|
|
1221
1233
|
.credentials => dispatchCredentialBridgeCommand(self, request, &result_buffer, &response_buffer),
|
|
1222
1234
|
};
|
|
1223
|
-
|
|
1235
|
+
// Dialogs answer later, when they finish.
|
|
1236
|
+
if (response) |bytes| try completeBridgeResponse(self, message.window_id, message.webview_label, bytes);
|
|
1224
1237
|
self.invalidateFor(.command, null);
|
|
1225
1238
|
return true;
|
|
1226
1239
|
}
|
|
@@ -1273,7 +1286,7 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
1273
1286
|
self.invalidateFor(.command, null);
|
|
1274
1287
|
return true;
|
|
1275
1288
|
}
|
|
1276
|
-
const result = if (is_command)
|
|
1289
|
+
const result: ?[]const u8 = if (is_command)
|
|
1277
1290
|
dispatchCommandBridgeCommand(self, app, request, message.window_id, message.webview_label, &result_buffer, &response_buffer)
|
|
1278
1291
|
else if (is_window)
|
|
1279
1292
|
dispatchWindowBridgeCommand(self, request, &result_buffer, &response_buffer)
|
|
@@ -1284,7 +1297,7 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
1284
1297
|
else if (is_platform)
|
|
1285
1298
|
dispatchPlatformBridgeCommand(self, request, &result_buffer, &response_buffer)
|
|
1286
1299
|
else if (is_dialog)
|
|
1287
|
-
dispatchDialogBridgeCommand(self, request, &result_buffer, &response_buffer)
|
|
1300
|
+
dispatchDialogBridgeCommand(self, request, message, &result_buffer, &response_buffer)
|
|
1288
1301
|
else if (is_clipboard)
|
|
1289
1302
|
dispatchClipboardBridgeCommand(self, request, &result_buffer, &response_buffer)
|
|
1290
1303
|
else if (is_credentials)
|
|
@@ -1292,7 +1305,8 @@ pub fn RuntimeFlow(comptime Runtime: type) type {
|
|
|
1292
1305
|
else
|
|
1293
1306
|
dispatchOsBridgeCommand(self, request, message.origin, &result_buffer, &response_buffer);
|
|
1294
1307
|
|
|
1295
|
-
|
|
1308
|
+
// Dialogs answer later, when they finish.
|
|
1309
|
+
if (result) |bytes| try completeBridgeResponse(self, message.window_id, message.webview_label, bytes);
|
|
1296
1310
|
self.invalidateFor(.command, null);
|
|
1297
1311
|
return true;
|
|
1298
1312
|
}
|
package/src/runtime/root.zig
CHANGED
|
@@ -40,6 +40,10 @@ pub const Event = core.Event;
|
|
|
40
40
|
pub const App = core.App;
|
|
41
41
|
pub const Options = core.Options;
|
|
42
42
|
pub const Runtime = core.Runtime;
|
|
43
|
+
pub const DialogCompletion = core.DialogCompletion;
|
|
44
|
+
pub const DialogRequestOptions = core.DialogRequestOptions;
|
|
45
|
+
pub const max_dialog_requests = core.max_dialog_requests;
|
|
46
|
+
pub const max_dialog_tag_bytes = core.max_dialog_tag_bytes;
|
|
43
47
|
pub const TestHarness = core.TestHarness;
|
|
44
48
|
pub const DispatchError = core.DispatchError;
|
|
45
49
|
pub const max_dispatch_errors = core.max_dispatch_errors;
|
|
@@ -165,6 +169,7 @@ pub const max_effect_pty_chunk_bytes = runtime_effects.max_effect_pty_chunk_byte
|
|
|
165
169
|
pub const max_effect_pty_write_bytes = runtime_effects.max_effect_pty_write_bytes;
|
|
166
170
|
pub const max_effect_pty_term_bytes = runtime_effects.max_effect_pty_term_bytes;
|
|
167
171
|
pub const EffectHostResult = runtime_effects.EffectHostResult;
|
|
172
|
+
pub const DesktopCapabilityCompletion = runtime_effects.DesktopCapabilityCompletion;
|
|
168
173
|
pub const HostCallBinding = runtime_effects.HostCallBinding;
|
|
169
174
|
pub const HostCallCompletion = runtime_effects.HostCallCompletion;
|
|
170
175
|
pub const ServiceHost = @import("service_host.zig").ServiceHost;
|
|
@@ -241,6 +246,10 @@ pub const max_session_journal_bytes = runtime_session_journal.max_session_journa
|
|
|
241
246
|
pub const max_session_record_bytes = runtime_session_journal.max_session_record_bytes;
|
|
242
247
|
pub const max_session_event_bytes = runtime_session_journal.max_session_event_bytes;
|
|
243
248
|
|
|
249
|
+
/// Manifest `single_instance` ownership; the launcher claims it before
|
|
250
|
+
/// startup and the `native-sdk.app.launches` source delivers launches.
|
|
251
|
+
pub const single_instance = @import("single_instance.zig");
|
|
252
|
+
|
|
244
253
|
const runtime_clock = @import("clock.zig");
|
|
245
254
|
pub const Clock = runtime_clock.Clock;
|
|
246
255
|
pub const TestClock = runtime_clock.TestClock;
|