chore: A round of "yarn fix" for everyone (#75)
This commit is contained in:
parent
08b34f4f76
commit
7c9d61d9e6
11 changed files with 58 additions and 42 deletions
2
CLI.md
2
CLI.md
|
|
@ -157,12 +157,10 @@ dxt unsign my-extension.dxt
|
||||||
For signing extensions, you need:
|
For signing extensions, you need:
|
||||||
|
|
||||||
1. **Certificate**: X.509 certificate in PEM format
|
1. **Certificate**: X.509 certificate in PEM format
|
||||||
|
|
||||||
- Should have Code Signing extended key usage
|
- Should have Code Signing extended key usage
|
||||||
- Can be self-signed (for development) or CA-issued (for production)
|
- Can be self-signed (for development) or CA-issued (for production)
|
||||||
|
|
||||||
2. **Private Key**: Corresponding private key in PEM format
|
2. **Private Key**: Corresponding private key in PEM format
|
||||||
|
|
||||||
- Must match the certificate's public key
|
- Must match the certificate's public key
|
||||||
|
|
||||||
3. **Intermediate Certificates** (optional): For CA-issued certificates
|
3. **Intermediate Certificates** (optional): For CA-issued certificates
|
||||||
|
|
|
||||||
|
|
@ -290,14 +290,12 @@ The `server` object defines how to run the MCP server:
|
||||||
### Server Types
|
### Server Types
|
||||||
|
|
||||||
1. **Python**: `server.type = "python"`
|
1. **Python**: `server.type = "python"`
|
||||||
|
|
||||||
- Requires `entry_point` to Python file
|
- Requires `entry_point` to Python file
|
||||||
- All dependencies must be bundled in the DXT
|
- All dependencies must be bundled in the DXT
|
||||||
- Can use `server/lib` for packages or `server/venv` for full virtual environment
|
- Can use `server/lib` for packages or `server/venv` for full virtual environment
|
||||||
- Python runtime version specified in `compatibility.runtimes.python`
|
- Python runtime version specified in `compatibility.runtimes.python`
|
||||||
|
|
||||||
2. **Node.js**: `server.type = "node"`
|
2. **Node.js**: `server.type = "node"`
|
||||||
|
|
||||||
- Requires `entry_point` to JavaScript file
|
- Requires `entry_point` to JavaScript file
|
||||||
- All dependencies must be bundled in `node_modules`
|
- All dependencies must be bundled in `node_modules`
|
||||||
- Node.js runtime version specified in `compatibility.runtimes.node`
|
- Node.js runtime version specified in `compatibility.runtimes.node`
|
||||||
|
|
|
||||||
|
|
@ -71,11 +71,7 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": ["api", "automation", "productivity"],
|
||||||
"api",
|
|
||||||
"automation",
|
|
||||||
"productivity"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"claude_desktop": ">=0.10.0",
|
"claude_desktop": ">=0.10.0",
|
||||||
|
|
@ -94,4 +90,4 @@
|
||||||
"default": []
|
"default": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,4 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/server-filesystem": "2025.1.14"
|
"@modelcontextprotocol/server-filesystem": "2025.1.14"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,20 +13,23 @@ const loadServer = async () => {
|
||||||
try {
|
try {
|
||||||
// Save original argv
|
// Save original argv
|
||||||
const originalArgv = process.argv;
|
const originalArgv = process.argv;
|
||||||
|
|
||||||
// The filesystem server expects directories as command line arguments
|
// The filesystem server expects directories as command line arguments
|
||||||
process.argv = [process.argv[0], process.argv[1], ...args];
|
process.argv = [process.argv[0], process.argv[1], ...args];
|
||||||
|
|
||||||
// Dynamically import the ESM module
|
// Dynamically import the ESM module
|
||||||
await import('@modelcontextprotocol/server-filesystem/dist/index.js');
|
await import("@modelcontextprotocol/server-filesystem/dist/index.js");
|
||||||
|
|
||||||
// Restore original argv
|
// Restore original argv
|
||||||
process.argv = originalArgv;
|
process.argv = originalArgv;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load @modelcontextprotocol/server-filesystem:', error);
|
console.error(
|
||||||
|
"Failed to load @modelcontextprotocol/server-filesystem:",
|
||||||
|
error,
|
||||||
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Execute the async function
|
// Execute the async function
|
||||||
loadServer();
|
loadServer();
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export default {
|
||||||
"^.+\\.ts$": [
|
"^.+\\.ts$": [
|
||||||
"ts-jest",
|
"ts-jest",
|
||||||
{
|
{
|
||||||
tsConfig: 'tsconfig.test.json'
|
tsConfig: "tsconfig.test.json",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -78,5 +78,6 @@
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@babel/helpers": "7.27.1",
|
"@babel/helpers": "7.27.1",
|
||||||
"@babel/parser": "7.27.3"
|
"@babel/parser": "7.27.3"
|
||||||
}
|
},
|
||||||
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ import fs from "node:fs/promises";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
|
||||||
const schemasToWrite = {
|
const schemasToWrite = {
|
||||||
'dxt-manifest': DxtManifestSchema,
|
"dxt-manifest": DxtManifestSchema,
|
||||||
'dxt-signature-info': DxtSignatureInfoSchema
|
"dxt-signature-info": DxtSignatureInfoSchema,
|
||||||
}
|
};
|
||||||
|
|
||||||
await fs.mkdir(path.join(import.meta.dirname, "../dist"), { recursive: true });
|
await fs.mkdir(path.join(import.meta.dirname, "../dist"), { recursive: true });
|
||||||
|
|
||||||
|
|
@ -20,4 +20,3 @@ for (const key in schemasToWrite) {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
import { unzipSync } from "fflate";
|
import { unzipSync } from "fflate";
|
||||||
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
import {
|
||||||
|
chmodSync,
|
||||||
|
existsSync,
|
||||||
|
mkdirSync,
|
||||||
|
readFileSync,
|
||||||
|
writeFileSync,
|
||||||
|
} from "fs";
|
||||||
import { join, resolve, sep } from "path";
|
import { join, resolve, sep } from "path";
|
||||||
|
|
||||||
import { extractSignatureBlock } from "../node/sign.js";
|
import { extractSignatureBlock } from "../node/sign.js";
|
||||||
|
|
@ -41,7 +47,7 @@ export async function unpackExtension({
|
||||||
if (isUnix) {
|
if (isUnix) {
|
||||||
// Parse ZIP central directory to extract file attributes
|
// Parse ZIP central directory to extract file attributes
|
||||||
const zipBuffer = originalContent;
|
const zipBuffer = originalContent;
|
||||||
|
|
||||||
// Find end of central directory record
|
// Find end of central directory record
|
||||||
let eocdOffset = -1;
|
let eocdOffset = -1;
|
||||||
for (let i = zipBuffer.length - 22; i >= 0; i--) {
|
for (let i = zipBuffer.length - 22; i >= 0; i--) {
|
||||||
|
|
@ -54,21 +60,25 @@ export async function unpackExtension({
|
||||||
if (eocdOffset !== -1) {
|
if (eocdOffset !== -1) {
|
||||||
const centralDirOffset = zipBuffer.readUInt32LE(eocdOffset + 16);
|
const centralDirOffset = zipBuffer.readUInt32LE(eocdOffset + 16);
|
||||||
const centralDirEntries = zipBuffer.readUInt16LE(eocdOffset + 8);
|
const centralDirEntries = zipBuffer.readUInt16LE(eocdOffset + 8);
|
||||||
|
|
||||||
let offset = centralDirOffset;
|
let offset = centralDirOffset;
|
||||||
|
|
||||||
for (let i = 0; i < centralDirEntries; i++) {
|
for (let i = 0; i < centralDirEntries; i++) {
|
||||||
if (zipBuffer.readUInt32LE(offset) === 0x02014b50) {
|
if (zipBuffer.readUInt32LE(offset) === 0x02014b50) {
|
||||||
const externalAttrs = zipBuffer.readUInt32LE(offset + 38);
|
const externalAttrs = zipBuffer.readUInt32LE(offset + 38);
|
||||||
const filenameLength = zipBuffer.readUInt16LE(offset + 28);
|
const filenameLength = zipBuffer.readUInt16LE(offset + 28);
|
||||||
const filename = zipBuffer.toString('utf8', offset + 46, offset + 46 + filenameLength);
|
const filename = zipBuffer.toString(
|
||||||
|
"utf8",
|
||||||
|
offset + 46,
|
||||||
|
offset + 46 + filenameLength,
|
||||||
|
);
|
||||||
|
|
||||||
// Extract Unix permissions from external attributes (upper 16 bits)
|
// Extract Unix permissions from external attributes (upper 16 bits)
|
||||||
const mode = (externalAttrs >> 16) & 0o777;
|
const mode = (externalAttrs >> 16) & 0o777;
|
||||||
if (mode > 0) {
|
if (mode > 0) {
|
||||||
fileAttributes.set(filename, mode);
|
fileAttributes.set(filename, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
const extraFieldLength = zipBuffer.readUInt16LE(offset + 30);
|
const extraFieldLength = zipBuffer.readUInt16LE(offset + 30);
|
||||||
const commentLength = zipBuffer.readUInt16LE(offset + 32);
|
const commentLength = zipBuffer.readUInt16LE(offset + 32);
|
||||||
offset += 46 + filenameLength + extraFieldLength + commentLength;
|
offset += 46 + filenameLength + extraFieldLength + commentLength;
|
||||||
|
|
|
||||||
|
|
@ -204,10 +204,13 @@ describe("DXT CLI", () => {
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create an executable script
|
// Create an executable script
|
||||||
const executableScript = join(tempExecDir, "run-script.sh");
|
const executableScript = join(tempExecDir, "run-script.sh");
|
||||||
fs.writeFileSync(executableScript, "#!/bin/bash\necho 'Hello from executable'");
|
fs.writeFileSync(
|
||||||
|
executableScript,
|
||||||
|
"#!/bin/bash\necho 'Hello from executable'",
|
||||||
|
);
|
||||||
fs.chmodSync(executableScript, 0o755); // Make it executable
|
fs.chmodSync(executableScript, 0o755); // Make it executable
|
||||||
|
|
||||||
// Create a regular file for comparison
|
// Create a regular file for comparison
|
||||||
|
|
@ -221,25 +224,33 @@ describe("DXT CLI", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Unpack the extension
|
// Unpack the extension
|
||||||
execSync(`node ${cliPath} unpack ${execPackedFilePath} ${execUnpackedDir}`, {
|
execSync(
|
||||||
encoding: "utf-8",
|
`node ${cliPath} unpack ${execPackedFilePath} ${execUnpackedDir}`,
|
||||||
});
|
{
|
||||||
|
encoding: "utf-8",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// Check that the executable file preserved its permissions
|
// Check that the executable file preserved its permissions
|
||||||
const originalStats = fs.statSync(executableScript);
|
const originalStats = fs.statSync(executableScript);
|
||||||
const unpackedStats = fs.statSync(join(execUnpackedDir, "run-script.sh"));
|
const unpackedStats = fs.statSync(
|
||||||
|
join(execUnpackedDir, "run-script.sh"),
|
||||||
|
);
|
||||||
|
|
||||||
// Check that executable permissions are preserved (0o755)
|
// Check that executable permissions are preserved (0o755)
|
||||||
expect(unpackedStats.mode & 0o777).toBe(0o755);
|
expect(unpackedStats.mode & 0o777).toBe(0o755);
|
||||||
expect(originalStats.mode & 0o777).toBe(unpackedStats.mode & 0o777);
|
expect(originalStats.mode & 0o777).toBe(unpackedStats.mode & 0o777);
|
||||||
|
|
||||||
// Check that regular file permissions are preserved (0o644)
|
// Check that regular file permissions are preserved (0o644)
|
||||||
const originalRegularStats = fs.statSync(regularFile);
|
const originalRegularStats = fs.statSync(regularFile);
|
||||||
const unpackedRegularStats = fs.statSync(join(execUnpackedDir, "regular-file.txt"));
|
const unpackedRegularStats = fs.statSync(
|
||||||
|
join(execUnpackedDir, "regular-file.txt"),
|
||||||
expect(unpackedRegularStats.mode & 0o777).toBe(0o644);
|
);
|
||||||
expect(originalRegularStats.mode & 0o777).toBe(unpackedRegularStats.mode & 0o777);
|
|
||||||
|
|
||||||
|
expect(unpackedRegularStats.mode & 0o777).toBe(0o644);
|
||||||
|
expect(originalRegularStats.mode & 0o777).toBe(
|
||||||
|
unpackedRegularStats.mode & 0o777,
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
// Clean up
|
// Clean up
|
||||||
fs.rmSync(tempExecDir, { recursive: true, force: true });
|
fs.rmSync(tempExecDir, { recursive: true, force: true });
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"module": "node18",
|
"module": "node18",
|
||||||
"moduleResolution": "node16",
|
"moduleResolution": "node16",
|
||||||
"types": ["node", "jest"],
|
"types": ["node", "jest"]
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts", "test/**/*.ts"]
|
"include": ["src/**/*.ts", "test/**/*.ts"]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue