@fungi.computer/tourtois 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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +127 -2
  3. package/dist/AgentMcpServers.d.ts +34 -0
  4. package/dist/AgentMcpServers.js +124 -0
  5. package/dist/AppAccessConsent.d.ts +23 -0
  6. package/dist/AppAccessConsent.js +122 -0
  7. package/dist/AppCallPermissions.d.ts +9 -0
  8. package/dist/AppCallPermissions.js +21 -0
  9. package/dist/AppDesktopSettings.d.ts +11 -0
  10. package/dist/AppDesktopSettings.js +102 -0
  11. package/dist/AppPane.d.ts +37 -0
  12. package/dist/AppPane.js +219 -0
  13. package/dist/AppWorkbench.d.ts +44 -0
  14. package/dist/AppWorkbench.js +575 -0
  15. package/dist/AvatarPicker.d.ts +7 -0
  16. package/dist/AvatarPicker.js +78 -0
  17. package/dist/AvatarPreview.d.ts +10 -0
  18. package/dist/AvatarPreview.js +6 -0
  19. package/dist/DesktopMenuBar.d.ts +18 -0
  20. package/dist/DesktopMenuBar.js +23 -0
  21. package/dist/FocusedAppMenus.d.ts +2 -0
  22. package/dist/FocusedAppMenus.js +10 -0
  23. package/dist/Keys.d.ts +131 -0
  24. package/dist/Keys.js +201 -0
  25. package/dist/MushroomMark.d.ts +2 -0
  26. package/dist/MushroomMark.js +5 -0
  27. package/dist/SettingsHome.d.ts +18 -0
  28. package/dist/SettingsHome.js +48 -0
  29. package/dist/SettingsNavigation.d.ts +17 -0
  30. package/dist/SettingsNavigation.js +153 -0
  31. package/dist/SystemSettings.d.ts +24 -0
  32. package/dist/SystemSettings.js +177 -0
  33. package/dist/TeamDesktop.d.ts +36 -0
  34. package/dist/TeamDesktop.js +39 -0
  35. package/dist/WorkbenchAppBar.d.ts +5 -0
  36. package/dist/WorkbenchAppBar.js +12 -0
  37. package/dist/app-authority.d.ts +150 -0
  38. package/dist/app-authority.js +41 -0
  39. package/dist/app-directory-reconciliation.d.ts +14 -0
  40. package/dist/app-directory-reconciliation.js +72 -0
  41. package/dist/app-directory.d.ts +206 -0
  42. package/dist/app-directory.js +21 -0
  43. package/dist/app-icon.d.ts +9 -0
  44. package/dist/app-icon.js +27 -0
  45. package/dist/app-launch.d.ts +53 -0
  46. package/dist/app-launch.js +204 -0
  47. package/dist/app-menus.d.ts +6 -0
  48. package/dist/app-menus.js +81 -0
  49. package/dist/app-open-url.d.ts +8 -0
  50. package/dist/app-open-url.js +63 -0
  51. package/dist/app-surface.d.ts +62 -0
  52. package/dist/app-surface.js +10 -0
  53. package/dist/app-windows.d.ts +134 -0
  54. package/dist/app-windows.js +21 -0
  55. package/dist/chrome.css +153 -0
  56. package/dist/command-dialogs.d.ts +42 -0
  57. package/dist/command-dialogs.js +194 -0
  58. package/dist/desktop/Desktop.d.ts +34 -0
  59. package/dist/desktop/Desktop.js +275 -0
  60. package/dist/desktop/consent.d.ts +4 -0
  61. package/dist/desktop/consent.js +64 -0
  62. package/dist/desktop/gill-frame.d.ts +14 -0
  63. package/dist/desktop/gill-frame.js +41 -0
  64. package/dist/desktop/gill-param-picker.d.ts +15 -0
  65. package/dist/desktop/gill-param-picker.js +145 -0
  66. package/dist/desktop/launcher-gill.d.ts +20 -0
  67. package/dist/desktop/launcher-gill.js +49 -0
  68. package/dist/desktop/own-launchers.d.ts +9 -0
  69. package/dist/desktop/own-launchers.js +9 -0
  70. package/dist/desktop/row-gill.d.ts +24 -0
  71. package/dist/desktop/row-gill.js +136 -0
  72. package/dist/desktop-api.d.ts +63 -0
  73. package/dist/desktop-api.js +31 -0
  74. package/dist/desktop-client.d.ts +19 -0
  75. package/dist/desktop-client.js +127 -0
  76. package/dist/desktop-layout.d.ts +117 -0
  77. package/dist/desktop-layout.js +305 -0
  78. package/dist/desktop-visibility.d.ts +8 -0
  79. package/dist/desktop-visibility.js +5 -0
  80. package/dist/layers.d.ts +5 -0
  81. package/dist/layers.js +31 -0
  82. package/dist/main.d.ts +2 -0
  83. package/dist/main.js +17 -0
  84. package/dist/member-avatar-cache.d.ts +15 -0
  85. package/dist/member-avatar-cache.js +69 -0
  86. package/dist/member-avatar.d.ts +39 -0
  87. package/dist/member-avatar.js +88 -0
  88. package/dist/menu-bar.d.ts +5 -0
  89. package/dist/menu-bar.js +5 -0
  90. package/dist/model.d.ts +6 -0
  91. package/dist/model.js +13 -0
  92. package/dist/oyster-platform-controls.d.ts +4 -0
  93. package/dist/oyster-platform-controls.js +107 -0
  94. package/dist/platform-controls.d.ts +84 -0
  95. package/dist/platform-controls.js +266 -0
  96. package/dist/queries.d.ts +7 -0
  97. package/dist/queries.js +7 -0
  98. package/dist/session-registry.d.ts +16 -0
  99. package/dist/session-registry.js +69 -0
  100. package/dist/session-selection.d.ts +6 -0
  101. package/dist/session-selection.js +22 -0
  102. package/dist/settings-leave-guard.d.ts +5 -0
  103. package/dist/settings-leave-guard.js +9 -0
  104. package/dist/settings-navigation.css +129 -0
  105. package/dist/settings-routes.d.ts +118 -0
  106. package/dist/settings-routes.js +216 -0
  107. package/dist/settings-sections.d.ts +74 -0
  108. package/dist/settings-sections.js +17 -0
  109. package/dist/shell-commands.d.ts +15 -0
  110. package/dist/shell-commands.js +95 -0
  111. package/dist/shell-host.d.ts +52 -0
  112. package/dist/shell-host.js +288 -0
  113. package/dist/shell-module.d.ts +12 -0
  114. package/dist/shell-module.js +17 -0
  115. package/dist/shell-release.d.ts +3 -0
  116. package/dist/shell-release.js +4 -0
  117. package/dist/shell.css +858 -0
  118. package/dist/shell.d.ts +6 -0
  119. package/dist/shell.js +83 -0
  120. package/dist/spa.css +11 -0
  121. package/dist/status-bar.d.ts +9 -0
  122. package/dist/status-bar.js +51 -0
  123. package/dist/team-directory.d.ts +3 -0
  124. package/dist/team-directory.js +6 -0
  125. package/dist/use-window-motion.d.ts +3 -0
  126. package/dist/use-window-motion.js +37 -0
  127. package/dist/useAppOpenUrlHandoff.d.ts +11 -0
  128. package/dist/useAppOpenUrlHandoff.js +62 -0
  129. package/dist/useAppWindowManager.d.ts +351 -0
  130. package/dist/useAppWindowManager.js +47 -0
  131. package/dist/useDirectoryCommands.d.ts +12 -0
  132. package/dist/useDirectoryCommands.js +80 -0
  133. package/dist/workbench.d.ts +3 -0
  134. package/dist/workbench.js +2 -0
  135. package/package.json +222 -3
