gtm-now 0.10.12 → 0.10.13

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/dist/index.js CHANGED
@@ -12770,10 +12770,11 @@ var init_provision = __esm({
12770
12770
  "export_mailboxes",
12771
12771
  "create_plusvibe_client",
12772
12772
  "save_config",
12773
+ "deploy_crm",
12773
12774
  "start_provision",
12774
12775
  "status"
12775
12776
  ],
12776
- description: "Action: check_domains (availability), check_balance (Zapmail wallet), buy_domains (purchase via wallet), list_domains (show all with status), list_mailboxes (show mailboxes), setup_dmarc (configure DMARC for domains), create_mailboxes (create on specific domains), export_mailboxes (export to PlusVibe), create_plusvibe_client (create client in existing workspace), save_config (persist provider config to ~/.gtm/config.yaml), start_provision (trigger full pipeline), status (check progress)"
12777
+ description: "Action: check_domains (availability), check_balance (Zapmail wallet), buy_domains (purchase via wallet), list_domains (show all with status), list_mailboxes (show mailboxes), setup_dmarc (configure DMARC for domains), create_mailboxes (create on specific domains), export_mailboxes (export to PlusVibe), create_plusvibe_client (create client in existing workspace), save_config (persist provider config to ~/.gtm/config.yaml), deploy_crm (generate Twenty CRM deployment instructions for Railway), start_provision (trigger full pipeline), status (check progress)"
12777
12778
  },
