[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6F8DAFEXWWSP6YWYT8F9P7W":3,"skill-same:01M6F8DAFEXWWSP6YWYT8F9P7W":75},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":55,"repositoryHtmlUrl":56,"repositoryHomepageUrl":57,"ownerHtmlUrl":58,"ownerBlogUrl":6,"ownerDescription":59,"updatedAt":60,"install":61,"resources":74},"01M6F8DAFEXWWSP6YWYT8F9P7W","clay-multi-env-setup",null,"Configure Clay integrations across development, staging, and production environments.\nUse when setting up per-environment Clay tables, managing webhook URLs per environment,\nor implementing environment-specific enrichment configurations.\nTrigger with phrases like \"clay environments\", \"clay staging\", \"clay dev prod\",\n\"clay environment setup\", \"clay config by env\".","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",66,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fjeremylongshore\u002Fclaude-code-plugins-plus-skills\u002Fclay-multi-env-setup\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"setup","multi","env setup","env","clay","clay multi env setup","up","environments","io","webhook","across","openclaw","edit","write","read","integrations","configure","Bash","code","config","2026-11-10 10:12:30",false,"---\nname: clay-multi-env-setup\ndescription: |\n  Configure Clay integrations across development, staging, and production environments.\n  Use when setting up per-environment Clay tables, managing webhook URLs per environment,\n  or implementing environment-specific enrichment configurations.\n  Trigger with phrases like \"clay environments\", \"clay staging\", \"clay dev prod\",\n  \"clay environment setup\", \"clay config by env\".\nallowed-tools: Read, Write, Edit, Bash(curl:*), Grep\nversion: 1.0.0\nlicense: MIT\nauthor: Jeremy Longshore \u003Cjeremy@intentsolutions.io>\ncompatible-with: claude-code, codex, openclaw\ntags: [saas, clay, deployment]\n\n---\n# Clay Multi-Environment Setup\n\n## Overview\n\nConfigure Clay integrations across dev\u002Fstaging\u002Fprod with isolated tables, separate webhook URLs, and environment-specific enrichment settings. Clay is a single workspace per account, so multi-environment isolation requires separate tables, careful naming, and environment-aware application code.\n\n## Prerequisites\n\n- Clay account (one workspace can hold multiple tables)\n- Environment variable management per deployment target\n- Understanding of Clay table and webhook concepts\n\n## Instructions\n\n### Step 1: Create Per-Environment Tables\n\nIn Clay, create separate tables for each environment:\n\n| Table Name | Environment | Webhook URL | Auto-Enrich | Credit Cap |\n|------------|-------------|-------------|-------------|------------|\n| `[DEV] Outbound Leads` | Development | Dev webhook | ON (small batches) | 100 rows |\n| `[STG] Outbound Leads` | Staging | Staging webhook | ON | 500 rows |\n| `Outbound Leads` | Production | Prod webhook | ON | 10,000 rows |\n\nEach table gets its own webhook URL. Copy each URL to the appropriate environment's secrets.\n\n### Step 2: Environment Configuration\n\n```typescript\n\u002F\u002F src\u002Fconfig\u002Fclay.ts — environment-aware Clay configuration\ninterface ClayEnvConfig {\n  webhookUrl: string;\n  apiKey?: string;                \u002F\u002F Enterprise API (if applicable)\n  maxRowsPerBatch: number;\n  delayBetweenRowsMs: number;\n  enableCRMSync: boolean;\n  tablePrefix: string;\n}\n\nfunction getClayConfig(): ClayEnvConfig {\n  const env = process.env.NODE_ENV || 'development';\n\n  const configs: Record\u003Cstring, ClayEnvConfig> = {\n    development: {\n      webhookUrl: process.env.CLAY_WEBHOOK_URL_DEV!,\n      maxRowsPerBatch: 10,          \u002F\u002F Small batches to conserve credits\n      delayBetweenRowsMs: 500,      \u002F\u002F Slow, safe\n      enableCRMSync: false,         \u002F\u002F Never push dev data to real CRM\n      tablePrefix: '[DEV]',\n    },\n    staging: {\n      webhookUrl: process.env.CLAY_WEBHOOK_URL_STG!,\n      maxRowsPerBatch: 100,\n      delayBetweenRowsMs: 250,\n      enableCRMSync: false,         \u002F\u002F Use sandbox CRM if needed\n      tablePrefix: '[STG]',\n    },\n    production: {\n      webhookUrl: process.env.CLAY_WEBHOOK_URL!,\n      apiKey: process.env.CLAY_API_KEY,\n      maxRowsPerBatch: 1000,\n      delayBetweenRowsMs: 100,\n      enableCRMSync: true,\n      tablePrefix: '',\n    },\n  };\n\n  const config = configs[env];\n  if (!config) throw new Error(`Unknown environment: ${env}`);\n  if (!config.webhookUrl) throw new Error(`CLAY_WEBHOOK_URL not set for ${env}`);\n\n  return config;\n}\n```\n\n### Step 3: Environment Variable Management\n\n```bash\n# .env.development\nCLAY_WEBHOOK_URL_DEV=https:\u002F\u002Fapp.clay.com\u002Fapi\u002Fv1\u002Fwebhooks\u002Fdev-webhook-id\nNODE_ENV=development\n\n# .env.staging\nCLAY_WEBHOOK_URL_STG=https:\u002F\u002Fapp.clay.com\u002Fapi\u002Fv1\u002Fwebhooks\u002Fstg-webhook-id\nNODE_ENV=staging\n\n# .env.production (never in git — use secrets manager)\nCLAY_WEBHOOK_URL=https:\u002F\u002Fapp.clay.com\u002Fapi\u002Fv1\u002Fwebhooks\u002Fprod-webhook-id\nCLAY_API_KEY=clay_ent_production_key\nNODE_ENV=production\n```\n\n```bash\n# GitHub Actions — per-environment secrets\ngh secret set CLAY_WEBHOOK_URL_DEV --body \"https:\u002F\u002Fapp.clay.com\u002Fapi\u002Fv1\u002Fwebhooks\u002Fdev-id\"\ngh secret set CLAY_WEBHOOK_URL_STG --body \"https:\u002F\u002Fapp.clay.com\u002Fapi\u002Fv1\u002Fwebhooks\u002Fstg-id\"\ngh secret set CLAY_WEBHOOK_URL --body \"https:\u002F\u002Fapp.clay.com\u002Fapi\u002Fv1\u002Fwebhooks\u002Fprod-id\"\ngh secret set CLAY_API_KEY --body \"clay_ent_production_key\"\n```\n\n### Step 4: Startup Validation\n\n```typescript\n\u002F\u002F src\u002Fconfig\u002Fvalidate.ts — fail fast if config is wrong\nimport { z } from 'zod';\n\nconst ClayConfigSchema = z.object({\n  webhookUrl: z.string().url().startsWith('https:\u002F\u002F'),\n  apiKey: z.string().startsWith('clay_ent_').optional(),\n  maxRowsPerBatch: z.number().positive().max(10_000),\n  delayBetweenRowsMs: z.number().min(0),\n  enableCRMSync: z.boolean(),\n  tablePrefix: z.string(),\n});\n\nexport function validateClayConfig(config: unknown) {\n  const result = ClayConfigSchema.safeParse(config);\n  if (!result.success) {\n    console.error('Clay configuration invalid:', result.error.format());\n    process.exit(1);\n  }\n  console.log(`Clay config validated for ${process.env.NODE_ENV}`);\n  return result.data;\n}\n```\n\n### Step 5: Environment-Aware Safety Guards\n\n```typescript\n\u002F\u002F src\u002Fclay\u002Fguards.ts — prevent production data in dev and vice versa\nfunction safetyCheck(env: string, rowCount: number): void {\n  if (env === 'development' && rowCount > 50) {\n    throw new Error(`Dev environment: refusing to process ${rowCount} rows (max 50). Use staging or production.`);\n  }\n  if (env === 'staging' && rowCount > 1000) {\n    throw new Error(`Staging environment: refusing to process ${rowCount} rows (max 1000). Use production.`);\n  }\n}\n\nfunction preventCrossEnvData(env: string, crmPushEnabled: boolean): void {\n  if (env !== 'production' && crmPushEnabled) {\n    throw new Error(`CRM sync is disabled in ${env}. Only production can push to CRM.`);\n  }\n}\n```\n\n## Error Handling\n\n| Issue | Cause | Solution |\n|-------|-------|----------|\n| Wrong table receives data | Dev webhook URL in production | Validate webhook URL matches environment |\n| Dev data in production CRM | CRM sync enabled in dev | Guard CRM sync to production only |\n| Credit waste in dev\u002Fstaging | Full enrichment on test data | Set low row caps on dev\u002Fstaging tables |\n| Missing webhook URL at startup | Environment variable not set | Add startup validation with Zod |\n\n## Resources\n\n- [Clay University -- Table Management Settings](https:\u002F\u002Funiversity.clay.com\u002Fdocs\u002Ftable-management-settings)\n- [Zod Documentation](https:\u002F\u002Fzod.dev\u002F)\n\n## Next Steps\n\nFor monitoring and observability, see `clay-observability`.\n\n","# Clay Multi-Environment Setup\n\n## Overview\n\nConfigure Clay integrations across dev\u002Fstaging\u002Fprod with isolated tables, separate webhook URLs, and environment-specific enrichment settings. Clay is a single workspace per account, so multi-environment isolation requires separate tables, careful naming, and environment-aware application code.\n\n## Prerequisites\n\n- Clay account (one workspace can hold multiple tables)\n- Environment variable management per deployment target\n- Understanding of Clay table and webhook concepts\n\n## Instructions\n\n### Step 1: Create Per-Environment Tables\n\nIn Clay, create separate tables for each environment:\n\n| Table Name | Environment | Webhook URL | Auto-Enrich | Credit Cap |\n|------------|-------------|-------------|-------------|------------|\n| `[DEV] Outbound Leads` | Development | Dev webhook | ON (small batches) | 100 rows |\n| `[STG] Outbound Leads` | Staging | Staging webhook | ON | 500 rows |\n| `Outbound Leads` | Production | Prod webhook | ON | 10,000 rows |\n\nEach table gets its own webhook URL. Copy each URL to the appropriate environment's secrets.\n\n### Step 2: Environment Configuration\n\n```typescript\n\u002F\u002F src\u002Fconfig\u002Fclay.ts — environment-aware Clay configuration\ninterface ClayEnvConfig {\n  webhookUrl: string;\n  apiKey?: string;                \u002F\u002F Enterprise API (if applicable)\n  maxRowsPerBatch: number;\n  delayBetweenRowsMs: number;\n  enableCRMSync: boolean;\n  tablePrefix: string;\n}\n\nfunction getClayConfig(): ClayEnvConfig {\n  const env = process.env.NODE_ENV || 'development';\n\n  const configs: Record\u003Cstring, ClayEnvConfig> = {\n    development: {\n      webhookUrl: process.env.CLAY_WEBHOOK_URL_DEV!,\n      maxRowsPerBatch: 10,          \u002F\u002F Small batches to conserve credits\n      delayBetweenRowsMs: 500,      \u002F\u002F Slow, safe\n      enableCRMSync: false,         \u002F\u002F Never push dev data to real CRM\n      tablePrefix: '[DEV]',\n    },\n    staging: {\n      webhookUrl: process.env.CLAY_WEBHOOK_URL_STG!,\n      maxRowsPerBatch: 100,\n      delayBetweenRowsMs: 250,\n      enableCRMSync: false,         \u002F\u002F Use sandbox CRM if needed\n      tablePrefix: '[STG]',\n    },\n    production: {\n      webhookUrl: process.env.CLAY_WEBHOOK_URL!,\n      apiKey: process.env.CLAY_API_KEY,\n      maxRowsPerBatch: 1000,\n      delayBetweenRowsMs: 100,\n      enableCRMSync: true,\n      tablePrefix: '',\n    },\n  };\n\n  const config = configs[env];\n  if (!config) throw new Error(`Unknown environment: ${env}`);\n  if (!config.webhookUrl) throw new Error(`CLAY_WEBHOOK_URL not set for ${env}`);\n\n  return config;\n}\n```\n\n### Step 3: Environment Variable Management\n\n```bash\n# .env.development\nCLAY_WEBHOOK_URL_DEV=https:\u002F\u002Fapp.clay.com\u002Fapi\u002Fv1\u002Fwebhooks\u002Fdev-webhook-id\nNODE_ENV=development\n\n# .env.staging\nCLAY_WEBHOOK_URL_STG=https:\u002F\u002Fapp.clay.com\u002Fapi\u002Fv1\u002Fwebhooks\u002Fstg-webhook-id\nNODE_ENV=staging\n\n# .env.production (never in git — use secrets manager)\nCLAY_WEBHOOK_URL=https:\u002F\u002Fapp.clay.com\u002Fapi\u002Fv1\u002Fwebhooks\u002Fprod-webhook-id\nCLAY_API_KEY=clay_ent_production_key\nNODE_ENV=production\n```\n\n```bash\n# GitHub Actions — per-environment secrets\ngh secret set CLAY_WEBHOOK_URL_DEV --body \"https:\u002F\u002Fapp.clay.com\u002Fapi\u002Fv1\u002Fwebhooks\u002Fdev-id\"\ngh secret set CLAY_WEBHOOK_URL_STG --body \"https:\u002F\u002Fapp.clay.com\u002Fapi\u002Fv1\u002Fwebhooks\u002Fstg-id\"\ngh secret set CLAY_WEBHOOK_URL --body \"https:\u002F\u002Fapp.clay.com\u002Fapi\u002Fv1\u002Fwebhooks\u002Fprod-id\"\ngh secret set CLAY_API_KEY --body \"clay_ent_production_key\"\n```\n\n### Step 4: Startup Validation\n\n```typescript\n\u002F\u002F src\u002Fconfig\u002Fvalidate.ts — fail fast if config is wrong\nimport { z } from 'zod';\n\nconst ClayConfigSchema = z.object({\n  webhookUrl: z.string().url().startsWith('https:\u002F\u002F'),\n  apiKey: z.string().startsWith('clay_ent_').optional(),\n  maxRowsPerBatch: z.number().positive().max(10_000),\n  delayBetweenRowsMs: z.number().min(0),\n  enableCRMSync: z.boolean(),\n  tablePrefix: z.string(),\n});\n\nexport function validateClayConfig(config: unknown) {\n  const result = ClayConfigSchema.safeParse(config);\n  if (!result.success) {\n    console.error('Clay configuration invalid:', result.error.format());\n    process.exit(1);\n  }\n  console.log(`Clay config validated for ${process.env.NODE_ENV}`);\n  return result.data;\n}\n```\n\n### Step 5: Environment-Aware Safety Guards\n\n```typescript\n\u002F\u002F src\u002Fclay\u002Fguards.ts — prevent production data in dev and vice versa\nfunction safetyCheck(env: string, rowCount: number): void {\n  if (env === 'development' && rowCount > 50) {\n    throw new Error(`Dev environment: refusing to process ${rowCount} rows (max 50). Use staging or production.`);\n  }\n  if (env === 'staging' && rowCount > 1000) {\n    throw new Error(`Staging environment: refusing to process ${rowCount} rows (max 1000). Use production.`);\n  }\n}\n\nfunction preventCrossEnvData(env: string, crmPushEnabled: boolean): void {\n  if (env !== 'production' && crmPushEnabled) {\n    throw new Error(`CRM sync is disabled in ${env}. Only production can push to CRM.`);\n  }\n}\n```\n\n## Error Handling\n\n| Issue | Cause | Solution |\n|-------|-------|----------|\n| Wrong table receives data | Dev webhook URL in production | Validate webhook URL matches environment |\n| Dev data in production CRM | CRM sync enabled in dev | Guard CRM sync to production only |\n| Credit waste in dev\u002Fstaging | Full enrichment on test data | Set low row caps on dev\u002Fstaging tables |\n| Missing webhook URL at startup | Environment variable not set | Add startup validation with Zod |\n\n## Resources\n\n- [Clay University -- Table Management Settings](https:\u002F\u002Funiversity.clay.com\u002Fdocs\u002Ftable-management-settings)\n- [Zod Documentation](https:\u002F\u002Fzod.dev\u002F)\n\n## Next Steps\n\nFor monitoring and observability, see `clay-observability`.\n\n",{"name":5,"tags":44,"author":47,"license":15,"version":48,"description":49,"allowed-tools":50,"compatible-with":51},[45,23,46],"saas","deployment","Jeremy Longshore \u003Cjeremy@intentsolutions.io>","1.0.0","Configure Clay integrations across development, staging, and production environments.\nUse when setting up per-environment Clay tables, managing webhook URLs per environment,\nor implementing environment-specific enrichment configurations.\nTrigger with phrases like \"clay environments\", \"clay staging\", \"clay dev prod\",\n\"clay environment setup\", \"clay config by env\".\n","Read, Write, Edit, Bash(curl:*), Grep","claude-code, codex, openclaw","main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Fjeremylongshore\u002Fclaude-code-plugins-plus-skills\u002Fclay-multi-env-setup",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":62,"prompt":72,"zipAvailable":73},[63,66,69],{"tool":64,"command":65},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill clay-multi-env-setup",{"tool":67,"command":68},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill clay-multi-env-setup",{"tool":70,"command":71},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill clay-multi-env-setup","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fjeremylongshore\u002Fclaude-code-plugins-plus-skills\u002Fclay-multi-env-setup\u002FSKILL.md",true,[],[76,90,100,109,115,122],{"skillNo":77,"name":78,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":86,"publishedAt":39},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[81],{"categoryNo":82,"categoryName":83,"taxonomyType":84,"taxonomyTypeDesc":85},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[87,88,89],"model","model hierarchy","model hierarchy skill",{"skillNo":91,"name":92,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":96,"publishedAt":39},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[95],{"categoryNo":82,"categoryName":83,"taxonomyType":84,"taxonomyTypeDesc":85},[97,98,99],"MCP","zoom","zoom mcp",{"skillNo":101,"name":102,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":105,"publishedAt":39},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[106,107,108,98],"sdk","zoom apps sdk","apps",{"skillNo":110,"name":111,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":112,"categories":113,"keywords":114,"publishedAt":39},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[111],{"skillNo":116,"name":117,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":118,"categories":119,"keywords":121,"publishedAt":39},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[120],{"categoryNo":82,"categoryName":83,"taxonomyType":84,"taxonomyTypeDesc":85},[117],{"skillNo":123,"name":124,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":127,"publishedAt":39},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[124]]