@wangyaoshen/remux 0.3.8-dev.29e114b
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/.github/ISSUE_TEMPLATE/bug_report.md +47 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +38 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +28 -0
- package/.github/dependabot.yml +33 -0
- package/.github/workflows/ci.yml +65 -0
- package/.github/workflows/deploy.yml +65 -0
- package/.github/workflows/publish.yml +312 -0
- package/.github/workflows/release-please.yml +21 -0
- package/.gitmodules +3 -0
- package/.nvmrc +1 -0
- package/.release-please-manifest.json +3 -0
- package/CLAUDE.md +104 -0
- package/Dockerfile +23 -0
- package/LICENSE +21 -0
- package/README.md +120 -0
- package/apps/ios/Config/signing.xcconfig +4 -0
- package/apps/ios/Package.swift +26 -0
- package/apps/ios/Remux.xcodeproj/project.pbxproj +477 -0
- package/apps/ios/Remux.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/Contents.json +23 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_1024x1024.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_120x120.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_152x152.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_167x167.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_180x180.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_20x20.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_29x29.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_40x40.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_58x58.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_60x60.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_76x76.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_80x80.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_87x87.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/Contents.json +6 -0
- package/apps/ios/Sources/Remux/Extensions/FaceIDManager.swift +29 -0
- package/apps/ios/Sources/Remux/Extensions/InspectCache.swift +66 -0
- package/apps/ios/Sources/Remux/MainTabView.swift +32 -0
- package/apps/ios/Sources/Remux/Remux.entitlements +8 -0
- package/apps/ios/Sources/Remux/RemuxiOSApp.swift +14 -0
- package/apps/ios/Sources/Remux/RootView.swift +130 -0
- package/apps/ios/Sources/Remux/Views/Control/ControlView.swift +102 -0
- package/apps/ios/Sources/Remux/Views/Inspect/InspectView.swift +98 -0
- package/apps/ios/Sources/Remux/Views/Live/LiveTerminalView.swift +132 -0
- package/apps/ios/Sources/Remux/Views/Now/NowView.swift +173 -0
- package/apps/ios/Sources/Remux/Views/Onboarding/ManualConnectView.swift +55 -0
- package/apps/ios/Sources/Remux/Views/Onboarding/OnboardingView.swift +70 -0
- package/apps/ios/Sources/Remux/Views/Onboarding/QRScannerView.swift +92 -0
- package/apps/ios/Sources/Remux/Views/Settings/MeView.swift +136 -0
- package/apps/macos/Package.swift +37 -0
- package/apps/macos/Resources/shell-integration/bash/bash-preexec.sh +382 -0
- package/apps/macos/Resources/shell-integration/bash/ghostty.bash +315 -0
- package/apps/macos/Resources/shell-integration/elvish/lib/ghostty-integration.elv +191 -0
- package/apps/macos/Resources/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish +246 -0
- package/apps/macos/Resources/shell-integration/nushell/vendor/autoload/ghostty.nu +110 -0
- package/apps/macos/Resources/shell-integration/zsh/.zshenv +61 -0
- package/apps/macos/Resources/shell-integration/zsh/ghostty-integration +458 -0
- package/apps/macos/Resources/terminfo/67/ghostty +0 -0
- package/apps/macos/Resources/terminfo/78/xterm-ghostty +0 -0
- package/apps/macos/Sources/Remux/AppDelegate.swift +257 -0
- package/apps/macos/Sources/Remux/CrashReporter.swift +210 -0
- package/apps/macos/Sources/Remux/FinderIntegration.swift +117 -0
- package/apps/macos/Sources/Remux/GhosttyConfig.swift +311 -0
- package/apps/macos/Sources/Remux/KeyboardShortcuts/ShortcutAction.swift +115 -0
- package/apps/macos/Sources/Remux/KeyboardShortcuts/ShortcutSettingsView.swift +271 -0
- package/apps/macos/Sources/Remux/KeyboardShortcuts/StoredShortcut.swift +149 -0
- package/apps/macos/Sources/Remux/MainContentView.swift +308 -0
- package/apps/macos/Sources/Remux/MenuBarManager.swift +275 -0
- package/apps/macos/Sources/Remux/NotificationManager.swift +145 -0
- package/apps/macos/Sources/Remux/PortScanner.swift +152 -0
- package/apps/macos/Sources/Remux/RemuxApp.swift +13 -0
- package/apps/macos/Sources/Remux/SSHDetector.swift +151 -0
- package/apps/macos/Sources/Remux/SessionPersistence.swift +226 -0
- package/apps/macos/Sources/Remux/SocketController.swift +258 -0
- package/apps/macos/Sources/Remux/UpdateChecker.swift +152 -0
- package/apps/macos/Sources/Remux/Views/CommandPalette.swift +198 -0
- package/apps/macos/Sources/Remux/Views/ConnectionView.swift +84 -0
- package/apps/macos/Sources/Remux/Views/InspectView.swift +127 -0
- package/apps/macos/Sources/Remux/Views/SettingsView.swift +77 -0
- package/apps/macos/Sources/Remux/Views/Sidebar/SidebarView.swift +410 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/BrowserPanel.swift +193 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/MarkdownPanel.swift +277 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/PanelProtocol.swift +14 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/SplitNode.swift +149 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/SplitView.swift +234 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/TerminalPanel.swift +26 -0
- package/apps/macos/Sources/Remux/Views/TabBarView.swift +94 -0
- package/apps/macos/Sources/Remux/Views/Terminal/ClipboardHelper.swift +101 -0
- package/apps/macos/Sources/Remux/Views/Terminal/CopyModeOverlay.swift +325 -0
- package/apps/macos/Sources/Remux/Views/Terminal/GhosttyNativeTerminalView.swift +39 -0
- package/apps/macos/Sources/Remux/Views/Terminal/GhosttyNativeView.swift +559 -0
- package/apps/macos/Sources/Remux/Views/Terminal/SurfaceSearchOverlay.swift +109 -0
- package/apps/macos/Sources/Remux/Views/Terminal/TerminalContainerView.swift +95 -0
- package/apps/macos/Sources/Remux/Views/Terminal/TerminalRelay.swift +117 -0
- package/build.mjs +33 -0
- package/native/android/DecodeGoldenPayloads.kt +487 -0
- package/native/android/ProtocolModels.kt +188 -0
- package/native/ios/DecodeGoldenPayloads.swift +711 -0
- package/native/ios/ProtocolModels.swift +200 -0
- package/package.json +45 -0
- package/packages/RemuxKit/Package.swift +27 -0
- package/packages/RemuxKit/Sources/RemuxKit/Device/DeviceManager.swift +27 -0
- package/packages/RemuxKit/Sources/RemuxKit/Models/ProtocolModels.swift +206 -0
- package/packages/RemuxKit/Sources/RemuxKit/Networking/MessageRouter.swift +108 -0
- package/packages/RemuxKit/Sources/RemuxKit/Networking/RemuxConnection.swift +395 -0
- package/packages/RemuxKit/Sources/RemuxKit/State/RemuxState.swift +188 -0
- package/packages/RemuxKit/Sources/RemuxKit/Storage/KeychainStore.swift +142 -0
- package/packages/RemuxKit/Sources/RemuxKit/Terminal/GhosttyBridge.swift +145 -0
- package/packages/RemuxKit/Sources/RemuxKit/Terminal/GhosttyTerminalView.swift +35 -0
- package/packages/RemuxKit/Sources/RemuxKit/Terminal/Resources/ghostty-terminal.html +91 -0
- package/packages/RemuxKit/Tests/RemuxKitTests/ConnectionIntegrationTest.swift +74 -0
- package/packages/RemuxKit/Tests/RemuxKitTests/KeychainStoreTests.swift +81 -0
- package/packages/RemuxKit/Tests/RemuxKitTests/ProtocolModelsTests.swift +179 -0
- package/packages/RemuxKit/Tests/RemuxKitTests/RemuxStateTests.swift +62 -0
- package/playwright.config.ts +17 -0
- package/pnpm-lock.yaml +1588 -0
- package/pty-daemon.js +303 -0
- package/release-please-config.json +14 -0
- package/scripts/auto-deploy.sh +46 -0
- package/scripts/build-dmg.sh +121 -0
- package/scripts/build-ghostty-kit.sh +43 -0
- package/scripts/check-active-terminology.mjs +132 -0
- package/scripts/setup-ci-secrets.sh +80 -0
- package/scripts/sync-ghostty-web.sh +28 -0
- package/scripts/upload-testflight.sh +100 -0
- package/server.js +7074 -0
- package/src/adapters/agent-events.ts +246 -0
- package/src/adapters/claude-code.ts +158 -0
- package/src/adapters/codex.ts +210 -0
- package/src/adapters/generic-shell.ts +58 -0
- package/src/adapters/index.ts +15 -0
- package/src/adapters/registry.ts +99 -0
- package/src/adapters/types.ts +41 -0
- package/src/auth.ts +174 -0
- package/src/e2ee.ts +236 -0
- package/src/git-service.ts +168 -0
- package/src/message-buffer.ts +137 -0
- package/src/pty-daemon.ts +357 -0
- package/src/push.ts +127 -0
- package/src/renderers.ts +455 -0
- package/src/server.ts +2407 -0
- package/src/service.ts +226 -0
- package/src/session.ts +978 -0
- package/src/store.ts +1422 -0
- package/src/team.ts +123 -0
- package/src/tunnel.ts +126 -0
- package/src/types.d.ts +50 -0
- package/src/vt-tracker.ts +188 -0
- package/src/workspace-head.ts +144 -0
- package/src/workspace.ts +153 -0
- package/src/ws-handler.ts +1526 -0
- package/start.ps1 +83 -0
- package/tests/adapters.test.js +171 -0
- package/tests/auth.test.js +243 -0
- package/tests/codex-adapter.test.js +535 -0
- package/tests/durable-stream.test.js +153 -0
- package/tests/e2e/app.spec.js +530 -0
- package/tests/e2ee.test.js +325 -0
- package/tests/message-buffer.test.js +245 -0
- package/tests/message-routing.test.js +305 -0
- package/tests/pty-daemon.test.js +346 -0
- package/tests/push.test.js +281 -0
- package/tests/renderers.test.js +391 -0
- package/tests/search-shell.test.js +499 -0
- package/tests/server.test.js +882 -0
- package/tests/service.test.js +267 -0
- package/tests/store.test.js +369 -0
- package/tests/tunnel.test.js +67 -0
- package/tests/workspace-head.test.js +116 -0
- package/tests/workspace.test.js +417 -0
- package/tsconfig.backend.json +11 -0
- package/tsconfig.json +15 -0
- package/tui/client/client_test.go +125 -0
- package/tui/client/connection.go +342 -0
- package/tui/client/host_manager.go +141 -0
- package/tui/config/cache.go +81 -0
- package/tui/config/config.go +53 -0
- package/tui/config/config_test.go +89 -0
- package/tui/go.mod +32 -0
- package/tui/go.sum +50 -0
- package/tui/main.go +261 -0
- package/tui/tests/integration_test.go +283 -0
- package/tui/ui/model.go +310 -0
- package/vitest.config.js +10 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report a regression or defect in the current Zellij-era product path
|
|
4
|
+
title: "[bug] "
|
|
5
|
+
labels: ["bug"]
|
|
6
|
+
assignees: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
Describe the problem in one paragraph.
|
|
12
|
+
|
|
13
|
+
## Affected Layer
|
|
14
|
+
|
|
15
|
+
- [ ] backend gateway
|
|
16
|
+
- [ ] zellij integration
|
|
17
|
+
- [ ] web frontend
|
|
18
|
+
- [ ] docs / devex
|
|
19
|
+
- [ ] tests / CI
|
|
20
|
+
|
|
21
|
+
## Environment
|
|
22
|
+
|
|
23
|
+
- Remux version:
|
|
24
|
+
- Node.js version:
|
|
25
|
+
- Zellij version:
|
|
26
|
+
- Browser / device:
|
|
27
|
+
|
|
28
|
+
## Reproduction
|
|
29
|
+
|
|
30
|
+
1.
|
|
31
|
+
2.
|
|
32
|
+
3.
|
|
33
|
+
|
|
34
|
+
## Expected Behavior
|
|
35
|
+
|
|
36
|
+
What should have happened?
|
|
37
|
+
|
|
38
|
+
## Validation
|
|
39
|
+
|
|
40
|
+
- [ ] `npm run typecheck`
|
|
41
|
+
- [ ] `npm test`
|
|
42
|
+
- [ ] `npm run build`
|
|
43
|
+
|
|
44
|
+
## Notes
|
|
45
|
+
|
|
46
|
+
Include logs, screenshots, or links when relevant.
|
|
47
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Propose a feature aligned with the current Zellij-era roadmap
|
|
4
|
+
title: "[feature] "
|
|
5
|
+
labels: ["enhancement"]
|
|
6
|
+
assignees: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
What capability should Remux gain?
|
|
12
|
+
|
|
13
|
+
## Scope Bucket
|
|
14
|
+
|
|
15
|
+
- [ ] v1 must ship
|
|
16
|
+
- [ ] v1.5 optional
|
|
17
|
+
- [ ] research / future
|
|
18
|
+
|
|
19
|
+
## Surfaces
|
|
20
|
+
|
|
21
|
+
- [ ] Inspect
|
|
22
|
+
- [ ] Live
|
|
23
|
+
- [ ] Control
|
|
24
|
+
- [ ] gateway / runtime
|
|
25
|
+
- [ ] docs / devex
|
|
26
|
+
|
|
27
|
+
## User Outcome
|
|
28
|
+
|
|
29
|
+
What becomes possible or easier after this lands?
|
|
30
|
+
|
|
31
|
+
## Acceptance
|
|
32
|
+
|
|
33
|
+
How will we know the work is done?
|
|
34
|
+
|
|
35
|
+
## Risks / Dependencies
|
|
36
|
+
|
|
37
|
+
What could block or complicate this?
|
|
38
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
- what changed
|
|
4
|
+
- why it changed
|
|
5
|
+
|
|
6
|
+
## Area
|
|
7
|
+
|
|
8
|
+
- [ ] backend gateway
|
|
9
|
+
- [ ] zellij integration
|
|
10
|
+
- [ ] web frontend
|
|
11
|
+
- [ ] docs / devex
|
|
12
|
+
- [ ] tests / CI
|
|
13
|
+
|
|
14
|
+
## Validation
|
|
15
|
+
|
|
16
|
+
- [ ] `npm run check:terminology`
|
|
17
|
+
- [ ] `npm run typecheck`
|
|
18
|
+
- [ ] `npm test`
|
|
19
|
+
- [ ] `npm run build`
|
|
20
|
+
|
|
21
|
+
## Acceptance Notes
|
|
22
|
+
|
|
23
|
+
List the user-visible or maintainer-visible acceptance outcomes here.
|
|
24
|
+
|
|
25
|
+
## Risk
|
|
26
|
+
|
|
27
|
+
Call out migration risk, compatibility risk, or follow-up work.
|
|
28
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "npm"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
day: "monday"
|
|
8
|
+
time: "06:00"
|
|
9
|
+
timezone: "UTC"
|
|
10
|
+
open-pull-requests-limit: 10
|
|
11
|
+
labels:
|
|
12
|
+
- "dependencies"
|
|
13
|
+
commit-message:
|
|
14
|
+
prefix: "deps"
|
|
15
|
+
groups:
|
|
16
|
+
npm-patch-minor:
|
|
17
|
+
update-types:
|
|
18
|
+
- "minor"
|
|
19
|
+
- "patch"
|
|
20
|
+
|
|
21
|
+
- package-ecosystem: "github-actions"
|
|
22
|
+
directory: "/"
|
|
23
|
+
schedule:
|
|
24
|
+
interval: "weekly"
|
|
25
|
+
day: "monday"
|
|
26
|
+
time: "06:30"
|
|
27
|
+
timezone: "UTC"
|
|
28
|
+
open-pull-requests-limit: 5
|
|
29
|
+
labels:
|
|
30
|
+
- "dependencies"
|
|
31
|
+
- "ci"
|
|
32
|
+
commit-message:
|
|
33
|
+
prefix: "deps(ci)"
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [dev, main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [dev, main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
node-version: [20, 22]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: pnpm/action-setup@v4
|
|
18
|
+
- uses: actions/setup-node@v4
|
|
19
|
+
with:
|
|
20
|
+
node-version: ${{ matrix.node-version }}
|
|
21
|
+
cache: pnpm
|
|
22
|
+
- run: pnpm install --frozen-lockfile
|
|
23
|
+
- run: pnpm run build
|
|
24
|
+
- run: pnpm test
|
|
25
|
+
|
|
26
|
+
swift-test:
|
|
27
|
+
runs-on: macos-15
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v4
|
|
30
|
+
with:
|
|
31
|
+
submodules: recursive
|
|
32
|
+
- run: cd packages/RemuxKit && swift build && swift test
|
|
33
|
+
|
|
34
|
+
# ── Dev prerelease: publish @dev tag on push to dev ──
|
|
35
|
+
prerelease:
|
|
36
|
+
if: github.ref == 'refs/heads/dev' && github.event_name == 'push'
|
|
37
|
+
needs: test
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
permissions:
|
|
40
|
+
contents: read
|
|
41
|
+
id-token: write
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v4
|
|
44
|
+
- uses: pnpm/action-setup@v4
|
|
45
|
+
- uses: actions/setup-node@v4
|
|
46
|
+
with:
|
|
47
|
+
node-version: 22.x
|
|
48
|
+
registry-url: https://registry.npmjs.org
|
|
49
|
+
cache: pnpm
|
|
50
|
+
- run: pnpm install --frozen-lockfile
|
|
51
|
+
- run: pnpm run build
|
|
52
|
+
|
|
53
|
+
- name: Set prerelease version
|
|
54
|
+
run: |
|
|
55
|
+
BASE=$(node -p "require('./package.json').version")
|
|
56
|
+
SHA=$(git rev-parse --short HEAD)
|
|
57
|
+
PREID="${BASE}-dev.${SHA}"
|
|
58
|
+
npm version "$PREID" --no-git-tag-version
|
|
59
|
+
echo "Publishing @wangyaoshen/remux@${PREID} to @dev tag"
|
|
60
|
+
|
|
61
|
+
- name: Publish @dev
|
|
62
|
+
run: pnpm publish --access public --no-git-checks --tag dev
|
|
63
|
+
continue-on-error: true
|
|
64
|
+
env:
|
|
65
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: Deploy
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, dev]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
branch:
|
|
9
|
+
description: "Branch to deploy (main or dev)"
|
|
10
|
+
required: true
|
|
11
|
+
default: "dev"
|
|
12
|
+
type: choice
|
|
13
|
+
options: [main, dev]
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
deploy:
|
|
17
|
+
runs-on: [self-hosted, remux-deploy]
|
|
18
|
+
timeout-minutes: 10
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- name: Resolve target
|
|
22
|
+
id: target
|
|
23
|
+
run: |
|
|
24
|
+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
25
|
+
BRANCH="${{ inputs.branch }}"
|
|
26
|
+
else
|
|
27
|
+
BRANCH="${GITHUB_REF#refs/heads/}"
|
|
28
|
+
fi
|
|
29
|
+
echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"
|
|
30
|
+
if [ "$BRANCH" = "main" ]; then
|
|
31
|
+
echo "app=remux-main" >> "$GITHUB_OUTPUT"
|
|
32
|
+
echo "worktree=$HOME/.remux/runtime-worktrees/runtime-main" >> "$GITHUB_OUTPUT"
|
|
33
|
+
else
|
|
34
|
+
echo "app=remux-dev" >> "$GITHUB_OUTPUT"
|
|
35
|
+
echo "worktree=$HOME/.remux/runtime-worktrees/runtime-dev" >> "$GITHUB_OUTPUT"
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
- name: Pull latest code
|
|
39
|
+
working-directory: ${{ steps.target.outputs.worktree }}
|
|
40
|
+
run: |
|
|
41
|
+
git fetch origin ${{ steps.target.outputs.branch }}
|
|
42
|
+
git checkout --detach origin/${{ steps.target.outputs.branch }}
|
|
43
|
+
|
|
44
|
+
- name: Install dependencies
|
|
45
|
+
working-directory: ${{ steps.target.outputs.worktree }}
|
|
46
|
+
run: |
|
|
47
|
+
# Use the same Node.js that the launchd service runs (node@20)
|
|
48
|
+
# to ensure native modules (better-sqlite3, node-pty) are compiled
|
|
49
|
+
# for the correct NODE_MODULE_VERSION
|
|
50
|
+
export PATH="/opt/homebrew/opt/node@20/bin:$PATH"
|
|
51
|
+
node --version
|
|
52
|
+
pnpm install
|
|
53
|
+
|
|
54
|
+
- name: Build
|
|
55
|
+
working-directory: ${{ steps.target.outputs.worktree }}
|
|
56
|
+
run: |
|
|
57
|
+
export PATH="/opt/homebrew/opt/node@20/bin:$PATH"
|
|
58
|
+
pnpm run build
|
|
59
|
+
|
|
60
|
+
- name: Restart launchd service
|
|
61
|
+
run: |
|
|
62
|
+
SERVICE="com.remux.${{ steps.target.outputs.branch }}"
|
|
63
|
+
launchctl kickstart -k "gui/$(id -u)/${SERVICE}"
|
|
64
|
+
sleep 2
|
|
65
|
+
launchctl print "gui/$(id -u)/${SERVICE}" 2>&1 | head -5
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
# Triggered by release-please creating a tag, or manual tag push
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
tags: ['v[0-9]+.[0-9]+.[0-9]+']
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
# ── npm publish (@latest) ────────────────────────────
|
|
10
|
+
npm:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
id-token: write
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: pnpm/action-setup@v4
|
|
18
|
+
- uses: actions/setup-node@v4
|
|
19
|
+
with:
|
|
20
|
+
node-version: 22.x
|
|
21
|
+
registry-url: https://registry.npmjs.org
|
|
22
|
+
cache: pnpm
|
|
23
|
+
- run: pnpm install --frozen-lockfile
|
|
24
|
+
- run: pnpm run build
|
|
25
|
+
- run: pnpm test
|
|
26
|
+
- run: pnpm publish --access public --no-git-checks --provenance
|
|
27
|
+
env:
|
|
28
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
29
|
+
|
|
30
|
+
# ── Docker image → ghcr.io ──────────────────────────
|
|
31
|
+
docker:
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
permissions:
|
|
34
|
+
contents: read
|
|
35
|
+
packages: write
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- uses: docker/login-action@v3
|
|
39
|
+
with:
|
|
40
|
+
registry: ghcr.io
|
|
41
|
+
username: ${{ github.actor }}
|
|
42
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
43
|
+
- uses: docker/metadata-action@v5
|
|
44
|
+
id: meta
|
|
45
|
+
with:
|
|
46
|
+
images: ghcr.io/${{ github.repository }}
|
|
47
|
+
tags: |
|
|
48
|
+
type=semver,pattern={{version}}
|
|
49
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
50
|
+
type=raw,value=latest
|
|
51
|
+
- uses: docker/build-push-action@v6
|
|
52
|
+
with:
|
|
53
|
+
context: .
|
|
54
|
+
push: true
|
|
55
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
56
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
57
|
+
|
|
58
|
+
# ── iOS → TestFlight ─────────────────────────────────
|
|
59
|
+
ios:
|
|
60
|
+
runs-on: macos-15
|
|
61
|
+
permissions:
|
|
62
|
+
contents: read
|
|
63
|
+
steps:
|
|
64
|
+
- uses: actions/checkout@v4
|
|
65
|
+
with:
|
|
66
|
+
submodules: recursive
|
|
67
|
+
|
|
68
|
+
- name: Set up signing
|
|
69
|
+
env:
|
|
70
|
+
CERTIFICATES_P12: ${{ secrets.APPLE_CERTIFICATES_P12 }}
|
|
71
|
+
CERTIFICATES_PASSWORD: ${{ secrets.APPLE_CERTIFICATES_PASSWORD }}
|
|
72
|
+
API_KEY_P8: ${{ secrets.APP_STORE_CONNECT_API_KEY_P8 }}
|
|
73
|
+
API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
|
74
|
+
run: |
|
|
75
|
+
# Create temporary keychain
|
|
76
|
+
KEYCHAIN_PATH="$RUNNER_TEMP/signing.keychain-db"
|
|
77
|
+
KEYCHAIN_PASSWORD="$(openssl rand -hex 16)"
|
|
78
|
+
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
|
79
|
+
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
|
|
80
|
+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
|
81
|
+
|
|
82
|
+
# Import certificates
|
|
83
|
+
echo "$CERTIFICATES_P12" | base64 --decode > "$RUNNER_TEMP/certs.p12"
|
|
84
|
+
security import "$RUNNER_TEMP/certs.p12" \
|
|
85
|
+
-P "$CERTIFICATES_PASSWORD" \
|
|
86
|
+
-A -t cert -f pkcs12 \
|
|
87
|
+
-k "$KEYCHAIN_PATH"
|
|
88
|
+
security set-key-partition-list -S apple-tool:,apple:,codesign: \
|
|
89
|
+
-s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
|
90
|
+
|
|
91
|
+
# Add keychain to search list
|
|
92
|
+
security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | tr -d '"')
|
|
93
|
+
|
|
94
|
+
# Install Apple WWDR G3 intermediate cert
|
|
95
|
+
curl -sO https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer
|
|
96
|
+
sudo security add-certificates -k /Library/Keychains/System.keychain AppleWWDRCAG3.cer
|
|
97
|
+
|
|
98
|
+
# Set up API key
|
|
99
|
+
mkdir -p ~/.private_keys
|
|
100
|
+
echo "$API_KEY_P8" | base64 --decode > ~/.private_keys/AuthKey_${API_KEY_ID}.p8
|
|
101
|
+
|
|
102
|
+
# Verify
|
|
103
|
+
security find-identity -v -p codesigning "$KEYCHAIN_PATH"
|
|
104
|
+
|
|
105
|
+
- name: Archive
|
|
106
|
+
env:
|
|
107
|
+
API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
|
108
|
+
API_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
|
|
109
|
+
run: |
|
|
110
|
+
TAG="${GITHUB_REF#refs/tags/}"
|
|
111
|
+
VERSION="${TAG#v}"
|
|
112
|
+
|
|
113
|
+
xcodebuild archive \
|
|
114
|
+
-project apps/ios/Remux.xcodeproj \
|
|
115
|
+
-scheme Remux \
|
|
116
|
+
-destination 'generic/platform=iOS' \
|
|
117
|
+
-archivePath "$RUNNER_TEMP/Remux.xcarchive" \
|
|
118
|
+
-allowProvisioningUpdates \
|
|
119
|
+
-authenticationKeyPath ~/.private_keys/AuthKey_${API_KEY_ID}.p8 \
|
|
120
|
+
-authenticationKeyID "$API_KEY_ID" \
|
|
121
|
+
-authenticationKeyIssuerID "$API_ISSUER_ID" \
|
|
122
|
+
CURRENT_PROJECT_VERSION="$(git rev-list --count HEAD)" \
|
|
123
|
+
MARKETING_VERSION="$VERSION" \
|
|
124
|
+
-quiet
|
|
125
|
+
|
|
126
|
+
- name: Export IPA
|
|
127
|
+
env:
|
|
128
|
+
API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
|
129
|
+
API_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
|
|
130
|
+
run: |
|
|
131
|
+
cat > "$RUNNER_TEMP/ExportOptions.plist" << 'PLIST'
|
|
132
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
133
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
134
|
+
<plist version="1.0">
|
|
135
|
+
<dict>
|
|
136
|
+
<key>method</key>
|
|
137
|
+
<string>app-store-connect</string>
|
|
138
|
+
<key>signingStyle</key>
|
|
139
|
+
<string>automatic</string>
|
|
140
|
+
<key>uploadSymbols</key>
|
|
141
|
+
<true/>
|
|
142
|
+
<key>manageAppVersionAndBuildNumber</key>
|
|
143
|
+
<true/>
|
|
144
|
+
</dict>
|
|
145
|
+
</plist>
|
|
146
|
+
PLIST
|
|
147
|
+
|
|
148
|
+
xcodebuild -exportArchive \
|
|
149
|
+
-archivePath "$RUNNER_TEMP/Remux.xcarchive" \
|
|
150
|
+
-exportOptionsPlist "$RUNNER_TEMP/ExportOptions.plist" \
|
|
151
|
+
-exportPath "$RUNNER_TEMP/export" \
|
|
152
|
+
-allowProvisioningUpdates \
|
|
153
|
+
-authenticationKeyPath ~/.private_keys/AuthKey_${API_KEY_ID}.p8 \
|
|
154
|
+
-authenticationKeyID "$API_KEY_ID" \
|
|
155
|
+
-authenticationKeyIssuerID "$API_ISSUER_ID" \
|
|
156
|
+
-quiet
|
|
157
|
+
|
|
158
|
+
- name: Upload to TestFlight
|
|
159
|
+
env:
|
|
160
|
+
API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
|
161
|
+
API_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
|
|
162
|
+
run: |
|
|
163
|
+
IPA=$(find "$RUNNER_TEMP/export" -name "*.ipa" | head -1)
|
|
164
|
+
xcrun altool --upload-app --type ios \
|
|
165
|
+
--file "$IPA" \
|
|
166
|
+
--apiKey "$API_KEY_ID" \
|
|
167
|
+
--apiIssuer "$API_ISSUER_ID"
|
|
168
|
+
|
|
169
|
+
- name: Set export compliance
|
|
170
|
+
run: |
|
|
171
|
+
pip3 install PyJWT cryptography
|
|
172
|
+
python3 << 'PYEOF'
|
|
173
|
+
import jwt, time, json, urllib.request, os
|
|
174
|
+
|
|
175
|
+
with open(os.path.expanduser(f"~/.private_keys/AuthKey_{os.environ['API_KEY_ID']}.p8")) as f:
|
|
176
|
+
key = f.read()
|
|
177
|
+
token = jwt.encode(
|
|
178
|
+
{"iss": os.environ["API_ISSUER_ID"], "iat": int(time.time()),
|
|
179
|
+
"exp": int(time.time()) + 1200, "aud": "appstoreconnect-v1"},
|
|
180
|
+
key, algorithm="ES256",
|
|
181
|
+
headers={"kid": os.environ["API_KEY_ID"], "typ": "JWT"})
|
|
182
|
+
|
|
183
|
+
# Find latest build
|
|
184
|
+
req = urllib.request.Request(
|
|
185
|
+
f"https://api.appstoreconnect.apple.com/v1/builds?filter[app]=6761521429&sort=-uploadedDate&limit=1",
|
|
186
|
+
headers={"Authorization": f"Bearer {token}"})
|
|
187
|
+
data = json.loads(urllib.request.urlopen(req).read())
|
|
188
|
+
build_id = data["data"][0]["id"]
|
|
189
|
+
|
|
190
|
+
# Set usesNonExemptEncryption = false
|
|
191
|
+
body = json.dumps({"data": {"type": "builds", "id": build_id,
|
|
192
|
+
"attributes": {"usesNonExemptEncryption": False}}}).encode()
|
|
193
|
+
req = urllib.request.Request(
|
|
194
|
+
f"https://api.appstoreconnect.apple.com/v1/builds/{build_id}",
|
|
195
|
+
data=body, method="PATCH",
|
|
196
|
+
headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"})
|
|
197
|
+
urllib.request.urlopen(req)
|
|
198
|
+
print(f"✓ Export compliance set for build {build_id}")
|
|
199
|
+
PYEOF
|
|
200
|
+
env:
|
|
201
|
+
API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
|
202
|
+
API_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
|
|
203
|
+
|
|
204
|
+
- name: Clean up keychain
|
|
205
|
+
if: always()
|
|
206
|
+
run: security delete-keychain "$RUNNER_TEMP/signing.keychain-db" 2>/dev/null || true
|
|
207
|
+
|
|
208
|
+
# ── macOS app (.dmg) → signed + notarized + GitHub Release ──
|
|
209
|
+
# Runs on self-hosted runner (Mac Mini) which has Developer ID cert installed
|
|
210
|
+
macos:
|
|
211
|
+
runs-on: [self-hosted, remux-deploy]
|
|
212
|
+
permissions:
|
|
213
|
+
contents: write
|
|
214
|
+
steps:
|
|
215
|
+
- uses: actions/checkout@v4
|
|
216
|
+
with:
|
|
217
|
+
submodules: recursive
|
|
218
|
+
|
|
219
|
+
- name: Verify signing identity
|
|
220
|
+
run: |
|
|
221
|
+
security find-identity -v -p codesigning | grep "Developer ID Application"
|
|
222
|
+
|
|
223
|
+
- name: Build GhosttyKit xcframework (if needed)
|
|
224
|
+
run: |
|
|
225
|
+
XCFW="vendor/ghostty/macos/GhosttyKit.xcframework"
|
|
226
|
+
if [ ! -d "$XCFW" ] || [ ! -f "$XCFW/Info.plist" ]; then
|
|
227
|
+
cd vendor/ghostty
|
|
228
|
+
zig build -Demit-xcframework=true -Dxcframework-target=native -Doptimize=ReleaseFast
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
- name: Build, sign, and notarize DMG
|
|
232
|
+
env:
|
|
233
|
+
API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
|
234
|
+
API_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
|
|
235
|
+
TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
236
|
+
run: |
|
|
237
|
+
TAG="${GITHUB_REF#refs/tags/}"
|
|
238
|
+
VERSION="${TAG#v}"
|
|
239
|
+
|
|
240
|
+
# Build .app and DMG
|
|
241
|
+
bash scripts/build-dmg.sh "$VERSION"
|
|
242
|
+
|
|
243
|
+
# Sign with Developer ID + hardened runtime + timestamp
|
|
244
|
+
codesign --force --deep --options runtime --timestamp \
|
|
245
|
+
--sign "Developer ID Application: Yaoshen Wang ($TEAM_ID)" \
|
|
246
|
+
"build/Remux.app"
|
|
247
|
+
|
|
248
|
+
# Rebuild DMG with signed app
|
|
249
|
+
DMG="build/Remux-${VERSION}-arm64.dmg"
|
|
250
|
+
rm -f "$DMG"
|
|
251
|
+
hdiutil create -volname "Remux" \
|
|
252
|
+
-srcfolder build/Remux.app \
|
|
253
|
+
-ov -format UDZO "$DMG"
|
|
254
|
+
codesign --force --timestamp \
|
|
255
|
+
--sign "Developer ID Application: Yaoshen Wang ($TEAM_ID)" "$DMG"
|
|
256
|
+
|
|
257
|
+
# Notarize
|
|
258
|
+
xcrun notarytool submit "$DMG" \
|
|
259
|
+
--key ~/.private_keys/AuthKey_${API_KEY_ID}.p8 \
|
|
260
|
+
--key-id "$API_KEY_ID" \
|
|
261
|
+
--issuer "$API_ISSUER_ID" \
|
|
262
|
+
--wait
|
|
263
|
+
|
|
264
|
+
xcrun stapler staple "$DMG"
|
|
265
|
+
|
|
266
|
+
- name: Upload DMG to GitHub Release
|
|
267
|
+
env:
|
|
268
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
269
|
+
run: |
|
|
270
|
+
TAG="${GITHUB_REF#refs/tags/}"
|
|
271
|
+
VERSION="${TAG#v}"
|
|
272
|
+
DMG="build/Remux-${VERSION}-arm64.dmg"
|
|
273
|
+
|
|
274
|
+
if [ -f "$DMG" ]; then
|
|
275
|
+
gh release upload "$TAG" "$DMG" --clobber
|
|
276
|
+
echo "✓ Uploaded $DMG to release $TAG"
|
|
277
|
+
fi
|
|
278
|
+
|
|
279
|
+
# ── Update Homebrew tap ─────────────────────────────
|
|
280
|
+
homebrew:
|
|
281
|
+
needs: [npm, macos]
|
|
282
|
+
runs-on: ubuntu-latest
|
|
283
|
+
permissions:
|
|
284
|
+
contents: read
|
|
285
|
+
steps:
|
|
286
|
+
- uses: actions/checkout@v4
|
|
287
|
+
|
|
288
|
+
- name: Update Homebrew formula and cask
|
|
289
|
+
env:
|
|
290
|
+
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
|
|
291
|
+
run: |
|
|
292
|
+
TAG="${GITHUB_REF#refs/tags/}"
|
|
293
|
+
VERSION="${TAG#v}"
|
|
294
|
+
|
|
295
|
+
git clone https://x-access-token:${GH_TOKEN}@github.com/yaoshenwang/homebrew-tap /tmp/tap
|
|
296
|
+
cd /tmp/tap
|
|
297
|
+
|
|
298
|
+
# Update cask version
|
|
299
|
+
sed -i "s/version \".*\"/version \"${VERSION}\"/" Casks/remux-app.rb
|
|
300
|
+
|
|
301
|
+
# Update formula URL
|
|
302
|
+
sed -i "s|remux-.*\.tgz|remux-${VERSION}.tgz|" Formula/remux.rb
|
|
303
|
+
|
|
304
|
+
# Compute sha256 for npm tarball
|
|
305
|
+
NPM_SHA=$(curl -sL "https://registry.npmjs.org/@wangyaoshen/remux/-/remux-${VERSION}.tgz" | sha256sum | cut -d' ' -f1)
|
|
306
|
+
sed -i "s/sha256 \".*\"/sha256 \"${NPM_SHA}\"/" Formula/remux.rb
|
|
307
|
+
|
|
308
|
+
git config user.name "github-actions[bot]"
|
|
309
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
310
|
+
git add -A
|
|
311
|
+
git diff --cached --quiet || git commit -m "Update to v${VERSION}"
|
|
312
|
+
git push origin main
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Release Please
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: write
|
|
9
|
+
pull-requests: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
release-please:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
outputs:
|
|
15
|
+
release_created: ${{ steps.release.outputs.release_created }}
|
|
16
|
+
tag_name: ${{ steps.release.outputs.tag_name }}
|
|
17
|
+
steps:
|
|
18
|
+
- uses: googleapis/release-please-action@v4
|
|
19
|
+
id: release
|
|
20
|
+
with:
|
|
21
|
+
release-type: node
|
package/.gitmodules
ADDED
package/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
25
|