marketing-mindset 1.14.0 → 1.14.2
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/README.md +3 -1
- package/bin/cli.js +16 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -67,7 +67,9 @@ npx marketing-mindset utm --file article.md --source devto --medium article --ca
|
|
|
67
67
|
|
|
68
68
|
`--file` rewrites the file in place and reports how many links it tagged; a second run tags nothing
|
|
69
69
|
(idempotent). Third-party links are left alone, existing query params are kept, and sentence
|
|
70
|
-
punctuation after a URL stays where it belongs.
|
|
70
|
+
punctuation after a URL stays where it belongs. Tagging a page of your own site?
|
|
71
|
+
Pass `--skip-host <site>` so its internal links stay clean — an internal link with UTM
|
|
72
|
+
restarts the session and doubles the visit. The convention it writes:
|
|
71
73
|
|
|
72
74
|
| parameter | what it holds | examples |
|
|
73
75
|
|---|---|---|
|
package/bin/cli.js
CHANGED
|
@@ -75,7 +75,7 @@ const OUR_HOSTS = [
|
|
|
75
75
|
"gymcamanalytics.com", "releazer.online", "dublicator.online", "spbilo.ru", "avtootkliki.ru",
|
|
76
76
|
];
|
|
77
77
|
|
|
78
|
-
function utmTag(url, source, medium, campaign, content) {
|
|
78
|
+
function utmTag(url, source, medium, campaign, content, skipHosts) {
|
|
79
79
|
if (!/^https?:\/\//i.test(url)) return url;
|
|
80
80
|
let host;
|
|
81
81
|
try {
|
|
@@ -83,6 +83,7 @@ function utmTag(url, source, medium, campaign, content) {
|
|
|
83
83
|
} catch (e) {
|
|
84
84
|
return url;
|
|
85
85
|
}
|
|
86
|
+
if (skipHosts && skipHosts.indexOf(host) !== -1) return url; // internal link of the page's own site
|
|
86
87
|
if (OUR_HOSTS.indexOf(host) === -1) return url; // only our own destinations
|
|
87
88
|
if (/[?&]utm_source=/i.test(url)) return url; // idempotent
|
|
88
89
|
const parts = [];
|
|
@@ -99,6 +100,12 @@ function runUtm(opts) {
|
|
|
99
100
|
const medium = opts.medium ? String(opts.medium) : "referral";
|
|
100
101
|
const campaign = opts.campaign ? String(opts.campaign) : null;
|
|
101
102
|
const content = opts.content ? String(opts.content) : null;
|
|
103
|
+
// A file that IS a page of our own site should not get utm on its internal links:
|
|
104
|
+
// pass --skip-host <that site> (comma separated for several).
|
|
105
|
+
const skipHosts = String(opts["skip-host"] || opts.skipHost || "")
|
|
106
|
+
.split(",")
|
|
107
|
+
.map((h) => h.trim().replace(/^www\./, ""))
|
|
108
|
+
.filter(Boolean);
|
|
102
109
|
|
|
103
110
|
// Tag links in prose, but never inside fenced blocks or `inline code` — those are examples.
|
|
104
111
|
function tagText(text) {
|
|
@@ -118,7 +125,7 @@ function runUtm(opts) {
|
|
|
118
125
|
const tailMatch = /[.,;:!?]+$/.exec(u); // sentence punctuation is not part of the url
|
|
119
126
|
const tail = tailMatch ? tailMatch[0] : "";
|
|
120
127
|
const core = tail ? u.slice(0, -tail.length) : u;
|
|
121
|
-
const t = utmTag(core, source, medium, campaign, content);
|
|
128
|
+
const t = utmTag(core, source, medium, campaign, content, skipHosts);
|
|
122
129
|
if (t !== core) n++;
|
|
123
130
|
return t + tail;
|
|
124
131
|
});
|
|
@@ -155,10 +162,11 @@ function runUtm(opts) {
|
|
|
155
162
|
- internal links of your own site carry NO utm — they would restart the session
|
|
156
163
|
- tag only links that leave for our own domains; a third-party link stays clean
|
|
157
164
|
- never tag twice: a url that already has utm_source is returned untouched
|
|
158
|
-
- existing query params are kept
|
|
165
|
+
- existing query params are kept
|
|
166
|
+
- tagging a page of your own site? pass --skip-host <site> so its internal links stay clean`);
|
|
159
167
|
return 1;
|
|
160
168
|
}
|
|
161
|
-
const tagged = utmTag(url, source, medium, campaign, content);
|
|
169
|
+
const tagged = utmTag(url, source, medium, campaign, content, skipHosts);
|
|
162
170
|
console.log(tagged);
|
|
163
171
|
if (tagged === url) {
|
|
164
172
|
console.error("(not tagged: internal/no-own-domain/already tagged — see rules)");
|
|
@@ -1117,7 +1125,10 @@ if (cmd === "sample") {
|
|
|
1117
1125
|
}
|
|
1118
1126
|
console.log("## " + hit.title + "\n" + hit.body.join("\n").trim());
|
|
1119
1127
|
} else if (cmd === "utm") {
|
|
1120
|
-
|
|
1128
|
+
const pos = rest.filter((a) => !a.startsWith("--"));
|
|
1129
|
+
const o = flags(rest);
|
|
1130
|
+
if (pos.length && !o.url) o.url = pos[0];
|
|
1131
|
+
process.exit(runUtm(o));
|
|
1121
1132
|
} else if (cmd === "install") {
|
|
1122
1133
|
require(path.join(__dirname, "install.js"));
|
|
1123
1134
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "marketing-mindset",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.2",
|
|
4
4
|
"description": "A marketer's operating mindset as an installable agent skill and CLI: test-size floors, kill rules, honest verdicts on finished tests, which funnel step can fund a verdict, which channel can actually fund a verdict, the lift a volume can read, a queue of readable tests with read-out dates, the cost of one readable verdict, and UTM tagging on every outbound link. npx marketing-mindset sample|kill|verdict|unit|fit|queue|cost|mde|budget|brief|plan|warmup|aeo|utm|jd|sections|read|install.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-skill",
|