Skip to main content

Pre-NPM-Publish Hook Documentation

Overview

Hook: pre-npm-publish.sh Type: PreToolUse (Blocking) Purpose: Validate npm packages before publishing to prevent bad releases Event: Triggered on npm publish commands Exit Codes:

  • 0 - Validation passed, allow publish
  • 2 - Validation failed, block publish

What It Does

This hook performs comprehensive validation of CODITECT npm packages before allowing publication to the npm registry. It acts as a quality gate to prevent common publishing mistakes.

Validation Checks

1. NPM Authentication

  • Verifies user is authenticated to npm registry
  • Checks via npm whoami
  • Blocks if: Not logged in to npm

2. Package Discovery

  • Scans packaging/packages/ directory
  • Identifies main packages (3) and binary packages (18)
  • Categorizes by platform (darwin, linux, win32)
  • Blocks if: Packages directory missing

3. Package.json Validation

  • Validates JSON syntax
  • Checks required fields:
    • name - Must match @coditect-ai/coditect-core* pattern
    • version - Must match expected version (1.0.0)
    • description - Required
    • author - Required
    • license - Required
  • Validates publishConfig.access (restricted/public)
  • Blocks if: Missing fields or invalid values

4. Version Consistency

  • Verifies all 21 packages have matching versions
  • Ensures no version drift between main/binary packages
  • Blocks if: Version mismatch detected

5. Binary Validation (Binary Packages Only)

  • Checks bin/ directory exists
  • Verifies binaries are present
  • Validates file executability (chmod +x)
  • Blocks if: Missing binaries or not executable

6. SHA256 Checksums

  • Verifies dist/SHA256SUMS file exists (optional)
  • Validates checksums match binary files
  • Uses sha256sum (Linux) or shasum (macOS)
  • Blocks if: Checksum verification fails
  • Warns if: Checksum file missing or tool unavailable

7. Secrets Scanning

  • Scans package contents for hardcoded secrets
  • Detects patterns:
    • AWS Access Keys (AKIA[0-9A-Z]{16})
    • API keys (api_key = "...")
    • Secret keys (secret_key = "...")
    • Passwords (password = "...")
    • Private keys (-----BEGIN PRIVATE KEY-----)
    • GitHub tokens (ghp_..., gho_...)
  • Blocks if: Secrets detected
  • Skips: Binary packages (binaries only)

8. Package Name Validation

  • Ensures all packages follow naming convention
  • Pattern: @coditect-ai/coditect-core-*
  • Examples:
    • @coditect-ai/coditect-core
    • @coditect-ai/coditect-core-full
    • @coditect-ai/coditect-core-developer-darwin-arm64
  • Blocks if: Package name doesn't match pattern

Usage

Integration with Claude Code

Add to .claude/settings.json:

{
"hooks": {
"PreToolUse": [
{
"matcher": {"tool_name": "Bash"},
"hooks": [
{
"type": "command",
"command": "bash /path/to/.coditect/hooks/pre-npm-publish.sh",
"timeout": 30000
}
]
}
]
}
}

Manual Testing

Test the hook without actually publishing:

# Test with mock npm publish command
echo '{"tool_name": "Bash", "input": {"command": "npm publish"}}' | \
bash hooks/pre-npm-publish.sh

Environment Variables

# Override packages directory (default: distribution/.../packages)
export PACKAGES_DIR="/custom/path/to/packages"

# Run hook
bash hooks/pre-npm-publish.sh

Output Examples

Success Output

=== Pre-NPM-Publish Validation Hook ===

ℹ Checking npm authentication...
✓ Authenticated as npm user: your-npm-username
ℹ Discovering packages...
✓ Found 3 main packages and 18 binary packages
ℹ Validating package.json files...
✓ Validated package: @coditect-ai/coditect-core (v1.0.0)
✓ Validated package: @coditect-ai/coditect-core-full (v1.0.0)
✓ Validated package: @coditect-ai/coditect-core-dev (v1.0.0)
✓ Validated binary package: @coditect-ai/coditect-core-developer-darwin-arm64 (v1.0.0) - 1 binaries
✓ Validated binary package: @coditect-ai/coditect-core-developer-darwin-x64 (v1.0.0) - 1 binaries
... (16 more binary packages)
ℹ Verifying SHA256 checksums...
✓ All SHA256 checksums verified
ℹ Scanning for secrets in package contents...
✓ No secrets detected in @coditect-ai/coditect-core
✓ No secrets detected in @coditect-ai/coditect-core-full
✓ No secrets detected in @coditect-ai/coditect-core-dev
ℹ Skipping secret scan for 18 binary packages (binaries only)
ℹ Verifying version consistency...
✓ All 21 packages have consistent version: 1.0.0

=== Validation Results ===

ℹ Validated Packages (21):
• @coditect-ai/coditect-core@1.0.0
• @coditect-ai/coditect-core-full@1.0.0
• @coditect-ai/coditect-core-dev@1.0.0
• @coditect-ai/coditect-core-developer-darwin-arm64@1.0.0
... (17 more)

=== VALIDATION PASSED ===
✓ All 21 npm packages are ready for publication.

ℹ Summary:
• Main packages: 3
• Binary packages: 18
• Total packages: 21
• Version: 1.0.0
• npm user: your-npm-username

Failure Output

=== Pre-NPM-Publish Validation Hook ===

