@akiojin/gwt 9.11.10 → 9.11.11
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.ja.md +1 -1
- package/README.md +1 -1
- package/bin/gwt.cjs +9 -73
- package/bin/gwtd.cjs +24 -0
- package/bin/launcher.cjs +84 -0
- package/installers/macos/install.sh +87 -0
- package/installers/macos/uninstall.sh +38 -0
- package/package.json +3 -2
- package/scripts/test_release_assets.cjs +27 -0
package/README.ja.md
CHANGED
|
@@ -12,7 +12,7 @@ gwt は Git worktree の管理と、`Claude Code` / `Codex` / `Gemini` /
|
|
|
12
12
|
|
|
13
13
|
- GUI 向けの主配布物: `gwt-macos-universal.dmg`
|
|
14
14
|
- マウントした DMG から `GWT.app` を開くとネイティブ GUI をそのまま起動できます
|
|
15
|
-
- `PATH` に `gwtd` CLI を入れたい場合は install script を使います
|
|
15
|
+
- `PATH` に `gwt` / `gwtd` CLI を入れたい場合は install script を使います
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
curl -fsSL https://raw.githubusercontent.com/akiojin/gwt/main/installers/macos/install.sh | bash
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ Download the release asset for your platform from
|
|
|
14
14
|
|
|
15
15
|
- GUI-first installer: `gwt-macos-universal.dmg`
|
|
16
16
|
- Open `GWT.app` from the mounted DMG for the native desktop launch surface
|
|
17
|
-
- Use the install script when you want the `gwtd`
|
|
17
|
+
- Use the install script when you want the `gwt` and `gwtd` CLIs in your `PATH`
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
curl -fsSL https://raw.githubusercontent.com/akiojin/gwt/main/installers/macos/install.sh | bash
|
package/bin/gwt.cjs
CHANGED
|
@@ -5,84 +5,20 @@
|
|
|
5
5
|
* it will be downloaded on-demand from GitHub Releases.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
const {
|
|
9
|
-
const
|
|
10
|
-
const fs = require("fs");
|
|
8
|
+
const { binaryNameForPlatform } = require("../scripts/release-assets.cjs");
|
|
9
|
+
const { createLauncher } = require("./launcher.cjs");
|
|
11
10
|
|
|
12
|
-
const {
|
|
13
|
-
|
|
11
|
+
const launcher = createLauncher({
|
|
12
|
+
commandName: "gwt",
|
|
14
13
|
binaryNameForPlatform,
|
|
15
|
-
|
|
16
|
-
releaseAssetUrl,
|
|
17
|
-
} = require("../scripts/release-assets.cjs");
|
|
18
|
-
|
|
19
|
-
const REPO = "akiojin/gwt";
|
|
20
|
-
const BIN_DIR = __dirname;
|
|
21
|
-
const BIN_NAME = binaryNameForPlatform(process.platform);
|
|
22
|
-
const BIN_PATH = path.join(BIN_DIR, BIN_NAME);
|
|
23
|
-
const BUNDLE_BINARIES = bundleBinaryNamesForPlatform(process.platform);
|
|
24
|
-
|
|
25
|
-
function readVersion() {
|
|
26
|
-
const pkg = path.join(__dirname, "..", "package.json");
|
|
27
|
-
return JSON.parse(fs.readFileSync(pkg, "utf8")).version;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async function ensureBinary() {
|
|
31
|
-
if (BUNDLE_BINARIES.every((name) => fs.existsSync(path.join(BIN_DIR, name)))) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const version = readVersion();
|
|
36
|
-
const { url } = releaseAssetUrl(REPO, version, process.platform, process.arch);
|
|
37
|
-
|
|
38
|
-
console.log(`Downloading gwt bundle for ${process.platform}-${process.arch}...`);
|
|
39
|
-
console.log(`Downloading from: ${url}`);
|
|
40
|
-
|
|
41
|
-
await installReleaseBinary({
|
|
42
|
-
repo: REPO,
|
|
43
|
-
version,
|
|
44
|
-
binDir: BIN_DIR,
|
|
45
|
-
platform: process.platform,
|
|
46
|
-
arch: process.arch,
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
console.log(`gwt bundle installed successfully: ${BUNDLE_BINARIES.join(", ")}`);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async function main() {
|
|
53
|
-
try {
|
|
54
|
-
await ensureBinary();
|
|
55
|
-
} catch (err) {
|
|
56
|
-
console.error(`Failed to download gwt binary: ${err.message}`);
|
|
57
|
-
console.error(`https://github.com/${REPO}/releases`);
|
|
58
|
-
process.exit(1);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const child = spawn(BIN_PATH, process.argv.slice(2), {
|
|
62
|
-
stdio: "inherit",
|
|
63
|
-
env: process.env,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
child.on("error", (err) => {
|
|
67
|
-
console.error(`Failed to start gwt: ${err.message}`);
|
|
68
|
-
process.exit(1);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
child.on("exit", (code, signal) => {
|
|
72
|
-
if (signal) {
|
|
73
|
-
process.kill(process.pid, signal);
|
|
74
|
-
} else {
|
|
75
|
-
process.exit(code ?? 0);
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
}
|
|
14
|
+
});
|
|
79
15
|
|
|
80
16
|
if (require.main === module) {
|
|
81
|
-
main();
|
|
17
|
+
launcher.main();
|
|
82
18
|
}
|
|
83
19
|
|
|
84
20
|
module.exports = {
|
|
85
|
-
ensureBinary,
|
|
86
|
-
main,
|
|
87
|
-
readVersion,
|
|
21
|
+
ensureBinary: launcher.ensureBinary,
|
|
22
|
+
main: launcher.main,
|
|
23
|
+
readVersion: launcher.readVersion,
|
|
88
24
|
};
|
package/bin/gwtd.cjs
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Wrapper script to execute the gwtd Rust binary.
|
|
4
|
+
* If the bundle is not found (e.g., bunx skips postinstall),
|
|
5
|
+
* it will be downloaded on-demand from GitHub Releases.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { daemonBinaryNameForPlatform } = require("../scripts/release-assets.cjs");
|
|
9
|
+
const { createLauncher } = require("./launcher.cjs");
|
|
10
|
+
|
|
11
|
+
const launcher = createLauncher({
|
|
12
|
+
commandName: "gwtd",
|
|
13
|
+
binaryNameForPlatform: daemonBinaryNameForPlatform,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
if (require.main === module) {
|
|
17
|
+
launcher.main();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = {
|
|
21
|
+
ensureBinary: launcher.ensureBinary,
|
|
22
|
+
main: launcher.main,
|
|
23
|
+
readVersion: launcher.readVersion,
|
|
24
|
+
};
|
package/bin/launcher.cjs
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const { spawn } = require("child_process");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
bundleBinaryNamesForPlatform,
|
|
7
|
+
installReleaseBinary,
|
|
8
|
+
releaseAssetUrl,
|
|
9
|
+
} = require("../scripts/release-assets.cjs");
|
|
10
|
+
|
|
11
|
+
const REPO = "akiojin/gwt";
|
|
12
|
+
const BIN_DIR = __dirname;
|
|
13
|
+
|
|
14
|
+
function readVersion() {
|
|
15
|
+
const pkg = path.join(__dirname, "..", "package.json");
|
|
16
|
+
return JSON.parse(fs.readFileSync(pkg, "utf8")).version;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function createLauncher({ commandName, binaryNameForPlatform }) {
|
|
20
|
+
const binName = binaryNameForPlatform(process.platform);
|
|
21
|
+
const binPath = path.join(BIN_DIR, binName);
|
|
22
|
+
const bundleBinaries = bundleBinaryNamesForPlatform(process.platform);
|
|
23
|
+
|
|
24
|
+
async function ensureBinary() {
|
|
25
|
+
if (bundleBinaries.every((name) => fs.existsSync(path.join(BIN_DIR, name)))) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const version = readVersion();
|
|
30
|
+
const { url } = releaseAssetUrl(REPO, version, process.platform, process.arch);
|
|
31
|
+
|
|
32
|
+
console.log(`Downloading gwt bundle for ${process.platform}-${process.arch}...`);
|
|
33
|
+
console.log(`Downloading from: ${url}`);
|
|
34
|
+
|
|
35
|
+
await installReleaseBinary({
|
|
36
|
+
repo: REPO,
|
|
37
|
+
version,
|
|
38
|
+
binDir: BIN_DIR,
|
|
39
|
+
platform: process.platform,
|
|
40
|
+
arch: process.arch,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
console.log(`gwt bundle installed successfully: ${bundleBinaries.join(", ")}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function main() {
|
|
47
|
+
try {
|
|
48
|
+
await ensureBinary();
|
|
49
|
+
} catch (err) {
|
|
50
|
+
console.error(`Failed to download gwt binary: ${err.message}`);
|
|
51
|
+
console.error(`https://github.com/${REPO}/releases`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const child = spawn(binPath, process.argv.slice(2), {
|
|
56
|
+
stdio: "inherit",
|
|
57
|
+
env: process.env,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
child.on("error", (err) => {
|
|
61
|
+
console.error(`Failed to start ${commandName}: ${err.message}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
child.on("exit", (code, signal) => {
|
|
66
|
+
if (signal) {
|
|
67
|
+
process.kill(process.pid, signal);
|
|
68
|
+
} else {
|
|
69
|
+
process.exit(code ?? 0);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
ensureBinary,
|
|
76
|
+
main,
|
|
77
|
+
readVersion,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = {
|
|
82
|
+
createLauncher,
|
|
83
|
+
readVersion,
|
|
84
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
REPO="akiojin/gwt"
|
|
5
|
+
INSTALL_DIR="${GWT_INSTALL_DIR:-$HOME/.local/bin}"
|
|
6
|
+
VERSION="latest"
|
|
7
|
+
|
|
8
|
+
usage() {
|
|
9
|
+
cat <<'USAGE'
|
|
10
|
+
Usage: install.sh [--version <version>] [--dir <install-dir>]
|
|
11
|
+
|
|
12
|
+
Installs both gwt and gwtd into the target directory.
|
|
13
|
+
Defaults:
|
|
14
|
+
version: latest GitHub Release
|
|
15
|
+
dir: $GWT_INSTALL_DIR or $HOME/.local/bin
|
|
16
|
+
USAGE
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
while [ "$#" -gt 0 ]; do
|
|
20
|
+
case "$1" in
|
|
21
|
+
--version)
|
|
22
|
+
VERSION="${2:?missing value for --version}"
|
|
23
|
+
shift 2
|
|
24
|
+
;;
|
|
25
|
+
--dir)
|
|
26
|
+
INSTALL_DIR="${2:?missing value for --dir}"
|
|
27
|
+
shift 2
|
|
28
|
+
;;
|
|
29
|
+
-h|--help)
|
|
30
|
+
usage
|
|
31
|
+
exit 0
|
|
32
|
+
;;
|
|
33
|
+
*)
|
|
34
|
+
echo "Unknown argument: $1" >&2
|
|
35
|
+
usage >&2
|
|
36
|
+
exit 2
|
|
37
|
+
;;
|
|
38
|
+
esac
|
|
39
|
+
done
|
|
40
|
+
|
|
41
|
+
case "$(uname -m)" in
|
|
42
|
+
arm64|aarch64)
|
|
43
|
+
ARCH="arm64"
|
|
44
|
+
;;
|
|
45
|
+
x86_64|amd64)
|
|
46
|
+
ARCH="x86_64"
|
|
47
|
+
;;
|
|
48
|
+
*)
|
|
49
|
+
echo "Unsupported macOS architecture: $(uname -m)" >&2
|
|
50
|
+
exit 1
|
|
51
|
+
;;
|
|
52
|
+
esac
|
|
53
|
+
|
|
54
|
+
ASSET="gwt-macos-${ARCH}.tar.gz"
|
|
55
|
+
if [ "$VERSION" = "latest" ]; then
|
|
56
|
+
URL="https://github.com/${REPO}/releases/latest/download/${ASSET}"
|
|
57
|
+
else
|
|
58
|
+
TAG="v${VERSION#v}"
|
|
59
|
+
URL="https://github.com/${REPO}/releases/download/${TAG}/${ASSET}"
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
TMPDIR="$(mktemp -d)"
|
|
63
|
+
trap 'rm -rf "$TMPDIR"' EXIT
|
|
64
|
+
|
|
65
|
+
mkdir -p "$INSTALL_DIR"
|
|
66
|
+
curl -fsSL "$URL" -o "$TMPDIR/$ASSET"
|
|
67
|
+
tar -xzf "$TMPDIR/$ASSET" -C "$TMPDIR"
|
|
68
|
+
|
|
69
|
+
for BIN in gwt gwtd; do
|
|
70
|
+
SOURCE="$(find "$TMPDIR" -type f -name "$BIN" | head -n 1)"
|
|
71
|
+
if [ -z "$SOURCE" ]; then
|
|
72
|
+
echo "Downloaded archive does not contain $BIN" >&2
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
75
|
+
cp "$SOURCE" "$INSTALL_DIR/$BIN"
|
|
76
|
+
chmod +x "$INSTALL_DIR/$BIN"
|
|
77
|
+
done
|
|
78
|
+
|
|
79
|
+
case ":$PATH:" in
|
|
80
|
+
*":$INSTALL_DIR:"*) ;;
|
|
81
|
+
*)
|
|
82
|
+
echo "Warning: $INSTALL_DIR is not in PATH." >&2
|
|
83
|
+
echo "Add it to your shell profile before running gwt or gwtd by name." >&2
|
|
84
|
+
;;
|
|
85
|
+
esac
|
|
86
|
+
|
|
87
|
+
echo "Installed gwt and gwtd into $INSTALL_DIR"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
INSTALL_DIR="${GWT_INSTALL_DIR:-$HOME/.local/bin}"
|
|
5
|
+
|
|
6
|
+
usage() {
|
|
7
|
+
cat <<'USAGE'
|
|
8
|
+
Usage: uninstall.sh [--dir <install-dir>]
|
|
9
|
+
|
|
10
|
+
Removes both gwt and gwtd from the target directory.
|
|
11
|
+
Defaults:
|
|
12
|
+
dir: $GWT_INSTALL_DIR or $HOME/.local/bin
|
|
13
|
+
USAGE
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
while [ "$#" -gt 0 ]; do
|
|
17
|
+
case "$1" in
|
|
18
|
+
--dir)
|
|
19
|
+
INSTALL_DIR="${2:?missing value for --dir}"
|
|
20
|
+
shift 2
|
|
21
|
+
;;
|
|
22
|
+
-h|--help)
|
|
23
|
+
usage
|
|
24
|
+
exit 0
|
|
25
|
+
;;
|
|
26
|
+
*)
|
|
27
|
+
echo "Unknown argument: $1" >&2
|
|
28
|
+
usage >&2
|
|
29
|
+
exit 2
|
|
30
|
+
;;
|
|
31
|
+
esac
|
|
32
|
+
done
|
|
33
|
+
|
|
34
|
+
for BIN in gwt gwtd; do
|
|
35
|
+
rm -f "$INSTALL_DIR/$BIN"
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
echo "Removed gwt and gwtd from $INSTALL_DIR"
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akiojin/gwt",
|
|
3
|
-
"version": "9.11.
|
|
3
|
+
"version": "9.11.11",
|
|
4
4
|
"description": "Desktop GUI for Git worktree management and coding agent launch",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"gwt": "bin/gwt.cjs"
|
|
7
|
+
"gwt": "bin/gwt.cjs",
|
|
8
|
+
"gwtd": "bin/gwtd.cjs"
|
|
8
9
|
},
|
|
9
10
|
"scripts": {
|
|
10
11
|
"postinstall": "node scripts/postinstall.cjs",
|
|
@@ -7,6 +7,7 @@ const { execFileSync } = require("child_process");
|
|
|
7
7
|
const {
|
|
8
8
|
binaryNameForPlatform,
|
|
9
9
|
bundleBinaryNamesForPlatform,
|
|
10
|
+
daemonBinaryNameForPlatform,
|
|
10
11
|
installBundleFromArchive,
|
|
11
12
|
primaryReleaseAssetName,
|
|
12
13
|
releaseAssetName,
|
|
@@ -47,6 +48,9 @@ run("release helper keeps platform binary names stable", () => {
|
|
|
47
48
|
assert.equal(binaryNameForPlatform("win32"), "gwt.exe");
|
|
48
49
|
assert.equal(binaryNameForPlatform("linux"), "gwt");
|
|
49
50
|
assert.equal(binaryNameForPlatform("darwin"), "gwt");
|
|
51
|
+
assert.equal(daemonBinaryNameForPlatform("win32"), "gwtd.exe");
|
|
52
|
+
assert.equal(daemonBinaryNameForPlatform("linux"), "gwtd");
|
|
53
|
+
assert.equal(daemonBinaryNameForPlatform("darwin"), "gwtd");
|
|
50
54
|
});
|
|
51
55
|
|
|
52
56
|
run("release helper keeps bundle binary names stable", () => {
|
|
@@ -56,8 +60,12 @@ run("release helper keeps bundle binary names stable", () => {
|
|
|
56
60
|
});
|
|
57
61
|
|
|
58
62
|
run("installer entrypoints are loadable under package type module", () => {
|
|
63
|
+
const daemonLauncher = require("../bin/gwtd.cjs");
|
|
64
|
+
|
|
59
65
|
assert.equal(typeof postinstall.main, "function");
|
|
60
66
|
assert.equal(typeof launcher.main, "function");
|
|
67
|
+
assert.equal(typeof daemonLauncher.main, "function");
|
|
68
|
+
assert.equal(typeof daemonLauncher.readVersion, "function");
|
|
61
69
|
});
|
|
62
70
|
|
|
63
71
|
run("windows installer definition includes the gwtd companion binary", () => {
|
|
@@ -78,6 +86,8 @@ run("release workflow packages gwtd alongside gwt", () => {
|
|
|
78
86
|
|
|
79
87
|
run("package scripts keep the GUI front door and release contract explicit", () => {
|
|
80
88
|
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "package.json"), "utf8"));
|
|
89
|
+
assert.equal(pkg.bin.gwt, "bin/gwt.cjs");
|
|
90
|
+
assert.equal(pkg.bin.gwtd, "bin/gwtd.cjs");
|
|
81
91
|
assert.equal(pkg.scripts["test:release-assets"], "node scripts/test_release_assets.cjs");
|
|
82
92
|
assert.equal(
|
|
83
93
|
pkg.scripts["test:frontend-bundle"],
|
|
@@ -88,6 +98,23 @@ run("package scripts keep the GUI front door and release contract explicit", ()
|
|
|
88
98
|
assert.equal(pkg.scripts.build, "cargo build --release -p gwt --bin gwt --bin gwtd");
|
|
89
99
|
});
|
|
90
100
|
|
|
101
|
+
run("macos install scripts install and remove both public command shims", () => {
|
|
102
|
+
const install = fs.readFileSync(
|
|
103
|
+
path.join(__dirname, "..", "installers", "macos", "install.sh"),
|
|
104
|
+
"utf8"
|
|
105
|
+
);
|
|
106
|
+
const uninstall = fs.readFileSync(
|
|
107
|
+
path.join(__dirname, "..", "installers", "macos", "uninstall.sh"),
|
|
108
|
+
"utf8"
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
assert.match(install, /gwt-macos-\$\{ARCH\}\.tar\.gz/);
|
|
112
|
+
assert.match(install, /for BIN in gwt gwtd/);
|
|
113
|
+
assert.match(install, /chmod \+x "\$INSTALL_DIR\/\$BIN"/);
|
|
114
|
+
assert.match(uninstall, /for BIN in gwt gwtd/);
|
|
115
|
+
assert.match(uninstall, /rm -f "\$INSTALL_DIR\/\$BIN"/);
|
|
116
|
+
});
|
|
117
|
+
|
|
91
118
|
run("test all script keeps rust tests plus frontend release checks", () => {
|
|
92
119
|
const testAll = fs.readFileSync(path.join(__dirname, "test-all.sh"), "utf8");
|
|
93
120
|
assert.match(testAll, /test -p gwt-core -p gwt --all-features/);
|