@opencoven/coven-code 0.0.12 → 0.0.13

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/bin/coven-code CHANGED
@@ -7,12 +7,12 @@ const os = require('os');
7
7
  const fs = require('fs');
8
8
 
9
9
  const ext = os.platform() === 'win32' ? '.exe' : '';
10
- const binary = path.join(__dirname, '..', 'native', `coven-code`);
10
+ const binary = path.join(__dirname, '..', 'native', `coven-code${ext}`);
11
11
 
12
12
  if (!fs.existsSync(binary)) {
13
13
  console.error(
14
14
  'coven-code: native binary not found.\n' +
15
- 'Try reinstalling: npm install -g /coven-code\n' +
15
+ 'Try reinstalling: npm install -g @opencoven/coven-code\n' +
16
16
  `Expected: ${binary}`
17
17
  );
18
18
  process.exit(1);
package/checksums.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "coven-code-windows-x86_64.zip": {
3
+ "sha256": "72745630211c6921018a779df724c99637af73e84168ffe851758c61bf680bdd"
4
+ },
5
+ "coven-code-linux-x86_64.tar.gz": {
6
+ "sha256": "223c1eedaad620af6df5ae776164f4b6d905ab28b55e07bc258601f5841bd366"
7
+ },
8
+ "coven-code-linux-aarch64.tar.gz": {
9
+ "sha256": "221eae094f6edb6d28ccdcc5bda90cf1c89e24d3a677bb4f7de51d8f1eff062f"
10
+ },
11
+ "coven-code-macos-x86_64.tar.gz": {
12
+ "sha256": "fd0ee2c2c605142198c48aa9c15adf6b7ee979aa47ef8b3f55edacb32251217d"
13
+ },
14
+ "coven-code-macos-aarch64.tar.gz": {
15
+ "sha256": "8b78b0475f32a233dab7a650f574ebd2f31a308fdcf79548697ebbb3107e3269"
16
+ }
17
+ }
package/install.js CHANGED
@@ -2,13 +2,14 @@
2
2
  'use strict';
3
3
 
4
4
  const https = require('https');
5
- const http = require('http');
6
5
  const fs = require('fs');
7
6
  const path = require('path');
8
7
  const os = require('os');
8
+ const crypto = require('crypto');
9
9
  const { execFileSync } = require('child_process');
10
10
 
11
11
  const pkg = require('./package.json');
12
+ const checksums = require('./checksums.json');
12
13
  const VERSION = pkg.version;
13
14
  const REPO = 'OpenCoven/coven-code';
14
15
  const BASE_URL = `https://github.com/${REPO}/releases/download/v${VERSION}`;
@@ -41,13 +42,29 @@ function getPlatform() {
41
42
 
42
43
  function download(url, dest) {
43
44
  return new Promise((resolve, reject) => {
45
+ const parsed = new URL(url);
46
+ if (parsed.protocol !== 'https:') {
47
+ reject(new Error(`Refusing to download non-HTTPS URL: ${url}`));
48
+ return;
49
+ }
50
+
44
51
  const file = fs.createWriteStream(dest);
45
- const get = url.startsWith('https') ? https : http;
46
- get.get(url, (res) => {
47
- if (res.statusCode === 301 || res.statusCode === 302) {
52
+ https.get(url, (res) => {
53
+ if ([301, 302, 303, 307, 308].includes(res.statusCode)) {
48
54
  file.close();
49
55
  try { fs.unlinkSync(dest); } catch (_) {}
50
- download(res.headers.location, dest).then(resolve).catch(reject);
56
+ if (!res.headers.location) {
57
+ reject(new Error(`Redirect without Location header downloading ${url}`));
58
+ return;
59
+ }
60
+ let location;
61
+ try {
62
+ location = new URL(res.headers.location, url).toString();
63
+ } catch (err) {
64
+ reject(err);
65
+ return;
66
+ }
67
+ download(location, dest).then(resolve).catch(reject);
51
68
  return;
52
69
  }
53
70
  if (res.statusCode !== 200) {
@@ -69,6 +86,31 @@ function download(url, dest) {
69
86
  });
70
87
  }
71
88
 
89
+ function sha256File(filePath) {
90
+ const hash = crypto.createHash('sha256');
91
+ const bytes = fs.readFileSync(filePath);
92
+ hash.update(bytes);
93
+ return hash.digest('hex');
94
+ }
95
+
96
+ function expectedSha256(archiveName) {
97
+ const entry = checksums[archiveName];
98
+ if (!entry || typeof entry.sha256 !== 'string') {
99
+ throw new Error(`Missing SHA-256 checksum for ${archiveName} in checksums.json`);
100
+ }
101
+ return entry.sha256;
102
+ }
103
+
104
+ function verifyChecksum(filePath, archiveName) {
105
+ const expected = expectedSha256(archiveName).toLowerCase();
106
+ const actual = sha256File(filePath).toLowerCase();
107
+ if (actual !== expected) {
108
+ throw new Error(
109
+ `Checksum mismatch for ${archiveName}: expected ${expected}, got ${actual}`
110
+ );
111
+ }
112
+ }
113
+
72
114
  async function main() {
73
115
  const { artifact, ext, archive } = getPlatform();
74
116
  const archiveName = `${artifact}${archive}`;
@@ -87,6 +129,9 @@ async function main() {
87
129
  console.log(` ${url}`);
88
130
  await download(url, tmpPath);
89
131
 
132
+ console.log('coven-code: verifying checksum...');
133
+ verifyChecksum(tmpPath, archiveName);
134
+
90
135
  console.log('coven-code: extracting...');
91
136
  if (archive === '.zip') {
92
137
  execFileSync('powershell', [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencoven/coven-code",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "description": "Open-source, multi-provider agentic coding TUI for the terminal — OpenCoven fork of Claurst",
5
5
  "license": "GPL-3.0-only",
6
6
  "repository": {
@@ -31,6 +31,7 @@
31
31
  "files": [
32
32
  "bin/",
33
33
  "install.js",
34
+ "checksums.json",
34
35
  "README.md",
35
36
  "ATTRIBUTION.md"
36
37
  ],