ℹ Checking npm authentication...
✗ Not authenticated to npm registry. Run: npm login
ℹ Discovering packages...
✓ Found 3 main packages and 18 binary packages
ℹ Validating package.json files...
✗ Version mismatch in @coditect-ai/coditect-core: 1.0.1 (expected 1.0.0)
✗ Binary package @coditect-ai/coditect-core-developer-darwin-arm64 missing bin/ directory
ℹ Scanning for secrets in package contents...
✗ Potential secret detected in @coditect-ai/coditect-core matching pattern: api_key = "..."

=== Validation Results ===

✗ Errors (3):
✗ Not authenticated to npm registry. Run: npm login
✗ Version mismatch in @coditect-ai/coditect-core: 1.0.1 (expected 1.0.0)
✗ Binary package @coditect-ai/coditect-core-developer-darwin-arm64 missing bin/ directory

=== PUBLISH BLOCKED ===
✗ Fix the errors above before publishing to npm.

Validation Workflow


Package Structure

Main Packages (3)

packages/coditect-core/
├── package.json # @coditect-ai/coditect-core
├── bin/
│ └── coditect # Symlink/wrapper
├── agents/ # AI agents
├── commands/ # Slash commands
├── skills/ # Production skills
└── docs/ # User documentation

Binary Packages (18)

packages/coditect-core-developer-darwin-arm64/
├── package.json # @coditect-ai/coditect-core-developer-darwin-arm64
└── bin/
└── coditect # Platform-specific binary (executable)

Platforms: 3 personas × 6 platforms = 18 binary packages

  • Personas: developer, user, contributor
  • Platforms: darwin-arm64, darwin-x64, linux-arm64, linux-x64, linux-x64-musl, win32-x64

Common Issues & Solutions

Issue: "Not authenticated to npm registry"

Cause: Not logged in to npm Solution:

npm login
# Or use automation token
npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN

Issue: "Version mismatch in package X"

Cause: Package versions not synchronized Solution:

# Update all package.json files to same version
VERSION="1.0.0"
for pkg in packages/*/package.json; do
jq ".version = \"$VERSION\"" "$pkg" > "$pkg.tmp" && mv "$pkg.tmp" "$pkg"
done

Issue: "Binary not executable"

Cause: Binary files don't have execute permissions Solution:

# Make all binaries executable
find packages/*/bin -type f -exec chmod +x {} \;

Issue: "SHA256 checksum verification failed"

Cause: Binary files modified after checksums generated Solution:

# Regenerate checksums
cd dist/
sha256sum * > SHA256SUMS
# Or on macOS:
shasum -a 256 * > SHA256SUMS

Issue: "Potential secret detected"

Cause: Hardcoded credentials in package files Solution:

  1. Remove hardcoded secrets from source files
  2. Use environment variables instead
  3. Add to .npmignore if test/example files
  4. Re-run hook to verify

Performance

  • Typical execution time: <3 seconds
  • Package validation: ~100ms per package
  • Checksum verification: ~500ms (binary packages)
  • Secret scanning: ~1 second (main packages only)
  • Total for 21 packages: <3 seconds

Integration Points

1. CI/CD Pipeline

Integrate into GitHub Actions:

# .github/workflows/publish.yml
- name: Validate packages before publish
run: |
echo '{"tool_name": "Bash", "input": {"command": "npm publish"}}' | \
bash hooks/pre-npm-publish.sh

2. Pre-Publish Script

Add to root package.json:

{
"scripts": {
"prepublishOnly": "bash hooks/pre-npm-publish.sh"
}
}

3. Manual Validation

Run standalone before publishing:

# Validate all packages
bash hooks/pre-npm-publish.sh <<'EOF'
{"tool_name": "Bash", "input": {"command": "npm publish"}}
EOF

# Check exit code
if [ $? -eq 0 ]; then
echo "Safe to publish!"
else
echo "Fix errors before publishing"
fi

Maintenance

Updating Expected Version

Edit the hook script:

# hooks/pre-npm-publish.sh
EXPECTED_VERSION="1.1.0" # Change this

Adding New Validation Checks

  1. Add validation function in hook script
  2. Call from main validation flow
  3. Update ERRORS or WARNINGS array
  4. Update this documentation

Testing Changes

# Create test package
mkdir -p /tmp/test-packages/test-package
cat > /tmp/test-packages/test-package/package.json <<'EOF'
{
"name": "@coditect-ai/coditect-core-test",
"version": "1.0.0",
"description": "Test package",
"author": "Test",
"license": "Proprietary"
}
EOF

# Run hook with test directory
PACKAGES_DIR=/tmp/test-packages bash hooks/pre-npm-publish.sh <<'EOF'
{"tool_name": "Bash", "input": {"command": "npm publish"}}
EOF

Security Considerations

Secrets Detection Patterns

The hook scans for common secret patterns:

PatternExampleRisk
AWS Access KeyAKIA1234567890ABCDEFHigh
API Keysapi_key = "sk_live_abc123..."High
Secret Keyssecret_key = "xyz789..."High
Passwordspassword = "hunter2"Medium
Private Keys-----BEGIN RSA PRIVATE KEY-----Critical
GitHub Tokensghp_abcdefghijklmnopqrstuvwxyz123456High

False Positives

If legitimate strings match patterns:

  1. Review if truly safe to publish
  2. Add to .npmignore if possible
  3. Comment pattern in code with explanation
  4. Consider using environment variables instead


Changelog

VersionDateChanges
1.0.02025-12-09Initial release with 10 validation checks

Last Updated: December 9, 2025 Maintainer: CODITECT DevOps Team Status: Production Ready