‹ 首页

debugger

@othmane-khadri · 收录于 5 天前 · 上游提交 1 个月前

Activate when any GTM-OS CLI command fails with an error. Also triggers on: 'debug', 'fix', 'not working', 'broken', 'troubleshoot', 'help me fix', 'what went wrong', 'why is this failing', or any variant indicating something is broken.

适合你,如果经常使用GTM-OS CLI并遇到命令执行失败

/ 通过 npx 安装 校验哈希
npx oh-my-skill add othmane-khadri/yalc-the-gtm-operating-system/debugger
/ 通过 bash 安装
curl -fsSL https://oh-my-skill.com/install.sh | bash -s -- othmane-khadri/yalc-the-gtm-operating-system/debugger
/ 已经装过?验证本机副本,不用重装
npx oh-my-skill verify othmane-khadri/yalc-the-gtm-operating-system/debugger
安装目标可用 --agent / --scope 或 --to 明确指定;省略时只会在唯一已存在的 agent 目录上自动选择,零命中或多命中会停止并提示。content_hash 缺失或不一致均拒装。
268GitHub stars
~3.1K最小装载
~7.1K含声明引用
~9.9K文本包总量
索引托管

怎么用

商店整理自技能原文 · 版本 ffc6e37 · 表述以原文为准
它做什么

当 GTM-OS 命令出错或你提到“调试”等词时,Claude 会自动执行 5 层诊断,从检查环境变量、数据库、配置文件到测试 API,找出错误原因,给出修复建议并等你批准。修复后还会重新运行原命令确认成功。

什么时候触发

当你运行任何 `pnpm cli --` 命令并看到错误或堆栈信息时,或者当你说出“debug”、“fix”、“not working”等关键词,或者粘贴来自 GTM-OS 的错误信息时触发。

装好后可以这样说
Claude 会从环境检查开始逐层诊断。
Claude 会识别涉及的提供商并运行针对性检查。
技能原文 SKILL.md作者撰写 · MIT · ffc6e37

GTM-OS Debugger

Systematic diagnostic skill that activates when any GTM-OS command fails. Runs a 5-layer funnel from cheapest checks (file reads) to most expensive (live API calls), identifies the root cause, and offers auto-fixes with user approval.

When This Skill Applies
  • Any pnpm cli -- command outputs an error or stack trace
  • User says "debug" / "fix" / "not working" / "broken" / "troubleshoot"
  • User says "help me fix [error]" / "what went wrong" / "why is this failing"
  • User pastes an error message or stack trace from GTM-OS
What This Skill Does NOT Do
  • Fix bugs in user's custom code outside GTM-OS
  • Debug network/firewall issues beyond basic connectivity checks
  • Modify GTM-OS source code (only configuration, env vars, and database state)
CRITICAL RULES
  1. Never skip layers. Always start at Layer 1 even if you think you know the issue. Cheap checks catch 80% of problems.
  2. Never auto-fix without approval. Always show the proposed change and ask before applying.
  3. Never expose secrets. When reading .env.local or api_connections, mask all API keys (e.g., sk-...redacted).
  4. Short-circuit on first finding. When a layer finds the root cause, stop and offer the fix. Don't keep checking.
  5. Re-run the original command after fixing. The debug session isn't done until the command succeeds.

Base Context: GTM-OS Architecture

GTM-OS is a CLI-first TypeScript system for AI-native go-to-market automation.

Entry point: src/cli/index.ts via npx tsx Env loading: .env.local via loadEnv() at CLI startup Config files: ~/.gtm-os/config.yaml (user prefs) + gtm-os.yaml (GTM framework) Database: SQLite via @libsql/client + Drizzle ORM. Default path: file:./gtm-os.db

Three-Layer Architecture

| Layer | Location | Purpose | |-------|----------|---------| | Service | src/lib/services/ | Singleton SDK wrappers (Unipile, Firecrawl, Notion). Lazy-init from env vars. | | Provider | src/lib/providers/builtin/ | StepExecutor implementations. Registry dispatches by capability. | | Skill | src/lib/skills/ | User-facing composable operations. |

