@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.
Files changed (43) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +72 -0
  3. package/dist/cli.js +268 -89
  4. package/kit/AGENTS.md +63 -63
  5. package/kit/providers/_template.md +1 -1
  6. package/kit/schemas/account.schema.json +2 -2
  7. package/kit/schemas/campaign-config.schema.json +3 -3
  8. package/kit/schemas/contact.schema.json +2 -2
  9. package/kit/schemas/icp.schema.json +3 -3
  10. package/kit/schemas/lead.schema.json +2 -2
  11. package/kit/schemas/{client.schema.json → project.schema.json} +7 -7
  12. package/kit/schemas/signal.schema.json +2 -2
  13. package/kit/schemas/signals.schema.json +3 -3
  14. package/kit/skills/00-intake/SKILL.md +12 -12
  15. package/kit/skills/01-icp/SKILL.md +9 -9
  16. package/kit/skills/02-tam/SKILL.md +5 -5
  17. package/kit/skills/03-enrich/SKILL.md +1 -1
  18. package/kit/skills/04-qualify/SKILL.md +4 -4
  19. package/kit/skills/05-copy/SKILL.md +6 -6
  20. package/kit/skills/06-qa/SKILL.md +2 -2
  21. package/kit/skills/07-launch/SKILL.md +3 -3
  22. package/kit/skills/08-results/SKILL.md +4 -4
  23. package/kit/templates/campaign/brief.md +1 -1
  24. package/kit/templates/campaign/config.yaml +3 -3
  25. package/kit/templates/outputs/qa-report.md +1 -1
  26. package/kit/templates/outputs/run-log.md +1 -1
  27. package/kit/templates/outputs/weekly-report.md +1 -1
  28. package/kit/templates/{client → project}/icp.md +1 -1
  29. package/kit/templates/{client → project}/icp.yaml +2 -2
  30. package/kit/templates/{client → project}/intake.md +11 -11
  31. package/kit/templates/{client → project}/offer.md +1 -1
  32. package/kit/templates/{client → project}/personas.md +1 -1
  33. package/kit/templates/project/project.yaml +12 -0
  34. package/kit/templates/{client → project}/proof.md +1 -1
  35. package/kit/templates/{client → project}/signals.yaml +2 -2
  36. package/kit/templates/{client → project}/voice.md +1 -1
  37. package/kit/templates/repo/{CLIENT.md → PROJECT.md} +5 -5
  38. package/kit/templates/repo/README.md +9 -9
  39. package/kit/templates/repo/github/workflows/gtm-upgrade.yml +10 -12
  40. package/kit/templates/repo/github/workflows/gtm.yml +14 -8
  41. package/kit/templates/repo/package.json +1 -2
  42. package/package.json +1 -1
  43. 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 client copy sign-off.
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 client approved.
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 client sign-off. Edits requested → change, re-present,
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
- `pnpm gtm approve copy <campaign> --by "<Name (client)>" --notes "<what was approved>"`. Quote the
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
- **Client copy sign-off (hard stop).** Recorded with `pnpm gtm approve copy <campaign>`, which pins a
49
- hash of `copy.md`. Any later change to the copy makes `pnpm gtm validate` fail and blocks the campaign
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. `pnpm gtm validate <campaign>` must pass.
17
- 2. `pnpm gtm job qa <campaign>`: validates every lead in send tiers against the `Lead` schema
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, `pnpm gtm validate` passes. Otherwise stop.
16
- 2. `pnpm gtm job push <campaign>`: creates the sender campaign **paused**, uploads the
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: `pnpm gtm job activate <campaign>`. Set `stage: results`.
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. `pnpm gtm job results <campaign>`: pulls events since the last pull into `outreach_events`,
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 client → "Learnings → PRs" in the run log, then a
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 `client.yaml` status if the engagement ends.
39
+ final report and set `project.yaml` status if the engagement ends.
40
40
 
41
41
  ## Next
42
- Next campaign: `pnpm gtm new-campaign <slug>` → routing table.
42
+ Next campaign: `npx gtm new-campaign <slug>` → routing table.
@@ -1,6 +1,6 @@
1
1
  # Campaign brief: __CAMPAIGN_ID__
2
2
 
3
- - **Client:** __CLIENT_ID__
3
+ - **Project:** __PROJECT_ID__
4
4
  - **Campaign id:** __CAMPAIGN_ID__
5
5
  - **Branch:** `campaign/__CAMPAIGN_ID__`
6
6
  - **Owner:** __OWNER__
@@ -1,10 +1,10 @@
1
1
  # yaml-language-server: $schema=../../.gtm/schemas/campaign-config.schema.json
2
- version: 1
3
- client_id: __CLIENT_ID__
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: __CLIENT_ID__-tam-TODO
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
- - [ ] `pnpm gtm validate <campaign>` passes
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
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Append-only. One file per run per user: runs/<YYYY-MM-DD>-<user>[-n].md. No PII.
4
4
 
5
- - **Client / campaign:**
5
+ - **Project / campaign:**
6
6
  - **Branch / commit:**
7
7
  - **Agent:** (Claude Code / Codex / other)
8
8
  - **Stage(s) worked:**
