@autodevjapan/godd-mcp-alpha 1.46.3 → 2.0.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 +47 -0
- package/assets/native/godd-native-aarch64-apple-darwin +0 -0
- package/assets/native/godd-native-aarch64-apple-darwin.sha256 +1 -0
- package/assets/native/godd-native-x86_64-apple-darwin +0 -0
- package/assets/native/godd-native-x86_64-apple-darwin.sha256 +1 -0
- package/assets/native/godd-native-x86_64-pc-windows-msvc.exe +0 -0
- package/assets/native/godd-native-x86_64-pc-windows-msvc.exe.sha256 +1 -0
- package/assets/native/godd-native-x86_64-unknown-linux-musl +0 -0
- package/assets/native/godd-native-x86_64-unknown-linux-musl.sha256 +1 -0
- package/dist/godd.cjs +151 -150
- package/native-assets.json +31 -0
- package/package.json +10 -1
- package/scripts/native-assets.js +185 -0
- package/scripts/postinstall-godd-native.js +48 -103
- package/scripts/postinstall.js +41 -15
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"releaseTag": "godd-native-v0.1.1",
|
|
4
|
+
"expectedVersion": "godd-native 0.1.1",
|
|
5
|
+
"baselineBytes": 43422580,
|
|
6
|
+
"maximumAssetBytes": 48000000,
|
|
7
|
+
"maximumTarballBytes": 25000000,
|
|
8
|
+
"maximumUnpackedBytes": 50000000,
|
|
9
|
+
"targets": {
|
|
10
|
+
"darwin-x64": {
|
|
11
|
+
"artifact": "godd-native-x86_64-apple-darwin",
|
|
12
|
+
"bytes": 11027072,
|
|
13
|
+
"sha256": "2cdac18a4fefa3983c882402376a3557b3224f45b8857f5181f6afca80edfc61"
|
|
14
|
+
},
|
|
15
|
+
"darwin-arm64": {
|
|
16
|
+
"artifact": "godd-native-aarch64-apple-darwin",
|
|
17
|
+
"bytes": 10689840,
|
|
18
|
+
"sha256": "d0e2af0d6d6486f4472ebd06b35783ca3b00a9154c7df965e7fddee0ffeb305c"
|
|
19
|
+
},
|
|
20
|
+
"linux-x64": {
|
|
21
|
+
"artifact": "godd-native-x86_64-unknown-linux-musl",
|
|
22
|
+
"bytes": 12479168,
|
|
23
|
+
"sha256": "ca2bc844643569a627a15ee1476d6cc51d4b594f9b7bcb81f1e70d39e0b3b317"
|
|
24
|
+
},
|
|
25
|
+
"win32-x64": {
|
|
26
|
+
"artifact": "godd-native-x86_64-pc-windows-msvc.exe",
|
|
27
|
+
"bytes": 9226240,
|
|
28
|
+
"sha256": "c912e4add2f0d3c438d3d507cb38837e032e5cd0a2b9d89b29b3a8480e24c5c8"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
package/package.json
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autodevjapan/godd-mcp-alpha",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "GoDD MCP α Server — AI Prompt Delivery System for Cursor, Claude Code, Codex, Kimi CLI, and Antigravity",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/AutoDevJapan/GoDD-MCP-Alpha.git",
|
|
10
|
+
"directory": "godd-mcp-alpha"
|
|
11
|
+
},
|
|
7
12
|
"main": "dist/godd.cjs",
|
|
8
13
|
"bin": {
|
|
9
14
|
"godd-a": "dist/godd.cjs"
|
|
10
15
|
},
|
|
11
16
|
"files": [
|
|
12
17
|
"assets/godd-mcp-alpha-icon.png",
|
|
18
|
+
"assets/native",
|
|
19
|
+
"native-assets.json",
|
|
13
20
|
"dist/godd.cjs",
|
|
14
21
|
"scripts/postinstall.js",
|
|
15
22
|
"scripts/postinstall-godd-native.js",
|
|
23
|
+
"scripts/native-assets.js",
|
|
16
24
|
"scripts/postinstall-godd-tk.js",
|
|
17
25
|
"scripts/write-sha256.js",
|
|
18
26
|
"README.md"
|
|
@@ -38,6 +46,7 @@
|
|
|
38
46
|
"typecheck": "tsc --noEmit",
|
|
39
47
|
"test": "vitest run",
|
|
40
48
|
"test:watch": "vitest",
|
|
49
|
+
"gate:v2": "node scripts/dispatch-npm-v2-gate.js",
|
|
41
50
|
"dev": "tsx src/index.ts serve",
|
|
42
51
|
"prepublishOnly": "pnpm build",
|
|
43
52
|
"postinstall": "node scripts/postinstall.js"
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const packageRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
7
|
+
const MANIFEST_KEYS = [
|
|
8
|
+
"baselineBytes",
|
|
9
|
+
"expectedVersion",
|
|
10
|
+
"maximumAssetBytes",
|
|
11
|
+
"maximumTarballBytes",
|
|
12
|
+
"maximumUnpackedBytes",
|
|
13
|
+
"releaseTag",
|
|
14
|
+
"schemaVersion",
|
|
15
|
+
"targets",
|
|
16
|
+
];
|
|
17
|
+
const TARGET_KEYS = ["artifact", "bytes", "sha256"];
|
|
18
|
+
const EXPECTED_TARGET_ARTIFACTS = Object.freeze({
|
|
19
|
+
"darwin-arm64": "godd-native-aarch64-apple-darwin",
|
|
20
|
+
"darwin-x64": "godd-native-x86_64-apple-darwin",
|
|
21
|
+
"linux-x64": "godd-native-x86_64-unknown-linux-musl",
|
|
22
|
+
"win32-x64": "godd-native-x86_64-pc-windows-msvc.exe",
|
|
23
|
+
});
|
|
24
|
+
const SHA256_PATTERN = /^[0-9a-f]{64}$/;
|
|
25
|
+
const RELEASE_TAG_PATTERN = /^godd-native-v(\d+\.\d+\.\d+)$/;
|
|
26
|
+
const SIDECAR_BYTES = 65;
|
|
27
|
+
const HARD_MAX_UNPACKED_BYTES = 64_000_000;
|
|
28
|
+
|
|
29
|
+
function isRecord(value) {
|
|
30
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function requireExactKeys(value, expected, label) {
|
|
34
|
+
if (!isRecord(value)) throw new Error(`${label} must be an object`);
|
|
35
|
+
const actual = Object.keys(value).sort();
|
|
36
|
+
const sortedExpected = [...expected].sort();
|
|
37
|
+
if (JSON.stringify(actual) !== JSON.stringify(sortedExpected)) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
`${label} keys mismatch: expected=${sortedExpected.join(",")} actual=${actual.join(",")}`,
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function requirePositiveInteger(value, label) {
|
|
45
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
46
|
+
throw new Error(`${label} must be a positive safe integer`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function validateNativeManifest(value) {
|
|
51
|
+
requireExactKeys(value, MANIFEST_KEYS, "Native manifest");
|
|
52
|
+
if (value.schemaVersion !== 1) {
|
|
53
|
+
throw new Error("Native manifest schemaVersion must be 1");
|
|
54
|
+
}
|
|
55
|
+
const tagMatch =
|
|
56
|
+
typeof value.releaseTag === "string"
|
|
57
|
+
? RELEASE_TAG_PATTERN.exec(value.releaseTag)
|
|
58
|
+
: null;
|
|
59
|
+
if (!tagMatch) throw new Error("Native manifest releaseTag is invalid");
|
|
60
|
+
if (value.expectedVersion !== `godd-native ${tagMatch[1]}`) {
|
|
61
|
+
throw new Error("Native manifest tag/version mismatch");
|
|
62
|
+
}
|
|
63
|
+
requirePositiveInteger(value.baselineBytes, "baselineBytes");
|
|
64
|
+
requirePositiveInteger(value.maximumAssetBytes, "maximumAssetBytes");
|
|
65
|
+
requirePositiveInteger(value.maximumTarballBytes, "maximumTarballBytes");
|
|
66
|
+
requirePositiveInteger(value.maximumUnpackedBytes, "maximumUnpackedBytes");
|
|
67
|
+
if (value.maximumUnpackedBytes > HARD_MAX_UNPACKED_BYTES) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
`maximumUnpackedBytes exceeds hard ceiling ${HARD_MAX_UNPACKED_BYTES}`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
requireExactKeys(
|
|
73
|
+
value.targets,
|
|
74
|
+
Object.keys(EXPECTED_TARGET_ARTIFACTS),
|
|
75
|
+
"Native manifest targets",
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const artifacts = new Set();
|
|
79
|
+
let expectedBaseline = 0;
|
|
80
|
+
for (const [target, expectedArtifact] of Object.entries(
|
|
81
|
+
EXPECTED_TARGET_ARTIFACTS,
|
|
82
|
+
)) {
|
|
83
|
+
const entry = value.targets[target];
|
|
84
|
+
requireExactKeys(entry, TARGET_KEYS, `Native manifest target ${target}`);
|
|
85
|
+
if (entry.artifact !== expectedArtifact) {
|
|
86
|
+
throw new Error(`Native manifest artifact mismatch for ${target}`);
|
|
87
|
+
}
|
|
88
|
+
if (artifacts.has(entry.artifact)) {
|
|
89
|
+
throw new Error(`Native manifest artifact is duplicated: ${entry.artifact}`);
|
|
90
|
+
}
|
|
91
|
+
artifacts.add(entry.artifact);
|
|
92
|
+
requirePositiveInteger(entry.bytes, `${target}.bytes`);
|
|
93
|
+
if (typeof entry.sha256 !== "string" || !SHA256_PATTERN.test(entry.sha256)) {
|
|
94
|
+
throw new Error(`Native manifest SHA-256 is invalid for ${target}`);
|
|
95
|
+
}
|
|
96
|
+
expectedBaseline += entry.bytes + SIDECAR_BYTES;
|
|
97
|
+
}
|
|
98
|
+
if (value.baselineBytes !== expectedBaseline) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`Native manifest baseline mismatch: expected=${expectedBaseline} actual=${value.baselineBytes}`,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
if (value.maximumAssetBytes < value.baselineBytes) {
|
|
104
|
+
throw new Error("maximumAssetBytes must cover baselineBytes");
|
|
105
|
+
}
|
|
106
|
+
if (value.maximumUnpackedBytes < value.baselineBytes) {
|
|
107
|
+
throw new Error("maximumUnpackedBytes must cover baselineBytes");
|
|
108
|
+
}
|
|
109
|
+
return value;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export const NATIVE_MANIFEST = Object.freeze(
|
|
113
|
+
validateNativeManifest(
|
|
114
|
+
JSON.parse(readFileSync(join(packageRoot, "native-assets.json"), "utf8")),
|
|
115
|
+
),
|
|
116
|
+
);
|
|
117
|
+
export const NATIVE_RELEASE_TAG = NATIVE_MANIFEST.releaseTag;
|
|
118
|
+
export const EXPECTED_NATIVE_VERSION = NATIVE_MANIFEST.expectedVersion;
|
|
119
|
+
export const NATIVE_ASSET_BASELINE_BYTES = NATIVE_MANIFEST.baselineBytes;
|
|
120
|
+
export const MAX_NATIVE_ASSET_BYTES = NATIVE_MANIFEST.maximumAssetBytes;
|
|
121
|
+
export const MAX_NPM_TARBALL_BYTES = NATIVE_MANIFEST.maximumTarballBytes;
|
|
122
|
+
export const MAX_NPM_UNPACKED_BYTES = NATIVE_MANIFEST.maximumUnpackedBytes;
|
|
123
|
+
export const NATIVE_ARTIFACTS = Object.freeze(
|
|
124
|
+
Object.fromEntries(
|
|
125
|
+
Object.entries(NATIVE_MANIFEST.targets).map(([target, value]) => [
|
|
126
|
+
target,
|
|
127
|
+
value.artifact,
|
|
128
|
+
]),
|
|
129
|
+
),
|
|
130
|
+
);
|
|
131
|
+
export const TRUSTED_NATIVE_ASSETS = Object.freeze(
|
|
132
|
+
Object.fromEntries(
|
|
133
|
+
Object.values(NATIVE_MANIFEST.targets).map((value) => [
|
|
134
|
+
value.artifact,
|
|
135
|
+
Object.freeze({ bytes: value.bytes, sha256: value.sha256 }),
|
|
136
|
+
]),
|
|
137
|
+
),
|
|
138
|
+
);
|
|
139
|
+
export const EXPECTED_NATIVE_ASSET_FILES = Object.freeze(
|
|
140
|
+
Object.values(NATIVE_ARTIFACTS).flatMap((artifact) => [
|
|
141
|
+
artifact,
|
|
142
|
+
`${artifact}.sha256`,
|
|
143
|
+
]),
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
export function checksumFile(path) {
|
|
147
|
+
return createHash("sha256").update(readFileSync(path)).digest("hex");
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function verifyBundledNativeAssets(
|
|
151
|
+
directory,
|
|
152
|
+
trustedAssets = TRUSTED_NATIVE_ASSETS,
|
|
153
|
+
) {
|
|
154
|
+
if (!existsSync(directory)) {
|
|
155
|
+
throw new Error(`Bundled native asset directory is missing: ${directory}`);
|
|
156
|
+
}
|
|
157
|
+
const actualFiles = readdirSync(directory).sort();
|
|
158
|
+
const expectedFiles = [...EXPECTED_NATIVE_ASSET_FILES].sort();
|
|
159
|
+
if (JSON.stringify(actualFiles) !== JSON.stringify(expectedFiles)) {
|
|
160
|
+
throw new Error(
|
|
161
|
+
`Bundled native asset set mismatch: expected=${expectedFiles.join(",")} actual=${actualFiles.join(",")}`,
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
let totalBytes = 0;
|
|
165
|
+
for (const artifact of Object.values(NATIVE_ARTIFACTS)) {
|
|
166
|
+
const artifactPath = join(directory, artifact);
|
|
167
|
+
const checksumPath = `${artifactPath}.sha256`;
|
|
168
|
+
const expected = readFileSync(checksumPath, "utf8").trim();
|
|
169
|
+
const trusted = trustedAssets[artifact];
|
|
170
|
+
if (!trusted) throw new Error(`Trusted manifest is missing ${artifact}`);
|
|
171
|
+
const bytes = readFileSync(artifactPath).byteLength;
|
|
172
|
+
if (bytes !== trusted.bytes) throw new Error(`Size mismatch for ${artifact}`);
|
|
173
|
+
const actual = checksumFile(artifactPath);
|
|
174
|
+
if (actual !== trusted.sha256 || expected !== trusted.sha256) {
|
|
175
|
+
throw new Error(`Checksum mismatch for ${artifact}`);
|
|
176
|
+
}
|
|
177
|
+
totalBytes += bytes + readFileSync(checksumPath).byteLength;
|
|
178
|
+
}
|
|
179
|
+
if (totalBytes > MAX_NATIVE_ASSET_BYTES) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
`Bundled native assets exceed ${MAX_NATIVE_ASSET_BYTES} bytes: ${totalBytes}`,
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
return { files: expectedFiles, totalBytes };
|
|
185
|
+
}
|
|
@@ -1,116 +1,61 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
chmodSync,
|
|
5
|
-
copyFileSync,
|
|
6
|
-
existsSync,
|
|
7
|
-
mkdirSync,
|
|
8
|
-
readFileSync,
|
|
9
|
-
renameSync,
|
|
10
|
-
rmSync,
|
|
11
|
-
} from "node:fs";
|
|
12
3
|
import { execFileSync } from "node:child_process";
|
|
13
|
-
import {
|
|
14
|
-
import { arch,
|
|
15
|
-
import { join } from "node:path";
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
process.env.LOCALAPPDATA || join(homedir(), "AppData", "Local"),
|
|
31
|
-
"godd-native",
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
return join(homedir(), ".local", "bin");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function installedBinary(directory) {
|
|
38
|
-
return join(directory, platform() === "win32" ? "godd-native.exe" : "godd-native");
|
|
4
|
+
import { chmodSync, existsSync } from "node:fs";
|
|
5
|
+
import { arch, platform } from "node:os";
|
|
6
|
+
import { dirname, join, resolve } from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import {
|
|
9
|
+
EXPECTED_NATIVE_VERSION,
|
|
10
|
+
NATIVE_ARTIFACTS,
|
|
11
|
+
verifyBundledNativeAssets,
|
|
12
|
+
} from "./native-assets.js";
|
|
13
|
+
|
|
14
|
+
const packageDirectory = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
15
|
+
|
|
16
|
+
export function isSourceCheckout(packageRoot = packageDirectory) {
|
|
17
|
+
return (
|
|
18
|
+
existsSync(join(packageRoot, "native", "Cargo.toml")) &&
|
|
19
|
+
existsSync(join(packageRoot, "..", ".git"))
|
|
20
|
+
);
|
|
39
21
|
}
|
|
40
22
|
|
|
41
|
-
function
|
|
42
|
-
|
|
23
|
+
export function verifyPackagedNative({
|
|
24
|
+
currentPlatform = platform(),
|
|
25
|
+
currentArch = arch(),
|
|
26
|
+
packageRoot = packageDirectory,
|
|
27
|
+
execute = execFileSync,
|
|
28
|
+
trustedAssets,
|
|
29
|
+
} = {}) {
|
|
30
|
+
const artifact = NATIVE_ARTIFACTS[`${currentPlatform}-${currentArch}`];
|
|
43
31
|
if (!artifact) {
|
|
44
|
-
|
|
45
|
-
process.exitCode = 1;
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const directory = installDirectory();
|
|
50
|
-
const destination = installedBinary(directory);
|
|
51
|
-
if (existsSync(destination)) {
|
|
52
|
-
try {
|
|
53
|
-
const version = execFileSync(destination, ["--version"], {
|
|
54
|
-
encoding: "utf-8",
|
|
55
|
-
timeout: 5_000,
|
|
56
|
-
}).trim();
|
|
57
|
-
if (version === EXPECTED_VERSION) return;
|
|
58
|
-
} catch {
|
|
59
|
-
// Replace a corrupt or incompatible existing binary.
|
|
60
|
-
}
|
|
32
|
+
throw new Error(`Unsupported platform: ${currentPlatform}-${currentArch}`);
|
|
61
33
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
34
|
+
const assetsDirectory = join(packageRoot, "assets", "native");
|
|
35
|
+
verifyBundledNativeAssets(assetsDirectory, trustedAssets);
|
|
36
|
+
const binary = join(assetsDirectory, artifact);
|
|
37
|
+
if (currentPlatform !== "win32") chmodSync(binary, 0o755);
|
|
38
|
+
const version = execute(binary, ["--version"], {
|
|
39
|
+
encoding: "utf-8",
|
|
40
|
+
timeout: 5_000,
|
|
41
|
+
}).trim();
|
|
42
|
+
if (version !== EXPECTED_NATIVE_VERSION) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Native version mismatch: expected=${EXPECTED_NATIVE_VERSION} actual=${version}`,
|
|
45
|
+
);
|
|
69
46
|
}
|
|
47
|
+
return binary;
|
|
48
|
+
}
|
|
70
49
|
|
|
71
|
-
|
|
72
|
-
const temporaryDirectory = join(directory, ".download");
|
|
73
|
-
rmSync(temporaryDirectory, { recursive: true, force: true });
|
|
74
|
-
mkdirSync(temporaryDirectory, { recursive: true });
|
|
75
|
-
|
|
50
|
+
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
76
51
|
try {
|
|
77
|
-
|
|
78
|
-
"
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"download",
|
|
82
|
-
VERSION_TAG,
|
|
83
|
-
"--repo",
|
|
84
|
-
REPOSITORY,
|
|
85
|
-
"--pattern",
|
|
86
|
-
`${artifact}*`,
|
|
87
|
-
"--dir",
|
|
88
|
-
temporaryDirectory,
|
|
89
|
-
"--clobber",
|
|
90
|
-
],
|
|
91
|
-
{ stdio: "pipe", timeout: 60_000 },
|
|
92
|
-
);
|
|
93
|
-
const downloaded = join(temporaryDirectory, artifact);
|
|
94
|
-
const expectedChecksum = readFileSync(`${downloaded}.sha256`, "utf-8").trim();
|
|
95
|
-
const actualChecksum = createHash("sha256")
|
|
96
|
-
.update(readFileSync(downloaded))
|
|
97
|
-
.digest("hex");
|
|
98
|
-
if (actualChecksum !== expectedChecksum) {
|
|
99
|
-
throw new Error(`Checksum mismatch for ${artifact}`);
|
|
52
|
+
if (isSourceCheckout()) {
|
|
53
|
+
console.error("[godd-native] Source-checkout install: packaged native verification skipped.");
|
|
54
|
+
} else {
|
|
55
|
+
verifyPackagedNative();
|
|
100
56
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
rmSync(destination, { force: true });
|
|
105
|
-
renameSync(staged, destination);
|
|
106
|
-
} finally {
|
|
107
|
-
rmSync(temporaryDirectory, { recursive: true, force: true });
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error(`[godd-native] Installation failed: ${error instanceof Error ? error.message : error}`);
|
|
59
|
+
process.exitCode = 1;
|
|
108
60
|
}
|
|
109
61
|
}
|
|
110
|
-
|
|
111
|
-
try {
|
|
112
|
-
main();
|
|
113
|
-
} catch (error) {
|
|
114
|
-
console.error(`[godd-native] Installation failed: ${error instanceof Error ? error.message : error}`);
|
|
115
|
-
process.exitCode = 1;
|
|
116
|
-
}
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,25 +1,51 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
4
|
+
import { dirname, join, resolve } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
|
|
7
7
|
const scriptsDirectory = dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
export const INSTALLERS = [
|
|
9
|
+
{ name: "godd-native", script: "postinstall-godd-native.js", required: true },
|
|
10
|
+
{
|
|
11
|
+
name: "godd-tk",
|
|
12
|
+
script: "postinstall-godd-tk.js",
|
|
13
|
+
required: false,
|
|
14
|
+
optInEnvironment: "GODD_INSTALL_GODD_TK",
|
|
15
|
+
},
|
|
11
16
|
];
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
export function runInstallers(execute = spawnSync) {
|
|
19
|
+
let failed = false;
|
|
20
|
+
for (const { name, script, required, optInEnvironment } of INSTALLERS) {
|
|
21
|
+
if (
|
|
22
|
+
optInEnvironment &&
|
|
23
|
+
process.env[optInEnvironment] !== "1"
|
|
24
|
+
) {
|
|
25
|
+
console.error(
|
|
26
|
+
`[${name}] Optional installer skipped; set ${optInEnvironment}=1 to opt in.`,
|
|
27
|
+
);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const result = execute(process.execPath, [join(scriptsDirectory, script)], {
|
|
31
|
+
stdio: "inherit",
|
|
32
|
+
timeout: 120_000,
|
|
33
|
+
});
|
|
34
|
+
if (result.error) {
|
|
35
|
+
console.error(`[${name}] Installer could not be executed: ${result.error.message}`);
|
|
36
|
+
if (required) failed = true;
|
|
37
|
+
} else if (result.status !== 0) {
|
|
38
|
+
if (required) {
|
|
39
|
+
console.error(`[${name}] Required installer exited with status ${result.status}; installation failed.`);
|
|
40
|
+
failed = true;
|
|
41
|
+
} else {
|
|
42
|
+
console.error(`[${name}] Optional installer exited with status ${result.status}; MCP installation continues without this optional component.`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
24
45
|
}
|
|
46
|
+
return failed ? 1 : 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
50
|
+
process.exitCode = runInstallers();
|
|
25
51
|
}
|