spirewise 1.0.1 → 1.0.3
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/bin/cli.js +71 -14
- package/install.sh +32 -8
- package/package.json +1 -1
- package/skills/f6s-copywriting/SKILL.md +51 -4
- package/skills/linkedin-copywriting/SKILL.md +52 -5
package/bin/cli.js
CHANGED
|
@@ -27,15 +27,60 @@ const PKG_ROOT = path.resolve(__dirname, '..');
|
|
|
27
27
|
const SKILLS_DIR = path.join(PKG_ROOT, 'skills');
|
|
28
28
|
const HOME = process.env.HOME || process.env.USERPROFILE || os.homedir();
|
|
29
29
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
const USE_COLOR = !process.env.NO_COLOR;
|
|
31
|
+
const RAW = {
|
|
32
|
+
reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
|
|
33
|
+
blue: '\x1b[1;34m', green: '\x1b[1;32m', yellow: '\x1b[1;33m',
|
|
34
|
+
red: '\x1b[1;31m', cyan: '\x1b[1;36m', magenta: '\x1b[1;35m',
|
|
33
35
|
};
|
|
36
|
+
const paint = (code, s) => (USE_COLOR ? `${code}${s}${RAW.reset}` : s);
|
|
37
|
+
const c = USE_COLOR
|
|
38
|
+
? RAW
|
|
39
|
+
: { reset: '', bold: '', dim: '', blue: '', green: '', yellow: '', red: '', cyan: '', magenta: '' };
|
|
40
|
+
|
|
34
41
|
const info = (m) => console.log(`${c.blue}==>${c.reset} ${m}`);
|
|
35
42
|
const ok = (m) => console.log(`${c.green} ok${c.reset} ${m}`);
|
|
36
43
|
const warn = (m) => console.error(`${c.yellow} !${c.reset} ${m}`);
|
|
37
44
|
const die = (m) => { console.error(`${c.red}err${c.reset} ${m}`); process.exit(1); };
|
|
38
45
|
|
|
46
|
+
let PKG_VERSION = '';
|
|
47
|
+
try { PKG_VERSION = require(path.join(PKG_ROOT, 'package.json')).version || ''; } catch (_) {}
|
|
48
|
+
|
|
49
|
+
const BANNER = [
|
|
50
|
+
' ███████╗██████╗ ██╗██████╗ ███████╗██╗ ██╗██╗███████╗███████╗',
|
|
51
|
+
' ██╔════╝██╔══██╗██║██╔══██╗██╔════╝██║ ██║██║██╔════╝██╔════╝',
|
|
52
|
+
' ███████╗██████╔╝██║██████╔╝█████╗ ██║ █╗ ██║██║███████╗█████╗ ',
|
|
53
|
+
' ╚════██║██╔═══╝ ██║██╔══██╗██╔══╝ ██║███╗██║██║╚════██║██╔══╝ ',
|
|
54
|
+
' ███████║██║ ██║██║ ██║███████╗╚███╔███╔╝██║███████║███████╗',
|
|
55
|
+
' ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚══╝╚══╝ ╚═╝╚══════╝╚══════╝',
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
function banner() {
|
|
59
|
+
console.log('');
|
|
60
|
+
for (const line of BANNER) console.log(paint(RAW.cyan, line));
|
|
61
|
+
const tag = ` Agent Skills · F6S & LinkedIn copywriting${PKG_VERSION ? ' · v' + PKG_VERSION : ''}`;
|
|
62
|
+
console.log(paint(RAW.magenta, tag));
|
|
63
|
+
console.log('');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let STEP_TOTAL = 4;
|
|
67
|
+
function step(n, msg) {
|
|
68
|
+
console.log(`${paint(RAW.cyan, ' ▸')} ${paint(RAW.bold, `Step ${n}/${STEP_TOTAL}`)} ${msg}`);
|
|
69
|
+
}
|
|
70
|
+
function substep(msg) {
|
|
71
|
+
console.log(` ${paint(RAW.green, '✓')} ${msg}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function box(lines) {
|
|
75
|
+
const vis = (s) => s.replace(/\x1b\[[0-9;]*m/g, '');
|
|
76
|
+
const width = Math.max(...lines.map((l) => vis(l).length));
|
|
77
|
+
const top = ' ┌' + '─'.repeat(width + 2) + '┐';
|
|
78
|
+
const bot = ' └' + '─'.repeat(width + 2) + '┘';
|
|
79
|
+
console.log(paint(RAW.green, top));
|
|
80
|
+
for (const l of lines) console.log(paint(RAW.green, ' │ ') + l + ' '.repeat(width - vis(l).length) + paint(RAW.green, ' │'));
|
|
81
|
+
console.log(paint(RAW.green, bot));
|
|
82
|
+
}
|
|
83
|
+
|
|
39
84
|
/**
|
|
40
85
|
* Agent registry. `format`:
|
|
41
86
|
* - 'skill': copy the skill folder verbatim (SKILL.md + any files)
|
|
@@ -120,13 +165,13 @@ function installToAgent(agentKey, agent, scope, skills) {
|
|
|
120
165
|
if (agent.format === 'skill') {
|
|
121
166
|
const dest = path.join(targetDir, skill);
|
|
122
167
|
copyDir(path.join(SKILLS_DIR, skill), dest);
|
|
123
|
-
|
|
168
|
+
console.log(` ${paint(RAW.green, '✓')} ${paint(RAW.bold, agent.label)} ${c.dim}(${scope})${c.reset} ${skill} ${c.dim}→ ${dest}${c.reset}`);
|
|
124
169
|
} else {
|
|
125
170
|
const { description, body } = readSkill(skill);
|
|
126
171
|
const front = `---\ndescription: ${description}\nalwaysApply: false\n---\n\n`;
|
|
127
172
|
const file = path.join(targetDir, skill + (agent.ext || '.md'));
|
|
128
173
|
fs.writeFileSync(file, front + body);
|
|
129
|
-
|
|
174
|
+
console.log(` ${paint(RAW.green, '✓')} ${paint(RAW.bold, agent.label)} ${c.dim}(${scope})${c.reset} ${skill} ${c.dim}→ ${file}${c.reset}`);
|
|
130
175
|
}
|
|
131
176
|
}
|
|
132
177
|
}
|
|
@@ -229,28 +274,40 @@ async function main() {
|
|
|
229
274
|
|
|
230
275
|
const o = parseArgs(argv);
|
|
231
276
|
|
|
277
|
+
banner();
|
|
278
|
+
|
|
279
|
+
step(1, 'Scanning available skills');
|
|
280
|
+
let skills = o.skills.length ? o.skills : available.slice();
|
|
281
|
+
for (const s of skills) if (!available.includes(s)) die(`Unknown skill '${s}'. Run "spirewise list".`);
|
|
282
|
+
substep(`${skills.length} skill(s): ${skills.join(', ')}`);
|
|
283
|
+
|
|
284
|
+
step(2, 'Selecting target agents');
|
|
232
285
|
let agentKeys = Object.keys(AGENTS);
|
|
233
286
|
if (o.agents) {
|
|
234
287
|
for (const k of o.agents) if (!AGENTS[k]) die(`Unknown agent '${k}'. Run "spirewise agents".`);
|
|
235
288
|
agentKeys = o.agents;
|
|
236
289
|
}
|
|
290
|
+
substep(`${agentKeys.length} agent(s): ${agentKeys.join(', ')}`);
|
|
237
291
|
|
|
238
|
-
|
|
239
|
-
for (const s of skills) if (!available.includes(s)) die(`Unknown skill '${s}'. Run "spirewise list".`);
|
|
240
|
-
|
|
292
|
+
step(3, 'Choosing install scope');
|
|
241
293
|
let scope = o.scope || await promptScope();
|
|
242
294
|
if (!['project', 'global', 'both'].includes(scope)) die(`Invalid scope '${scope}'.`);
|
|
243
295
|
const scopes = scope === 'both' ? ['project', 'global'] : [scope];
|
|
296
|
+
substep(`scope: ${paint(RAW.bold, scope === 'project' ? 'workspace' : scope)}`);
|
|
244
297
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
298
|
+
step(4, 'Installing');
|
|
299
|
+
let count = 0;
|
|
248
300
|
for (const sc of scopes) {
|
|
249
|
-
for (const k of agentKeys) installToAgent(k, AGENTS[k], sc, skills);
|
|
301
|
+
for (const k of agentKeys) { installToAgent(k, AGENTS[k], sc, skills); count += skills.length; }
|
|
250
302
|
}
|
|
251
303
|
|
|
252
|
-
|
|
253
|
-
|
|
304
|
+
console.log('');
|
|
305
|
+
box([
|
|
306
|
+
`Installed ${paint(RAW.bold, String(skills.length))} skill(s) into ${paint(RAW.bold, String(agentKeys.length))} agent(s)`,
|
|
307
|
+
`scope: ${scopes.map((s) => (s === 'project' ? 'workspace' : s)).join(' + ')} · ${count} item(s) written`,
|
|
308
|
+
`next: open your agent and say "write our F6S profile copy"`,
|
|
309
|
+
]);
|
|
310
|
+
console.log('');
|
|
254
311
|
}
|
|
255
312
|
|
|
256
313
|
main().catch((e) => die(e && e.message ? e.message : String(e)));
|
package/install.sh
CHANGED
|
@@ -37,6 +37,19 @@ info() { printf '%s %s\n' "$(color '1;34' '==>')" "$1"; }
|
|
|
37
37
|
ok() { printf '%s %s\n' "$(color '1;32' ' ok')" "$1"; }
|
|
38
38
|
warn() { printf '%s %s\n' "$(color '1;33' ' !')" "$1" >&2; }
|
|
39
39
|
die() { printf '%s %s\n' "$(color '1;31' 'err')" "$1" >&2; exit 1; }
|
|
40
|
+
step() { printf '%s %s %s\n' "$(color '1;36' ' >')" "$(color '1' "Step $1/4")" "$2"; }
|
|
41
|
+
substep() { printf ' %s %s\n' "$(color '1;32' 'v')" "$1"; }
|
|
42
|
+
|
|
43
|
+
banner() {
|
|
44
|
+
printf '\n'
|
|
45
|
+
color '1;36' ' ███████╗██████╗ ██╗██████╗ ███████╗██╗ ██╗██╗███████╗███████╗'; printf '\n'
|
|
46
|
+
color '1;36' ' ██╔════╝██╔══██╗██║██╔══██╗██╔════╝██║ ██║██║██╔════╝██╔════╝'; printf '\n'
|
|
47
|
+
color '1;36' ' ███████╗██████╔╝██║██████╔╝█████╗ ██║ █╗ ██║██║███████╗█████╗ '; printf '\n'
|
|
48
|
+
color '1;36' ' ╚════██║██╔═══╝ ██║██╔══██╗██╔══╝ ██║███╗██║██║╚════██║██╔══╝ '; printf '\n'
|
|
49
|
+
color '1;36' ' ███████║██║ ██║██║ ██║███████╗╚███╔███╔╝██║███████║███████╗'; printf '\n'
|
|
50
|
+
color '1;36' ' ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚══╝╚══╝ ╚═╝╚══════╝╚══════╝'; printf '\n'
|
|
51
|
+
color '1;35' ' Agent Skills · F6S & LinkedIn copywriting'; printf '\n\n'
|
|
52
|
+
}
|
|
40
53
|
|
|
41
54
|
usage() {
|
|
42
55
|
cat <<EOF
|
|
@@ -148,13 +161,13 @@ install_for_agent() {
|
|
|
148
161
|
if [[ "$fmt" == "skill" ]]; then
|
|
149
162
|
mkdir -p "$dir/$s"
|
|
150
163
|
cp -R "$base/$s/." "$dir/$s/"
|
|
151
|
-
|
|
164
|
+
substep "$label ($scope) $s -> $dir/$s"
|
|
152
165
|
else
|
|
153
166
|
local desc body file
|
|
154
167
|
desc="$(skill_description "$base/$s/SKILL.md")"
|
|
155
168
|
file="$dir/$s$ext"
|
|
156
169
|
{ printf -- '---\ndescription: %s\nalwaysApply: false\n---\n\n' "$desc"; skill_body "$base/$s/SKILL.md"; } >"$file"
|
|
157
|
-
|
|
170
|
+
substep "$label ($scope) $s -> $file"
|
|
158
171
|
fi
|
|
159
172
|
done
|
|
160
173
|
}
|
|
@@ -187,14 +200,23 @@ if $DO_LIST; then
|
|
|
187
200
|
info "Available skills:"; printf ' - %s\n' "${AVAILABLE[@]}"; exit 0
|
|
188
201
|
fi
|
|
189
202
|
|
|
190
|
-
|
|
203
|
+
banner
|
|
204
|
+
|
|
205
|
+
# Step 1: skills (default all).
|
|
206
|
+
step 1 "Scanning available skills"
|
|
191
207
|
[[ ${#SELECTED[@]} -eq 0 ]] && SELECTED=("${AVAILABLE[@]}")
|
|
192
208
|
for s in "${SELECTED[@]}"; do
|
|
193
209
|
found=false; for a in "${AVAILABLE[@]}"; do [[ "$s" == "$a" ]] && found=true && break; done
|
|
194
210
|
$found || die "Unknown skill '$s'. Use --list."
|
|
195
211
|
done
|
|
212
|
+
substep "${#SELECTED[@]} skill(s): ${SELECTED[*]}"
|
|
213
|
+
|
|
214
|
+
# Step 2: agents
|
|
215
|
+
step 2 "Selecting target agents"
|
|
216
|
+
if [[ -n "$AGENT_FILTER" ]]; then substep "agents: $AGENT_FILTER"; else substep "agents: all supported"; fi
|
|
196
217
|
|
|
197
|
-
#
|
|
218
|
+
# Step 3: scope — prompt if not given.
|
|
219
|
+
step 3 "Choosing install scope"
|
|
198
220
|
if [[ -z "$SCOPE" ]]; then
|
|
199
221
|
if [[ -t 0 ]]; then
|
|
200
222
|
info "Where should the skills be installed?"
|
|
@@ -209,11 +231,12 @@ if [[ -z "$SCOPE" ]]; then
|
|
|
209
231
|
SCOPE="project"
|
|
210
232
|
fi
|
|
211
233
|
fi
|
|
234
|
+
[[ "$SCOPE" == "project" ]] && substep "scope: workspace" || substep "scope: $SCOPE"
|
|
212
235
|
|
|
213
236
|
SCOPES=("$SCOPE"); [[ "$SCOPE" == "both" ]] && SCOPES=("project" "global")
|
|
214
237
|
|
|
215
|
-
|
|
216
|
-
|
|
238
|
+
# Step 4: install
|
|
239
|
+
step 4 "Installing"
|
|
217
240
|
for sc in "${SCOPES[@]}"; do
|
|
218
241
|
for entry in "${AGENTS[@]}"; do
|
|
219
242
|
IFS='|' read -r key label fmt ext pdir gdir <<<"$entry"
|
|
@@ -225,5 +248,6 @@ for sc in "${SCOPES[@]}"; do
|
|
|
225
248
|
done
|
|
226
249
|
done
|
|
227
250
|
|
|
228
|
-
|
|
229
|
-
|
|
251
|
+
printf '\n'
|
|
252
|
+
ok "Installed ${#SELECTED[@]} skill(s). Next: open your agent and say \"write our F6S profile copy\"."
|
|
253
|
+
|
package/package.json
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
name: f6s-copywriting
|
|
3
3
|
description: >-
|
|
4
4
|
Generate complete, ready-to-paste copywriting for an F6S (f6s.com) startup/company
|
|
5
|
-
profile page
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
profile page, written like a senior unicorn-startup marketer — humanized,
|
|
6
|
+
attention-grabbing, and conversion-focused. Use when the user asks to "write our
|
|
7
|
+
F6S profile", "create F6S copy", "fill out F6S page", or prepare content for an
|
|
8
|
+
accelerator / investor application on F6S. Produces a single .txt file under an
|
|
9
|
+
`f6s/` folder in the project root, with every field kept STRICTLY under its
|
|
10
|
+
character limit.
|
|
9
11
|
---
|
|
10
12
|
|
|
11
13
|
# F6S Profile Copywriting
|
|
@@ -69,6 +71,49 @@ keep the same "stay under" headroom rule.
|
|
|
69
71
|
- Write in third person or first-person plural ("we") consistently.
|
|
70
72
|
- No keyword stuffing; F6S profiles are read by humans (accelerators/investors).
|
|
71
73
|
|
|
74
|
+
## Voice & quality standard — write like a unicorn-startup marketer
|
|
75
|
+
|
|
76
|
+
Write every word as if you are a **senior brand + growth marketer who has led
|
|
77
|
+
messaging for category-defining startups** (think the caliber of Stripe, Notion,
|
|
78
|
+
Linear, Ramp, Airbnb). The copy an accelerator partner or investor reads should
|
|
79
|
+
feel sharp, confident, and unmistakably human. Non-negotiable bar:
|
|
80
|
+
|
|
81
|
+
**1. Humanized — sounds like a real person, never "AI-generated".**
|
|
82
|
+
- Vary sentence length. Mix short, punchy lines with one longer, rhythmic one.
|
|
83
|
+
- Use plain, concrete language a smart 12-year-old could follow. Cut jargon.
|
|
84
|
+
- Write with a point of view and a pulse — confident, not corporate-bland.
|
|
85
|
+
- Read it aloud in your head; if a sentence sounds robotic, rewrite it.
|
|
86
|
+
|
|
87
|
+
**2. Banned "AI tells" — never use these.**
|
|
88
|
+
- Filler verbs/phrases: "leverage", "utilize", "seamlessly", "robust",
|
|
89
|
+
"cutting-edge", "state-of-the-art", "empower", "unlock", "elevate",
|
|
90
|
+
"revolutionize", "game-changer", "in today's fast-paced world",
|
|
91
|
+
"we are committed to", "at the intersection of".
|
|
92
|
+
- Hype with no proof: "best", "#1", "world-class", "industry-leading".
|
|
93
|
+
- Em-dash overuse, three-item lists on autopilot, and symmetrical "not only…
|
|
94
|
+
but also" scaffolding. Break the pattern; write like a human, not a template.
|
|
95
|
+
|
|
96
|
+
**3. Attracting & focused — earn the next 5 seconds of attention.**
|
|
97
|
+
- Hook first. The opening line must make the reader want the next one.
|
|
98
|
+
- One core idea per field. If it does two jobs, split or cut.
|
|
99
|
+
- Specific > vague every time: real numbers, named customers, concrete outcomes.
|
|
100
|
+
"Cut onboarding from 3 weeks to 2 days for 40+ teams" beats "improves
|
|
101
|
+
efficiency".
|
|
102
|
+
- Lead with the customer's problem and the outcome, not your feature list.
|
|
103
|
+
- Active voice, present tense, strong verbs. Subject does the thing.
|
|
104
|
+
|
|
105
|
+
**4. Investor/accelerator lens (this is F6S).**
|
|
106
|
+
- Make the *why now*, the *traction*, and the *wedge* obvious fast.
|
|
107
|
+
- Show momentum with evidence (growth %, revenue, retention, logos, waitlist).
|
|
108
|
+
- Sound fundable and grounded — ambitious vision backed by real proof.
|
|
109
|
+
|
|
110
|
+
**5. Final humanization pass (always run before saving).**
|
|
111
|
+
- Remove every banned word above; replace with plain, specific language.
|
|
112
|
+
- Delete adjectives that aren't earned by a fact.
|
|
113
|
+
- Tighten: if a word can be cut without losing meaning, cut it.
|
|
114
|
+
- Ensure no two consecutive sentences share the same shape or opener.
|
|
115
|
+
- Confirm it reads like one confident human voice end to end.
|
|
116
|
+
|
|
72
117
|
## Required .txt output template
|
|
73
118
|
|
|
74
119
|
Write the file using exactly this structure. Put the live character count in
|
|
@@ -130,3 +175,5 @@ Other: <url>
|
|
|
130
175
|
3. No field is empty unless intentionally a `[PLACEHOLDER]`.
|
|
131
176
|
4. No banned hype words; tone is factual and specific.
|
|
132
177
|
5. Confirm counts programmatically (e.g. `awk`/`wc -m` per field) — do not trust eyeballing.
|
|
178
|
+
6. Humanization pass done: zero banned "AI tells", varied sentence shapes, reads
|
|
179
|
+
like one confident human marketer wrote it, and every claim is specific.
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: linkedin-copywriting
|
|
3
3
|
description: >-
|
|
4
|
-
Generate complete, ready-to-paste copywriting for a LinkedIn Company Page
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
Generate complete, ready-to-paste copywriting for a LinkedIn Company Page,
|
|
5
|
+
written like a senior unicorn-startup marketer — humanized, attention-grabbing,
|
|
6
|
+
and conversion-focused. Use when the user asks to "write our LinkedIn page",
|
|
7
|
+
"create LinkedIn company copy", "fill out the About section", or prepare LinkedIn
|
|
8
|
+
page content. Produces a single .txt file under a `linkedin copywriting/` folder
|
|
9
|
+
in the project root, with every field kept STRICTLY under its character limit.
|
|
9
10
|
---
|
|
10
11
|
|
|
11
12
|
# LinkedIn Company Page Copywriting
|
|
@@ -68,6 +69,50 @@ the same "stay under" headroom rule.
|
|
|
68
69
|
- Tone: professional, confident, specific. Avoid empty hype.
|
|
69
70
|
- End the About section with a clear next step (visit site, follow, contact).
|
|
70
71
|
|
|
72
|
+
## Voice & quality standard — write like a unicorn-startup marketer
|
|
73
|
+
|
|
74
|
+
Write every word as if you are a **senior brand + growth marketer who has led
|
|
75
|
+
messaging for category-defining startups** (think the caliber of Stripe, Notion,
|
|
76
|
+
Linear, Ramp, Airbnb). The page should feel sharp, confident, and unmistakably
|
|
77
|
+
human — like a person customers and recruiters *want* to follow. Non-negotiable:
|
|
78
|
+
|
|
79
|
+
**1. Humanized — sounds like a real person, never "AI-generated".**
|
|
80
|
+
- Vary sentence length. Mix short, punchy lines with one longer, rhythmic one.
|
|
81
|
+
- Plain, concrete language a smart 12-year-old could follow. Cut jargon.
|
|
82
|
+
- Write with a point of view and a pulse — confident, not corporate-bland.
|
|
83
|
+
- Read it aloud in your head; if a sentence sounds robotic, rewrite it.
|
|
84
|
+
|
|
85
|
+
**2. Banned "AI tells" — never use these.**
|
|
86
|
+
- Filler: "leverage", "utilize", "seamlessly", "robust", "cutting-edge",
|
|
87
|
+
"state-of-the-art", "empower", "unlock", "elevate", "revolutionize",
|
|
88
|
+
"game-changer", "in today's fast-paced world", "we are committed to",
|
|
89
|
+
"passionate about", "at the intersection of", "solutions provider".
|
|
90
|
+
- Hype with no proof: "best", "#1", "world-class", "industry-leading".
|
|
91
|
+
- Em-dash overuse, robotic three-item lists, and "not only… but also"
|
|
92
|
+
scaffolding. Break the pattern; write like a human, not a template.
|
|
93
|
+
|
|
94
|
+
**3. Attracting & focused — earn the next 5 seconds of attention.**
|
|
95
|
+
- The first ~150 chars of About are the hook shown before "see more" — make them
|
|
96
|
+
a magnetic, standalone value statement, not a throat-clearing intro.
|
|
97
|
+
- One core idea per section. Specific > vague every time: real numbers, named
|
|
98
|
+
customers, concrete outcomes. "Helps 12,000 founders raise faster" beats
|
|
99
|
+
"provides solutions for startups".
|
|
100
|
+
- Lead with the reader's problem and the outcome, then how you deliver it.
|
|
101
|
+
- Active voice, present tense, strong verbs. Subject does the thing.
|
|
102
|
+
|
|
103
|
+
**4. LinkedIn lens (humans + search).**
|
|
104
|
+
- Weave the terms customers/recruiters/partners actually search — naturally,
|
|
105
|
+
never stuffed. Keywords serve the sentence, not the other way around.
|
|
106
|
+
- Tagline = benefit- or category-led with a real hook, not a hollow slogan.
|
|
107
|
+
- Close About with one clear next step (follow, visit site, get in touch).
|
|
108
|
+
|
|
109
|
+
**5. Final humanization pass (always run before saving).**
|
|
110
|
+
- Remove every banned word above; replace with plain, specific language.
|
|
111
|
+
- Delete adjectives that aren't earned by a fact.
|
|
112
|
+
- Tighten: if a word can be cut without losing meaning, cut it.
|
|
113
|
+
- Ensure no two consecutive sentences share the same shape or opener.
|
|
114
|
+
- Confirm it reads like one confident human voice end to end.
|
|
115
|
+
|
|
71
116
|
## Required .txt output template
|
|
72
117
|
|
|
73
118
|
Write the file using exactly this structure. Put the live character count in
|
|
@@ -118,3 +163,5 @@ Generated: <YYYY-MM-DD>
|
|
|
118
163
|
3. Specialties: ≤ 20 items, each ≤ 28 chars.
|
|
119
164
|
4. About section's first ~150 chars work as a standalone preview hook.
|
|
120
165
|
5. Confirm counts programmatically (e.g. `awk`/`wc -m` per field) — do not trust eyeballing.
|
|
166
|
+
6. Humanization pass done: zero banned "AI tells", varied sentence shapes, reads
|
|
167
|
+
like one confident human marketer wrote it, and every claim is specific.
|