feat: add publish script for claude-mem
- Implemented a CLI tool for version bumping, building, and publishing to npm. - Added checks for uncommitted changes and current version retrieval. - Included options for patch, minor, major, and custom version bumps. - Integrated git commit and tagging after version update. - Added npm publish functionality and git push after successful publish. - Implemented error handling and user confirmations throughout the process.
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
# Build & Publish Guide
|
||||
|
||||
This repository is now the primary source for `claude-mem`. All builds and publishes happen from this repo.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Bun](https://bun.sh) - Fast JavaScript runtime and bundler
|
||||
- npm account with publish access to `claude-mem`
|
||||
|
||||
## Building
|
||||
|
||||
Build the project to create a bundled, minified executable:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
# or
|
||||
node build.js
|
||||
```
|
||||
|
||||
This will:
|
||||
1. Bundle all TypeScript source files using Bun
|
||||
2. Minify the output
|
||||
3. Add shebang (`#!/usr/bin/env node`)
|
||||
4. Set executable permissions
|
||||
5. Output to `dist/claude-mem.min.js`
|
||||
|
||||
### Build Output
|
||||
|
||||
- **Entry point:** `src/bin/cli.ts`
|
||||
- **Output:** `dist/claude-mem.min.js` (~350KB minified)
|
||||
- **Target:** Node.js (via Bun's `--target=node`)
|
||||
- **Externals:** `@anthropic-ai/claude-agent-sdk` (not bundled)
|
||||
|
||||
## Publishing
|
||||
|
||||
To publish a new version to npm:
|
||||
|
||||
```bash
|
||||
npm run publish:npm
|
||||
# or
|
||||
node publish.js
|
||||
```
|
||||
|
||||
The publish script will:
|
||||
1. Check git status (warn if uncommitted changes)
|
||||
2. Show current version and prompt for version bump type:
|
||||
- `patch` - Bug fixes (1.0.X)
|
||||
- `minor` - New features (1.X.0)
|
||||
- `major` - Breaking changes (X.0.0)
|
||||
- `custom` - Enter version manually
|
||||
3. Update `package.json` with new version
|
||||
4. Run build script
|
||||
5. Run tests (if configured)
|
||||
6. Create git commit and tag (`v{version}`)
|
||||
7. Publish to npm
|
||||
8. Push commit and tags to GitHub
|
||||
|
||||
### Manual Publishing
|
||||
|
||||
If you prefer to do it manually:
|
||||
|
||||
```bash
|
||||
# 1. Update version in package.json
|
||||
# 2. Build
|
||||
npm run build
|
||||
|
||||
# 3. Commit and tag
|
||||
git add package.json dist/
|
||||
git commit -m "Release v3.9.17"
|
||||
git tag v3.9.17
|
||||
|
||||
# 4. Publish
|
||||
npm publish
|
||||
|
||||
# 5. Push
|
||||
git push && git push --tags
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
Run the CLI directly from source without building:
|
||||
|
||||
```bash
|
||||
npm run dev -- [command] [options]
|
||||
# or
|
||||
bun run src/bin/cli.ts [command] [options]
|
||||
```
|
||||
|
||||
Example:
|
||||
```bash
|
||||
npm run dev -- status
|
||||
npm run dev -- --version
|
||||
```
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
claude-mem/
|
||||
├── src/ # TypeScript source
|
||||
│ ├── bin/cli.ts # CLI entry point
|
||||
│ ├── commands/ # Command implementations
|
||||
│ ├── services/ # Core services
|
||||
│ └── shared/ # Shared utilities
|
||||
├── dist/ # Build output
|
||||
│ └── claude-mem.min.js # Bundled executable
|
||||
├── build.js # Build script
|
||||
├── publish.js # Publish script
|
||||
└── package.json # Package configuration
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- The build process embeds the version from `package.json` at build time
|
||||
- `prepublishOnly` script ensures build runs before npm publish
|
||||
- Dependencies are bundled except for external packages
|
||||
- The published package includes: `dist/`, `hook-templates/`, `commands/`, `src/`
|
||||
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Build script for claude-mem
|
||||
* Bundles TypeScript source into a single minified executable
|
||||
*/
|
||||
|
||||
import { exec } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
async function build() {
|
||||
console.log('🔨 Building claude-mem...\n');
|
||||
|
||||
try {
|
||||
// Read version from package.json
|
||||
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
|
||||
const version = packageJson.version;
|
||||
console.log(`📌 Version: ${version}`);
|
||||
|
||||
// Check if bun is installed
|
||||
try {
|
||||
await execAsync('bun --version');
|
||||
console.log('✓ Bun detected');
|
||||
} catch {
|
||||
console.error('❌ Bun is not installed. Please install it from https://bun.sh');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Clean dist directory
|
||||
console.log('\n📦 Cleaning dist directory...');
|
||||
if (fs.existsSync('dist')) {
|
||||
fs.rmSync('dist', { recursive: true });
|
||||
}
|
||||
fs.mkdirSync('dist', { recursive: true });
|
||||
console.log('✓ Cleaned dist directory');
|
||||
|
||||
// Build with bun
|
||||
console.log('\n🔧 Bundling with Bun...');
|
||||
const buildCommand = [
|
||||
'bun build',
|
||||
'src/bin/cli.ts',
|
||||
'--target=node',
|
||||
'--outfile=dist/claude-mem.min.js',
|
||||
'--minify',
|
||||
'--external @anthropic-ai/claude-agent-sdk',
|
||||
`--define __DEFAULT_PACKAGE_VERSION__='"${version}"'`
|
||||
].join(' ');
|
||||
|
||||
const { stdout, stderr } = await execAsync(buildCommand);
|
||||
if (stdout) console.log(stdout);
|
||||
if (stderr && !stderr.includes('warn')) console.error(stderr);
|
||||
console.log('✓ Bundle created');
|
||||
|
||||
// Add shebang to output
|
||||
console.log('\n📝 Adding shebang...');
|
||||
const distFile = 'dist/claude-mem.min.js';
|
||||
const content = fs.readFileSync(distFile, 'utf-8');
|
||||
if (!content.startsWith('#!/usr/bin/env node')) {
|
||||
fs.writeFileSync(distFile, `#!/usr/bin/env node\n${content}`);
|
||||
}
|
||||
console.log('✓ Shebang added');
|
||||
|
||||
// Make executable
|
||||
console.log('\n🔐 Setting executable permissions...');
|
||||
fs.chmodSync(distFile, 0o755);
|
||||
console.log('✓ Made executable');
|
||||
|
||||
// Check file size
|
||||
const stats = fs.statSync(distFile);
|
||||
const sizeInKB = (stats.size / 1024).toFixed(2);
|
||||
console.log(`\n✅ Build complete! (${sizeInKB} KB)`);
|
||||
console.log(` Output: ${distFile}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('\n❌ Build failed:', error.message);
|
||||
if (error.stderr) {
|
||||
console.error('\nError details:', error.stderr);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
build();
|
||||
@@ -0,0 +1,260 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "claude-mem",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/claude-agent-sdk": "^0.1.0",
|
||||
"@clack/prompts": "^0.11.0",
|
||||
"better-sqlite3": "^11.8.1",
|
||||
"boxen": "^8.0.1",
|
||||
"chalk": "^5.6.0",
|
||||
"commander": "^14.0.0",
|
||||
"glob": "^11.0.3",
|
||||
"gradient-string": "^3.0.0",
|
||||
"handlebars": "^4.7.8",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.1.15", "", { "optionalDependencies": { "@img/sharp-darwin-arm64": "^0.33.5", "@img/sharp-darwin-x64": "^0.33.5", "@img/sharp-linux-arm": "^0.33.5", "@img/sharp-linux-arm64": "^0.33.5", "@img/sharp-linux-x64": "^0.33.5", "@img/sharp-win32-x64": "^0.33.5" }, "peerDependencies": { "zod": "^3.24.1" } }, "sha512-x0UR/YW87lRel3wYVimWjAkUOEGapg/nXx2GYNLbUD1ORsetRHeXZGFdJMuhRkk1Jt9sbn5m/RpT42b5R0pgYg=="],
|
||||
|
||||
"@clack/core": ["@clack/core@0.5.0", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow=="],
|
||||
|
||||
"@clack/prompts": ["@clack/prompts@0.11.0", "", { "dependencies": { "@clack/core": "0.5.0", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw=="],
|
||||
|
||||
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="],
|
||||
|
||||
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.0.4" }, "os": "darwin", "cpu": "x64" }, "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q=="],
|
||||
|
||||
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.0.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg=="],
|
||||
|
||||
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.0.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ=="],
|
||||
|
||||
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.0.5", "", { "os": "linux", "cpu": "arm" }, "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g=="],
|
||||
|
||||
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA=="],
|
||||
|
||||
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw=="],
|
||||
|
||||
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.0.5" }, "os": "linux", "cpu": "arm" }, "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ=="],
|
||||
|
||||
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.0.4" }, "os": "linux", "cpu": "arm64" }, "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA=="],
|
||||
|
||||
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.0.4" }, "os": "linux", "cpu": "x64" }, "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA=="],
|
||||
|
||||
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.33.5", "", { "os": "win32", "cpu": "x64" }, "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg=="],
|
||||
|
||||
"@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="],
|
||||
|
||||
"@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.0", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA=="],
|
||||
|
||||
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
|
||||
|
||||
"@types/tinycolor2": ["@types/tinycolor2@1.4.6", "", {}, "sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw=="],
|
||||
|
||||
"ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="],
|
||||
|
||||
"ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
|
||||
|
||||
"ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
||||
|
||||
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
||||
|
||||
"better-sqlite3": ["better-sqlite3@11.10.0", "", { "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" } }, "sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ=="],
|
||||
|
||||
"bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="],
|
||||
|
||||
"bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
|
||||
|
||||
"boxen": ["boxen@8.0.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^8.0.0", "chalk": "^5.3.0", "cli-boxes": "^3.0.0", "string-width": "^7.2.0", "type-fest": "^4.21.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0" } }, "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw=="],
|
||||
|
||||
"buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
|
||||
|
||||
"camelcase": ["camelcase@8.0.0", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="],
|
||||
|
||||
"chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
|
||||
|
||||
"chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="],
|
||||
|
||||
"cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="],
|
||||
|
||||
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||
|
||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||
|
||||
"commander": ["commander@14.0.1", "", {}, "sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A=="],
|
||||
|
||||
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
||||
|
||||
"decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="],
|
||||
|
||||
"deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="],
|
||||
|
||||
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
||||
|
||||
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
|
||||
|
||||
"emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
|
||||
|
||||
"end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
|
||||
|
||||
"expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="],
|
||||
|
||||
"file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="],
|
||||
|
||||
"foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
|
||||
|
||||
"fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="],
|
||||
|
||||
"get-east-asian-width": ["get-east-asian-width@1.4.0", "", {}, "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q=="],
|
||||
|
||||
"github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="],
|
||||
|
||||
"glob": ["glob@11.0.3", "", { "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", "minimatch": "^10.0.3", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA=="],
|
||||
|
||||
"gradient-string": ["gradient-string@3.0.0", "", { "dependencies": { "chalk": "^5.3.0", "tinygradient": "^1.1.5" } }, "sha512-frdKI4Qi8Ihp4C6wZNB565de/THpIaw3DjP5ku87M+N9rNSGmPTjfkq61SdRXB7eCaL8O1hkKDvf6CDMtOzIAg=="],
|
||||
|
||||
"handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": { "handlebars": "bin/handlebars" } }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="],
|
||||
|
||||
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
||||
|
||||
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
||||
|
||||
"ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="],
|
||||
|
||||
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
|
||||
|
||||
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
||||
|
||||
"jackspeak": ["jackspeak@4.1.1", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" } }, "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ=="],
|
||||
|
||||
"lru-cache": ["lru-cache@11.2.2", "", {}, "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg=="],
|
||||
|
||||
"mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="],
|
||||
|
||||
"minimatch": ["minimatch@10.0.3", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw=="],
|
||||
|
||||
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
||||
|
||||
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
|
||||
|
||||
"mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="],
|
||||
|
||||
"napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="],
|
||||
|
||||
"neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="],
|
||||
|
||||
"node-abi": ["node-abi@3.78.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-E2wEyrgX/CqvicaQYU3Ze1PFGjc4QYPGsjUrlYkqAE0WjHEZwgOsGMPMzkMse4LjJbDmaEuDX3CM036j5K2DSQ=="],
|
||||
|
||||
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
|
||||
|
||||
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
|
||||
|
||||
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
||||
|
||||
"path-scurry": ["path-scurry@2.0.0", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg=="],
|
||||
|
||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||
|
||||
"prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="],
|
||||
|
||||
"pump": ["pump@3.0.3", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="],
|
||||
|
||||
"rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
|
||||
|
||||
"readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
||||
|
||||
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||
|
||||
"semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
||||
|
||||
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
||||
|
||||
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
||||
|
||||
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
|
||||
|
||||
"simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="],
|
||||
|
||||
"simple-get": ["simple-get@4.0.1", "", { "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA=="],
|
||||
|
||||
"sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
|
||||
|
||||
"source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
||||
|
||||
"string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
|
||||
|
||||
"string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||
|
||||
"string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
|
||||
|
||||
"strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
|
||||
|
||||
"strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||
|
||||
"strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
|
||||
|
||||
"tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="],
|
||||
|
||||
"tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
|
||||
|
||||
"tinycolor2": ["tinycolor2@1.6.0", "", {}, "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw=="],
|
||||
|
||||
"tinygradient": ["tinygradient@1.1.5", "", { "dependencies": { "@types/tinycolor2": "^1.4.0", "tinycolor2": "^1.0.0" } }, "sha512-8nIfc2vgQ4TeLnk2lFj4tRLvvJwEfQuabdsmvDdQPT0xlk9TaNtpGd6nNRxXoK6vQhN6RSzj+Cnp5tTQmpxmbw=="],
|
||||
|
||||
"tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
|
||||
|
||||
"type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
|
||||
|
||||
"uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="],
|
||||
|
||||
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
||||
|
||||
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||
|
||||
"widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="],
|
||||
|
||||
"wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="],
|
||||
|
||||
"wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="],
|
||||
|
||||
"wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
||||
|
||||
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
|
||||
|
||||
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||
|
||||
"@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
|
||||
|
||||
"@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
|
||||
|
||||
"ansi-align/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||
|
||||
"string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||
|
||||
"string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||
|
||||
"strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||
|
||||
"wrap-ansi-cjs/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||
|
||||
"wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||
|
||||
"@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
||||
|
||||
"ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||
|
||||
"ansi-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||
|
||||
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||
|
||||
"wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||
|
||||
"wrap-ansi-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||
|
||||
"ansi-align/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||
}
|
||||
}
|
||||
Vendored
+214
-225
File diff suppressed because one or more lines are too long
@@ -35,9 +35,16 @@
|
||||
"bin": {
|
||||
"claude-mem": "./dist/claude-mem.min.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node build.js",
|
||||
"publish:npm": "node publish.js",
|
||||
"dev": "bun run src/bin/cli.ts",
|
||||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anthropic-ai/claude-agent-sdk": "^0.1.0",
|
||||
"@clack/prompts": "^0.11.0",
|
||||
"better-sqlite3": "^11.8.1",
|
||||
"boxen": "^8.0.1",
|
||||
"chalk": "^5.6.0",
|
||||
"commander": "^14.0.0",
|
||||
|
||||
Executable
+172
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Publish script for claude-mem
|
||||
* Handles version bumping, building, and publishing to npm
|
||||
*/
|
||||
|
||||
import { exec } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
import fs from 'fs';
|
||||
import readline from 'readline';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
|
||||
const question = (query) => new Promise((resolve) => rl.question(query, resolve));
|
||||
|
||||
async function publish() {
|
||||
try {
|
||||
console.log('📦 Claude-mem Publishing Tool\n');
|
||||
|
||||
// Check git status
|
||||
console.log('🔍 Checking git status...');
|
||||
const { stdout: gitStatus } = await execAsync('git status --porcelain');
|
||||
if (gitStatus.trim()) {
|
||||
console.log('⚠️ Uncommitted changes detected:');
|
||||
console.log(gitStatus);
|
||||
const proceed = await question('\nContinue anyway? (y/N) ');
|
||||
if (proceed.toLowerCase() !== 'y') {
|
||||
console.log('Aborted.');
|
||||
rl.close();
|
||||
process.exit(0);
|
||||
}
|
||||
} else {
|
||||
console.log('✓ Working directory clean');
|
||||
}
|
||||
|
||||
// Get current version
|
||||
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
|
||||
const currentVersion = packageJson.version;
|
||||
console.log(`\n📌 Current version: ${currentVersion}`);
|
||||
|
||||
// Ask for version bump type
|
||||
console.log('\nVersion bump type:');
|
||||
console.log(' 1. patch (x.x.X) - Bug fixes');
|
||||
console.log(' 2. minor (x.X.0) - New features');
|
||||
console.log(' 3. major (X.0.0) - Breaking changes');
|
||||
console.log(' 4. custom - Enter version manually');
|
||||
|
||||
const bumpType = await question('\nSelect bump type (1-4): ');
|
||||
let newVersion;
|
||||
|
||||
switch (bumpType.trim()) {
|
||||
case '1':
|
||||
newVersion = bumpVersion(currentVersion, 'patch');
|
||||
break;
|
||||
case '2':
|
||||
newVersion = bumpVersion(currentVersion, 'minor');
|
||||
break;
|
||||
case '3':
|
||||
newVersion = bumpVersion(currentVersion, 'major');
|
||||
break;
|
||||
case '4':
|
||||
newVersion = await question('Enter version: ');
|
||||
if (!isValidVersion(newVersion)) {
|
||||
throw new Error('Invalid version format. Use semver (e.g., 1.2.3)');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error('Invalid selection');
|
||||
}
|
||||
|
||||
console.log(`\n🎯 New version: ${newVersion}`);
|
||||
const confirm = await question('\nProceed with publish? (y/N) ');
|
||||
if (confirm.toLowerCase() !== 'y') {
|
||||
console.log('Aborted.');
|
||||
rl.close();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Update package.json version
|
||||
console.log('\n📝 Updating package.json...');
|
||||
packageJson.version = newVersion;
|
||||
fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2) + '\n');
|
||||
console.log('✓ Version updated');
|
||||
|
||||
// Run build
|
||||
console.log('\n🔨 Building...');
|
||||
await execAsync('node build.js');
|
||||
console.log('✓ Build complete');
|
||||
|
||||
// Run tests if they exist
|
||||
if (packageJson.scripts?.test) {
|
||||
console.log('\n🧪 Running tests...');
|
||||
try {
|
||||
await execAsync('npm test');
|
||||
console.log('✓ Tests passed');
|
||||
} catch (error) {
|
||||
console.error('❌ Tests failed:', error.message);
|
||||
const continueAnyway = await question('\nPublish anyway? (y/N) ');
|
||||
if (continueAnyway.toLowerCase() !== 'y') {
|
||||
console.log('Aborted.');
|
||||
rl.close();
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Git commit and tag
|
||||
console.log('\n📌 Creating git commit and tag...');
|
||||
await execAsync('git add package.json dist/');
|
||||
await execAsync(`git commit -m "Release v${newVersion}
|
||||
|
||||
Published from npm package build
|
||||
Source: https://github.com/thedotmack/claude-mem"`);
|
||||
await execAsync(`git tag v${newVersion}`);
|
||||
console.log(`✓ Created commit and tag v${newVersion}`);
|
||||
|
||||
// Publish to npm
|
||||
console.log('\n🚀 Publishing to npm...');
|
||||
await execAsync('npm publish');
|
||||
console.log('✓ Published to npm');
|
||||
|
||||
// Push to git
|
||||
console.log('\n⬆️ Pushing to git...');
|
||||
await execAsync('git push');
|
||||
await execAsync('git push --tags');
|
||||
console.log('✓ Pushed to git');
|
||||
|
||||
console.log(`\n✅ Successfully published v${newVersion}! 🎉`);
|
||||
console.log(`\n📦 Package: https://www.npmjs.com/package/claude-mem`);
|
||||
console.log(`🏷️ Tag: https://github.com/thedotmack/claude-mem/releases/tag/v${newVersion}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('\n❌ Publish failed:', error.message);
|
||||
if (error.stderr) {
|
||||
console.error('\nError details:', error.stderr);
|
||||
}
|
||||
process.exit(1);
|
||||
} finally {
|
||||
rl.close();
|
||||
}
|
||||
}
|
||||
|
||||
function bumpVersion(version, type) {
|
||||
const parts = version.split('.').map(Number);
|
||||
switch (type) {
|
||||
case 'patch':
|
||||
parts[2]++;
|
||||
break;
|
||||
case 'minor':
|
||||
parts[1]++;
|
||||
parts[2] = 0;
|
||||
break;
|
||||
case 'major':
|
||||
parts[0]++;
|
||||
parts[1] = 0;
|
||||
parts[2] = 0;
|
||||
break;
|
||||
}
|
||||
return parts.join('.');
|
||||
}
|
||||
|
||||
function isValidVersion(version) {
|
||||
return /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/.test(version);
|
||||
}
|
||||
|
||||
publish();
|
||||
@@ -22,11 +22,6 @@ import { storeMemory } from '../commands/store-memory.js';
|
||||
import { storeOverview } from '../commands/store-overview.js';
|
||||
import { updateSessionMetadata } from '../commands/update-session-metadata.js';
|
||||
import { generateTitle } from '../commands/generate-title.js';
|
||||
import {
|
||||
executeChromaMCPTool,
|
||||
loadChromaMCPTools,
|
||||
generateCommandOptions
|
||||
} from '../commands/chroma-mcp.js';
|
||||
|
||||
const program = new Command();
|
||||
// </Block> =======================================
|
||||
@@ -230,37 +225,6 @@ program
|
||||
|
||||
// </Block> =======================================
|
||||
|
||||
// <Block> 1.12 ===================================
|
||||
// Dynamic Chroma MCP Commands
|
||||
// Natural pattern: Register all Chroma MCP tools as CLI commands
|
||||
try {
|
||||
const chromaTools = loadChromaMCPTools();
|
||||
|
||||
for (const tool of chromaTools) {
|
||||
const cmd = program
|
||||
.command(tool.name)
|
||||
.description(tool.description || `Execute ${tool.name} MCP tool`);
|
||||
|
||||
// Add options from tool schema
|
||||
const options = generateCommandOptions(tool.inputSchema);
|
||||
for (const opt of options) {
|
||||
if (opt.required) {
|
||||
cmd.requiredOption(opt.flag, opt.description);
|
||||
} else {
|
||||
cmd.option(opt.flag, opt.description);
|
||||
}
|
||||
}
|
||||
|
||||
// Set action handler
|
||||
cmd.action(async (options: OptionValues) => {
|
||||
await executeChromaMCPTool(tool.name, options);
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Warning: Could not load Chroma MCP tools:', error);
|
||||
}
|
||||
// </Block> =======================================
|
||||
|
||||
// <Block> 1.11 ===================================
|
||||
// CLI Execution
|
||||
// Natural pattern: After defining all commands, parse and execute
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
import { OptionValues } from 'commander';
|
||||
import ChromaMCPClient from '../../chroma-mcp-tools/chroma-mcp-client.js';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
/**
|
||||
* Generic Chroma MCP tool executor
|
||||
* Dynamically calls any Chroma MCP tool with provided arguments
|
||||
*/
|
||||
export async function executeChromaMCPTool(toolName: string, options: OptionValues): Promise<void> {
|
||||
const client = new ChromaMCPClient();
|
||||
|
||||
try {
|
||||
await client.connect();
|
||||
|
||||
// Convert commander options to tool arguments
|
||||
const toolArgs = convertOptionsToArgs(toolName, options);
|
||||
|
||||
// Call the MCP tool
|
||||
const result = await client.callTool(toolName, toolArgs);
|
||||
|
||||
// Parse and format the result nicely
|
||||
const formatted = formatMCPResult(result);
|
||||
console.log(formatted);
|
||||
|
||||
await client.disconnect();
|
||||
process.exit(0);
|
||||
} catch (error: any) {
|
||||
console.error(JSON.stringify({
|
||||
success: false,
|
||||
error: error.message || 'Unknown error calling MCP tool',
|
||||
tool: toolName
|
||||
}, null, 2));
|
||||
|
||||
await client.disconnect();
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format MCP tool result for clean CLI output
|
||||
*/
|
||||
function formatMCPResult(result: any): string {
|
||||
// If result has content array (MCP protocol format)
|
||||
if (result?.content && Array.isArray(result.content)) {
|
||||
const textContent = result.content
|
||||
.filter((item: any) => item.type === 'text')
|
||||
.map((item: any) => item.text)
|
||||
.join('\n');
|
||||
|
||||
// Try to parse as JSON for prettier output
|
||||
try {
|
||||
const parsed = JSON.parse(textContent);
|
||||
return JSON.stringify(parsed, null, 2);
|
||||
} catch {
|
||||
// Not JSON, return as-is
|
||||
return textContent;
|
||||
}
|
||||
}
|
||||
|
||||
// If result is already an object, pretty print it
|
||||
if (typeof result === 'object') {
|
||||
return JSON.stringify(result, null, 2);
|
||||
}
|
||||
|
||||
// Fallback to string
|
||||
return String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert CLI options to MCP tool arguments
|
||||
* Handles type conversion and array parsing
|
||||
*/
|
||||
function convertOptionsToArgs(toolName: string, options: OptionValues): Record<string, any> {
|
||||
const args: Record<string, any> = {};
|
||||
|
||||
for (const [key, value] of Object.entries(options)) {
|
||||
// Skip commander internal properties
|
||||
if (key.startsWith('_') || typeof value === 'function') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to parse JSON strings
|
||||
if (typeof value === 'string') {
|
||||
try {
|
||||
args[key] = JSON.parse(value);
|
||||
} catch {
|
||||
args[key] = value;
|
||||
}
|
||||
} else {
|
||||
args[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Chroma MCP tool definitions from JSON
|
||||
*/
|
||||
export function loadChromaMCPTools(): Array<{
|
||||
name: string;
|
||||
description: string;
|
||||
inputSchema: any;
|
||||
}> {
|
||||
// Try multiple path resolutions for dev vs production
|
||||
const possiblePaths = [
|
||||
path.join(__dirname, '../../chroma-mcp-tools/CHROMA_MCP_TOOLS.json'),
|
||||
path.join(process.cwd(), 'chroma-mcp-tools/CHROMA_MCP_TOOLS.json'),
|
||||
path.join(__dirname, '../chroma-mcp-tools/CHROMA_MCP_TOOLS.json')
|
||||
];
|
||||
|
||||
for (const toolsPath of possiblePaths) {
|
||||
if (fs.existsSync(toolsPath)) {
|
||||
const toolsJson = fs.readFileSync(toolsPath, 'utf-8');
|
||||
return JSON.parse(toolsJson);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('Could not find CHROMA_MCP_TOOLS.json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate CLI command options from MCP tool schema
|
||||
*/
|
||||
export function generateCommandOptions(schema: any): Array<{
|
||||
flag: string;
|
||||
description: string;
|
||||
required: boolean;
|
||||
type: string;
|
||||
}> {
|
||||
const options: Array<{
|
||||
flag: string;
|
||||
description: string;
|
||||
required: boolean;
|
||||
type: string;
|
||||
}> = [];
|
||||
|
||||
if (!schema.properties) return options;
|
||||
|
||||
const required = schema.required || [];
|
||||
|
||||
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
||||
const prop = propSchema as any;
|
||||
const isRequired = required.includes(propName);
|
||||
|
||||
// Determine type
|
||||
let type = 'string';
|
||||
if (prop.type === 'integer' || prop.type === 'number') {
|
||||
type = 'number';
|
||||
} else if (prop.type === 'array') {
|
||||
type = 'array';
|
||||
} else if (prop.type === 'object') {
|
||||
type = 'json';
|
||||
} else if (prop.anyOf) {
|
||||
// Handle nullable types
|
||||
const nonNullType = prop.anyOf.find((t: any) => t.type !== 'null');
|
||||
if (nonNullType?.type === 'integer' || nonNullType?.type === 'number') {
|
||||
type = 'number';
|
||||
} else if (nonNullType?.type === 'array') {
|
||||
type = 'array';
|
||||
} else if (nonNullType?.type === 'object') {
|
||||
type = 'json';
|
||||
}
|
||||
}
|
||||
|
||||
// Build flag
|
||||
const flag = isRequired
|
||||
? `--${propName} <${type}>`
|
||||
: `--${propName} [${type}]`;
|
||||
|
||||
// Build description
|
||||
let description = prop.title || propName;
|
||||
if (prop.default !== undefined) {
|
||||
description += ` (default: ${JSON.stringify(prop.default)})`;
|
||||
}
|
||||
if (type === 'array') {
|
||||
description += ' (JSON array)';
|
||||
} else if (type === 'json') {
|
||||
description += ' (JSON object)';
|
||||
}
|
||||
|
||||
options.push({
|
||||
flag,
|
||||
description,
|
||||
required: isRequired,
|
||||
type
|
||||
});
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
Reference in New Issue
Block a user