@@ -0,0 +1,47 @@
1
+ import { useEffect, useMemo, useRef } from "react";
2
+ import { createAppWindowManager, } from "./app-windows.js";
3
+ /** One mounted host connection owns its windows, including StrictMode teardown. */
4
+ export function useAppWindowManager(host, teamId, events) {
5
+ const latest = useRef(events);
6
+ latest.current = events;
7
+ const manager = useMemo(() => createAppWindowManager({
8
+ waitForAttachment: true,
9
+ mount: async (container, launch, signal, projectionEvents) => {
10
+ if (!host)
11
+ throw new Error("App host unavailable");
12
+ return await host.mount(container, launch, signal, {
13
+ onAgentSessionSelection: (selection) => {
14
+ if (!host.reportAgentSessionSelection)
15
+ return Promise.reject(new Error("Hub Agent browser host unavailable"));
16
+ return Promise.resolve(host.reportAgentSessionSelection(teamId, launch.windowId, selection)).then(() => undefined);
17
+ },
18
+ onNavigation: (input) => latest.current.onNavigation(input),
19
+ onAppOpen: (input) => latest.current.onAppOpen(input),
20
+ onAppRole: (role) => latest.current.onAppRole(role),
21
+ onSelectionChanged: () => latest.current.onSelectionChanged(launch),
22
+ onFocus: () => {
23
+ latest.current.onAppFocus(launch);
24
+ },
25
+ onNavigationState: projectionEvents.onNavigationState,
26
+ onStatusItems: projectionEvents.onStatusItems,
27
+ onComputerChoice: projectionEvents.onComputerChoice,
28
+ });
29
+ },
30
+ }), [host, teamId]);
31
+ const setups = useRef(new Map());
32
+ useEffect(() => {
33
+ setups.current.set(manager, (setups.current.get(manager) ?? 0) + 1);
34
+ return () => {
35
+ queueMicrotask(() => {
36
+ const remaining = (setups.current.get(manager) ?? 1) - 1;
37
+ if (remaining === 0) {
38
+ setups.current.delete(manager);
39
+ void manager.dispose();
40
+ }
41
+ else
42
+ setups.current.set(manager, remaining);
43
+ });
44
+ };
45
+ }, [manager]);
46
+ return manager;
47
+ }
@@ -0,0 +1,12 @@
1
+ import type { TourtoisAppSurfaceHost } from "./app-surface.js";
2
+ import type { AppDirectoryApp } from "./app-launch.js";
3
+ import type { createAppWindowManager, AppLaunchDescriptor } from "./app-windows.js";
4
+ /** Keep declared commands addressable before their App has mounted. */
5
+ export declare function useDirectoryCommands({ host, directory, manager, launchFor, onFocus, onError, }: {
6
+ host: TourtoisAppSurfaceHost | null;
7
+ directory: readonly AppDirectoryApp[];
8
+ manager: ReturnType<typeof createAppWindowManager>;
9
+ launchFor: (app: AppDirectoryApp) => AppLaunchDescriptor | null;
10
+ onFocus: (windowId: string) => void;
11
+ onError: (message: string) => void;
12
+ }): void;
@@ -0,0 +1,80 @@
1
+ import { useEffect, useMemo, useRef } from "react";
2
+ function waitForPaletteCommand(host, commandId) {
3
+ const isReady = () => host.active().palette.some((command) => command.commandId === commandId);
4
+ if (isReady())
5
+ return Promise.resolve();
6
+ return new Promise((resolve, reject) => {
7
+ const timeout = window.setTimeout(() => {
8
+ unsubscribe();
9
+ reject(new Error("The App did not register its declared command."));
10
+ }, 10_000);
11
+ const finish = () => {
12
+ window.clearTimeout(timeout);
13
+ unsubscribe();
14
+ resolve();
15
+ };
16
+ const check = () => {
17
+ if (isReady())
18
+ finish();
19
+ };
20
+ const unsubscribe = host.subscribe(check);
21
+ check();
22
+ });
23
+ }
24
+ /** Keep declared commands addressable before their App has mounted. */
25
+ export function useDirectoryCommands({ host, directory, manager, launchFor, onFocus, onError, }) {
26
+ const advertisedCommands = useMemo(() => directory.flatMap((installation) => installation.commands.map((command) => ({
27
+ surfaceId: installation.surfaceId,
28
+ appTitle: installation.displayName ?? "App",
29
+ command,
30
+ }))), [directory]);
31
+ const directoryCommandContext = useRef({
32
+ manager,
33
+ directory,
34
+ onFocus,
35
+ onError,
36
+ launchFor,
37
+ });
38
+ directoryCommandContext.current = {
39
+ manager,
40
+ directory,
41
+ onFocus,
42
+ onError,
43
+ launchFor,
44
+ };
45
+ useEffect(() => {
46
+ if (!host?.registerDirectoryCommands)
47
+ return;
48
+ return host.registerDirectoryCommands(advertisedCommands, async (surfaceId, commandId) => {
49
+ const context = directoryCommandContext.current;
50
+ const installation = context.directory.find((app) => app.surfaceId === surfaceId);
51
+ if (!installation)
52
+ throw new Error("This App is no longer available.");
53
+ const launch = context.launchFor(installation);
54
+ if (!launch)
55
+ throw new Error("This App is no longer available.");
56
+ try {
57
+ await context.manager.open(launch);
58
+ context.onFocus(launch.windowId);
59
+ const runtimeCommandId = `${encodeURIComponent(surfaceId)}:${commandId}`;
60
+ await waitForPaletteCommand(host, runtimeCommandId);
61
+ const outcome = await host.execute(runtimeCommandId, {
62
+ origin: "palette",
63
+ });
64
+ if (outcome.status === "handled")
65
+ return;
66
+ if (outcome.status === "failed")
67
+ throw new Error(outcome.error.message);
68
+ if (outcome.status === "unavailable")
69
+ throw new Error(outcome.reason);
70
+ throw new Error("The App command is no longer available.");
71
+ }
72
+ catch (error) {
73
+ context.onError(error instanceof Error
74
+ ? error.message
75
+ : `${installation.displayName ?? "App"} could not run this command.`);
76
+ throw error;
77
+ }
78
+ });
79
+ }, [host, advertisedCommands]);
80
+ }
@@ -0,0 +1,3 @@
1
+ export { TeamTourtois } from "./TeamDesktop.js";
2
+ export { AppSurfaceHostProvider } from "./app-surface.js";
3
+ export type { TourtoisAppMountEvents, TourtoisAppSurfaceHost, } from "./app-surface.js";
@@ -0,0 +1,2 @@
1
+ export { TeamTourtois } from "./TeamDesktop.js";
2
+ export { AppSurfaceHostProvider } from "./app-surface.js";
package/package.json CHANGED
@@ -1,6 +1,225 @@
1
1
  {
2
2
  "name": "@fungi.computer/tourtois",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "author": "Levi <levi@technomancy.dev>",
5
+ "description": "Tourtois: the trusted desktop shell for Oyster and Fungi, with host-supplied Settings sections",
6
+ "type": "module",
7
+ "exports": {
8
+ "./shell": {
9
+ "types": "./dist/shell.d.ts",
10
+ "import": "./dist/shell.js"
11
+ },
12
+ "./shell-module": {
13
+ "types": "./dist/shell-module.d.ts",
14
+ "import": "./dist/shell-module.js"
15
+ },
16
+ "./app-directory": {
17
+ "types": "./dist/app-directory.d.ts",
18
+ "import": "./dist/app-directory.js"
19
+ },
20
+ "./app-open-url": {
21
+ "types": "./dist/app-open-url.d.ts",
22
+ "import": "./dist/app-open-url.js"
23
+ },
24
+ "./app-surface": {
25
+ "types": "./dist/app-surface.d.ts",
26
+ "import": "./dist/app-surface.js"
27
+ },
28
+ "./styles.css": "./dist/shell.css",
29
+ "./workbench": {
30
+ "types": "./dist/workbench.d.ts",
31
+ "import": "./dist/workbench.js"
32
+ },
33
+ "./platform-controls": {
34
+ "types": "./dist/platform-controls.d.ts",
35
+ "import": "./dist/platform-controls.js"
36
+ },
37
+ "./settings-routes": {
38
+ "types": "./dist/settings-routes.d.ts",
39
+ "import": "./dist/settings-routes.js"
40
+ },
41
+ "./team-directory": {
42
+ "types": "./dist/team-directory.d.ts",
43
+ "import": "./dist/team-directory.js"
44
+ },
45
+ "./app-authority": {
46
+ "types": "./dist/app-authority.d.ts",
47
+ "import": "./dist/app-authority.js"
48
+ },
49
+ "./app-call-permissions": {
50
+ "types": "./dist/AppCallPermissions.d.ts",
51
+ "import": "./dist/AppCallPermissions.js"
52
+ },
53
+ "./settings-leave-guard": {
54
+ "types": "./dist/settings-leave-guard.d.ts",
55
+ "import": "./dist/settings-leave-guard.js"
56
+ },
57
+ "./app-icon": {
58
+ "types": "./dist/app-icon.d.ts",
59
+ "import": "./dist/app-icon.js"
60
+ },
61
+ "./app-access-consent": {
62
+ "types": "./dist/AppAccessConsent.d.ts",
63
+ "import": "./dist/AppAccessConsent.js"
64
+ }
65
+ },
66
+ "files": [
67
+ "dist",
68
+ "README.md",
69
+ "LICENSE"
70
+ ],
71
+ "dependencies": {
72
+ "@fungi.computer/agar": "0.2.0",
73
+ "@fungi.computer/cairn": "0.0.1",
74
+ "@fungi.computer/caps": "0.1.0",
75
+ "@fungi.computer/gills": "0.1.0",
76
+ "@fungi.computer/maosaico": "0.0.1",
77
+ "@fungi.computer/oyster": "0.2.0",
78
+ "@fungi.computer/parakeet": "0.1.0",
79
+ "@fungi.computer/puffball": "0.1.0",
80
+ "@fungi.computer/shiitake": "0.2.0",
81
+ "@fungi.computer/sigils": "0.1.0",
82
+ "@fungi.computer/sprite": "0.1.0",
83
+ "@fungi.computer/sprite-zdog": "0.1.0",
84
+ "@fungi.computer/whistle": "0.0.2",
85
+ "@tanstack/history": "1.162.1",
86
+ "@tanstack/react-form": "1.33.2",
87
+ "@tanstack/react-query": "5.102.8",
88
+ "@tanstack/react-router": "1.170.28",
89
+ "@tanstack/router-core": "1.171.23",
90
+ "animejs": "4.5.0",
91
+ "effect": "4.0.2",
92
+ "lucide-react": "0.460.0",
93
+ "react-dom": "18.3.1",
94
+ "zod": "4.4.3"
95
+ },
96
+ "peerDependencies": {
97
+ "react": "^18.3.1 || ^19.2.0"
98
+ },
99
+ "devDependencies": {
100
+ "@cloudflare/workers-types": "5.20260828.1",
101
+ "@fungi.computer/forage": "0.1.0",
102
+ "@fungi.computer/mycelium": "0.1.0",
103
+ "@ladle/react": "5.1.1",
104
+ "@types/react": "18.3.3",
105
+ "@vitejs/plugin-react": "6.1.1",
106
+ "playwright": "1.62.1",
107
+ "react": "18.3.1",
108
+ "typescript": "5.9.3",
109
+ "vite": "8.2.2",
110
+ "vitest": "4.1.11",
111
+ "wrangler": "4.135.0",
112
+ "eslint": "10.9.1",
113
+ "oxlint": "1.78.0",
114
+ "tsx": "4.23.12",
115
+ "jsdom": "29.0.1",
116
+ "@types/node": "24.13.3",
117
+ "@types/react-dom": "18.3.0"
118
+ },
119
+ "fungi": {
120
+ "app": {
121
+ "displayName": "Tourtois",
122
+ "icon": "tourtois",
123
+ "capabilities": [
124
+ "team.workbenchHost",
125
+ "app.storage"
126
+ ],
127
+ "handlers": [],
128
+ "roles": [
129
+ "dashboard"
130
+ ],
131
+ "commands": [],
132
+ "storage": [
133
+ {
134
+ "key": "desktop",
135
+ "scopes": [
136
+ "team",
137
+ "member"
138
+ ],
139
+ "maxBytes": 16384
140
+ }
141
+ ],
142
+ "backend": {
143
+ "bindings": [
144
+ {
145
+ "name": "APP_STORAGE",
146
+ "operations": [
147
+ "read",
148
+ "write",
149
+ "reset"
150
+ ]
151
+ },
152
+ {
153
+ "name": "APPS",
154
+ "operations": [
155
+ "catalog"
156
+ ]
157
+ }
158
+ ]
159
+ }
160
+ },
161
+ "backendDefinition": "backend/methods.ts",
162
+ "build": {
163
+ "react": true,
164
+ "shellEntry": "src/shell-module.ts",
165
+ "packageStylesheets": [
166
+ "@fungi.computer/caps",
167
+ "@fungi.computer/parakeet"
168
+ ]
169
+ }
170
+ },
171
+ "license": "MIT",
172
+ "botanical": {
173
+ "role": "app",
174
+ "operations": {
175
+ "lint": "required",
176
+ "typecheck": "required",
177
+ "build": "required",
178
+ "test": "required",
179
+ "docs": {
180
+ "status": "not-applicable",
181
+ "reason": "App shell documented in README; shared docs tooling not yet wired for this App"
182
+ },
183
+ "pack": {
184
+ "status": "not-applicable",
185
+ "reason": "Shared pack tooling not yet wired for this App"
186
+ },
187
+ "smoke": {
188
+ "status": "not-applicable",
189
+ "reason": "The Bonsai standalone test:app-set and Hub browser proofs exercise the shell"
190
+ },
191
+ "stranger": {
192
+ "status": "not-applicable",
193
+ "reason": "Shared stranger consumer proof not yet wired for this App"
194
+ }
195
+ }
196
+ },
197
+ "publishConfig": {
198
+ "access": "public"
199
+ },
200
+ "repository": {
201
+ "type": "git",
202
+ "url": "git+https://github.com/fungi-computer/tourtois.git"
203
+ },
204
+ "scripts": {
205
+ "clean": "node --input-type=module --eval \"import { rm } from 'node:fs/promises'; await rm('dist', { recursive: true, force: true });\"",
206
+ "lint": "eslint src backend test workbench .ladle --max-warnings=0 && oxlint --config ../../oxlint.config.ts --deny-warnings src backend test workbench .ladle",
207
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.workbench.json && tsc -p backend/tsconfig.json && tsc -p test/workerd/tsconfig.json",
208
+ "build": "pnpm run clean && tsc -p tsconfig.build.json && cp src/shell.css src/chrome.css src/spa.css src/settings-navigation.css dist/",
209
+ "build:spa": "vite build",
210
+ "dev": "vite",
211
+ "workbench": "ladle serve --host 127.0.0.1 --port 61001",
212
+ "workbench:build": "ladle build --outDir ../../.botanical/tourtois-ladle",
213
+ "test:overlay-layering": "node test/overlay-layering.browser.mjs",
214
+ "test:workbench": "node test/workbench.browser.mjs && node test/desktop-gills.browser.mjs && node test/app-directory-isolation.browser.mjs && node test/workflows-launcher-icon.browser.mjs && node test/landing-bugs.browser.mjs && node test/desktop-under-windows.browser.mjs && node test/show-desktop.browser.mjs && node test/window-stack.browser.mjs && node test/region-layers.browser.mjs && node test/window-chrome-back.browser.mjs && node test/app-bar-menu.browser.mjs && node test/launcher-gill.browser.mjs && node test/desktop-storage.browser.mjs && node test/desktop-method-editing.browser.mjs && node test/phone-desktop.browser.mjs && node test/phone-layout.browser.mjs && node test/phone-app-switcher.browser.mjs && node test/computer-choice.browser.mjs",
215
+ "test": "pnpm run test:unit && pnpm run test:merge",
216
+ "test:settings-icons": "node --import tsx ../../tooling/repository/scripts/workbench-proofs.mjs --output ../../.botanical/tourtois-ladle --origin-env TOURTOIS_WORKBENCH_URL test/settings-icons.browser.mjs",
217
+ "format:check": "node ../../tooling/repository/scripts/format-package-check.mjs",
218
+ "lint:anti-slop": "node ../../tooling/repository/scripts/lint-package-anti-slop.mjs",
219
+ "build:workbench": "pnpm run workbench:build",
220
+ "test:nightly": "node test/permission-matrix.browser.mjs && node --import tsx ../../tooling/repository/scripts/workbench-proofs.mjs --output ../../.botanical/tourtois-ladle --origin-env TOURTOIS_WORKBENCH_URL test/member-avatar.browser.mjs test/settings-icons.browser.mjs",
221
+ "test:unit": "vitest run",
222
+ "test:merge": "node test/layout-backend.native.mjs && node --import tsx test/desktop-refresh.native.mjs",
223
+ "test:app-call-permissions": "node --import tsx ../../tooling/repository/scripts/workbench-proofs.mjs --output ../../.botanical/tourtois-ladle --origin-env TOURTOIS_WORKBENCH_URL test/app-call-permissions.browser.mjs"
224
+ }
6
225
  }