@grainulation/grainulation 1.1.0 → 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/lib/doctor.js +19 -20
- package/lib/router.js +6 -6
- package/lib/server.mjs +10 -4
- package/lib/setup.js +2 -2
- package/package.json +2 -3
package/lib/doctor.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const { existsSync } = require('node:fs');
|
|
1
|
+
const { execFileSync } = require('node:child_process');
|
|
2
|
+
const { existsSync, readFileSync, readdirSync } = require('node:fs');
|
|
3
3
|
const path = require('node:path');
|
|
4
4
|
const { getInstallable } = require('./ecosystem');
|
|
5
5
|
|
|
@@ -17,8 +17,8 @@ const { getInstallable } = require('./ecosystem');
|
|
|
17
17
|
*/
|
|
18
18
|
function checkGlobal(packageName) {
|
|
19
19
|
try {
|
|
20
|
-
const out =
|
|
21
|
-
stdio: 'pipe',
|
|
20
|
+
const out = execFileSync('npm', ['list', '-g', packageName, '--depth=0'], {
|
|
21
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
22
22
|
encoding: 'utf-8',
|
|
23
23
|
timeout: 5000,
|
|
24
24
|
});
|
|
@@ -35,8 +35,8 @@ function checkGlobal(packageName) {
|
|
|
35
35
|
*/
|
|
36
36
|
function checkNpxCache(packageName) {
|
|
37
37
|
try {
|
|
38
|
-
const prefix =
|
|
39
|
-
stdio: 'pipe',
|
|
38
|
+
const prefix = execFileSync('npm', ['config', 'get', 'cache'], {
|
|
39
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
40
40
|
encoding: 'utf-8',
|
|
41
41
|
timeout: 5000,
|
|
42
42
|
}).trim();
|
|
@@ -44,14 +44,13 @@ function checkNpxCache(packageName) {
|
|
|
44
44
|
if (!existsSync(npxDir)) return null;
|
|
45
45
|
|
|
46
46
|
// npx cache has hash-named directories, each with node_modules
|
|
47
|
-
const { readdirSync } = require('node:fs');
|
|
48
47
|
const entries = readdirSync(npxDir, { withFileTypes: true });
|
|
49
48
|
for (const entry of entries) {
|
|
50
49
|
if (!entry.isDirectory()) continue;
|
|
51
50
|
const pkgJson = path.join(npxDir, entry.name, 'node_modules', packageName, 'package.json');
|
|
52
51
|
if (existsSync(pkgJson)) {
|
|
53
52
|
try {
|
|
54
|
-
const pkg = JSON.parse(
|
|
53
|
+
const pkg = JSON.parse(readFileSync(pkgJson, 'utf-8'));
|
|
55
54
|
return { version: pkg.version || 'installed', method: 'npx cache' };
|
|
56
55
|
} catch {
|
|
57
56
|
return { version: 'installed', method: 'npx cache' };
|
|
@@ -72,7 +71,7 @@ function checkLocal(packageName) {
|
|
|
72
71
|
try {
|
|
73
72
|
const pkgJson = path.join(process.cwd(), 'node_modules', packageName, 'package.json');
|
|
74
73
|
if (existsSync(pkgJson)) {
|
|
75
|
-
const pkg = JSON.parse(
|
|
74
|
+
const pkg = JSON.parse(readFileSync(pkgJson, 'utf-8'));
|
|
76
75
|
return { version: pkg.version || 'installed', method: 'local' };
|
|
77
76
|
}
|
|
78
77
|
return null;
|
|
@@ -98,7 +97,7 @@ function checkSource(packageName) {
|
|
|
98
97
|
const pkgJson = candidate.endsWith('package.json') ? candidate : path.join(candidate, 'package.json');
|
|
99
98
|
if (existsSync(pkgJson)) {
|
|
100
99
|
try {
|
|
101
|
-
const pkg = JSON.parse(
|
|
100
|
+
const pkg = JSON.parse(readFileSync(pkgJson, 'utf-8'));
|
|
102
101
|
if (pkg.name === packageName) {
|
|
103
102
|
return { version: pkg.version || 'installed', method: 'source' };
|
|
104
103
|
}
|
|
@@ -117,8 +116,8 @@ function checkSource(packageName) {
|
|
|
117
116
|
*/
|
|
118
117
|
function checkNpxNoInstall(packageName) {
|
|
119
118
|
try {
|
|
120
|
-
const out =
|
|
121
|
-
stdio: 'pipe',
|
|
119
|
+
const out = execFileSync('npx', ['--no-install', packageName, '--version'], {
|
|
120
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
122
121
|
encoding: 'utf-8',
|
|
123
122
|
timeout: 5000,
|
|
124
123
|
}).trim();
|
|
@@ -163,8 +162,8 @@ function getNodeVersion() {
|
|
|
163
162
|
|
|
164
163
|
function getNpmVersion() {
|
|
165
164
|
try {
|
|
166
|
-
return
|
|
167
|
-
stdio: 'pipe',
|
|
165
|
+
return execFileSync('npm', ['--version'], {
|
|
166
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
168
167
|
encoding: 'utf-8',
|
|
169
168
|
timeout: 5000,
|
|
170
169
|
}).trim();
|
|
@@ -175,8 +174,8 @@ function getNpmVersion() {
|
|
|
175
174
|
|
|
176
175
|
function getPnpmVersion() {
|
|
177
176
|
try {
|
|
178
|
-
return
|
|
179
|
-
stdio: 'pipe',
|
|
177
|
+
return execFileSync('pnpm', ['--version'], {
|
|
178
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
180
179
|
encoding: 'utf-8',
|
|
181
180
|
timeout: 5000,
|
|
182
181
|
}).trim();
|
|
@@ -187,8 +186,8 @@ function getPnpmVersion() {
|
|
|
187
186
|
|
|
188
187
|
function getBiomeVersion() {
|
|
189
188
|
try {
|
|
190
|
-
const out =
|
|
191
|
-
stdio: 'pipe',
|
|
189
|
+
const out = execFileSync('npx', ['biome', '--version'], {
|
|
190
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
192
191
|
encoding: 'utf-8',
|
|
193
192
|
timeout: 5000,
|
|
194
193
|
}).trim();
|
|
@@ -201,8 +200,8 @@ function getBiomeVersion() {
|
|
|
201
200
|
|
|
202
201
|
function getHooksPath() {
|
|
203
202
|
try {
|
|
204
|
-
return
|
|
205
|
-
stdio: 'pipe',
|
|
203
|
+
return execFileSync('git', ['config', 'core.hooksPath'], {
|
|
204
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
206
205
|
encoding: 'utf-8',
|
|
207
206
|
timeout: 5000,
|
|
208
207
|
}).trim();
|
package/lib/router.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { execFileSync, spawn } = require('node:child_process');
|
|
2
|
-
const { existsSync } = require('node:fs');
|
|
2
|
+
const { existsSync, readFileSync } = require('node:fs');
|
|
3
3
|
const path = require('node:path');
|
|
4
4
|
const { getByName, getInstallable } = require('./ecosystem');
|
|
5
5
|
|
|
@@ -92,7 +92,7 @@ function findSourceBin(tool) {
|
|
|
92
92
|
try {
|
|
93
93
|
const pkgPath = path.join(dir, 'package.json');
|
|
94
94
|
if (!existsSync(pkgPath)) continue;
|
|
95
|
-
const pkg = JSON.parse(
|
|
95
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
96
96
|
if (pkg.name !== tool.package) continue;
|
|
97
97
|
// Find the bin entry
|
|
98
98
|
if (pkg.bin) {
|
|
@@ -261,7 +261,7 @@ function statusData() {
|
|
|
261
261
|
|
|
262
262
|
if (hasClaims) {
|
|
263
263
|
try {
|
|
264
|
-
const claimsRaw =
|
|
264
|
+
const claimsRaw = readFileSync(path.join(cwd, 'claims.json'), 'utf-8');
|
|
265
265
|
const claims = JSON.parse(claimsRaw);
|
|
266
266
|
const claimList = Array.isArray(claims) ? claims : claims.claims || [];
|
|
267
267
|
const byType = {};
|
|
@@ -281,7 +281,7 @@ function statusData() {
|
|
|
281
281
|
for (const pidFile of [farmerPidPath, farmerPidAlt]) {
|
|
282
282
|
if (existsSync(pidFile)) {
|
|
283
283
|
try {
|
|
284
|
-
const pid =
|
|
284
|
+
const pid = readFileSync(pidFile, 'utf-8').trim();
|
|
285
285
|
process.kill(Number(pid), 0);
|
|
286
286
|
farmerPidValue = Number(pid);
|
|
287
287
|
} catch {
|
|
@@ -339,7 +339,7 @@ function status(opts) {
|
|
|
339
339
|
|
|
340
340
|
if (hasClaims) {
|
|
341
341
|
try {
|
|
342
|
-
const claimsRaw =
|
|
342
|
+
const claimsRaw = readFileSync(path.join(cwd, 'claims.json'), 'utf-8');
|
|
343
343
|
const claims = JSON.parse(claimsRaw);
|
|
344
344
|
const claimList = Array.isArray(claims) ? claims : claims.claims || [];
|
|
345
345
|
const total = claimList.length;
|
|
@@ -377,7 +377,7 @@ function status(opts) {
|
|
|
377
377
|
for (const pidFile of [farmerPid, farmerPidAlt]) {
|
|
378
378
|
if (existsSync(pidFile)) {
|
|
379
379
|
try {
|
|
380
|
-
const pid =
|
|
380
|
+
const pid = readFileSync(pidFile, 'utf-8').trim();
|
|
381
381
|
// Check if process is still running
|
|
382
382
|
process.kill(Number(pid), 0);
|
|
383
383
|
farmerRunning = true;
|
package/lib/server.mjs
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* grainulation serve [--port 9098]
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import { execFileSync } from 'node:child_process';
|
|
15
15
|
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, statSync, writeFileSync } from 'node:fs';
|
|
16
16
|
import { createServer } from 'node:http';
|
|
17
17
|
import { createRequire } from 'node:module';
|
|
@@ -176,7 +176,10 @@ function detectTool(pkg) {
|
|
|
176
176
|
|
|
177
177
|
// 1. Global npm
|
|
178
178
|
try {
|
|
179
|
-
const out =
|
|
179
|
+
const out = execFileSync('npm', ['list', '-g', pkg, '--depth=0'], {
|
|
180
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
181
|
+
encoding: 'utf-8',
|
|
182
|
+
});
|
|
180
183
|
const match = out.match(new RegExp(`${escapeRegex(pkg)}@(\\S+)`));
|
|
181
184
|
if (match) return { installed: true, version: match[1], method: 'global' };
|
|
182
185
|
} catch {
|
|
@@ -185,7 +188,10 @@ function detectTool(pkg) {
|
|
|
185
188
|
|
|
186
189
|
// 2. npx cache
|
|
187
190
|
try {
|
|
188
|
-
const prefix =
|
|
191
|
+
const prefix = execFileSync('npm', ['config', 'get', 'cache'], {
|
|
192
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
193
|
+
encoding: 'utf-8',
|
|
194
|
+
}).trim();
|
|
189
195
|
const npxDir = join(prefix, '_npx');
|
|
190
196
|
if (existsSync(npxDir)) {
|
|
191
197
|
const entries = readdirSync(npxDir, { withFileTypes: true });
|
|
@@ -242,7 +248,7 @@ function runDoctor() {
|
|
|
242
248
|
const nodeVersion = process.version;
|
|
243
249
|
let npmVersion = 'unknown';
|
|
244
250
|
try {
|
|
245
|
-
npmVersion =
|
|
251
|
+
npmVersion = execFileSync('npm', ['--version'], { stdio: ['pipe', 'pipe', 'ignore'], encoding: 'utf-8' }).trim();
|
|
246
252
|
} catch {
|
|
247
253
|
/* ignore */
|
|
248
254
|
}
|
package/lib/setup.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const readline = require('node:readline');
|
|
2
|
-
const {
|
|
2
|
+
const { execFileSync } = require('node:child_process');
|
|
3
3
|
const { getInstallable, getCategories } = require('./ecosystem');
|
|
4
4
|
const { getVersion } = require('./doctor');
|
|
5
5
|
|
|
@@ -108,7 +108,7 @@ async function run() {
|
|
|
108
108
|
for (const tool of toInstall) {
|
|
109
109
|
console.log(` Installing ${tool.package}...`);
|
|
110
110
|
try {
|
|
111
|
-
|
|
111
|
+
execFileSync('npm', ['install', '-g', tool.package], { stdio: 'pipe' });
|
|
112
112
|
console.log(` \x1b[32m\u2713\x1b[0m ${tool.name} installed`);
|
|
113
113
|
} catch (err) {
|
|
114
114
|
console.log(` \x1b[31m\u2717\x1b[0m ${tool.name} failed: ${err.message}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grainulation/grainulation",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Structured research for decisions that satisfice",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"workspaces": [
|
|
@@ -25,8 +25,7 @@
|
|
|
25
25
|
"test": "node test/basic.test.js",
|
|
26
26
|
"lint": "biome ci .",
|
|
27
27
|
"format": "biome check --write .",
|
|
28
|
-
"start": "node bin/grainulation.js"
|
|
29
|
-
"postinstall": "git config core.hooksPath .githooks || true"
|
|
28
|
+
"start": "node bin/grainulation.js"
|
|
30
29
|
},
|
|
31
30
|
"keywords": [
|
|
32
31
|
"research",
|