agentic-payments 0.1.9 → 0.1.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-payments",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Dual-protocol payment infrastructure for autonomous AI commerce (AP2 + ACP)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -40,6 +40,7 @@
40
40
  "dist",
41
41
  "bin",
42
42
  "completions",
43
+ "scripts",
43
44
  "README.md",
44
45
  "LICENSE-MIT",
45
46
  "LICENSE-APACHE"
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * WASM Build Script - Production-ready multi-target compilation
5
+ * Builds optimized WASM modules for web, Node.js, and bundler environments
6
+ *
7
+ * Target size: <200KB gzipped WASM
8
+ * Features: Ed25519 crypto, protocol routing, batch verification
9
+ */
10
+
11
+ import { spawnSync } from 'child_process';
12
+ import { existsSync, mkdirSync, rmSync, statSync, readFileSync } from 'fs';
13
+ import { join, dirname } from 'path';
14
+ import { fileURLToPath } from 'url';
15
+ import { gzipSync } from 'zlib';
16
+
17
+ const __filename = fileURLToPath(import.meta.url);
18
+ const __dirname = dirname(__filename);
19
+ const ROOT_DIR = join(__dirname, '..', '..');
20
+ const NPM_DIR = join(ROOT_DIR, 'npm');
21
+ const DIST_WASM_DIR = join(NPM_DIR, 'dist', 'wasm');
22
+
23
+ // ANSI colors for terminal output
24
+ const colors = {
25
+ reset: '\x1b[0m',
26
+ red: '\x1b[31m',
27
+ green: '\x1b[32m',
28
+ yellow: '\x1b[33m',
29
+ blue: '\x1b[34m',
30
+ magenta: '\x1b[35m',
31
+ cyan: '\x1b[36m',
32
+ white: '\x1b[37m',
33
+ bold: '\x1b[1m',
34
+ };
35
+
36
+ const log = {
37
+ info: (msg) => console.log(`${colors.blue}ℹ${colors.reset} ${msg}`),
38
+ success: (msg) => console.log(`${colors.green}✓${colors.reset} ${msg}`),
39
+ warning: (msg) => console.log(`${colors.yellow}⚠${colors.reset} ${msg}`),
40
+ error: (msg) => console.error(`${colors.red}✗${colors.reset} ${msg}`),
41
+ step: (msg) => console.log(`${colors.cyan}▶${colors.reset} ${colors.bold}${msg}${colors.reset}`),
42
+ };
43
+
44
+ /**
45
+ * Execute shell command with error handling
46
+ */
47
+ function exec(command, args, options = {}) {
48
+ log.info(`Running: ${command} ${args.join(' ')}`);
49
+
50
+ const result = spawnSync(command, args, {
51
+ stdio: 'inherit',
52
+ cwd: ROOT_DIR,
53
+ ...options,
54
+ });
55
+
56
+ if (result.error) {
57
+ log.error(`Failed to execute: ${result.error.message}`);
58
+ throw result.error;
59
+ }
60
+
61
+ if (result.status !== 0) {
62
+ log.error(`Command failed with exit code ${result.status}`);
63
+ process.exit(result.status || 1);
64
+ }
65
+
66
+ return result;
67
+ }
68
+
69
+ /**
70
+ * Get file size in KB
71
+ */
72
+ function getFileSize(filepath) {
73
+ if (!existsSync(filepath)) return 0;
74
+ return Math.round(statSync(filepath).size / 1024);
75
+ }
76
+
77
+ /**
78
+ * Get gzipped size
79
+ */
80
+ function getGzipSize(filepath) {
81
+ if (!existsSync(filepath)) return 0;
82
+ const content = readFileSync(filepath);
83
+ const compressed = gzipSync(content, { level: 9 });
84
+ return Math.round(compressed.length / 1024);
85
+ }
86
+
87
+ /**
88
+ * Print build summary
89
+ */
90
+ function printSummary(targets) {
91
+ console.log('\n' + '='.repeat(60));
92
+ log.step('Build Summary');
93
+ console.log('='.repeat(60));
94
+
95
+ for (const target of targets) {
96
+ const wasmPath = join(DIST_WASM_DIR, target, 'agentic_payments_bg.wasm');
97
+ const jsPath = join(DIST_WASM_DIR, target, 'agentic_payments.js');
98
+
99
+ if (!existsSync(wasmPath)) {
100
+ log.warning(`${target}: Build artifacts not found`);
101
+ continue;
102
+ }
103
+
104
+ const wasmSize = getFileSize(wasmPath);
105
+ const wasmGzip = getGzipSize(wasmPath);
106
+ const jsSize = getFileSize(jsPath);
107
+ const jsGzip = getGzipSize(jsPath);
108
+ const totalGzip = wasmGzip + jsGzip;
109
+
110
+ console.log(`\n${colors.bold}${target}:${colors.reset}`);
111
+ console.log(` WASM: ${wasmSize} KB (${wasmGzip} KB gzipped)`);
112
+ console.log(` JS: ${jsSize} KB (${jsGzip} KB gzipped)`);
113
+ console.log(` Total: ${totalGzip} KB gzipped`);
114
+
115
+ if (totalGzip > 200) {
116
+ log.warning(` Exceeds 200KB target by ${totalGzip - 200} KB`);
117
+ } else {
118
+ log.success(` Within 200KB target (${200 - totalGzip} KB margin)`);
119
+ }
120
+ }
121
+
122
+ console.log('\n' + '='.repeat(60) + '\n');
123
+ }
124
+
125
+ /**
126
+ * Check if wasm-pack is installed
127
+ */
128
+ function checkWasmPack() {
129
+ log.step('Checking dependencies');
130
+
131
+ try {
132
+ const result = spawnSync('wasm-pack', ['--version'], { stdio: 'pipe' });
133
+ if (result.status === 0) {
134
+ const version = result.stdout.toString().trim();
135
+ log.success(`wasm-pack found: ${version}`);
136
+ return true;
137
+ }
138
+ } catch (error) {
139
+ // wasm-pack not found
140
+ }
141
+
142
+ log.error('wasm-pack not found!');
143
+ log.info('Install with: cargo install wasm-pack');
144
+ process.exit(1);
145
+ }
146
+
147
+ /**
148
+ * Main build function
149
+ */
150
+ async function main() {
151
+ const startTime = Date.now();
152
+
153
+ console.log(`
154
+ ${colors.cyan}╔═══════════════════════════════════════════════════════════╗
155
+ ║ Agentic Payments - WASM Build ║
156
+ ║ Multi-target compilation with size optimization ║
157
+ ╚═══════════════════════════════════════════════════════════╝${colors.reset}
158
+ `);
159
+
160
+ // Check dependencies
161
+ checkWasmPack();
162
+
163
+ // Clean previous builds
164
+ log.step('Cleaning previous builds');
165
+ if (existsSync(DIST_WASM_DIR)) {
166
+ rmSync(DIST_WASM_DIR, { recursive: true, force: true });
167
+ log.success('Cleaned dist/wasm directory');
168
+ }
169
+ mkdirSync(DIST_WASM_DIR, { recursive: true });
170
+
171
+ // Build targets
172
+ const targets = [
173
+ { name: 'web', desc: 'Browser (ES modules)' },
174
+ { name: 'nodejs', desc: 'Node.js (CommonJS)' },
175
+ { name: 'bundler', desc: 'Webpack/Rollup/Vite' },
176
+ ];
177
+
178
+ for (const target of targets) {
179
+ log.step(`Building for ${target.desc}`);
180
+
181
+ const outDir = join(DIST_WASM_DIR, target.name);
182
+
183
+ exec('wasm-pack', [
184
+ 'build',
185
+ '--target', target.name,
186
+ '--out-dir', outDir,
187
+ '--out-name', 'agentic_payments',
188
+ '--scope', 'agentic-catalog',
189
+ '--release',
190
+ '--',
191
+ '--no-default-features',
192
+ '--features', 'wasm',
193
+ ]);
194
+
195
+ log.success(`${target.name} build complete`);
196
+ }
197
+
198
+ // Print summary
199
+ printSummary(targets.map(t => t.name));
200
+
201
+ const duration = ((Date.now() - startTime) / 1000).toFixed(2);
202
+ log.success(`Build completed in ${duration}s`);
203
+ }
204
+
205
+ // Run build
206
+ main().catch((error) => {
207
+ log.error(`Build failed: ${error.message}`);
208
+ process.exit(1);
209
+ });
@@ -0,0 +1,204 @@
1
+ #!/usr/bin/env bash
2
+
3
+ #
4
+ # WASM Build Script - Multi-target WASM compilation
5
+ # Builds optimized WASM modules for web, Node.js, and bundler environments
6
+ #
7
+ # Usage: ./scripts/build-wasm.sh [target]
8
+ # target: web, nodejs, bundler, or all (default: all)
9
+ #
10
+ # Requirements:
11
+ # - Rust toolchain (1.70+)
12
+ # - wasm-pack (cargo install wasm-pack)
13
+ #
14
+
15
+ set -euo pipefail
16
+
17
+ # Colors for output
18
+ RED='\033[0;31m'
19
+ GREEN='\033[0;32m'
20
+ YELLOW='\033[1;33m'
21
+ BLUE='\033[0;34m'
22
+ CYAN='\033[0;36m'
23
+ BOLD='\033[1m'
24
+ RESET='\033[0m'
25
+
26
+ # Directories
27
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
28
+ ROOT_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)"
29
+ NPM_DIR="${ROOT_DIR}/npm"
30
+ DIST_WASM_DIR="${NPM_DIR}/dist/wasm"
31
+
32
+ # Functions
33
+ log_info() {
34
+ echo -e "${BLUE}ℹ${RESET} $1"
35
+ }
36
+
37
+ log_success() {
38
+ echo -e "${GREEN}✓${RESET} $1"
39
+ }
40
+
41
+ log_warning() {
42
+ echo -e "${YELLOW}⚠${RESET} $1"
43
+ }
44
+
45
+ log_error() {
46
+ echo -e "${RED}✗${RESET} $1"
47
+ }
48
+
49
+ log_step() {
50
+ echo -e "${CYAN}▶${RESET} ${BOLD}$1${RESET}"
51
+ }
52
+
53
+ check_dependencies() {
54
+ log_step "Checking dependencies"
55
+
56
+ # Check Rust
57
+ if ! command -v cargo &> /dev/null; then
58
+ log_error "Rust not found! Install from https://rustup.rs"
59
+ exit 1
60
+ fi
61
+ log_success "Rust found: $(cargo --version)"
62
+
63
+ # Check wasm-pack
64
+ if ! command -v wasm-pack &> /dev/null; then
65
+ log_error "wasm-pack not found!"
66
+ log_info "Install with: cargo install wasm-pack"
67
+ exit 1
68
+ fi
69
+ log_success "wasm-pack found: $(wasm-pack --version)"
70
+ }
71
+
72
+ get_file_size() {
73
+ local filepath="$1"
74
+ if [[ -f "$filepath" ]]; then
75
+ local size=$(du -k "$filepath" | cut -f1)
76
+ echo "${size} KB"
77
+ else
78
+ echo "N/A"
79
+ fi
80
+ }
81
+
82
+ get_gzip_size() {
83
+ local filepath="$1"
84
+ if [[ -f "$filepath" ]]; then
85
+ local size=$(gzip -c "$filepath" | wc -c)
86
+ local kb=$((size / 1024))
87
+ echo "${kb} KB"
88
+ else
89
+ echo "N/A"
90
+ fi
91
+ }
92
+
93
+ build_target() {
94
+ local target="$1"
95
+ local description="$2"
96
+
97
+ log_step "Building for ${description}"
98
+
99
+ local out_dir="${DIST_WASM_DIR}/${target}"
100
+
101
+ cd "${ROOT_DIR}"
102
+
103
+ wasm-pack build \
104
+ --target "${target}" \
105
+ --out-dir "${out_dir}" \
106
+ --out-name "agentic_payments" \
107
+ --scope agentic-catalog \
108
+ --release \
109
+ -- \
110
+ --no-default-features \
111
+ --features wasm
112
+
113
+ log_success "${target} build complete"
114
+
115
+ # Print sizes
116
+ local wasm_path="${out_dir}/agentic_payments_bg.wasm"
117
+ local js_path="${out_dir}/agentic_payments.js"
118
+
119
+ if [[ -f "$wasm_path" ]]; then
120
+ echo " WASM: $(get_file_size "$wasm_path") ($(get_gzip_size "$wasm_path") gzipped)"
121
+ echo " JS: $(get_file_size "$js_path") ($(get_gzip_size "$js_path") gzipped)"
122
+ fi
123
+ }
124
+
125
+ print_summary() {
126
+ echo ""
127
+ echo "============================================================"
128
+ log_step "Build Summary"
129
+ echo "============================================================"
130
+
131
+ for target in web nodejs bundler; do
132
+ local wasm_path="${DIST_WASM_DIR}/${target}/agentic_payments_bg.wasm"
133
+ local js_path="${DIST_WASM_DIR}/${target}/agentic_payments.js"
134
+
135
+ if [[ -f "$wasm_path" ]]; then
136
+ echo ""
137
+ echo "${BOLD}${target}:${RESET}"
138
+ echo " WASM: $(get_file_size "$wasm_path") ($(get_gzip_size "$wasm_path") gzipped)"
139
+ echo " JS: $(get_file_size "$js_path") ($(get_gzip_size "$js_path") gzipped)"
140
+ fi
141
+ done
142
+
143
+ echo ""
144
+ echo "============================================================"
145
+ }
146
+
147
+ main() {
148
+ local target="${1:-all}"
149
+
150
+ local start_time=$(date +%s)
151
+
152
+ echo ""
153
+ echo -e "${CYAN}╔═══════════════════════════════════════════════════════════╗${RESET}"
154
+ echo -e "${CYAN}║ Agentic Payments - WASM Build ║${RESET}"
155
+ echo -e "${CYAN}║ Multi-target compilation with size optimization ║${RESET}"
156
+ echo -e "${CYAN}╚═══════════════════════════════════════════════════════════╝${RESET}"
157
+ echo ""
158
+
159
+ # Check dependencies
160
+ check_dependencies
161
+
162
+ # Clean previous builds
163
+ log_step "Cleaning previous builds"
164
+ rm -rf "${DIST_WASM_DIR}"
165
+ mkdir -p "${DIST_WASM_DIR}"
166
+ log_success "Cleaned dist/wasm directory"
167
+
168
+ # Build targets
169
+ case "$target" in
170
+ web)
171
+ build_target "web" "Browser (ES modules)"
172
+ ;;
173
+ nodejs)
174
+ build_target "nodejs" "Node.js (CommonJS)"
175
+ ;;
176
+ bundler)
177
+ build_target "bundler" "Webpack/Rollup/Vite"
178
+ ;;
179
+ all)
180
+ build_target "web" "Browser (ES modules)"
181
+ build_target "nodejs" "Node.js (CommonJS)"
182
+ build_target "bundler" "Webpack/Rollup/Vite"
183
+ ;;
184
+ *)
185
+ log_error "Unknown target: $target"
186
+ echo "Usage: $0 [web|nodejs|bundler|all]"
187
+ exit 1
188
+ ;;
189
+ esac
190
+
191
+ # Print summary
192
+ if [[ "$target" == "all" ]]; then
193
+ print_summary
194
+ fi
195
+
196
+ local end_time=$(date +%s)
197
+ local duration=$((end_time - start_time))
198
+
199
+ echo ""
200
+ log_success "Build completed in ${duration}s"
201
+ }
202
+
203
+ # Run main function
204
+ main "$@"
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * NPX Cache Cleanup Script
4
+ * Fixes ENOTEMPTY errors on remote installs by cleaning up stale npx cache
5
+ *
6
+ * This script addresses the common npx caching issue where:
7
+ * - npm tries to rename cached directories during updates
8
+ * - Directory is not empty, causing ENOTEMPTY errors
9
+ * - Particularly problematic in remote/containerized environments
10
+ */
11
+
12
+ import { fileURLToPath } from 'url';
13
+ import { dirname, join } from 'path';
14
+ import { existsSync, rmSync, readdirSync } from 'fs';
15
+ import { homedir } from 'os';
16
+
17
+ const __filename = fileURLToPath(import.meta.url);
18
+ const __dirname = dirname(__filename);
19
+
20
+ async function cleanupNpxCache() {
21
+ try {
22
+ const npmHome = process.env.NPM_CONFIG_CACHE || join(homedir(), '.npm');
23
+ const npxCacheDir = join(npmHome, '_npx');
24
+
25
+ if (!existsSync(npxCacheDir)) {
26
+ return; // No cache to clean
27
+ }
28
+
29
+ console.log('[agentic-payments] Cleaning npx cache to prevent ENOTEMPTY errors...');
30
+
31
+ let cleanedCount = 0;
32
+ const cacheEntries = readdirSync(npxCacheDir);
33
+
34
+ for (const entry of cacheEntries) {
35
+ try {
36
+ const entryPath = join(npxCacheDir, entry);
37
+ const pkgPath = join(entryPath, 'node_modules', 'agentic-payments');
38
+
39
+ if (existsSync(pkgPath)) {
40
+ console.log(`[agentic-payments] Removing stale cache: ${entry}`);
41
+
42
+ // Try multiple removal strategies for robustness
43
+ try {
44
+ rmSync(entryPath, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
45
+ cleanedCount++;
46
+ } catch (rmError) {
47
+ // Fallback: try removing just the package directory
48
+ try {
49
+ rmSync(pkgPath, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
50
+ cleanedCount++;
51
+ } catch (fallbackError) {
52
+ console.warn(`[agentic-payments] Could not remove cache entry: ${entry}`);
53
+ }
54
+ }
55
+ }
56
+ } catch (entryError) {
57
+ // Continue with other entries even if one fails
58
+ continue;
59
+ }
60
+ }
61
+
62
+ if (cleanedCount > 0) {
63
+ console.log(`[agentic-payments] Cache cleanup complete (${cleanedCount} entries removed)`);
64
+ } else {
65
+ console.log('[agentic-payments] No stale cache entries found');
66
+ }
67
+ } catch (error) {
68
+ // Silently fail - don't block installation
69
+ console.warn('[agentic-payments] Cache cleanup failed (non-fatal):', error.message);
70
+ }
71
+ }
72
+
73
+ // Run cleanup
74
+ cleanupNpxCache().catch(() => {
75
+ // Ignore errors - preinstall should not fail
76
+ });
@@ -0,0 +1,204 @@
1
+ #!/bin/bash
2
+ # Validation and Publishing Script
3
+ # Validates npx cache fix in Docker, then publishes point release
4
+
5
+ set -e
6
+
7
+ RED='\033[0;31m'
8
+ GREEN='\033[0;32m'
9
+ YELLOW='\033[1;33m'
10
+ BLUE='\033[0;34m'
11
+ NC='\033[0m' # No Color
12
+
13
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
15
+ CURRENT_VERSION=$(node -p "require('$PROJECT_ROOT/package.json').version")
16
+
17
+ echo -e "${BLUE}========================================${NC}"
18
+ echo -e "${BLUE}Agentic Payments - Validation & Release${NC}"
19
+ echo -e "${BLUE}Current Version: ${CURRENT_VERSION}${NC}"
20
+ echo -e "${BLUE}========================================${NC}"
21
+ echo ""
22
+
23
+ # Step 1: Build the package
24
+ echo -e "${YELLOW}Step 1: Building package...${NC}"
25
+ cd "$PROJECT_ROOT"
26
+ npm run clean
27
+ npm run build || {
28
+ echo -e "${RED}❌ Build failed${NC}"
29
+ exit 1
30
+ }
31
+ echo -e "${GREEN}✓ Build successful${NC}"
32
+ echo ""
33
+
34
+ # Step 2: Run tests
35
+ echo -e "${YELLOW}Step 2: Running tests...${NC}"
36
+ npm run test || {
37
+ echo -e "${RED}❌ Tests failed${NC}"
38
+ exit 1
39
+ }
40
+ echo -e "${GREEN}✓ Tests passed${NC}"
41
+ echo ""
42
+
43
+ # Step 3: Docker validation
44
+ echo -e "${YELLOW}Step 3: Running Docker validation...${NC}"
45
+ cd "$PROJECT_ROOT/tests/docker"
46
+
47
+ # Build and run validation container
48
+ echo "Building validation container..."
49
+ docker build -f npx-cache-validation.Dockerfile -t agentic-payments-validation . || {
50
+ echo -e "${RED}❌ Docker build failed${NC}"
51
+ exit 1
52
+ }
53
+
54
+ echo "Running validation tests..."
55
+ docker run --rm agentic-payments-validation || {
56
+ echo -e "${RED}❌ Docker validation failed${NC}"
57
+ exit 1
58
+ }
59
+ echo -e "${GREEN}✓ Docker validation passed${NC}"
60
+ echo ""
61
+
62
+ # Step 4: Version bump prompt
63
+ cd "$PROJECT_ROOT"
64
+ echo -e "${YELLOW}Step 4: Version update${NC}"
65
+ echo "Current version: ${CURRENT_VERSION}"
66
+ echo ""
67
+ echo "What type of release is this?"
68
+ echo " 1) Patch (bug fix, e.g., 0.1.7 -> 0.1.8)"
69
+ echo " 2) Minor (new feature, e.g., 0.1.7 -> 0.2.0)"
70
+ echo " 3) Major (breaking change, e.g., 0.1.7 -> 1.0.0)"
71
+ echo " 4) Custom version"
72
+ echo " 5) Skip version bump"
73
+ echo ""
74
+ read -p "Enter choice (1-5): " VERSION_CHOICE
75
+
76
+ case $VERSION_CHOICE in
77
+ 1)
78
+ echo "Bumping patch version..."
79
+ npm version patch --no-git-tag-version
80
+ ;;
81
+ 2)
82
+ echo "Bumping minor version..."
83
+ npm version minor --no-git-tag-version
84
+ ;;
85
+ 3)
86
+ echo "Bumping major version..."
87
+ npm version major --no-git-tag-version
88
+ ;;
89
+ 4)
90
+ read -p "Enter custom version (e.g., 0.1.8): " CUSTOM_VERSION
91
+ npm version "$CUSTOM_VERSION" --no-git-tag-version
92
+ ;;
93
+ 5)
94
+ echo "Skipping version bump"
95
+ ;;
96
+ *)
97
+ echo -e "${RED}Invalid choice${NC}"
98
+ exit 1
99
+ ;;
100
+ esac
101
+
102
+ NEW_VERSION=$(node -p "require('$PROJECT_ROOT/package.json').version")
103
+ echo -e "${GREEN}✓ Version updated: ${CURRENT_VERSION} -> ${NEW_VERSION}${NC}"
104
+ echo ""
105
+
106
+ # Step 5: Update CHANGELOG
107
+ echo -e "${YELLOW}Step 5: Updating CHANGELOG...${NC}"
108
+ CHANGELOG_ENTRY="## [${NEW_VERSION}] - $(date +%Y-%m-%d)
109
+
110
+ ### Fixed
111
+ - Enhanced npx cache cleanup to prevent ENOTEMPTY errors in remote environments
112
+ - Added stale cache detection (24-hour threshold)
113
+ - Improved retry logic with 5 retries and 100ms delay
114
+ - Added comprehensive Docker validation tests
115
+
116
+ ### Added
117
+ - Triple-layer cache cleanup protection (preinstall, runtime, age-based)
118
+ - Detailed NPX_CACHE_FIX.md documentation
119
+ - Docker validation environment and scripts
120
+
121
+ ### Changed
122
+ - Increased cache cleanup robustness in all binary entry points
123
+ - Enhanced error handling in cleanup scripts
124
+ "
125
+
126
+ if [ -f "$PROJECT_ROOT/CHANGELOG.md" ]; then
127
+ # Prepend to existing CHANGELOG
128
+ echo "$CHANGELOG_ENTRY" | cat - "$PROJECT_ROOT/CHANGELOG.md" > "$PROJECT_ROOT/CHANGELOG.tmp"
129
+ mv "$PROJECT_ROOT/CHANGELOG.tmp" "$PROJECT_ROOT/CHANGELOG.md"
130
+ else
131
+ # Create new CHANGELOG
132
+ echo "# Changelog" > "$PROJECT_ROOT/CHANGELOG.md"
133
+ echo "" >> "$PROJECT_ROOT/CHANGELOG.md"
134
+ echo "$CHANGELOG_ENTRY" >> "$PROJECT_ROOT/CHANGELOG.md"
135
+ fi
136
+ echo -e "${GREEN}✓ CHANGELOG updated${NC}"
137
+ echo ""
138
+
139
+ # Step 6: Rebuild with new version
140
+ echo -e "${YELLOW}Step 6: Rebuilding with new version...${NC}"
141
+ npm run build || {
142
+ echo -e "${RED}❌ Rebuild failed${NC}"
143
+ exit 1
144
+ }
145
+ echo -e "${GREEN}✓ Rebuild successful${NC}"
146
+ echo ""
147
+
148
+ # Step 7: Publish confirmation
149
+ echo -e "${YELLOW}Step 7: Ready to publish${NC}"
150
+ echo ""
151
+ echo "Package: agentic-payments"
152
+ echo "Version: ${NEW_VERSION}"
153
+ echo "Registry: https://registry.npmjs.org/"
154
+ echo ""
155
+ echo "Files to be published:"
156
+ npm pack --dry-run 2>&1 | grep -E "^\s+(dist|bin|scripts)" | head -n 10
157
+ echo ""
158
+ read -p "Proceed with npm publish? (y/N): " PUBLISH_CONFIRM
159
+
160
+ if [[ "$PUBLISH_CONFIRM" =~ ^[Yy]$ ]]; then
161
+ echo -e "${YELLOW}Publishing to npm...${NC}"
162
+ npm publish --access public || {
163
+ echo -e "${RED}❌ Publish failed${NC}"
164
+ exit 1
165
+ }
166
+ echo -e "${GREEN}✓ Published to npm registry${NC}"
167
+ echo ""
168
+
169
+ # Step 8: Git tag
170
+ echo -e "${YELLOW}Step 8: Creating git tag...${NC}"
171
+ git add package.json CHANGELOG.md
172
+ git commit -m "chore(release): v${NEW_VERSION} - NPX cache fix improvements" || true
173
+ git tag -a "v${NEW_VERSION}" -m "Release v${NEW_VERSION}: NPX cache fix improvements"
174
+
175
+ echo -e "${GREEN}✓ Git tag created${NC}"
176
+ echo ""
177
+
178
+ read -p "Push to remote? (y/N): " PUSH_CONFIRM
179
+ if [[ "$PUSH_CONFIRM" =~ ^[Yy]$ ]]; then
180
+ git push origin HEAD
181
+ git push origin "v${NEW_VERSION}"
182
+ echo -e "${GREEN}✓ Pushed to remote${NC}"
183
+ fi
184
+ else
185
+ echo -e "${YELLOW}Publish cancelled${NC}"
186
+ exit 0
187
+ fi
188
+
189
+ # Final summary
190
+ echo ""
191
+ echo -e "${GREEN}========================================${NC}"
192
+ echo -e "${GREEN}Release Complete!${NC}"
193
+ echo -e "${GREEN}========================================${NC}"
194
+ echo ""
195
+ echo "Package: agentic-payments@${NEW_VERSION}"
196
+ echo "Registry: https://www.npmjs.com/package/agentic-payments"
197
+ echo "Install: npx agentic-payments@latest"
198
+ echo ""
199
+ echo "Next steps:"
200
+ echo " 1. Verify on npm: npm view agentic-payments@${NEW_VERSION}"
201
+ echo " 2. Test install: npx agentic-payments@${NEW_VERSION} mcp --help"
202
+ echo " 3. Monitor for issues: https://github.com/agentic-catalog/agentic-payments/issues"
203
+ echo ""
204
+ echo -e "${GREEN}🎉 Release published successfully!${NC}"