Provider Dependency Matrix

| Provider | Required Env Vars | Health Check | Common Failure | |----------|------------------|--------------|----------------| | Qualify | ANTHROPIC_API_KEY | Key format check | Missing or invalid key | | Firecrawl | FIRECRAWL_API_KEY | 5s timeout scrape test | Expired key, timeout | | Unipile | UNIPILE_API_KEY + UNIPILE_DSN | getAccounts() | Missing DSN, no LinkedIn account | | Notion | NOTION_API_KEY | Light search() | Insufficient scopes | | Crustdata | CRUSTDATA_API_KEY | Key format check | Credits exhausted | | FullEnrich | FULLENRICH_API_KEY | Key format check | Invalid key format | | Instantly | INSTANTLY_API_KEY | — | Invalid account |

Critical Files Map

| Issue Domain | Files to Check | |-------------|----------------| | Environment | .env.local, .env.example | | Database | src/lib/db/schema.ts, src/lib/db/index.ts, drizzle.config.ts | | Providers | src/lib/services/{name}.ts, src/lib/providers/builtin/{name}-provider.ts | | Framework | gtm-os.yaml, src/lib/framework/context.ts | | Config | ~/.gtm-os/config.yaml, src/lib/config/loader.ts | | Encryption | src/lib/crypto.ts | | Rate limits | src/lib/rate-limiter/index.ts | | CLI entry | src/cli/index.ts |


Diagnostic Workflow
Step 0: Capture Error Context

Before starting the funnel, capture:

  1. The exact error message and stack trace
  2. Which CLI command was run (e.g., campaign:track, leads:qualify)
  3. Which provider is involved (extract from error message or command)

Store this context — you'll reference it throughout the funnel.

Step 1: Layer 1 — Environment Validation (FREE)

Check .env.local existence and content. No API calls needed.

# Check .env.local exists
test -f .env.local && echo "OK: .env.local exists" || echo "FAIL: .env.local missing"
# Check required vars are set (mask values)
for var in ANTHROPIC_API_KEY DATABASE_URL ENCRYPTION_KEY; do
  if grep -q "^${var}=" .env.local 2>/dev/null; then
    echo "OK: $var is set"
  else
    echo "FAIL: $var is missing"
  fi
done
# Check provider-specific vars for the failing provider
# (run only the relevant check based on Step 0 context)

# Unipile check:
grep -q "^UNIPILE_API_KEY=" .env.local && echo "OK: UNIPILE_API_KEY set" || echo "FAIL: UNIPILE_API_KEY missing"
grep -q "^UNIPILE_DSN=" .env.local && echo "OK: UNIPILE_DSN set" || echo "FAIL: UNIPILE_DSN missing"

# Validate UNIPILE_DSN format (must be https://api{N}.unipile.com:{PORT})
grep "^UNIPILE_DSN=" .env.local | grep -qE "^UNIPILE_DSN=https://api[0-9]+\.unipile\.com:[0-9]+" && echo "OK: DSN format valid" || echo "FAIL: DSN format invalid"
# Check for common env var mistakes
# Trailing whitespace:
grep -n ' $' .env.local && echo "WARNING: Trailing whitespace found" || echo "OK: No trailing whitespace"
# Quoted values (should NOT be quoted):
grep -nE '^[A-Z_]+=".+"' .env.local && echo "WARNING: Quoted values found — remove quotes" || echo "OK: No quoted values"

If any FAIL found: Stop here. Explain the issue and offer to fix it.

Auto-fix actions:

  • Missing .env.local → "I'll copy .env.example to .env.local. You'll need to fill in your API keys."
  • Missing env var → "I'll add {VAR}= to your .env.local. Please paste your key value."
  • Invalid DSN format → Show the correct format: UNIPILE_DSN=https://api{N}.unipile.com:{PORT}
  • Quoted values → "I'll remove the quotes around the value."
  • Trailing whitespace → "I'll trim the whitespace."
Step 2: Layer 2 — Database Validation (FREE)

Check database file and schema state. Local queries only.