12778
12779
  domains: {
12779
12780
  type: "array",
@@ -13280,7 +13281,7 @@ Note: HarvestAPI charges per request. For engagement mining, each post lookup co
13280
13281
  gtm_feedback: "Submit feedback, bug reports, feature requests, or provider requests. Feedback is stored for the gtm-now maintainers to review.",
13281
13282
  gtm_review: "Push data to a visual review table hosted at view.gtmnow.com. Users see an interactive AG Grid in their browser with checkboxes to select/deselect rows. Creates a temporary table (24h TTL) with a shareable URL. Use after finding companies or contacts to let the user review before spending enrichment credits. Three actions: create (new table from data array), update (modify existing table \u2014 add columns, update rows), get_selected (fetch only the rows the user has checked).",
13282
13283
  gtm_batch: 'Process a CSV file through a pipeline of GTM tool steps. Each row runs through each step sequentially \u2014 results are extracted as new columns in the output CSV. Use rows: "0:1" to pilot on a single row before full execution, and dry_run: true to preview without API calls. Template placeholders ({{column}}) are replaced with row values. Multiple steps can form a waterfall: set waterfall: true on later steps to skip rows already filled by earlier steps.',
13283
- gtm_provision: "Infrastructure provisioning for client setup. Twelve actions: check_domains (Zapmail domain availability), check_balance (Zapmail wallet), buy_domains (purchase via wallet), list_domains (all domains with status), list_mailboxes (mailboxes for a domain), setup_dmarc (DMARC for domain IDs), create_mailboxes (mailboxes on domains), export_mailboxes (export to PlusVibe/Instantly), create_plusvibe_client (client in existing workspace), save_config (persist provider config), start_provision (trigger full provisioning pipeline via gtm-api), status (check provisioning progress).",
13284
+ gtm_provision: "Infrastructure provisioning for client setup. Thirteen actions: check_domains (Zapmail domain availability), check_balance (Zapmail wallet), buy_domains (purchase via wallet), list_domains (all domains with status), list_mailboxes (mailboxes for a domain), setup_dmarc (DMARC for domain IDs), create_mailboxes (mailboxes on domains), export_mailboxes (export to PlusVibe/Instantly), create_plusvibe_client (client in existing workspace), save_config (persist provider config), deploy_crm (Twenty CRM deployment instructions for Railway), start_provision (trigger full provisioning pipeline via gtm-api), status (check provisioning progress).",
13284
13285
  // ─── Maestro (Knowledge Graph) ────────────────────────
13285
13286
  maestro_get_context: "Assemble full business context from the knowledge graph using a named strategy (call_prep, content_generation, lead_scoring, personalization, campaign_planning, general). Each strategy tunes which entities are included and their priority. Optionally narrow by query string or persona_id.",
13286
13287
  maestro_upsert_product: "Create or update a product in the knowledge graph. Products are what the business sells \u2014 services, courses, SaaS, consulting packages. Upserts by owner_id + name.",
@@ -16137,6 +16138,8 @@ async function handleProvision(args, ctx) {
16137
16138
  return createPlusVibeClient(a, ctx);
16138
16139
  case "save_config":
16139
16140
  return saveConfig(a, ctx);
16141
+ case "deploy_crm":
16142
+ return deployCrm(a, ctx);
16140
16143
  case "start_provision":
16141
16144
  return startProvision(a);
16142
16145
  case "status":
@@ -16353,6 +16356,120 @@ async function saveConfig(args, ctx) {
16353
16356
  fields: Object.keys(args.config_values)
16354
16357
  };
16355
16358
  }
16359
+ async function deployCrm(args, ctx) {
16360
+ if (!args.name) throw new Error("name is required for deploy_crm (client name)");
16361
+ const clientSlug = args.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+$/, "");
16362
+ const projectName = `twenty-${clientSlug}`;
16363
+ const serviceName = `twenty-crm-${clientSlug}`;
16364
+ const config = ctx.session.getActiveContext().config;
16365
+ const existingUrl = config.providers.twenty?.base_url;
16366
+ const existingKey = config.providers.twenty?.api_key;
16367
+ const steps = [];
16368
+ steps.push({
16369
+ step: 1,
16370
+ title: "Create Railway project",
16371
+ type: "cli",
16372
+ commands: [
16373
+ `railway login`,
16374
+ `railway init --name ${projectName}`
16375
+ ],
16376
+ notes: "Creates a new Railway project. Skip if project already exists."
16377
+ });
16378
+ steps.push({
16379
+ step: 2,
16380
+ title: "Deploy Twenty CRM service",
16381
+ type: "cli",
16382
+ commands: [
16383
+ `railway add --service ${serviceName}`,
16384
+ `railway variables set SERVER_URL=https://${serviceName}.up.railway.app -s ${serviceName}`,
16385
+ `railway variables set FRONT_BASE_URL=https://${serviceName}.up.railway.app -s ${serviceName}`,
16386
+ `railway variables set IS_SIGN_UP_DISABLED=true -s ${serviceName}`,
16387
+ `railway variables set NODE_ENV=production -s ${serviceName}`
16388
+ ],
16389
+ notes: "Uses Twenty Docker image twentycrm/twenty:latest. Alternatively deploy from Railway template: https://railway.app/template/twenty",
16390
+ env_vars: {
16391
+ SERVER_URL: `https://${serviceName}.up.railway.app`,
16392
+ FRONT_BASE_URL: `https://${serviceName}.up.railway.app`,
16393
+ IS_SIGN_UP_DISABLED: "true"
16394
+ }
16395
+ });
16396
+ steps.push({
16397
+ step: 3,
16398
+ title: "Add PostgreSQL database",
16399
+ type: "cli",
16400
+ commands: [
16401
+ `railway add --database postgres --service ${serviceName}-db`,
16402
+ `railway variables set DATABASE_URL=\${{${serviceName}-db.DATABASE_URL}} -s ${serviceName}`
16403
+ ],
16404
+ notes: "Twenty requires PostgreSQL 15+. Railway provisions this automatically."
16405
+ });
16406
+ steps.push({
16407
+ step: 4,
16408
+ title: "Add Redis cache",
16409
+ type: "cli",
16410
+ commands: [
16411
+ `railway add --database redis --service ${serviceName}-redis`,
16412
+ `railway variables set REDIS_URL=\${{${serviceName}-redis.REDIS_URL}} -s ${serviceName}`
16413
+ ],
16414
+ notes: "Required for Twenty job queue and caching."
16415
+ });
16416
+ steps.push({
16417
+ step: 5,
16418
+ title: "Deploy and wait for health",
16419
+ type: "cli",
16420
+ commands: [
16421
+ `railway up -s ${serviceName} --image twentycrm/twenty:latest`,
16422
+ `# Wait ~2-3 minutes for first deploy`,
16423
+ `# Verify: curl https://${serviceName}.up.railway.app/healthz`
16424
+ ],
16425
+ notes: "First deploy runs database migrations automatically. May take 2-3 minutes."
16426
+ });
16427
+ steps.push({
16428
+ step: 6,
16429
+ title: "Create admin account",
16430
+ type: "manual",
16431
+ notes: `Open https://${serviceName}.up.railway.app in browser. Sign up is enabled on first visit (even with IS_SIGN_UP_DISABLED). Create an admin account with email: ${args.email ?? `admin@${clientSlug}.com`}. After first account creation, sign-up is locked.`
16432
+ });
16433
+ steps.push({
16434
+ step: 7,
16435
+ title: "Generate API key",
16436
+ type: "manual",
16437
+ notes: `In Twenty dashboard \u2192 Settings \u2192 API Keys \u2192 Generate. Copy the API key \u2014 needed for gtm-now configuration.`
16438
+ });
16439
+ steps.push({
16440
+ step: 8,
16441
+ title: "Save CRM config to gtm-now",
16442
+ type: "automated",
16443
+ commands: [
16444
+ `gtm exec gtm_provision --arg action=save_config --arg provider=twenty --arg 'config_values={"api_key":"<API_KEY_FROM_STEP_7>","base_url":"https://${serviceName}.up.railway.app"}'`
16445
+ ],
16446
+ notes: "Replace <API_KEY_FROM_STEP_7> with the actual key. " + (args.client_name ? `Will save under client "${args.client_name}".` : "Will save under the active client config.")
16447
+ });
16448
+ steps.push({
16449
+ step: 9,
16450
+ title: "Verify CRM connection",
16451
+ type: "automated",
16452
+ commands: [
16453
+ `gtm exec gtm_crm --arg action=find --arg 'query={"email":"test@verify.com"}'`,
16454
+ `gtm exec gtm_status --arg provider=twenty`
16455
+ ],
16456
+ notes: "Should return empty results (no error). Status should show twenty as connected."
16457
+ });
16458
+ return {
16459
+ action: "deploy_crm",
16460
+ crm: "twenty",
16461
+ project: projectName,
16462
+ service: serviceName,
16463
+ base_url: existingUrl ?? `https://${serviceName}.up.railway.app`,
16464
+ already_configured: !!(existingUrl && existingKey),
16465
+ total_steps: steps.length,
16466
+ cli_steps: steps.filter((s) => s.type === "cli").length,
16467
+ manual_steps: steps.filter((s) => s.type === "manual").length,
16468
+ steps,
16469
+ railway_template_url: "https://railway.app/template/twenty",
16470
+ note: "Railway template is the fastest path \u2014 1-click deploy, then only steps 6-9 are needed."
16471
+ };
16472
+ }
16356
16473
  var init_provision2 = __esm({
16357
16474
  "src/handlers/provision.ts"() {
16358
16475
  "use strict";
@@ -18744,11 +18861,12 @@ var init_validation = __esm({
18744
18861
  "export_mailboxes",
18745
18862
  "create_plusvibe_client",
18746
18863
  "save_config",
18864
+ "deploy_crm",
18747
18865
  "start_provision",
18748
18866
  "status"
18749
18867
  ],
18750
18868
  {
18751
- message: "action must be one of: check_domains, check_balance, buy_domains, list_domains, list_mailboxes, setup_dmarc, create_mailboxes, export_mailboxes, create_plusvibe_client, save_config, start_provision, status"
18869
+ message: "action must be one of: check_domains, check_balance, buy_domains, list_domains, list_mailboxes, setup_dmarc, create_mailboxes, export_mailboxes, create_plusvibe_client, save_config, deploy_crm, start_provision, status"
18752
18870
  }
18753
18871
  ),
18754
18872
  domains: z2.array(z2.string()).optional(),