@@ -1,4 +1,4 @@
1
- # Weekly report: <client> · week <YYYY-Www>
1
+ # Weekly report: <project> · week <YYYY-Www>
2
2
 
3
3
  > Saved as campaigns/<campaign>/reports/<YYYY-Www>.md. Aggregates only.
4
4
 
@@ -1,4 +1,4 @@
1
- # ICP: __CLIENT_NAME__
1
+ # ICP: __PROJECT_NAME__
2
2
 
3
3
  > Human-readable rationale. The machine-readable version is `icp.yaml`. Keep them in sync.
4
4
 
@@ -1,6 +1,6 @@
1
1
  # yaml-language-server: $schema=../.gtm/schemas/icp.schema.json
2
- version: 1
3
- client_id: __CLIENT_ID__
2
+ version: 2
3
+ project_id: __PROJECT_ID__
4
4
  approval:
5
5
  status: pending # only a named human approves (AGENTS.md hard stop)
6
6
  approved_by: null
@@ -1,4 +1,4 @@
1
- # Intake: __CLIENT_NAME__
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 | client | |
35
- | Do-not-contact list | client | |
36
- | Previously contacted list (last 90 days) | client | |
37
- | Sending domains purchased | agency | |
38
- | Inboxes created + warmup started (date) | agency | |
39
- | Sender workspace created | agency | |
40
- | Calendar / booking link | client | |
41
- | Lawful basis documented (LIA for EU/UK legitimate interest) | client + agency | |
42
- | Privacy notice URL | client | |
43
- | Named approver for ICP + copy | client | |
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 | |
@@ -1,4 +1,4 @@
1
- # Offer: __CLIENT_NAME__
1
+ # Offer: __PROJECT_NAME__
2
2
 
3
3
  - **Core offer:**
4
4
  - **Outbound CTA (low friction):**
@@ -1,4 +1,4 @@
1
- # Personas: __CLIENT_NAME__
1
+ # Personas: __PROJECT_NAME__
2
2
 
3
3
  ## <persona-id> (role)
4
4
  - **Cares about:**
@@ -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,4 +1,4 @@
1
- # Proof: __CLIENT_NAME__
1
+ # Proof: __PROJECT_NAME__
2
2
 
3
3
  Only items marked **approved for outbound** may appear in copy.
4
4
 
@@ -1,6 +1,6 @@
1
1
  # yaml-language-server: $schema=../.gtm/schemas/signals.schema.json
2
- version: 1
3
- client_id: __CLIENT_ID__
2
+ version: 2
3
+ project_id: __PROJECT_ID__
4
4
  signals:
5
5
  - key: signal-one
6
6
  description: TODO
@@ -1,4 +1,4 @@
1
- # Voice: __CLIENT_NAME__
1
+ # Voice: __PROJECT_NAME__
2
2
 
3
3
  - Language / spelling:
4
4
  - Tone:
@@ -1,16 +1,16 @@
1
- # CLIENT.md: __CLIENT_NAME__
1
+ # PROJECT.md: __PROJECT_NAME__
2
2
 
3
- Client-specific rules for agents and people working in this repo. Read after AGENTS.md.
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 client, propose the change
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; client wants 2 variants max.)
13
+ - 05-copy: (e.g. All copy in British English; approver wants 2 variants max.)
14
14
 
15
15
  ## Contacts
16
- - Client approver: see client.yaml → owners.client_approver
16
+ - Project approver: see project.yaml → owners.approver
@@ -1,24 +1,24 @@
1
- # gtm-client-__CLIENT_ID__ · __CLIENT_NAME__
1
+ # gtm-project-__PROJECT_ID__ · __PROJECT_NAME__
2
2
 
3
- Private client repo. Runs the standard gtm-brain process from the public core package
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 CLIENT.md.
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
- pnpm gtm status
12
- pnpm gtm validate
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
- | `CLIENT.md` | this client | yes: client-specific additions only |
20
- | `client.yaml`, `context/`, `tam/`, `campaigns/` | this client | yes: through the stage playbooks |
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: `pnpm gtm upgrade` (refuses while a campaign is between QA and launch).
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
- - run: pnpm install --frozen-lockfile
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
- pnpm exec gtm upgrade 2>&1 | tee upgrade.log || true
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
- cache: pnpm
19
- - run: pnpm install --frozen-lockfile
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: pnpm exec gtm sync --check
22
- - name: Validate client repo
23
- run: pnpm exec gtm validate
27
+ run: npx gtm sync --check
28
+ - name: Validate project repo
29
+ run: npx gtm validate
@@ -1,8 +1,7 @@
1
1
  {
2
- "name": "gtm-client-__CLIENT_ID__",
2
+ "name": "gtm-project-__PROJECT_ID__",
3
3
  "private": true,
4
4
  "type": "module",
5
- "packageManager": "pnpm@10.34.7",
6
5
  "scripts": {
7
6
  "gtm": "gtm",
8
7
  "check": "gtm sync --check && gtm validate"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veleads/gtm",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "gtm-brain core: process kit (AGENTS.md, skills, templates, schemas) and the gtm CLI for client repos",
5
5
  "keywords": [
6
6
  "gtm",
@@ -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)