# Extract DB path from .env.local (default: ./gtm-os.db)
DB_URL=$(grep "^DATABASE_URL=" .env.local 2>/dev/null | cut -d= -f2-)
DB_PATH="${DB_URL:-file:./gtm-os.db}"
DB_PATH="${DB_PATH#file:}"
echo "Database path: $DB_PATH"
test -f "$DB_PATH" && echo "OK: Database file exists" || echo "FAIL: Database file missing"
# Check core tables exist (need at least these)
sqlite3 "$DB_PATH" "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;" 2>&1

Expected tables (minimum): conversations, messages, workflows, workflow_steps, result_sets, result_rows, knowledge_items, api_connections, frameworks, rate_limit_buckets, campaigns, campaign_leads, campaign_variants, campaign_messages

# Check FTS5 virtual table
sqlite3 "$DB_PATH" "SELECT name FROM sqlite_master WHERE type='table' AND name='knowledge_fts';" 2>&1
# Check pragmas
sqlite3 "$DB_PATH" "PRAGMA journal_mode;" 2>&1
sqlite3 "$DB_PATH" "PRAGMA foreign_keys;" 2>&1

If any FAIL found: Stop here.

Auto-fix actions:

  • Database file missing → "I'll run pnpm db:push to create the database and tables. Approve?"
  • Missing tables → "Tables are missing. I'll run pnpm db:push to apply the schema. Approve?"
  • FTS5 missing → "The full-text search index is missing. This usually self-heals on next startup. Try re-running your command."
  • WAL mode off → "I'll enable WAL mode: sqlite3 gtm-os.db 'PRAGMA journal_mode=WAL;'. Approve?"
Step 3: Layer 3 — Configuration Validation (FREE)

Check YAML config files exist and parse correctly.

# Check gtm-os.yaml
test -f gtm-os.yaml && echo "OK: gtm-os.yaml exists" || echo "FAIL: gtm-os.yaml missing"
# Validate YAML syntax
node -e "
try {
  require('js-yaml').load(require('fs').readFileSync('gtm-os.yaml','utf8'));
  console.log('OK: Valid YAML');
} catch(e) {
  console.log('FAIL: Invalid YAML -', e.message);
}
" 2>&1
# Check onboarding status
node -e "
const y = require('js-yaml').load(require('fs').readFileSync('gtm-os.yaml','utf8'));
console.log('onboarding_complete:', y.onboarding_complete || false);
" 2>&1
# Check user config
test -f ~/.gtm-os/config.yaml && echo "OK: User config exists" || echo "FAIL: User config missing at ~/.gtm-os/config.yaml"

Auto-fix actions:

  • Missing gtm-os.yaml → "Run yalc-gtm onboard to create your GTM framework. This asks 5 questions about your business."
  • Invalid YAML → Show the syntax error location and offer to fix it
  • onboarding_complete: false → "Run yalc-gtm onboard to complete setup."
  • Missing user config → "I'll create ~/.gtm-os/config.yaml with defaults. Approve?"
Step 4: Layer 4 — Provider Connectivity (1 API call)

Only test the provider involved in the error. Never test all providers.

Identify the provider from the error message or command:

  • campaign:track, leads:scrape-post, linkedin:* → Unipile
  • search_web_*, web scraping errors → Firecrawl
  • export, notion:*, Notion errors → Notion
  • qualify, Claude/AI errors → Anthropic
  • enrich, email errors → Crustdata / FullEnrich

Provider-specific health checks:

# Unipile: Check accounts exist
source .env.local 2>/dev/null
curl -s -w "\nHTTP_STATUS:%{http_code}" -H "X-API-KEY: $UNIPILE_API_KEY" "$UNIPILE_DSN/api/v1/accounts" 2>&1 | tail -5
# Firecrawl: Lightweight check (don't scrape, just verify auth)
source .env.local 2>/dev/null
curl -s -w "\nHTTP_STATUS:%{http_code}" -H "Authorization: Bearer $FIRECRAWL_API_KEY" "https://api.firecrawl.dev/v1/scrape" -X POST -H "Content-Type: application/json" -d '{"url":"https://example.com","formats":["markdown"],"timeout":5000}' 2>&1 | tail -5
# Notion: Light search
source .env.local 2>/dev/null
curl -s -w "\nHTTP_STATUS:%{http_code}" -H "Authorization: Bearer $NOTION_API_KEY" -H "Notion-Version: 2022-06-28" "https://api.notion.com/v1/search" -X POST -H "Content-Type: application/json" -d '{"page_size":1}' 2>&1 | tail -5

