@veleads/gtm 0.2.0 → 0.3.0
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/CHANGELOG.md +18 -0
- package/README.md +72 -0
- package/dist/cli.js +268 -89
- package/kit/AGENTS.md +63 -63
- package/kit/providers/_template.md +1 -1
- package/kit/schemas/account.schema.json +2 -2
- package/kit/schemas/campaign-config.schema.json +3 -3
- package/kit/schemas/contact.schema.json +2 -2
- package/kit/schemas/icp.schema.json +3 -3
- package/kit/schemas/lead.schema.json +2 -2
- package/kit/schemas/{client.schema.json → project.schema.json} +7 -7
- package/kit/schemas/signal.schema.json +2 -2
- package/kit/schemas/signals.schema.json +3 -3
- package/kit/skills/00-intake/SKILL.md +12 -12
- package/kit/skills/01-icp/SKILL.md +9 -9
- package/kit/skills/02-tam/SKILL.md +5 -5
- package/kit/skills/03-enrich/SKILL.md +1 -1
- package/kit/skills/04-qualify/SKILL.md +4 -4
- package/kit/skills/05-copy/SKILL.md +6 -6
- package/kit/skills/06-qa/SKILL.md +2 -2
- package/kit/skills/07-launch/SKILL.md +3 -3
- package/kit/skills/08-results/SKILL.md +4 -4
- package/kit/templates/campaign/brief.md +1 -1
- package/kit/templates/campaign/config.yaml +3 -3
- package/kit/templates/outputs/qa-report.md +1 -1
- package/kit/templates/outputs/run-log.md +1 -1
- package/kit/templates/outputs/weekly-report.md +1 -1
- package/kit/templates/{client → project}/icp.md +1 -1
- package/kit/templates/{client → project}/icp.yaml +2 -2
- package/kit/templates/{client → project}/intake.md +11 -11
- package/kit/templates/{client → project}/offer.md +1 -1
- package/kit/templates/{client → project}/personas.md +1 -1
- package/kit/templates/project/project.yaml +12 -0
- package/kit/templates/{client → project}/proof.md +1 -1
- package/kit/templates/{client → project}/signals.yaml +2 -2
- package/kit/templates/{client → project}/voice.md +1 -1
- package/kit/templates/repo/{CLIENT.md → PROJECT.md} +5 -5
- package/kit/templates/repo/README.md +9 -9
- package/kit/templates/repo/github/workflows/gtm-upgrade.yml +10 -12
- package/kit/templates/repo/github/workflows/gtm.yml +14 -8
- package/kit/templates/repo/package.json +1 -2
- package/package.json +1 -1
- package/kit/templates/client/client.yaml +0 -12
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: 05-copy
|
|
3
|
-
description: Stage 5 of the gtm-brain process. Writes the email sequence and personalization per segment × persona and signal angle in copy.md, grounded in personas, offer, approved proof and voice. Ends at a hard stop for
|
|
3
|
+
description: Stage 5 of the gtm-brain process. Writes the email sequence and personalization per segment × persona and signal angle in copy.md, grounded in personas, offer, approved proof and voice. Ends at a hard stop for copy sign-off by the project approver.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# 05 · Copy
|
|
7
7
|
|
|
8
8
|
## Purpose
|
|
9
9
|
Write messages the target persona would actually reply to, using only facts
|
|
10
|
-
the
|
|
10
|
+
the approver signed off.
|
|
11
11
|
|
|
12
12
|
## Inputs
|
|
13
13
|
- `context/personas.md`, `offer.md`, `proof.md` (only "approved for outbound: yes"), `voice.md`
|
|
@@ -27,9 +27,9 @@ the client approved.
|
|
|
27
27
|
a variable.
|
|
28
28
|
5. Self-review against the checklist below, then render each step once with a fictional example
|
|
29
29
|
lead (fictional name and company) for the human.
|
|
30
|
-
6. **HARD STOP.** Present all variants for
|
|
30
|
+
6. **HARD STOP.** Present all variants for sign-off. Edits requested → change, re-present,
|
|
31
31
|
still pending. Only after explicit approval from the named approver, record it:
|
|
32
|
-
`
|
|
32
|
+
`npx gtm approve copy <campaign> --by "<Name (role)>" --notes "<what was approved>"`. Quote the
|
|
33
33
|
approval in the run log and commit `copy.md`, `config.yaml` and the run log together.
|
|
34
34
|
|
|
35
35
|
## Outputs
|
|
@@ -45,8 +45,8 @@ the client approved.
|
|
|
45
45
|
- [ ] Plain-text friendly; at most one link, none in step 1 preferred
|
|
46
46
|
|
|
47
47
|
## Gate
|
|
48
|
-
**
|
|
49
|
-
hash of `copy.md`. Any later change to the copy makes `
|
|
48
|
+
**Copy sign-off (hard stop).** Recorded with `npx gtm approve copy <campaign>`, which pins a
|
|
49
|
+
hash of `copy.md`. Any later change to the copy makes `npx gtm validate` fail and blocks the campaign
|
|
50
50
|
past `copy` until it is re-approved (or the change is reverted). Note lines starting with `>` (status,
|
|
51
51
|
available variables) and whitespace-only changes do not count.
|
|
52
52
|
|
|
@@ -13,8 +13,8 @@ Catch every avoidable problem before a single email is sent. QA is a checklist,
|
|
|
13
13
|
- `.gtm/templates/outputs/qa-report.md`
|
|
14
14
|
|
|
15
15
|
## Steps
|
|
16
|
-
1. `
|
|
17
|
-
2. `
|
|
16
|
+
1. `npx gtm validate <campaign>` must pass.
|
|
17
|
+
2. `npx gtm job qa <campaign>`: validates every lead in send tiers against the `Lead` schema
|
|
18
18
|
(`.gtm/schemas/lead.schema.json`: verified email, allowed tier, suppression checked, `field_sources.email`
|
|
19
19
|
present), checks every copy variable is filled, prints counts and rejection reasons.
|
|
20
20
|
3. Re-run suppression if the last check is older than 24h at planned launch time.
|
|
@@ -12,15 +12,15 @@ Get the approved leads and copy into the sender safely, and start sending only o
|
|
|
12
12
|
- `qa.md` (ready: yes), `config.yaml` → `sending`, `gates.copy` (approved), `copy.md`
|
|
13
13
|
|
|
14
14
|
## Steps
|
|
15
|
-
1. Verify: `gates.copy.status == approved`, `qa.md` ready, `
|
|
16
|
-
2. `
|
|
15
|
+
1. Verify: `gates.copy.status == approved`, `qa.md` ready, `npx gtm validate` passes. Otherwise stop.
|
|
16
|
+
2. `npx gtm job push <campaign>`: creates the sender campaign **paused**, uploads the
|
|
17
17
|
sequence from `copy.md`, pushes leads in send tiers, sets the schedule from `sending`. Write the
|
|
18
18
|
returned reference into `config.yaml` → `sending.sender_campaign_ref`.
|
|
19
19
|
3. Read the push counts: accepted vs. rejected (with reasons). Rejections > 2% → investigate first.
|
|
20
20
|
4. **HARD STOP: go/no-go.** Present: leads pushed by tier, daily volume and ramp, first send
|
|
21
21
|
date/time, spend so far vs. cap, QA summary, sender campaign ref (paused). Ask the campaign owner
|
|
22
22
|
or GTM engineer for an explicit go. Record in `config.yaml` → `gates.launch` per AGENTS.md section 4.
|
|
23
|
-
5. Only after approval: `
|
|
23
|
+
5. Only after approval: `npx gtm job activate <campaign>`. Set `stage: results`.
|
|
24
24
|
6. Run log: push counts, who approved, exact time activated.
|
|
25
25
|
|
|
26
26
|
## Outputs
|
|
@@ -12,7 +12,7 @@ Know what is working by segment × variant, protect deliverability, and feed lea
|
|
|
12
12
|
- `config.yaml` → `sending.sender_campaign_ref`; `brief.md` success metrics
|
|
13
13
|
|
|
14
14
|
## Steps
|
|
15
|
-
1. `
|
|
15
|
+
1. `npx gtm job results <campaign>`: pulls events since the last pull into `outreach_events`,
|
|
16
16
|
updates lead statuses, adds bounces/unsubscribes to suppression, prints aggregates by
|
|
17
17
|
segment × variant × step.
|
|
18
18
|
2. Health check first: bounce rate > 3% or any spam complaints → mandatory stop; recommend pausing
|
|
@@ -22,7 +22,7 @@ Know what is working by segment × variant, protect deliverability, and feed lea
|
|
|
22
22
|
4. Write the run log (counts only). Weekly: `reports/<YYYY-Www>.md` from `.gtm/templates/outputs/weekly-report.md`.
|
|
23
23
|
5. Compare against brief metrics. Recommend changes (variant to pause, segment to expand), but
|
|
24
24
|
copy changes go back through `05-copy` and its gate, and targeting changes through `01-icp`/`04-qualify`.
|
|
25
|
-
6. Learnings that apply beyond this
|
|
25
|
+
6. Learnings that apply beyond this project → "Learnings → PRs" in the run log, then a
|
|
26
26
|
PR to Veleads/gtm-core editing the relevant skill (never edit `.gtm/` here).
|
|
27
27
|
|
|
28
28
|
## Outputs
|
|
@@ -36,7 +36,7 @@ Run log per pull; weekly report; suppression updated (DB).
|
|
|
36
36
|
|
|
37
37
|
## Gate
|
|
38
38
|
None (recurring). The campaign ends when the brief's timeframe ends or the human stops it. Write a
|
|
39
|
-
final report and set `
|
|
39
|
+
final report and set `project.yaml` status if the engagement ends.
|
|
40
40
|
|
|
41
41
|
## Next
|
|
42
|
-
Next campaign: `
|
|
42
|
+
Next campaign: `npx gtm new-campaign <slug>` → routing table.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# yaml-language-server: $schema=../../.gtm/schemas/campaign-config.schema.json
|
|
2
|
-
version:
|
|
3
|
-
|
|
2
|
+
version: 2
|
|
3
|
+
project_id: __PROJECT_ID__
|
|
4
4
|
campaign_id: __CAMPAIGN_ID__
|
|
5
5
|
owner: __OWNER__
|
|
6
6
|
stage: icp
|
|
7
|
-
tam_id:
|
|
7
|
+
tam_id: __PROJECT_ID__-tam-TODO
|
|
8
8
|
segments: [segment-one]
|
|
9
9
|
personas: [persona-one]
|
|
10
10
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> Stage 6 output, saved as campaigns/<campaign>/qa.md. Every box must be checked or explained.
|
|
4
4
|
|
|
5
5
|
## 1. Data
|
|
6
|
-
- [ ] `
|
|
6
|
+
- [ ] `npx gtm validate <campaign>` passes
|
|
7
7
|
- [ ] Lead export validated against schemas `Lead`: <n> valid / <n> rejected (reasons)
|
|
8
8
|
- [ ] Only send_tiers present; tier counts: A <n> · B <n>
|
|
9
9
|
- [ ] Suppression re-checked within 24h of launch: <n> removed
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Intake:
|
|
1
|
+
# Intake: __PROJECT_NAME__
|
|
2
2
|
|
|
3
3
|
> Stage 0 output. Fill every section; write "unknown" rather than leaving blanks.
|
|
4
4
|
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
## Access checklist
|
|
32
32
|
| Item | Owner | Status |
|
|
33
33
|
|---|---|---|
|
|
34
|
-
| CRM export: customers + open deals (domains only) for suppression |
|
|
35
|
-
| Do-not-contact list |
|
|
36
|
-
| Previously contacted list (last 90 days) |
|
|
37
|
-
| Sending domains purchased |
|
|
38
|
-
| Inboxes created + warmup started (date) |
|
|
39
|
-
| Sender workspace created |
|
|
40
|
-
| Calendar / booking link |
|
|
41
|
-
| Lawful basis documented (LIA for EU/UK legitimate interest) |
|
|
42
|
-
| Privacy notice URL |
|
|
43
|
-
| Named approver for ICP + copy |
|
|
34
|
+
| CRM export: customers + open deals (domains only) for suppression | stakeholder | |
|
|
35
|
+
| Do-not-contact list | stakeholder | |
|
|
36
|
+
| Previously contacted list (last 90 days) | stakeholder | |
|
|
37
|
+
| Sending domains purchased | GTM team | |
|
|
38
|
+
| Inboxes created + warmup started (date) | GTM team | |
|
|
39
|
+
| Sender workspace created | GTM team | |
|
|
40
|
+
| Calendar / booking link | stakeholder | |
|
|
41
|
+
| Lawful basis documented (LIA for EU/UK legitimate interest) | stakeholder + GTM team | |
|
|
42
|
+
| Privacy notice URL | stakeholder | |
|
|
43
|
+
| Named approver for ICP + copy | stakeholder | |
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# yaml-language-server: $schema=.gtm/schemas/project.schema.json
|
|
2
|
+
version: 2
|
|
3
|
+
project_id: __PROJECT_ID__
|
|
4
|
+
name: __PROJECT_NAME__
|
|
5
|
+
status: onboarding
|
|
6
|
+
started_at: __TODAY__
|
|
7
|
+
owners:
|
|
8
|
+
gtm_engineer: TODO
|
|
9
|
+
sdrs: []
|
|
10
|
+
approver: TODO # person who signs off ICP and copy for this project
|
|
11
|
+
regions: [TODO]
|
|
12
|
+
features: {} # opt-in core features (see .gtm/ CHANGELOG / FEATURES)
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
#
|
|
1
|
+
# PROJECT.md: __PROJECT_NAME__
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Project-specific rules for agents and people working in this repo. Read after AGENTS.md.
|
|
4
4
|
|
|
5
5
|
Rules here may ADD steps or constraints to a stage. They may never remove a step, skip a check,
|
|
6
|
-
or weaken a hard stop from AGENTS.md. If a core rule seems wrong for this
|
|
6
|
+
or weaken a hard stop from AGENTS.md. If a core rule seems wrong for this project, propose the change
|
|
7
7
|
in Veleads/gtm-core instead.
|
|
8
8
|
|
|
9
9
|
## Standing constraints
|
|
10
10
|
- (e.g. Never target subsidiaries of X. Legal must review any mention of Y.)
|
|
11
11
|
|
|
12
12
|
## Stage additions
|
|
13
|
-
- 05-copy: (e.g. All copy in British English;
|
|
13
|
+
- 05-copy: (e.g. All copy in British English; approver wants 2 variants max.)
|
|
14
14
|
|
|
15
15
|
## Contacts
|
|
16
|
-
-
|
|
16
|
+
- Project approver: see project.yaml → owners.approver
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
# gtm-
|
|
1
|
+
# gtm-project-__PROJECT_ID__ · __PROJECT_NAME__
|
|
2
2
|
|
|
3
|
-
Private
|
|
3
|
+
Private project repo. Runs the standard gtm-brain process from the public core package
|
|
4
4
|
[`@veleads/gtm`](https://www.npmjs.com/package/@veleads/gtm), pinned in
|
|
5
|
-
`package.json`. **Start with AGENTS.md** (generated from core; do not edit) and then
|
|
5
|
+
`package.json`. **Start with AGENTS.md** (generated from core; do not edit) and then PROJECT.md.
|
|
6
6
|
|
|
7
7
|
## Setup
|
|
8
8
|
```bash
|
|
9
|
-
pnpm install
|
|
9
|
+
npm install # or: pnpm install / yarn install
|
|
10
10
|
cp .env.example .env
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
npx gtm status
|
|
12
|
+
npx gtm validate
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## What lives where
|
|
16
16
|
| Path | Owner | Edit? |
|
|
17
17
|
|---|---|---|
|
|
18
18
|
| `AGENTS.md`, `.gtm/` | core (`gtm sync`) | never: changes go to Veleads/gtm-core |
|
|
19
|
-
| `
|
|
20
|
-
| `
|
|
19
|
+
| `PROJECT.md` | this project | yes: project-specific additions only |
|
|
20
|
+
| `project.yaml`, `context/`, `tam/`, `campaigns/` | this project | yes: through the stage playbooks |
|
|
21
21
|
|
|
22
22
|
## Core upgrades
|
|
23
23
|
A weekly workflow opens a PR when a new core is released (`.github/workflows/gtm-upgrade.yml`).
|
|
24
|
-
Manually: `
|
|
24
|
+
Manually: `npx gtm upgrade` (refuses while a campaign is between QA and launch).
|
|
@@ -14,19 +14,25 @@ jobs:
|
|
|
14
14
|
pull-requests: write
|
|
15
15
|
steps:
|
|
16
16
|
- uses: actions/checkout@v7
|
|
17
|
-
- uses: pnpm/action-setup@v6
|
|
18
17
|
- uses: actions/setup-node@v7
|
|
19
18
|
with:
|
|
20
19
|
node-version: 22
|
|
21
|
-
-
|
|
20
|
+
- name: Install
|
|
21
|
+
run: |
|
|
22
|
+
if [ -f pnpm-lock.yaml ]; then npx -y pnpm@10 install --frozen-lockfile
|
|
23
|
+
elif [ -f yarn.lock ]; then npx -y yarn@1 install --frozen-lockfile
|
|
24
|
+
elif [ -f package-lock.json ]; then npm ci
|
|
25
|
+
else npm install
|
|
26
|
+
fi
|
|
22
27
|
- name: Upgrade core (sync + migrate + validate)
|
|
23
28
|
id: upgrade
|
|
24
29
|
run: |
|
|
25
30
|
before=$(node -p "require('./package.json').devDependencies['@veleads/gtm']")
|
|
26
|
-
|
|
31
|
+
npx gtm upgrade 2>&1 | tee "$RUNNER_TEMP/upgrade.log" || true
|
|
27
32
|
after=$(node -p "require('./package.json').devDependencies['@veleads/gtm']")
|
|
28
33
|
echo "before=$before" >> "$GITHUB_OUTPUT"
|
|
29
34
|
echo "after=$after" >> "$GITHUB_OUTPUT"
|
|
35
|
+
# Commits every change the upgrade made (kit, AGENTS.md, lockfile, migrated and renamed files).
|
|
30
36
|
- name: Open PR
|
|
31
37
|
if: steps.upgrade.outputs.before != steps.upgrade.outputs.after
|
|
32
38
|
uses: peter-evans/create-pull-request@v8
|
|
@@ -34,12 +40,4 @@ jobs:
|
|
|
34
40
|
branch: upgrade/core-v${{ steps.upgrade.outputs.after }}
|
|
35
41
|
title: "chore: core ${{ steps.upgrade.outputs.before }} → ${{ steps.upgrade.outputs.after }}"
|
|
36
42
|
commit-message: "chore: core v${{ steps.upgrade.outputs.after }}"
|
|
37
|
-
body-path: upgrade.log
|
|
38
|
-
add-paths: |
|
|
39
|
-
package.json
|
|
40
|
-
pnpm-lock.yaml
|
|
41
|
-
AGENTS.md
|
|
42
|
-
.gtm/**
|
|
43
|
-
client.yaml
|
|
44
|
-
context/*.yaml
|
|
45
|
-
campaigns/*/config.yaml
|
|
43
|
+
body-path: ${{ runner.temp }}/upgrade.log
|
|
@@ -4,20 +4,26 @@ on:
|
|
|
4
4
|
push:
|
|
5
5
|
branches: [main]
|
|
6
6
|
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
7
10
|
jobs:
|
|
8
11
|
check:
|
|
9
12
|
runs-on: ubuntu-latest
|
|
10
|
-
permissions:
|
|
11
|
-
contents: read
|
|
12
13
|
steps:
|
|
13
14
|
- uses: actions/checkout@v7
|
|
14
|
-
- uses: pnpm/action-setup@v6
|
|
15
15
|
- uses: actions/setup-node@v7
|
|
16
16
|
with:
|
|
17
17
|
node-version: 22
|
|
18
|
-
|
|
19
|
-
-
|
|
18
|
+
# Works with whichever package manager this repo uses (detected from the committed lockfile).
|
|
19
|
+
- name: Install
|
|
20
|
+
run: |
|
|
21
|
+
if [ -f pnpm-lock.yaml ]; then npx -y pnpm@10 install --frozen-lockfile
|
|
22
|
+
elif [ -f yarn.lock ]; then npx -y yarn@1 install --frozen-lockfile
|
|
23
|
+
elif [ -f package-lock.json ]; then npm ci
|
|
24
|
+
else npm install
|
|
25
|
+
fi
|
|
20
26
|
- name: Core files untouched and in sync
|
|
21
|
-
run:
|
|
22
|
-
- name: Validate
|
|
23
|
-
run:
|
|
27
|
+
run: npx gtm sync --check
|
|
28
|
+
- name: Validate project repo
|
|
29
|
+
run: npx gtm validate
|
package/package.json
CHANGED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# yaml-language-server: $schema=.gtm/schemas/client.schema.json
|
|
2
|
-
version: 1
|
|
3
|
-
client_id: __CLIENT_ID__
|
|
4
|
-
name: __CLIENT_NAME__
|
|
5
|
-
status: onboarding
|
|
6
|
-
started_at: __TODAY__
|
|
7
|
-
owners:
|
|
8
|
-
gtm_engineer: TODO
|
|
9
|
-
sdrs: []
|
|
10
|
-
client_approver: TODO # client-side person who signs off ICP and copy
|
|
11
|
-
regions: [TODO]
|
|
12
|
-
features: {} # opt-in core features (see .gtm/ CHANGELOG / FEATURES)
|