@lattices/cli 0.4.14 → 0.5.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/README.md +5 -7
- package/apps/mac/Info.plist +2 -2
- package/apps/mac/Lattices.app/Contents/Info.plist +4 -12
- package/apps/mac/Lattices.app/Contents/MacOS/Lattices +0 -0
- package/bin/lattices-app.ts +110 -17
- package/bin/lattices-build +125 -0
- package/bin/lattices-dev +89 -16
- package/bin/lattices.ts +977 -16
- package/docs/agents.md +81 -4
- package/docs/ai-chat-ux-review.md +416 -0
- package/docs/api.md +135 -3
- package/docs/app.md +30 -8
- package/docs/config.md +4 -0
- package/docs/mouse-gestures.md +60 -1
- package/docs/proposals/LAT-004-interactive-overlay-actors.md +1 -1
- package/docs/proposals/LAT-005-action-runtime-product-spine.md +914 -0
- package/docs/proposals/LAT-006-mira-in-lattices.md +553 -0
- package/docs/reference/dewey.config.ts +2 -2
- package/docs/release.md +171 -0
- package/docs/repo-structure.md +4 -5
- package/docs/voice.md +11 -27
- package/package.json +9 -10
- package/apps/mac/Package.swift +0 -27
- package/apps/mac/Sources/AppShell/App.swift +0 -26
- package/apps/mac/Sources/AppShell/AppActivationCoordinator.swift +0 -27
- package/apps/mac/Sources/AppShell/AppDelegate.swift +0 -189
- package/apps/mac/Sources/AppShell/AppServicesBootstrap.swift +0 -25
- package/apps/mac/Sources/AppShell/AppShellView.swift +0 -171
- package/apps/mac/Sources/AppShell/AppUpdater.swift +0 -305
- package/apps/mac/Sources/AppShell/CliActionLauncher.swift +0 -50
- package/apps/mac/Sources/AppShell/HomeDashboardView.swift +0 -133
- package/apps/mac/Sources/AppShell/HotkeyBootstrap.swift +0 -87
- package/apps/mac/Sources/AppShell/KeyRecorderView.swift +0 -210
- package/apps/mac/Sources/AppShell/LatticesRuntime.swift +0 -104
- package/apps/mac/Sources/AppShell/MainView.swift +0 -847
- package/apps/mac/Sources/AppShell/MainWindow.swift +0 -83
- package/apps/mac/Sources/AppShell/MenuBarController.swift +0 -177
- package/apps/mac/Sources/AppShell/OnboardingView.swift +0 -483
- package/apps/mac/Sources/AppShell/PermissionsAssistantView.swift +0 -366
- package/apps/mac/Sources/AppShell/PermissionsAssistantWindow.swift +0 -70
- package/apps/mac/Sources/AppShell/Preferences.swift +0 -297
- package/apps/mac/Sources/AppShell/SettingsView.swift +0 -3163
- package/apps/mac/Sources/AppShell/SettingsWindow.swift +0 -34
- package/apps/mac/Sources/AppShell/WorkspaceInspectorPresenter.swift +0 -13
- package/apps/mac/Sources/Core/Actions/HotkeyManager.swift +0 -256
- package/apps/mac/Sources/Core/Actions/HotkeyStore.swift +0 -399
- package/apps/mac/Sources/Core/Actions/IntentEngine.swift +0 -988
- package/apps/mac/Sources/Core/Actions/IntentSchema.swift +0 -94
- package/apps/mac/Sources/Core/Actions/Intents/CreateLayerIntent.swift +0 -54
- package/apps/mac/Sources/Core/Actions/Intents/DistributeIntent.swift +0 -56
- package/apps/mac/Sources/Core/Actions/Intents/FocusIntent.swift +0 -69
- package/apps/mac/Sources/Core/Actions/Intents/HelpIntent.swift +0 -41
- package/apps/mac/Sources/Core/Actions/Intents/KillIntent.swift +0 -47
- package/apps/mac/Sources/Core/Actions/Intents/LatticeIntent.swift +0 -53
- package/apps/mac/Sources/Core/Actions/Intents/LaunchIntent.swift +0 -67
- package/apps/mac/Sources/Core/Actions/Intents/ListSessionsIntent.swift +0 -32
- package/apps/mac/Sources/Core/Actions/Intents/ListWindowsIntent.swift +0 -30
- package/apps/mac/Sources/Core/Actions/Intents/ScanIntent.swift +0 -52
- package/apps/mac/Sources/Core/Actions/Intents/SearchIntent.swift +0 -190
- package/apps/mac/Sources/Core/Actions/Intents/SwitchLayerIntent.swift +0 -50
- package/apps/mac/Sources/Core/Actions/Intents/TileIntent.swift +0 -61
- package/apps/mac/Sources/Core/Actions/PaletteCommand.swift +0 -439
- package/apps/mac/Sources/Core/Actions/VoiceIntentResolver.swift +0 -713
- package/apps/mac/Sources/Core/Companion/CompanionActivityLog.swift +0 -70
- package/apps/mac/Sources/Core/Companion/CompanionKeyboardController.swift +0 -141
- package/apps/mac/Sources/Core/Companion/LatticesCompanionBridgeServer.swift +0 -454
- package/apps/mac/Sources/Core/Companion/LatticesCompanionCockpit.swift +0 -555
- package/apps/mac/Sources/Core/Companion/LatticesCompanionSecurityCoordinator.swift +0 -629
- package/apps/mac/Sources/Core/Companion/LatticesCompanionTrackpadController.swift +0 -204
- package/apps/mac/Sources/Core/Companion/LatticesDeckHost.swift +0 -1463
- package/apps/mac/Sources/Core/Daemon/DaemonProtocol.swift +0 -114
- package/apps/mac/Sources/Core/Daemon/DaemonServer.swift +0 -427
- package/apps/mac/Sources/Core/Daemon/LatticesApi.swift +0 -2965
- package/apps/mac/Sources/Core/Desktop/AccessibilityTextExtractor.swift +0 -111
- package/apps/mac/Sources/Core/Desktop/AppTypeClassifier.swift +0 -106
- package/apps/mac/Sources/Core/Desktop/DesktopModel.swift +0 -331
- package/apps/mac/Sources/Core/Desktop/DesktopModelTypes.swift +0 -73
- package/apps/mac/Sources/Core/Desktop/InventoryManager.swift +0 -35
- package/apps/mac/Sources/Core/Desktop/InventoryPath.swift +0 -43
- package/apps/mac/Sources/Core/Desktop/MouseFinder.swift +0 -527
- package/apps/mac/Sources/Core/Desktop/OcrModel.swift +0 -467
- package/apps/mac/Sources/Core/Desktop/OcrStore.swift +0 -329
- package/apps/mac/Sources/Core/Desktop/PlacementSpec.swift +0 -195
- package/apps/mac/Sources/Core/Desktop/SessionWindowLocator.swift +0 -139
- package/apps/mac/Sources/Core/Desktop/TilePickerView.swift +0 -209
- package/apps/mac/Sources/Core/Desktop/WindowCapture.swift +0 -33
- package/apps/mac/Sources/Core/Desktop/WindowDragSnapController.swift +0 -429
- package/apps/mac/Sources/Core/Desktop/WindowPreviewCard.swift +0 -100
- package/apps/mac/Sources/Core/Desktop/WindowPreviewStore.swift +0 -112
- package/apps/mac/Sources/Core/Desktop/WindowSelectionStore.swift +0 -76
- package/apps/mac/Sources/Core/Desktop/WindowTiler.swift +0 -2222
- package/apps/mac/Sources/Core/Input/EventTapBreaker.swift +0 -124
- package/apps/mac/Sources/Core/Input/EventTapThread.swift +0 -54
- package/apps/mac/Sources/Core/Input/InputCaptureResetCenter.swift +0 -20
- package/apps/mac/Sources/Core/Input/KeyboardRemapConfig.swift +0 -69
- package/apps/mac/Sources/Core/Input/KeyboardRemapController.swift +0 -346
- package/apps/mac/Sources/Core/Input/KeyboardRemapStore.swift +0 -141
- package/apps/mac/Sources/Core/Input/MouseGestureConfig.swift +0 -499
- package/apps/mac/Sources/Core/Input/MouseGestureController.swift +0 -2583
- package/apps/mac/Sources/Core/Input/MouseInputDeviceStore.swift +0 -98
- package/apps/mac/Sources/Core/Input/MouseInputEventViewer.swift +0 -272
- package/apps/mac/Sources/Core/Input/MouseShortcutStore.swift +0 -170
- package/apps/mac/Sources/Core/Input/SecureEventInputMonitor.swift +0 -39
- package/apps/mac/Sources/Core/Input/ShapeRecognizer.swift +0 -624
- package/apps/mac/Sources/Core/Input/TapBudgetMeter.swift +0 -56
- package/apps/mac/Sources/Core/Overlays/AppWindowShell.swift +0 -63
- package/apps/mac/Sources/Core/Overlays/CommandMode/CommandModeState.swift +0 -1566
- package/apps/mac/Sources/Core/Overlays/CommandMode/CommandModeView.swift +0 -1927
- package/apps/mac/Sources/Core/Overlays/CommandMode/CommandModeWindow.swift +0 -196
- package/apps/mac/Sources/Core/Overlays/CommandPalette/CommandPaletteView.swift +0 -307
- package/apps/mac/Sources/Core/Overlays/CommandPalette/CommandPaletteWindow.swift +0 -67
- package/apps/mac/Sources/Core/Overlays/HUD/CheatSheetHUD.swift +0 -576
- package/apps/mac/Sources/Core/Overlays/HUD/HUDBottomBar.swift +0 -279
- package/apps/mac/Sources/Core/Overlays/HUD/HUDController.swift +0 -1158
- package/apps/mac/Sources/Core/Overlays/HUD/HUDLeftBar.swift +0 -849
- package/apps/mac/Sources/Core/Overlays/HUD/HUDMinimap.swift +0 -179
- package/apps/mac/Sources/Core/Overlays/HUD/HUDRightBar.swift +0 -596
- package/apps/mac/Sources/Core/Overlays/HUD/HUDState.swift +0 -367
- package/apps/mac/Sources/Core/Overlays/HUD/HUDTopBar.swift +0 -243
- package/apps/mac/Sources/Core/Overlays/HUD/LauncherHUD.swift +0 -334
- package/apps/mac/Sources/Core/Overlays/HUD/LayerBezel.swift +0 -203
- package/apps/mac/Sources/Core/Overlays/OmniSearch/OmniSearchState.swift +0 -280
- package/apps/mac/Sources/Core/Overlays/OmniSearch/OmniSearchView.swift +0 -422
- package/apps/mac/Sources/Core/Overlays/OmniSearch/OmniSearchWindow.swift +0 -94
- package/apps/mac/Sources/Core/Overlays/OverlayPanelShell.swift +0 -241
- package/apps/mac/Sources/Core/Overlays/ScreenMap/ScreenMapState.swift +0 -3135
- package/apps/mac/Sources/Core/Overlays/ScreenMap/ScreenMapView.swift +0 -3977
- package/apps/mac/Sources/Core/Overlays/ScreenMap/ScreenMapWindowController.swift +0 -119
- package/apps/mac/Sources/Core/Overlays/ScreenOverlayCanvasController.swift +0 -1217
- package/apps/mac/Sources/Core/Overlays/Voice/VoiceCommandWindow.swift +0 -1575
- package/apps/mac/Sources/Core/Pi/PiAuthNextStepCard.swift +0 -148
- package/apps/mac/Sources/Core/Pi/PiAuthPromptCard.swift +0 -90
- package/apps/mac/Sources/Core/Pi/PiChatDock.swift +0 -564
- package/apps/mac/Sources/Core/Pi/PiChatSession.swift +0 -1948
- package/apps/mac/Sources/Core/Pi/PiInstallCallout.swift +0 -86
- package/apps/mac/Sources/Core/Pi/PiProviderSetupCallout.swift +0 -99
- package/apps/mac/Sources/Core/Pi/PiWorkspaceView.swift +0 -510
- package/apps/mac/Sources/Core/System/Capability.swift +0 -79
- package/apps/mac/Sources/Core/System/DiagnosticLog.swift +0 -373
- package/apps/mac/Sources/Core/System/EventBus.swift +0 -31
- package/apps/mac/Sources/Core/System/PermissionChecker.swift +0 -224
- package/apps/mac/Sources/Core/System/ProcessModel.swift +0 -199
- package/apps/mac/Sources/Core/System/ProcessQuery.swift +0 -151
- package/apps/mac/Sources/Core/System/SystemTelemetryMonitor.swift +0 -273
- package/apps/mac/Sources/Core/Voice/AdvisorLearningStore.swift +0 -90
- package/apps/mac/Sources/Core/Voice/AgentSession.swift +0 -377
- package/apps/mac/Sources/Core/Voice/AudioProvider.swift +0 -555
- package/apps/mac/Sources/Core/Voice/HandsOffSession.swift +0 -839
- package/apps/mac/Sources/Core/Voice/VoiceChatView.swift +0 -192
- package/apps/mac/Sources/Core/Voice/VoxClient.swift +0 -454
- package/apps/mac/Sources/Core/Workspace/Project.swift +0 -28
- package/apps/mac/Sources/Core/Workspace/ProjectScanner.swift +0 -141
- package/apps/mac/Sources/Core/Workspace/SessionLayerStore.swift +0 -285
- package/apps/mac/Sources/Core/Workspace/SessionManager.swift +0 -75
- package/apps/mac/Sources/Core/Workspace/Terminal/Terminal.swift +0 -259
- package/apps/mac/Sources/Core/Workspace/Terminal/TerminalQuery.swift +0 -156
- package/apps/mac/Sources/Core/Workspace/Terminal/TerminalSynthesizer.swift +0 -200
- package/apps/mac/Sources/Core/Workspace/Tmux/TmuxModel.swift +0 -60
- package/apps/mac/Sources/Core/Workspace/Tmux/TmuxQuery.swift +0 -105
- package/apps/mac/Sources/Core/Workspace/WorkspaceManager.swift +0 -1027
- package/apps/mac/Sources/UI/ActionRow.swift +0 -78
- package/apps/mac/Sources/UI/OrphanRow.swift +0 -129
- package/apps/mac/Sources/UI/ProjectRow.swift +0 -368
- package/apps/mac/Sources/UI/TabGroupRow.swift +0 -178
- package/apps/mac/Sources/UI/Theme.swift +0 -164
- package/apps/mac/Tests/StageDragTests.swift +0 -333
- package/apps/mac/Tests/StageJoinTests.swift +0 -313
- package/apps/mac/Tests/StageManagerTests.swift +0 -280
- package/apps/mac/Tests/StageTileTests.swift +0 -353
- package/swift/Package.swift +0 -20
- package/swift/Sources/DeckKit/DeckAction.swift +0 -51
- package/swift/Sources/DeckKit/DeckBridgeSecurity.swift +0 -152
- package/swift/Sources/DeckKit/DeckCockpit.swift +0 -82
- package/swift/Sources/DeckKit/DeckHost.swift +0 -7
- package/swift/Sources/DeckKit/DeckManifest.swift +0 -145
- package/swift/Sources/DeckKit/DeckRuntimeSnapshot.swift +0 -533
- package/swift/Sources/DeckKit/DeckTrackpad.swift +0 -63
- package/swift/Sources/DeckKit/DeckValue.swift +0 -93
- package/swift/Sources/DeckKit/DeckVoiceError.swift +0 -88
- package/swift/Tests/DeckKitTests/DeckKitTests.swift +0 -286
package/README.md
CHANGED
|
@@ -42,15 +42,11 @@ The CLI and app work independently — use either or both.
|
|
|
42
42
|
git clone https://github.com/arach/lattices.git
|
|
43
43
|
cd lattices
|
|
44
44
|
|
|
45
|
-
# Build the menu bar app (requires Swift 6.2 / Xcode 26+)
|
|
46
|
-
cd apps/mac && swift build -c release && cd ../..
|
|
47
|
-
|
|
48
45
|
# Install CLI dependencies
|
|
49
46
|
npm install
|
|
50
47
|
|
|
51
|
-
#
|
|
52
|
-
|
|
53
|
-
bun bin/lattices-app.ts # launch it
|
|
48
|
+
# Build/install/relaunch the dev app at the stable permission target
|
|
49
|
+
./run.sh
|
|
54
50
|
```
|
|
55
51
|
|
|
56
52
|
To build a signed, notarized DMG for distribution:
|
|
@@ -59,10 +55,12 @@ To build a signed, notarized DMG for distribution:
|
|
|
59
55
|
# Requires a Developer ID certificate and notarytool keychain profile
|
|
60
56
|
./tools/release/build-dmg.sh
|
|
61
57
|
|
|
62
|
-
#
|
|
58
|
+
# Create/update v<package.json version> and upload DMG assets
|
|
63
59
|
./tools/release/ship.sh
|
|
64
60
|
```
|
|
65
61
|
|
|
62
|
+
See [Release](docs/release.md) for the CI and local maintainer workflows.
|
|
63
|
+
|
|
66
64
|
## Quick start
|
|
67
65
|
|
|
68
66
|
```sh
|
package/apps/mac/Info.plist
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<plist version="1.0">
|
|
4
4
|
<dict>
|
|
5
5
|
<key>CFBundleIdentifier</key>
|
|
6
|
-
<string>
|
|
6
|
+
<string>dev.lattices.app</string>
|
|
7
7
|
<key>CFBundleName</key>
|
|
8
8
|
<string>Lattices</string>
|
|
9
9
|
<key>CFBundleDisplayName</key>
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<array>
|
|
19
19
|
<dict>
|
|
20
20
|
<key>CFBundleURLName</key>
|
|
21
|
-
<string>
|
|
21
|
+
<string>dev.lattices.app</string>
|
|
22
22
|
<key>CFBundleURLSchemes</key>
|
|
23
23
|
<array>
|
|
24
24
|
<string>lattices</string>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<plist version="1.0">
|
|
4
4
|
<dict>
|
|
5
5
|
<key>CFBundleIdentifier</key>
|
|
6
|
-
<string>
|
|
6
|
+
<string>dev.lattices.app</string>
|
|
7
7
|
<key>CFBundleName</key>
|
|
8
8
|
<string>Lattices</string>
|
|
9
9
|
<key>CFBundleDisplayName</key>
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<array>
|
|
19
19
|
<dict>
|
|
20
20
|
<key>CFBundleURLName</key>
|
|
21
|
-
<string>
|
|
21
|
+
<string>dev.lattices.app</string>
|
|
22
22
|
<key>CFBundleURLSchemes</key>
|
|
23
23
|
<array>
|
|
24
24
|
<string>lattices</string>
|
|
@@ -26,17 +26,9 @@
|
|
|
26
26
|
</dict>
|
|
27
27
|
</array>
|
|
28
28
|
<key>CFBundleVersion</key>
|
|
29
|
-
<string>0.
|
|
29
|
+
<string>0.5.0</string>
|
|
30
30
|
<key>CFBundleShortVersionString</key>
|
|
31
|
-
<string>0.
|
|
32
|
-
<key>LatticesBuildChannel</key>
|
|
33
|
-
<string>dev</string>
|
|
34
|
-
<key>LatticesBuildTrack</key>
|
|
35
|
-
<string>latest</string>
|
|
36
|
-
<key>LatticesBuildRevision</key>
|
|
37
|
-
<string>5aace7d</string>
|
|
38
|
-
<key>LatticesBuildTimestamp</key>
|
|
39
|
-
<string>2026-05-05T15:30:06Z</string>
|
|
31
|
+
<string>0.5.0</string>
|
|
40
32
|
<key>LSMinimumSystemVersion</key>
|
|
41
33
|
<string>13.0</string>
|
|
42
34
|
<key>LSUIElement</key>
|
|
Binary file
|
package/bin/lattices-app.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
-
import { execSync, spawn } from "node:child_process";
|
|
3
|
+
import { execFileSync, execSync, spawn } from "node:child_process";
|
|
4
4
|
import { existsSync, mkdirSync, chmodSync, createWriteStream, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { join, resolve } from "node:path";
|
|
@@ -23,6 +23,8 @@ const RELEASE_APP_ASSET_NAMES = ["Lattices.dmg"];
|
|
|
23
23
|
const RELEASE_BINARY_ASSET_NAMES = ["Lattices-macos-arm64", "LatticeApp-macos-arm64"];
|
|
24
24
|
type ReleaseAsset = { name: string; browser_download_url: string };
|
|
25
25
|
const selfScriptPath = resolve(__dirname, "lattices-app.ts");
|
|
26
|
+
const CAPS_LOCK_HID_USAGE = 0x700000039;
|
|
27
|
+
const F18_HID_USAGE = 0x70000006D;
|
|
26
28
|
|
|
27
29
|
// ── Helpers ──────────────────────────────────────────────────────────
|
|
28
30
|
|
|
@@ -35,21 +37,112 @@ function isRunning(): boolean {
|
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
function
|
|
40
|
+
function sleep(ms: number): void {
|
|
41
|
+
execFileSync("/bin/sleep", [(ms / 1000).toString()], { stdio: "ignore" });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function waitForExit(timeoutMs: number): boolean {
|
|
45
|
+
const deadline = Date.now() + timeoutMs;
|
|
46
|
+
while (Date.now() < deadline) {
|
|
47
|
+
if (!isRunning()) return true;
|
|
48
|
+
sleep(100);
|
|
49
|
+
}
|
|
50
|
+
return !isRunning();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
type HIDKeyboardMapping = { src: number; dst: number };
|
|
54
|
+
|
|
55
|
+
function hasOwnedCapsLockTransportMapping(): boolean {
|
|
39
56
|
try {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
execSync("pkill -9 -x Lattices", { stdio: "pipe" });
|
|
46
|
-
}
|
|
47
|
-
return true;
|
|
57
|
+
return execFileSync(
|
|
58
|
+
"/usr/bin/defaults",
|
|
59
|
+
["read", "dev.lattices.app", "keyboardRemaps.capsLockHIDTransportOwned"],
|
|
60
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }
|
|
61
|
+
).trim() === "1";
|
|
48
62
|
} catch {
|
|
49
63
|
return false;
|
|
50
64
|
}
|
|
51
65
|
}
|
|
52
66
|
|
|
67
|
+
function readHIDKeyboardMappings(): HIDKeyboardMapping[] {
|
|
68
|
+
try {
|
|
69
|
+
const output = execFileSync(
|
|
70
|
+
"/usr/bin/hidutil",
|
|
71
|
+
["property", "--get", "UserKeyMapping"],
|
|
72
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }
|
|
73
|
+
);
|
|
74
|
+
return Array.from(output.matchAll(/HIDKeyboardModifierMappingDst\s*=\s*(\d+);\s*HIDKeyboardModifierMappingSrc\s*=\s*(\d+);/g))
|
|
75
|
+
.map((match) => ({ dst: Number(match[1]), src: Number(match[2]) }));
|
|
76
|
+
} catch {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function writeHIDKeyboardMappings(mappings: HIDKeyboardMapping[]): void {
|
|
82
|
+
const pairs = mappings.map((mapping) => ({
|
|
83
|
+
HIDKeyboardModifierMappingSrc: mapping.src,
|
|
84
|
+
HIDKeyboardModifierMappingDst: mapping.dst,
|
|
85
|
+
}));
|
|
86
|
+
execFileSync(
|
|
87
|
+
"/usr/bin/hidutil",
|
|
88
|
+
["property", "--set", JSON.stringify({ UserKeyMapping: pairs })],
|
|
89
|
+
{ stdio: "ignore" }
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function clearOwnedCapsLockTransportMapping(): void {
|
|
94
|
+
if (!hasOwnedCapsLockTransportMapping()) return;
|
|
95
|
+
|
|
96
|
+
const mappings = readHIDKeyboardMappings();
|
|
97
|
+
const filtered = mappings.filter((mapping) => (
|
|
98
|
+
mapping.src !== CAPS_LOCK_HID_USAGE || mapping.dst !== F18_HID_USAGE
|
|
99
|
+
));
|
|
100
|
+
|
|
101
|
+
if (filtered.length !== mappings.length) {
|
|
102
|
+
try {
|
|
103
|
+
writeHIDKeyboardMappings(filtered);
|
|
104
|
+
} catch {
|
|
105
|
+
console.log("Warning: failed to clear Caps Lock HID transport mapping.");
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
execFileSync("/usr/bin/defaults", ["delete", "dev.lattices.app", "keyboardRemaps.capsLockHIDTransportOwned"], { stdio: "ignore" });
|
|
112
|
+
} catch {}
|
|
113
|
+
try {
|
|
114
|
+
execFileSync("/usr/bin/defaults", ["delete", "dev.lattices.app", "keyboardRemaps.capsLockHIDTransportOriginalMappings"], { stdio: "ignore" });
|
|
115
|
+
} catch {}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function quit(): boolean {
|
|
119
|
+
if (!isRunning()) {
|
|
120
|
+
clearOwnedCapsLockTransportMapping();
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
execFileSync(
|
|
126
|
+
"/usr/bin/osascript",
|
|
127
|
+
["-e", 'tell application id "dev.lattices.app" to quit'],
|
|
128
|
+
{ stdio: "ignore" }
|
|
129
|
+
);
|
|
130
|
+
} catch {}
|
|
131
|
+
|
|
132
|
+
if (!waitForExit(2_000)) {
|
|
133
|
+
try { execSync("pkill -x Lattices", { stdio: "pipe" }); } catch {}
|
|
134
|
+
waitForExit(1_000);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (isRunning()) {
|
|
138
|
+
try { execSync("pkill -9 -x Lattices", { stdio: "pipe" }); } catch {}
|
|
139
|
+
waitForExit(500);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
clearOwnedCapsLockTransportMapping();
|
|
143
|
+
return !isRunning();
|
|
144
|
+
}
|
|
145
|
+
|
|
53
146
|
function hasSwift(): boolean {
|
|
54
147
|
try {
|
|
55
148
|
execSync("which swift", { stdio: "pipe" });
|
|
@@ -112,8 +205,8 @@ function relaunchIfNeeded(shouldLaunch: boolean, extraArgs: string[] = []): void
|
|
|
112
205
|
function resolveSigningIdentity(): string | null {
|
|
113
206
|
try {
|
|
114
207
|
const identities = execSync("security find-identity -v -p codesigning", { stdio: "pipe" }).toString();
|
|
115
|
-
return identities.match(
|
|
116
|
-
|| identities.match(
|
|
208
|
+
return identities.match(/^\s*\d+\)\s+([A-F0-9]{40})\s+"Developer ID Application:[^"]+"/m)?.[1]
|
|
209
|
+
|| identities.match(/^\s*\d+\)\s+([A-F0-9]{40})\s+"Apple Development:[^"]+"/m)?.[1]
|
|
117
210
|
|| null;
|
|
118
211
|
} catch {
|
|
119
212
|
return null;
|
|
@@ -133,7 +226,7 @@ function signBundle(): void {
|
|
|
133
226
|
console.log(`Signing with: ${identity}`);
|
|
134
227
|
try {
|
|
135
228
|
execSync(
|
|
136
|
-
`codesign --force --sign '${identity}'${entFlag} --identifier
|
|
229
|
+
`codesign --force --options runtime --deep --sign '${identity}'${entFlag} --identifier dev.lattices.app '${bundlePath}'`,
|
|
137
230
|
{ stdio: "pipe" }
|
|
138
231
|
);
|
|
139
232
|
return;
|
|
@@ -145,7 +238,7 @@ function signBundle(): void {
|
|
|
145
238
|
}
|
|
146
239
|
|
|
147
240
|
execSync(
|
|
148
|
-
`codesign --force --sign -${entFlag} --identifier
|
|
241
|
+
`codesign --force --options runtime --deep --sign -${entFlag} --identifier dev.lattices.app '${bundlePath}'`,
|
|
149
242
|
{ stdio: "pipe" }
|
|
150
243
|
);
|
|
151
244
|
|
|
@@ -188,7 +281,7 @@ function writeInfoPlist(metadata: BundleBuildMetadata = {}): void {
|
|
|
188
281
|
<plist version="1.0">
|
|
189
282
|
<dict>
|
|
190
283
|
<key>CFBundleIdentifier</key>
|
|
191
|
-
<string>
|
|
284
|
+
<string>dev.lattices.app</string>
|
|
192
285
|
<key>CFBundleName</key>
|
|
193
286
|
<string>Lattices</string>
|
|
194
287
|
<key>CFBundleDisplayName</key>
|
|
@@ -203,7 +296,7 @@ function writeInfoPlist(metadata: BundleBuildMetadata = {}): void {
|
|
|
203
296
|
<array>
|
|
204
297
|
<dict>
|
|
205
298
|
<key>CFBundleURLName</key>
|
|
206
|
-
<string>
|
|
299
|
+
<string>dev.lattices.app</string>
|
|
207
300
|
<key>CFBundleURLSchemes</key>
|
|
208
301
|
<array>
|
|
209
302
|
<string>lattices</string>
|
|
@@ -256,7 +349,7 @@ function buildFromSource(): boolean {
|
|
|
256
349
|
|
|
257
350
|
mkdirSync(binaryDir, { recursive: true });
|
|
258
351
|
execSync(`cp '${builtPath}' '${binaryPath}'`);
|
|
259
|
-
writeInfoPlist(
|
|
352
|
+
writeInfoPlist();
|
|
260
353
|
syncBundleResources();
|
|
261
354
|
|
|
262
355
|
// Re-sign the bundle so macOS TCC recognizes a stable identity across rebuilds.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# lattices-build - explicit dev/package/dist build entry points
|
|
3
|
+
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
SCRIPT_PATH="$(readlink -f "$0" 2>/dev/null || python3 -c "import os,sys; print(os.path.realpath(sys.argv[1]))" "$0")"
|
|
7
|
+
ROOT="$(cd "$(dirname "$SCRIPT_PATH")/.." && pwd)"
|
|
8
|
+
|
|
9
|
+
DEV_APPS_DIR="${LATTICES_DEV_APPS_DIR:-$HOME/Applications/dev/Lattices}"
|
|
10
|
+
DEV_BUNDLE="${LATTICES_DEV_APP:-$DEV_APPS_DIR/Lattices.app}"
|
|
11
|
+
DEV_BUNDLE_ID="${LATTICES_DEV_BUNDLE_ID:-dev.lattices.app.dev}"
|
|
12
|
+
RELEASE_BUNDLE="$ROOT/apps/mac/Lattices.app"
|
|
13
|
+
RELEASE_BUNDLE_ID="dev.lattices.app"
|
|
14
|
+
DIST_BUNDLE="$ROOT/dist/Lattices.app"
|
|
15
|
+
DIST_DMG="$ROOT/dist/Lattices.dmg"
|
|
16
|
+
PROD_INSTALL_BUNDLE="/Applications/Lattices.app"
|
|
17
|
+
|
|
18
|
+
green() { printf "\033[32m%s\033[0m\n" "$*"; }
|
|
19
|
+
dim() { printf "\033[2m%s\033[0m\n" "$*"; }
|
|
20
|
+
red() { printf "\033[31m%s\033[0m\n" "$*"; }
|
|
21
|
+
|
|
22
|
+
usage() {
|
|
23
|
+
cat <<EOF
|
|
24
|
+
lattices-build - build Lattices without mixing dev and release identities
|
|
25
|
+
|
|
26
|
+
Usage:
|
|
27
|
+
bin/lattices-build dev Build/install dev app
|
|
28
|
+
bin/lattices-build dev:restart Build/install/relaunch dev app
|
|
29
|
+
bin/lattices-build package Build repo app bundle for npm packaging
|
|
30
|
+
bin/lattices-build dist Build signed/notarized release DMG
|
|
31
|
+
bin/lattices-build dist:local Build local release DMG without notarizing
|
|
32
|
+
bin/lattices-build where Show canonical paths and bundle ids
|
|
33
|
+
|
|
34
|
+
Channels:
|
|
35
|
+
dev $DEV_BUNDLE_ID -> $DEV_BUNDLE
|
|
36
|
+
release $RELEASE_BUNDLE_ID -> $PROD_INSTALL_BUNDLE via $DIST_DMG
|
|
37
|
+
EOF
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
plist_value() {
|
|
41
|
+
local app="$1"
|
|
42
|
+
local key="$2"
|
|
43
|
+
[ -d "$app" ] || return 0
|
|
44
|
+
/usr/bin/defaults read "$app/Contents/Info.plist" "$key" 2>/dev/null || true
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
show_app() {
|
|
48
|
+
local label="$1"
|
|
49
|
+
local app="$2"
|
|
50
|
+
|
|
51
|
+
echo "$label"
|
|
52
|
+
echo " path: $app"
|
|
53
|
+
if [ -d "$app" ]; then
|
|
54
|
+
echo " bundle id: $(plist_value "$app" CFBundleIdentifier)"
|
|
55
|
+
echo " channel: $(plist_value "$app" LatticesBuildChannel)"
|
|
56
|
+
echo " built at: $(plist_value "$app" LatticesBuildTimestamp)"
|
|
57
|
+
else
|
|
58
|
+
echo " status: not built"
|
|
59
|
+
fi
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
cmd_dev() {
|
|
63
|
+
"$ROOT/bin/lattices-dev" build
|
|
64
|
+
show_app "Dev app" "$DEV_BUNDLE"
|
|
65
|
+
green "Dev permission target: $DEV_BUNDLE"
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
cmd_dev_restart() {
|
|
69
|
+
"$ROOT/bin/lattices-dev" restart
|
|
70
|
+
show_app "Running dev app" "$DEV_BUNDLE"
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
cmd_package() {
|
|
74
|
+
if ! command -v bun >/dev/null 2>&1; then
|
|
75
|
+
red "bun is required for package builds."
|
|
76
|
+
exit 1
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
bun "$ROOT/bin/lattices-app.ts" build
|
|
80
|
+
show_app "Package app bundle" "$RELEASE_BUNDLE"
|
|
81
|
+
green "Package bundle ready: $RELEASE_BUNDLE"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
cmd_dist() {
|
|
85
|
+
"$ROOT/tools/release/build-dmg.sh" "$@"
|
|
86
|
+
show_app "Release app artifact" "$DIST_BUNDLE"
|
|
87
|
+
[ -f "$DIST_DMG" ] && ls -lh "$DIST_DMG"
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
cmd_dist_local() {
|
|
91
|
+
LATTICES_SKIP_NOTARIZE=1 "$ROOT/tools/release/build-dmg.sh" "$@"
|
|
92
|
+
show_app "Local release app artifact" "$DIST_BUNDLE"
|
|
93
|
+
[ -f "$DIST_DMG" ] && ls -lh "$DIST_DMG"
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
cmd_where() {
|
|
97
|
+
show_app "Dev app" "$DEV_BUNDLE"
|
|
98
|
+
echo " expected bundle id: $DEV_BUNDLE_ID"
|
|
99
|
+
echo
|
|
100
|
+
show_app "Package app bundle" "$RELEASE_BUNDLE"
|
|
101
|
+
echo " expected bundle id: $RELEASE_BUNDLE_ID"
|
|
102
|
+
echo
|
|
103
|
+
show_app "Release app artifact" "$DIST_BUNDLE"
|
|
104
|
+
echo " expected install target: $PROD_INSTALL_BUNDLE"
|
|
105
|
+
[ -f "$DIST_DMG" ] && echo " dmg: $DIST_DMG"
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
cmd="${1:-help}"
|
|
109
|
+
shift || true
|
|
110
|
+
|
|
111
|
+
case "$cmd" in
|
|
112
|
+
dev) cmd_dev ;;
|
|
113
|
+
dev:restart|restart) cmd_dev_restart ;;
|
|
114
|
+
package) cmd_package ;;
|
|
115
|
+
dist) cmd_dist "$@" ;;
|
|
116
|
+
dist:local) cmd_dist_local "$@" ;;
|
|
117
|
+
where) cmd_where ;;
|
|
118
|
+
help|-h|--help) usage ;;
|
|
119
|
+
*)
|
|
120
|
+
red "Unknown command: $cmd"
|
|
121
|
+
echo
|
|
122
|
+
usage
|
|
123
|
+
exit 1
|
|
124
|
+
;;
|
|
125
|
+
esac
|
package/bin/lattices-dev
CHANGED
|
@@ -8,10 +8,14 @@ APP_DIR="$(cd "$(dirname "$SCRIPT_PATH")/../apps/mac" && pwd)"
|
|
|
8
8
|
ROOT="$(cd "$(dirname "$SCRIPT_PATH")/.." && pwd)"
|
|
9
9
|
LOG_FILE="$HOME/.lattices/lattices.log"
|
|
10
10
|
BINARY="$APP_DIR/.build/release/Lattices"
|
|
11
|
-
|
|
11
|
+
BUILD_BASE="$ROOT/build/macos/Lattices"
|
|
12
|
+
BUNDLE="$BUILD_BASE/Build/Products/Debug/Lattices.app"
|
|
13
|
+
DEV_APPS_DIR="${LATTICES_DEV_APPS_DIR:-$HOME/Applications/dev/Lattices}"
|
|
14
|
+
INSTALL_BUNDLE="${LATTICES_DEV_APP:-$DEV_APPS_DIR/Lattices.app}"
|
|
12
15
|
BUNDLE_BIN="$BUNDLE/Contents/MacOS/Lattices"
|
|
13
16
|
RESOURCES_DIR="$BUNDLE/Contents/Resources"
|
|
14
17
|
ENTITLEMENTS="$APP_DIR/Lattices.entitlements"
|
|
18
|
+
BUNDLE_ID="${LATTICES_DEV_BUNDLE_ID:-dev.lattices.app.dev}"
|
|
15
19
|
ICON="$ROOT/assets/AppIcon.icns"
|
|
16
20
|
TAP_SOUND="$APP_DIR/Resources/tap.wav"
|
|
17
21
|
VERSION="$(node -p "require('$ROOT/package.json').version" 2>/dev/null || echo '0.1.0')"
|
|
@@ -25,9 +29,14 @@ dim() { printf "\033[2m%s\033[0m\n" "$*"; }
|
|
|
25
29
|
select_sign_identity() {
|
|
26
30
|
local identities identity=""
|
|
27
31
|
identities="$(security find-identity -v -p codesigning 2>/dev/null || true)"
|
|
28
|
-
|
|
32
|
+
# Prefer Developer ID Application: its designated requirement pins to the stable
|
|
33
|
+
# team OU, so TCC permissions survive rebuilds and Apple Development cert rotations.
|
|
34
|
+
# Apple Development is only a fallback (its DR pins a specific cert that Xcode rotates,
|
|
35
|
+
# which silently resets every granted permission). Keep this order in sync with
|
|
36
|
+
# resolveSigningIdentity() in bin/lattices-app.ts.
|
|
37
|
+
identity="$(printf '%s\n' "$identities" | sed -n 's/^[[:space:]]*[0-9]*)[[:space:]]*\([A-F0-9]\{40\}\)[[:space:]]*"Developer ID Application:[^"]*".*/\1/p' | head -n 1)"
|
|
29
38
|
if [ -z "$identity" ]; then
|
|
30
|
-
identity="$(printf '%s\n' "$identities" | sed -n 's
|
|
39
|
+
identity="$(printf '%s\n' "$identities" | sed -n 's/^[[:space:]]*[0-9]*)[[:space:]]*\([A-F0-9]\{40\}\)[[:space:]]*"Apple Development:[^"]*".*/\1/p' | head -n 1)"
|
|
31
40
|
fi
|
|
32
41
|
printf '%s' "$identity"
|
|
33
42
|
}
|
|
@@ -45,7 +54,7 @@ sign_bundle() {
|
|
|
45
54
|
identity="$(select_sign_identity)"
|
|
46
55
|
if [ -n "$identity" ]; then
|
|
47
56
|
dim "Signing with: $identity"
|
|
48
|
-
if ! codesign --force --sign "$identity" "${ent_flags[@]}" --identifier
|
|
57
|
+
if ! codesign --force --options runtime --deep --sign "$identity" "${ent_flags[@]}" --identifier "$BUNDLE_ID" "$BUNDLE"; then
|
|
49
58
|
red "Signing with '$identity' failed. Falling back to ad-hoc."
|
|
50
59
|
sign_status=1
|
|
51
60
|
fi
|
|
@@ -55,12 +64,62 @@ sign_bundle() {
|
|
|
55
64
|
|
|
56
65
|
if [ "$sign_status" -ne 0 ]; then
|
|
57
66
|
dim "No usable signing identity found. Using ad-hoc signature."
|
|
58
|
-
codesign --force --sign - "${ent_flags[@]}" --identifier
|
|
67
|
+
codesign --force --options runtime --deep --sign - "${ent_flags[@]}" --identifier "$BUNDLE_ID" "$BUNDLE"
|
|
59
68
|
fi
|
|
60
69
|
|
|
61
70
|
rm -f "$BUNDLE_BIN".cstemp
|
|
62
71
|
}
|
|
63
72
|
|
|
73
|
+
sync_bundle_copy() {
|
|
74
|
+
local destination="$1"
|
|
75
|
+
|
|
76
|
+
mkdir -p "$(dirname "$destination")"
|
|
77
|
+
rm -rf "$destination"
|
|
78
|
+
ditto "$BUNDLE" "$destination"
|
|
79
|
+
xattr -dr com.apple.quarantine "$destination" 2>/dev/null || true
|
|
80
|
+
touch "$destination" "$destination/Contents"
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
ensure_install_bundle() {
|
|
84
|
+
if [ -d "$INSTALL_BUNDLE" ]; then
|
|
85
|
+
return
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
if [ -d "$BUNDLE" ]; then
|
|
89
|
+
sync_bundle_copy "$INSTALL_BUNDLE"
|
|
90
|
+
return
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
cmd_build
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
clear_lattices_drag_cache() {
|
|
97
|
+
local cache_dir
|
|
98
|
+
|
|
99
|
+
for cache_dir in "$HOME"/Library/Caches/com.apple.SwiftUI.Drag-*; do
|
|
100
|
+
[ -d "$cache_dir" ] || continue
|
|
101
|
+
if [ -d "$cache_dir/Lattices.app" ]; then
|
|
102
|
+
rm -rf "$cache_dir/Lattices.app"
|
|
103
|
+
rmdir "$cache_dir" 2>/dev/null || true
|
|
104
|
+
fi
|
|
105
|
+
done
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
is_install_bundle_running() {
|
|
109
|
+
local target="$INSTALL_BUNDLE/Contents/MacOS/Lattices"
|
|
110
|
+
local pid args
|
|
111
|
+
|
|
112
|
+
while IFS= read -r pid; do
|
|
113
|
+
[ -n "$pid" ] || continue
|
|
114
|
+
args="$(ps -p "$pid" -o args= 2>/dev/null || true)"
|
|
115
|
+
case "$args" in
|
|
116
|
+
"$target"|"${target} "*) return 0 ;;
|
|
117
|
+
esac
|
|
118
|
+
done < <(pgrep -x Lattices 2>/dev/null || true)
|
|
119
|
+
|
|
120
|
+
return 1
|
|
121
|
+
}
|
|
122
|
+
|
|
64
123
|
write_info_plist() {
|
|
65
124
|
mkdir -p "$BUNDLE/Contents"
|
|
66
125
|
cat > "$BUNDLE/Contents/Info.plist" <<PLIST
|
|
@@ -69,7 +128,7 @@ write_info_plist() {
|
|
|
69
128
|
<plist version="1.0">
|
|
70
129
|
<dict>
|
|
71
130
|
<key>CFBundleIdentifier</key>
|
|
72
|
-
<string
|
|
131
|
+
<string>$BUNDLE_ID</string>
|
|
73
132
|
<key>CFBundleName</key>
|
|
74
133
|
<string>Lattices</string>
|
|
75
134
|
<key>CFBundleDisplayName</key>
|
|
@@ -84,7 +143,7 @@ write_info_plist() {
|
|
|
84
143
|
<array>
|
|
85
144
|
<dict>
|
|
86
145
|
<key>CFBundleURLName</key>
|
|
87
|
-
<string
|
|
146
|
+
<string>$BUNDLE_ID</string>
|
|
88
147
|
<key>CFBundleURLSchemes</key>
|
|
89
148
|
<array>
|
|
90
149
|
<string>lattices</string>
|
|
@@ -117,10 +176,11 @@ PLIST
|
|
|
117
176
|
}
|
|
118
177
|
|
|
119
178
|
cmd_build() {
|
|
120
|
-
echo "Building
|
|
179
|
+
echo "Building dev app..."
|
|
121
180
|
cd "$APP_DIR" && swift build -c release
|
|
122
|
-
#
|
|
123
|
-
|
|
181
|
+
# Build into a repo-local dev artifact, then install to a stable app path
|
|
182
|
+
# that macOS permissions can trust across rebuilds.
|
|
183
|
+
rm -rf "$BUNDLE"
|
|
124
184
|
mkdir -p "$(dirname "$BUNDLE_BIN")" "$RESOURCES_DIR"
|
|
125
185
|
cp "$BINARY" "$BUNDLE_BIN"
|
|
126
186
|
if [ -f "$ICON" ]; then
|
|
@@ -132,18 +192,26 @@ cmd_build() {
|
|
|
132
192
|
write_info_plist
|
|
133
193
|
# Re-sign so TCC permissions persist across rebuilds
|
|
134
194
|
sign_bundle
|
|
195
|
+
touch "$BUNDLE" "$BUNDLE/Contents"
|
|
196
|
+
sync_bundle_copy "$INSTALL_BUNDLE"
|
|
197
|
+
clear_lattices_drag_cache
|
|
135
198
|
green "Build complete."
|
|
199
|
+
dim "Installed: $INSTALL_BUNDLE"
|
|
136
200
|
}
|
|
137
201
|
|
|
138
202
|
cmd_restart() {
|
|
139
203
|
echo "Restarting Lattices..."
|
|
204
|
+
/usr/bin/osascript -e 'tell application id "dev.lattices.app.dev" to quit' >/dev/null 2>&1 || true
|
|
205
|
+
/usr/bin/osascript -e 'tell application id "dev.lattices.app" to quit' >/dev/null 2>&1 || true
|
|
140
206
|
pkill -x Lattices 2>/dev/null && sleep 1 || true
|
|
141
207
|
cmd_build
|
|
142
|
-
open "$
|
|
208
|
+
open "$INSTALL_BUNDLE" --args --lattices-cli-root "$ROOT" "$@"
|
|
143
209
|
green "Lattices restarted."
|
|
144
210
|
}
|
|
145
211
|
|
|
146
212
|
cmd_quit() {
|
|
213
|
+
/usr/bin/osascript -e 'tell application id "dev.lattices.app.dev" to quit' >/dev/null 2>&1 || true
|
|
214
|
+
/usr/bin/osascript -e 'tell application id "dev.lattices.app" to quit' >/dev/null 2>&1 || true
|
|
147
215
|
if pkill -x Lattices 2>/dev/null; then
|
|
148
216
|
green "Lattices stopped."
|
|
149
217
|
else
|
|
@@ -152,10 +220,15 @@ cmd_quit() {
|
|
|
152
220
|
}
|
|
153
221
|
|
|
154
222
|
cmd_launch() {
|
|
155
|
-
if
|
|
156
|
-
dim "Lattices is already running."
|
|
223
|
+
if is_install_bundle_running; then
|
|
224
|
+
dim "Lattices dev app is already running."
|
|
157
225
|
else
|
|
158
|
-
|
|
226
|
+
if pgrep -x Lattices >/dev/null 2>&1; then
|
|
227
|
+
dim "A different Lattices bundle is running. Switching to the dev permission target."
|
|
228
|
+
cmd_quit
|
|
229
|
+
fi
|
|
230
|
+
ensure_install_bundle
|
|
231
|
+
open "$INSTALL_BUNDLE" --args --lattices-cli-root "$ROOT" "$@"
|
|
159
232
|
green "Lattices launched."
|
|
160
233
|
fi
|
|
161
234
|
}
|
|
@@ -249,10 +322,10 @@ cmd_help() {
|
|
|
249
322
|
case "${1:-help}" in
|
|
250
323
|
link) cmd_link ;;
|
|
251
324
|
unlink) cmd_unlink ;;
|
|
252
|
-
restart) cmd_restart ;;
|
|
325
|
+
restart) cmd_restart "${@:2}" ;;
|
|
253
326
|
build) cmd_build ;;
|
|
254
327
|
quit|stop) cmd_quit ;;
|
|
255
|
-
launch|start) cmd_launch ;;
|
|
328
|
+
launch|start) cmd_launch "${@:2}" ;;
|
|
256
329
|
logs) cmd_logs ;;
|
|
257
330
|
log) cmd_log "${2:-30}" ;;
|
|
258
331
|
clear-logs) cmd_clear_logs ;;
|