Interpret results:

  • HTTP 200 → Provider is working. Issue is elsewhere (proceed to Layer 5).
  • HTTP 401/403 → Authentication failure. Key is invalid or expired.
  • HTTP 429 → Rate limited. Wait and retry.
  • Connection refused / timeout → Network issue or DSN wrong.
  • HTTP 404 → Endpoint changed or DSN format wrong.

Auto-fix actions:

  • Auth failure → "Your API key for {provider} is invalid or expired. Get a new one from {provider dashboard URL} and update .env.local."
  • Rate limited → "You've hit the rate limit. Wait 60 seconds and try again."
  • Unipile no accounts → "No LinkedIn account is connected in Unipile. Go to your Unipile dashboard to connect one."
  • DSN connection failure → "The Unipile DSN is unreachable. Check if it matches the format https://api{N}.unipile.com:{PORT} — the DSN can rotate."
Step 5: Layer 5 — Deep Diagnosis (varies)

If Layers 1-4 all pass, the issue is in application logic. Analyze the stack trace.

  1. Parse the stack trace — identify the failing file and function
  2. Read the failing source file — understand what it's trying to do
  3. Check for known runtime errors — reference config/error-catalog.md
  4. Check rate limit state:
DB_PATH=$(grep "^DATABASE_URL=" .env.local 2>/dev/null | cut -d= -f2- | sed 's/^file://')
DB_PATH="${DB_PATH:-./gtm-os.db}"
sqlite3 "$DB_PATH" "SELECT provider, tokens_remaining, last_refill_at FROM rate_limit_buckets;" 2>&1
  1. Check encryption state:
sqlite3 "$DB_PATH" "SELECT provider, status, substr(encrypted_key, 1, 20) || '...' as key_preview FROM api_connections;" 2>&1
  1. Check for concurrent access:
# Check if another process has the DB locked
lsof "$DB_PATH" 2>/dev/null | head -5

Auto-fix actions vary by finding. Always explain what you found and propose a specific fix.

Step 6: Unresolved — Generate Diagnostic Report

If all layers pass but the error persists:

  1. Collect a diagnostic summary:
  2. OS + Node.js version
  3. GTM-OS version (from package.json)
  4. Env vars present (names only, never values)
  5. Database table count
  6. Provider availability status
  7. The original error + stack trace
  1. Save to ./debug-report-{YYYYMMDD-HHmmss}.md
  1. Tell the user:
"I've exhausted the standard diagnostic checks and couldn't identify the root cause. I've saved a diagnostic report to debug-report-{timestamp}.md. You can share this when filing a GitHub issue — it contains no secrets."

After Fixing

Once a fix is applied:

  1. Re-run the exact command that originally failed
  2. If it succeeds → "Fixed! The command ran successfully."
  3. If it fails with a NEW error → restart the funnel from Layer 1 with the new error
  4. If it fails with the SAME error → escalate to the next layer

Provider Dashboard URLs (for guiding users to regenerate keys)

| Provider | Dashboard | |----------|-----------| | Anthropic | https://console.anthropic.com/settings/keys | | Unipile | Your Unipile admin panel (URL varies by account) | | Firecrawl | https://firecrawl.dev/app/api-keys | | Notion | https://www.notion.so/my-integrations | | Crustdata | https://crustdata.com/app/api-keys | | FullEnrich | https://app.fullenrich.com/api-keys | | Instantly | https://app.instantly.ai/app/settings/api |

按 MIT 许可原样转载,未经改动 · 在 GitHub 查看 →

评论

登录即可评论;带「已验证安装」的,是发布者名下有本店的安装或持有记录。