๐Ÿ“… let's chat! explore the endless possibilities creating industries that don't exist. click here

evernote-debug-bundle

Debug Evernote API issues with diagnostic tools and techniques. Use when troubleshooting API calls, inspecting requests/responses, or diagnosing integration problems. Trigger with phrases like "debug evernote", "evernote diagnostic", "troubleshoot evernote", "evernote logs", "inspect evernote". allowed-tools: Read, Write, Edit, Bash(npm:*), Bash(node:*), Grep version: 1.0.0 license: MIT author: Jeremy Longshore <jeremy@intentsolutions.io>

Allowed Tools

No tools specified

Provided by Plugin

evernote-pack

Claude Code skill pack for Evernote (24 skills)

saas packs v1.0.0
View Plugin

Installation

This skill is included in the evernote-pack plugin:

/plugin install evernote-pack@claude-code-plugins-plus

Click to copy

Instructions

# Evernote Debug Bundle ## Overview Comprehensive debugging toolkit for Evernote API integrations, including request logging, ENML validation, token inspection, and diagnostic utilities. ## Prerequisites - Evernote SDK installed - Node.js environment - Understanding of common Evernote errors ## Instructions ### Step 1: Debug Logger ```javascript // utils/debug-logger.js const fs = require('fs'); const path = require('path'); class EvernoteDebugLogger { constructor(options = {}) { this.enabled = options.enabled ?? process.env.EVERNOTE_DEBUG === 'true'; this.logFile = options.logFile || 'evernote-debug.log'; this.logDir = options.logDir || './logs'; this.maxLogSize = options.maxLogSize || 10 * 1024 * 1024; // 10MB if (this.enabled) { fs.mkdirSync(this.logDir, { recursive: true }); } } log(operation, data) { if (!this.enabled) return; const entry = { timestamp: new Date().toISOString(), operation, ...data }; // Console output console.log(`[EVERNOTE DEBUG] ${operation}`, JSON.stringify(data, null, 2)); // File output this.writeToFile(entry); } logRequest(operation, params) { this.log(operation, { type: 'REQUEST', params: this.sanitizeParams(params) }); } logResponse(operation, response) { this.log(operation, { type: 'RESPONSE', response: this.summarizeResponse(response) }); } logError(operation, error) { this.log(operation, { type: 'ERROR', errorCode: error.errorCode, parameter: error.parameter, identifier: error.identifier, key: error.key, rateLimitDuration: error.rateLimitDuration, message: error.message, stack: error.stack }); } sanitizeParams(params) { // Remove sensitive data from logs const sanitized = { ...params }; if (sanitized.token) sanitized.token = '[REDACTED]'; if (sanitized.password) sanitized.password = '[REDACTED]'; if (sanitized.content && sanitized.content.length > 500) { sanitized.content = sanitized.content.substring(0, 500) + '...[truncated]'; } return sanitized; } summarizeResponse(response) { if (!response) return null; // Summarize common response types if (response.guid) { return { guid: response.guid, title: response.title, created: response.created, updated: response.updated, contentLength: response.content?.length }; } if (Array.isArray(response)) { return { count: response.length, items: response.slice(0, 3).map(item => ({ guid: item.guid, title: item.title || item.name })) }; } return response; } writeToFile(entry) { const filePath = path.join(this.logDir, this.logFile); const line = JSON.stringify(entry) + '\n'; try { fs.appendFileSync(filePath, line); this.rotateIfNeeded(filePath); } catch (error) { console.error('Failed to write debug log:', error.message); } } rotateIfNeeded(filePath) { try { const stats = fs.statSync(filePath); if (stats.size > this.maxLogSize) { const rotated = `${filePath}.${Date.now()}`; fs.renameSync(filePath, rotated); } } catch (error) { // Ignore rotation errors } } } module.exports = EvernoteDebugLogger; ``` ### Step 2: Instrumented Client Wrapper ```javascript // utils/instrumented-client.js const Evernote = require('evernote'); const EvernoteDebugLogger = require('./debug-logger'); class InstrumentedEvernoteClient { constructor(client, logger = null) { this.client = client; this.logger = logger || new EvernoteDebugLogger(); this._noteStore = null; this._userStore = null; } get noteStore() { if (!this._noteStore) { this._noteStore = this.wrapStore( this.client.getNoteStore(), 'NoteStore' ); } return this._noteStore; } get userStore() { if (!this._userStore) { this._userStore = this.wrapStore( this.client.getUserStore(), 'UserStore' ); } return this._userStore; } wrapStore(store, storeName) { const logger = this.logger; return new Proxy(store, { get(target, prop) { const original = target[prop]; if (typeof original !== 'function') { return original; } return async (...args) => { const operation = `${storeName}.${prop}`; const startTime = Date.now(); logger.logRequest(operation, { args: args.map((arg, i) => ({ index: i, type: typeof arg, value: typeof arg === 'object' ? arg : String(arg).substring(0, 100) })) }); try { const result = await original.apply(target, args); const duration = Date.now() - startTime; logger.logResponse(operation, { duration, result }); return result; } catch (error) { const duration = Date.now() - startTime; logger.logError(operation, { duration, error }); throw error; } }; } }); } } module.exports = InstrumentedEvernoteClient; ``` ### Step 3: ENML Validator ```javascript // utils/enml-validator.js class ENMLValidator { static validate(content) { const errors = []; const warnings = []; // Required structure if (!content.includes('' }); } if (!content.includes('' }); } if (!/]*>/.test(content)) { errors.push({ type: 'MISSING_ROOT', message: 'Missing root element', fix: 'Wrap content in ...' }); } if (!content.includes('')) { errors.push({ type: 'UNCLOSED_ROOT', message: 'Missing closing tag', fix: 'Add closing tag' }); } // Forbidden elements const forbidden = [ { pattern: /