@ggcode-cli/ggcode 1.0.7 → 1.1.1

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 ADDED
@@ -0,0 +1,62 @@
1
+ # @ggcode-cli/ggcode
2
+
3
+ `@ggcode-cli/ggcode` is a thin npm wrapper for the `ggcode` terminal agent.
4
+
5
+ It does not bundle the native binary in the package. Instead, the wrapper downloads the latest
6
+ `ggcode` GitHub Release for your platform on install or first run, caches it locally, and then
7
+ launches it for you.
8
+
9
+ ## Install
10
+
11
+ For normal CLI usage, install it globally:
12
+
13
+ ```bash
14
+ npm install -g @ggcode-cli/ggcode
15
+ ```
16
+
17
+ Then run:
18
+
19
+ ```bash
20
+ ggcode
21
+ ```
22
+
23
+ If you install it locally, use `npx ggcode` or `./node_modules/.bin/ggcode`.
24
+
25
+ ## What it does
26
+
27
+ - Detects your platform and architecture
28
+ - Downloads the latest matching `ggcode` binary from GitHub Releases
29
+ - Verifies the downloaded archive with `checksums.txt`
30
+ - Extracts and caches the binary for reuse
31
+
32
+ ## Pin a specific ggcode release
33
+
34
+ By default, the wrapper always resolves the latest `ggcode` release.
35
+
36
+ If you need to pin a specific release, set `GGCODE_INSTALL_VERSION`:
37
+
38
+ ```bash
39
+ GGCODE_INSTALL_VERSION=vX.Y.Z ggcode
40
+ ```
41
+
42
+ or:
43
+
44
+ ```bash
45
+ GGCODE_INSTALL_VERSION=X.Y.Z ggcode
46
+ ```
47
+
48
+ ## Supported platforms
49
+
50
+ - macOS
51
+ - Linux
52
+ - Windows
53
+
54
+ Supported architectures:
55
+
56
+ - x86_64 / amd64
57
+ - arm64
58
+
59
+ ## Project links
60
+
61
+ - Repository: https://github.com/topcheer/ggcode
62
+ - Issues: https://github.com/topcheer/ggcode/issues
package/bin/ggcode.js CHANGED
@@ -1,11 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const { spawnSync } = require("child_process");
4
- const pkg = require("../package.json");
5
4
  const { ensureInstalled } = require("../lib/install");
6
5
 
7
6
  async function main() {
8
- const binary = await ensureInstalled(process.env.GGCODE_INSTALL_VERSION, pkg.version, true);
7
+ const binary = await ensureInstalled(process.env.GGCODE_INSTALL_VERSION, true);
9
8
  const result = spawnSync(binary, process.argv.slice(2), { stdio: "inherit" });
10
9
  if (result.error) {
11
10
  throw result.error;
package/lib/install.js CHANGED
@@ -10,9 +10,8 @@ const REPO = "ggcode";
10
10
  const BINARY = process.platform === "win32" ? "ggcode.exe" : "ggcode";
11
11
 
12
12
  function normalizeVersion(version) {
13
- const envVersion = process.env.GGCODE_INSTALL_VERSION;
14
- const selected = (envVersion || version || "").trim();
15
- if (!selected || selected === "latest" || selected.startsWith("0.0.0-")) {
13
+ const selected = (version || "").trim();
14
+ if (!selected || selected === "latest") {
16
15
  return "latest";
17
16
  }
18
17
  return selected.startsWith("v") ? selected : `v${selected}`;
@@ -66,8 +65,9 @@ function binaryPath(version, target) {
66
65
  return path.join(installRoot(version, target), target.binaryName);
67
66
  }
68
67
 
69
- async function ensureInstalled(version, packageVersion, quiet) {
70
- const resolvedVersion = normalizeVersion(version || packageVersion);
68
+ async function ensureInstalled(version, quiet) {
69
+ const requestedVersion = normalizeVersion(version);
70
+ const resolvedVersion = await resolveReleaseVersion(requestedVersion);
71
71
  const target = resolveTarget();
72
72
  const dest = binaryPath(resolvedVersion, target);
73
73
  if (fs.existsSync(dest)) {
@@ -106,6 +106,19 @@ async function ensureInstalled(version, packageVersion, quiet) {
106
106
  return dest;
107
107
  }
108
108
 
109
+ async function resolveReleaseVersion(version) {
110
+ if (version !== "latest") {
111
+ return version;
112
+ }
113
+
114
+ const latestURL = await resolveFinalURL(`https://github.com/${OWNER}/${REPO}/releases/latest`);
115
+ const match = latestURL.match(/\/releases\/tag\/([^/?#]+)/);
116
+ if (!match) {
117
+ throw new Error(`Could not resolve latest ggcode release from ${latestURL}`);
118
+ }
119
+ return decodeURIComponent(match[1]);
120
+ }
121
+
109
122
  function verifyChecksum(assetName, archive, checksumsText) {
110
123
  const lines = checksumsText.split(/\r?\n/);
111
124
  let expected = null;
@@ -179,8 +192,32 @@ function downloadBuffer(url) {
179
192
  });
180
193
  }
181
194
 
195
+ function resolveFinalURL(url) {
196
+ return new Promise((resolve, reject) => {
197
+ const get = (target) => {
198
+ https
199
+ .get(target, (res) => {
200
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
201
+ res.resume();
202
+ get(new URL(res.headers.location, target).toString());
203
+ return;
204
+ }
205
+ if (res.statusCode !== 200) {
206
+ reject(new Error(`${target} returned ${res.statusCode}`));
207
+ return;
208
+ }
209
+ res.resume();
210
+ resolve(target);
211
+ })
212
+ .on("error", reject);
213
+ };
214
+ get(url);
215
+ });
216
+ }
217
+
182
218
  module.exports = {
183
219
  ensureInstalled,
184
220
  normalizeVersion,
221
+ resolveReleaseVersion,
185
222
  resolveTarget,
186
223
  };
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@ggcode-cli/ggcode",
3
- "version": "1.0.7",
3
+ "version": "1.1.1",
4
4
  "description": "Thin npm wrapper that installs the ggcode GitHub Release binary",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://github.com/topcheer/ggcode.git"
8
+ "url": "https://github.com/topcheer/ggcode.git"
9
9
  },
10
10
  "homepage": "https://github.com/topcheer/ggcode",
11
11
  "bugs": {
@@ -1,9 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const pkg = require("../package.json");
4
3
  const { ensureInstalled } = require("../lib/install");
5
4
 
6
- ensureInstalled(process.env.GGCODE_INSTALL_VERSION, pkg.version, false).catch((err) => {
5
+ ensureInstalled(process.env.GGCODE_INSTALL_VERSION, false).catch((err) => {
7
6
  console.warn(`ggcode postinstall warning: ${err.message}`);
8
7
  console.warn("The wrapper will try again on first run.");
9
8
  });