agemon 6.0.0 → 6.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/README.md +313 -64
- package/assets/skills/design/agemon-design/NOTICE.md +34 -0
- package/assets/skills/design/agemon-design/SKILL.md +95 -358
- package/assets/skills/design/agemon-design/references/actions.md +215 -0
- package/assets/skills/design/agemon-design/references/brief.md +13 -9
- package/assets/skills/design/agemon-design/references/core-rules.md +166 -0
- package/assets/skills/design/agemon-design/references/craft-intent.md +16 -14
- package/assets/skills/design/agemon-design/references/dashboard.md +1 -1
- package/assets/skills/design/agemon-design/references/dataviz.md +8 -8
- package/assets/skills/design/agemon-design/references/finish-bar.md +1 -1
- package/assets/skills/design/agemon-design/references/heuristics.md +56 -140
- package/assets/skills/design/agemon-design/references/inspiration.md +6 -6
- package/assets/skills/design/agemon-design/references/loops.md +9 -9
- package/assets/skills/design/agemon-design/references/motion.md +1 -1
- package/assets/skills/design/agemon-design/references/personas.md +4 -4
- package/assets/skills/design/{agemon-design-dashboard/SKILL.md → agemon-design/references/preset-dashboard.md} +8 -12
- package/assets/skills/design/{agemon-design-editorial/SKILL.md → agemon-design/references/preset-editorial.md} +5 -9
- package/assets/skills/design/{agemon-design-minimal/SKILL.md → agemon-design/references/preset-minimal.md} +8 -12
- package/assets/skills/design/agemon-design/references/principles-catalog.md +3 -3
- package/assets/skills/design/agemon-design/references/recipe-auth.md +3 -3
- package/assets/skills/design/agemon-design/references/recipe-dashboard.md +2 -2
- package/assets/skills/design/agemon-design/references/recipe-landing.md +9 -11
- package/assets/skills/design/agemon-design/references/review.md +7 -7
- package/assets/skills/design/agemon-design/references/routing.md +143 -0
- package/assets/skills/design/agemon-design/references/spec.md +8 -8
- package/assets/skills/design/agemon-design/references/stack.md +1 -1
- package/assets/skills/design/agemon-design/references/stage-assets.md +106 -0
- package/assets/skills/design/agemon-design/references/stage-build.md +46 -0
- package/assets/skills/design/agemon-design/references/stage-critique.md +34 -0
- package/assets/skills/design/agemon-design/references/stage-directions.md +44 -0
- package/assets/skills/design/agemon-design/references/stage-intake.md +34 -0
- package/assets/skills/design/agemon-design/references/stage-verify.md +44 -0
- package/assets/skills/design/agemon-design/references/state-design.md +1 -1
- package/assets/skills/design/agemon-design/references/tells-2026-11.md +32 -0
- package/assets/skills/design/agemon-design/references/themes.md +24 -20
- package/assets/skills/design/agemon-design/references/third-party-licenses.md +323 -0
- package/assets/skills/design/agemon-design/references/typography.md +11 -9
- package/assets/skills/design/agemon-design/scripts/audit-page.js +532 -0
- package/assets/skills/design/agemon-design/scripts/check-source.mjs +358 -0
- package/assets/skills/design/agemon-design/scripts/deal.mjs +231 -0
- package/assets/skills/design/agemon-design/scripts/inventory.mjs +676 -0
- package/assets/skills/{design/agemon-design-dashboard → essentials/web-design-guidelines}/LICENSE +1 -1
- package/assets/skills/essentials/web-design-guidelines/NOTICE.md +14 -0
- package/assets/skills/essentials/web-design-guidelines/SKILL.md +18 -0
- package/assets/skills/essentials/web-design-guidelines/references/guidelines.md +184 -0
- package/assets/skills/{design/agemon-design-minimal → essentials/writing-guidelines}/LICENSE +1 -1
- package/assets/skills/essentials/writing-guidelines/NOTICE.md +14 -0
- package/assets/skills/essentials/writing-guidelines/SKILL.md +18 -0
- package/assets/skills/essentials/writing-guidelines/references/guidelines.md +250 -0
- package/assets/skills/founder/agemon-founder-board/LICENSE +21 -0
- package/assets/skills/founder/agemon-founder-board/NOTICE.md +11 -0
- package/assets/skills/founder/agemon-founder-board/SKILL.md +111 -0
- package/assets/skills/founder/agemon-founder-board/lenses.md +84 -0
- package/assets/skills/founder/agemon-founder-brand/LICENSE +21 -0
- package/assets/skills/founder/agemon-founder-brand/NOTICE.md +12 -0
- package/assets/skills/founder/agemon-founder-brand/SKILL.md +77 -0
- package/assets/skills/founder/agemon-founder-cfo/LICENSE +21 -0
- package/assets/skills/founder/agemon-founder-cfo/NOTICE.md +12 -0
- package/assets/skills/founder/agemon-founder-cfo/SKILL.md +109 -0
- package/assets/skills/founder/agemon-founder-cfo/example.json +27 -0
- package/assets/skills/founder/agemon-founder-cfo/unit_economics.py +270 -0
- package/assets/skills/founder/agemon-founder-competitors/LICENSE +21 -0
- package/assets/skills/founder/agemon-founder-competitors/NOTICE.md +12 -0
- package/assets/skills/founder/agemon-founder-competitors/SKILL.md +84 -0
- package/assets/skills/founder/agemon-founder-consumer/LICENSE +21 -0
- package/assets/skills/founder/agemon-founder-consumer/NOTICE.md +11 -0
- package/assets/skills/founder/agemon-founder-consumer/SKILL.md +126 -0
- package/assets/skills/founder/agemon-founder-consumer/customer.example.json +34 -0
- package/assets/skills/founder/agemon-founder-consumer/panel.py +424 -0
- package/assets/skills/founder/agemon-founder-consumer/pitch.example.md +3 -0
- package/assets/skills/founder/agemon-founder-launch/LICENSE +21 -0
- package/assets/skills/founder/agemon-founder-launch/NOTICE.md +11 -0
- package/assets/skills/founder/agemon-founder-launch/SKILL.md +65 -0
- package/assets/skills/founder/agemon-founder-marketing/LICENSE +21 -0
- package/assets/skills/founder/agemon-founder-marketing/NOTICE.md +11 -0
- package/assets/skills/founder/agemon-founder-marketing/SKILL.md +80 -0
- package/assets/skills/founder/agemon-founder-offer/LICENSE +21 -0
- package/assets/skills/founder/agemon-founder-offer/NOTICE.md +11 -0
- package/assets/skills/founder/agemon-founder-offer/SKILL.md +75 -0
- package/assets/skills/founder/agemon-founder-ops/LICENSE +21 -0
- package/assets/skills/founder/agemon-founder-ops/NOTICE.md +12 -0
- package/assets/skills/founder/agemon-founder-ops/SKILL.md +77 -0
- package/assets/skills/founder/agemon-founder-plan/LICENSE +21 -0
- package/assets/skills/founder/agemon-founder-plan/NOTICE.md +11 -0
- package/assets/skills/founder/agemon-founder-plan/SKILL.md +88 -0
- package/assets/skills/founder/agemon-founder-plan/compile.py +178 -0
- package/assets/skills/founder/agemon-founder-pricing/LICENSE +21 -0
- package/assets/skills/founder/agemon-founder-pricing/NOTICE.md +12 -0
- package/assets/skills/founder/agemon-founder-pricing/SKILL.md +92 -0
- package/assets/skills/founder/agemon-founder-pricing/van_westendorp.py +172 -0
- package/assets/skills/{design/agemon-design-editorial → output-style/agemon-adhd}/LICENSE +1 -1
- package/assets/skills/output-style/agemon-adhd/NOTICE.md +13 -0
- package/assets/skills/output-style/agemon-adhd/SKILL.md +138 -0
- package/assets/skills/security/agemon-security-audit/AI-AND-LLM.md +83 -0
- package/assets/skills/security/agemon-security-audit/ATTACK-CLASSES.md +130 -0
- package/assets/skills/security/agemon-security-audit/CLIENT-SIDE.md +83 -0
- package/assets/skills/security/agemon-security-audit/CLOUD-AND-DEPLOYMENT.md +86 -0
- package/assets/skills/security/agemon-security-audit/DATA-ISOLATION-AND-LIFECYCLE.md +84 -0
- package/assets/skills/security/agemon-security-audit/DESKTOP-MOBILE-AND-LOCAL-IPC.md +89 -0
- package/assets/skills/security/agemon-security-audit/HUNTING.md +251 -0
- package/assets/skills/security/agemon-security-audit/LICENSE +21 -0
- package/assets/skills/security/agemon-security-audit/MEMORY-SAFETY-AND-BINARY.md +101 -0
- package/assets/skills/security/agemon-security-audit/NOTICE.md +12 -0
- package/assets/skills/security/agemon-security-audit/PROTOCOLS-RPC-AND-MESSAGING.md +81 -0
- package/assets/skills/security/agemon-security-audit/RECONNAISSANCE.md +156 -0
- package/assets/skills/security/agemon-security-audit/RESOURCE-EXHAUSTION-AND-AVAILABILITY.md +78 -0
- package/assets/skills/security/agemon-security-audit/SKILL.md +192 -0
- package/assets/skills/security/agemon-security-audit/SUPPLY-CHAIN-AND-RELEASE.md +73 -0
- package/assets/skills/security/agemon-security-audit/VALIDATION-AND-REPORTING.md +186 -0
- package/assets/skills/security/agemon-security-audit/WEB-PROTOCOL-AND-AUTH.md +105 -0
- package/assets/skills/security/agemon-security-audit/report-schema.json +461 -0
- package/assets/skills/security/agemon-security-audit/validate-coverage-ledger.cjs +872 -0
- package/assets/skills/security/agemon-security-audit/validate-findings.cjs +773 -0
- package/assets/skills/workflow/agemon-brainstorming/LICENSE +21 -0
- package/assets/skills/workflow/agemon-brainstorming/NOTICE.md +14 -0
- package/assets/skills/workflow/agemon-brainstorming/SKILL.md +287 -0
- package/assets/skills/workflow/agemon-brainstorming/builder-check-prompt.md +23 -0
- package/assets/skills/workflow/agemon-dispatching-parallel-agents/LICENSE +21 -0
- package/assets/skills/workflow/agemon-dispatching-parallel-agents/NOTICE.md +13 -0
- package/assets/skills/workflow/agemon-dispatching-parallel-agents/SKILL.md +167 -0
- package/assets/skills/workflow/agemon-executing-plans/LICENSE +21 -0
- package/assets/skills/workflow/agemon-executing-plans/NOTICE.md +15 -0
- package/assets/skills/workflow/agemon-executing-plans/SKILL.md +322 -0
- package/assets/skills/workflow/agemon-executing-plans/scripts/task-done +55 -0
- package/assets/skills/workflow/agemon-executing-plans/scripts/task-start +32 -0
- package/assets/skills/workflow/agemon-finishing-a-development-branch/LICENSE +21 -0
- package/assets/skills/workflow/agemon-finishing-a-development-branch/NOTICE.md +13 -0
- package/assets/skills/workflow/agemon-finishing-a-development-branch/SKILL.md +225 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/LICENSE +21 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/NOTICE.md +15 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/SKILL.md +339 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/code-reviewer.md +198 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/implementer-prompt.md +154 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/re-review-prompt.md +116 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/references/batching.md +11 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/references/cannot-verify.md +10 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/references/final-review.md +49 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/references/fix-loop.md +77 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/references/handling-reports.md +15 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/references/preflight.md +26 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/references/resuming.md +12 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/references/role-scout.md +18 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/references/role-worker.md +19 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/scripts/review-package +64 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/scripts/sdd-repo +54 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/scripts/sdd-workspace +110 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/scripts/task-brief +108 -0
- package/assets/skills/workflow/agemon-subagent-driven-development/task-reviewer-prompt.md +209 -0
- package/assets/skills/workflow/agemon-test-driven-development/LICENSE +21 -0
- package/assets/skills/workflow/agemon-test-driven-development/NOTICE.md +14 -0
- package/assets/skills/workflow/agemon-test-driven-development/SKILL.md +330 -0
- package/assets/skills/workflow/agemon-test-driven-development/writing-good-tests.md +198 -0
- package/assets/skills/workflow/agemon-using-git-worktrees/LICENSE +21 -0
- package/assets/skills/workflow/agemon-using-git-worktrees/NOTICE.md +13 -0
- package/assets/skills/workflow/agemon-using-git-worktrees/SKILL.md +167 -0
- package/assets/skills/workflow/agemon-writing-plans/LICENSE +21 -0
- package/assets/skills/workflow/agemon-writing-plans/NOTICE.md +13 -0
- package/assets/skills/workflow/agemon-writing-plans/SKILL.md +204 -0
- package/dist/{chunk-5LATHJYU.js → chunk-ZZBF3GOV.js} +369 -944
- package/dist/chunk-ZZBF3GOV.js.map +1 -0
- package/dist/{fake-subprocess-2BETWZVZ.js → fake-subprocess-IV4ML77S.js} +3 -33
- package/dist/fake-subprocess-IV4ML77S.js.map +1 -0
- package/dist/index.js +3477 -731
- package/dist/index.js.map +1 -1
- package/package.json +8 -1
- package/assets/skills/design/agemon-design/references/agents.md +0 -63
- package/assets/skills/design/agemon-design-dashboard/NOTICE.md +0 -9
- package/assets/skills/design/agemon-design-editorial/NOTICE.md +0 -9
- package/assets/skills/design/agemon-design-minimal/NOTICE.md +0 -9
- package/dist/chunk-5LATHJYU.js.map +0 -1
- package/dist/fake-subprocess-2BETWZVZ.js.map +0 -1
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""The buyer panel for agemon-founder-consumer. Standard library only, no network.
|
|
3
|
+
|
|
4
|
+
It does the bookkeeping for a swarm of simulated buyers: it deals one persona card
|
|
5
|
+
per buyer from your target-customer profile (income, age, behaviour, objection),
|
|
6
|
+
writes one brief per buyer for a sub-agent to answer, checks the answers, and
|
|
7
|
+
tallies who buys, who doesn't, and why.
|
|
8
|
+
|
|
9
|
+
python3 panel.py init --customer founder/customer.json --pitch founder/pitch.md [--n 100] [--seed 7]
|
|
10
|
+
python3 panel.py prompts [--wave 10] # one brief per buyer still to run, listed in waves
|
|
11
|
+
python3 panel.py check # which answers are missing or broken
|
|
12
|
+
python3 panel.py save P003 < reply.txt # file a buyer's own JSON that it printed instead of writing
|
|
13
|
+
python3 panel.py tally [--out founder/panel/results.md]
|
|
14
|
+
python3 panel.py status
|
|
15
|
+
|
|
16
|
+
State lives in founder/panel/ (--dir to change it): panel.json, personas.json,
|
|
17
|
+
briefs/<id>.md, answers/<id>.json, results.md, results.json.
|
|
18
|
+
|
|
19
|
+
The tool never answers for a buyer. Every number in results.md is counted from
|
|
20
|
+
the answer files the sub-agents wrote. Simulated buyers are a fast, cheap way to
|
|
21
|
+
find objections and weak spots. They are not customers: confirm what matters
|
|
22
|
+
with real ones (a pre-sale, a waitlist, a landing page with a price on it).
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
import argparse
|
|
26
|
+
import json
|
|
27
|
+
import os
|
|
28
|
+
import random
|
|
29
|
+
import sys
|
|
30
|
+
|
|
31
|
+
FIRST_NAMES = [
|
|
32
|
+
"Maya", "Jordan", "Priya", "Marcus", "Sofia", "Ethan", "Aisha", "Liam", "Chloe", "Daniel", "Nadia", "Owen",
|
|
33
|
+
"Grace", "Ravi", "Emma", "Kenji", "Zoe", "Luca", "Hana", "Noah", "Fatima", "Caleb", "Isla", "Mateo", "Leah",
|
|
34
|
+
"Omar", "Ava", "Theo", "Mei", "Jonah", "Sara", "Diego", "Ruby", "Kofi", "Nora", "Felix", "Amara", "Ben", "Lina",
|
|
35
|
+
"Sam", "Aria", "Julian", "Keisha", "Marco", "Ines", "Tariq", "Elena", "Hugo", "Yara", "Callum", "Rosa", "Idris",
|
|
36
|
+
"Freya", "Andre", "Leila", "Mason", "Talia", "Rohan", "Esme", "Victor", "Anya", "Kai", "Beatriz", "Declan",
|
|
37
|
+
"Sana", "Jasper", "Min", "Gabriel", "Olivia", "Arjun", "Clara", "Malik", "Iris", "Wes", "Noor", "Rafael", "Ivy",
|
|
38
|
+
"Dev", "Maeve", "Tomas", "Celine", "Adrian", "Lucia", "Hamza", "Poppy", "Ezra", "Sienna", "Darius", "Quinn",
|
|
39
|
+
"Selin", "Rhys", "Nia", "Oscar", "Tess", "Bilal", "Jade", "Luis", "Harper", "Emil", "Kira", "Pablo", "Alma",
|
|
40
|
+
"Seth", "Zara", "Nico", "Farah", "Levi", "June", "Eli", "Ana", "Yusuf", "Lena", "Cole", "Mira", "Raj", "Elle",
|
|
41
|
+
"Finn", "Dana", "Sol", "Ada",
|
|
42
|
+
]
|
|
43
|
+
REASONS = ["price", "habit", "need", "trust", "quality", "convenience", "timing", "values", "other"]
|
|
44
|
+
ANSWER_FIELDS = {"id", "buys", "reason_code", "reason"}
|
|
45
|
+
WAVE = 10
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class PanelError(Exception):
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# ── dealing ─────────────────────────────────────────────────────────────────────
|
|
53
|
+
def _quota(items, n, key="share"):
|
|
54
|
+
"""Split n across items by their shares, exactly (largest remainder)."""
|
|
55
|
+
total = sum(float(it.get(key, 1)) for it in items) or 1.0
|
|
56
|
+
raw = [n * float(it.get(key, 1)) / total for it in items]
|
|
57
|
+
counts = [int(r) for r in raw]
|
|
58
|
+
order = sorted(range(len(items)), key=lambda i: raw[i] - counts[i], reverse=True)
|
|
59
|
+
for i in order[: n - sum(counts)]:
|
|
60
|
+
counts[i] += 1
|
|
61
|
+
return counts
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def validate_customer(c):
|
|
65
|
+
for k in ("business", "target", "segments", "behaviours", "objections"):
|
|
66
|
+
if k not in c or c[k] in ("", [], None):
|
|
67
|
+
raise PanelError("customer.json needs '%s'" % k)
|
|
68
|
+
for s in c["segments"]:
|
|
69
|
+
if "name" not in s or "income" not in s or len(s["income"]) != 2:
|
|
70
|
+
raise PanelError("every segment needs a name and an income [low, high]")
|
|
71
|
+
for b in c["behaviours"]:
|
|
72
|
+
if "name" not in b:
|
|
73
|
+
raise PanelError("every behaviour needs a name")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def deal(customer, n=100, seed=7):
|
|
77
|
+
"""Deal n persona cards. Same customer + n + seed = the same cards, every time."""
|
|
78
|
+
validate_customer(customer)
|
|
79
|
+
if n < 1:
|
|
80
|
+
raise PanelError("--n must be at least 1")
|
|
81
|
+
rng = random.Random(seed)
|
|
82
|
+
age = customer.get("age", [25, 45])
|
|
83
|
+
segs = []
|
|
84
|
+
for s, k in zip(customer["segments"], _quota(customer["segments"], n)):
|
|
85
|
+
segs += [s] * k
|
|
86
|
+
behs = []
|
|
87
|
+
for b, k in zip(customer["behaviours"], _quota(customer["behaviours"], n)):
|
|
88
|
+
behs += [b] * k
|
|
89
|
+
rng.shuffle(segs)
|
|
90
|
+
rng.shuffle(behs)
|
|
91
|
+
names = FIRST_NAMES[:]
|
|
92
|
+
rng.shuffle(names)
|
|
93
|
+
while len(names) < n:
|
|
94
|
+
names += ["%s %d" % (x, len(names) // len(FIRST_NAMES) + 1) for x in FIRST_NAMES]
|
|
95
|
+
objections = customer["objections"]
|
|
96
|
+
habits = customer.get("habits") or []
|
|
97
|
+
cards = []
|
|
98
|
+
for i in range(n):
|
|
99
|
+
s, b = segs[i], behs[i]
|
|
100
|
+
lo, hi = float(s["income"][0]), float(s["income"][1])
|
|
101
|
+
cards.append({
|
|
102
|
+
"id": "P%03d" % (i + 1),
|
|
103
|
+
"name": names[i],
|
|
104
|
+
"age": rng.randint(int(age[0]), int(age[1])),
|
|
105
|
+
"segment": s["name"],
|
|
106
|
+
"income": int(round(rng.uniform(lo, hi), -3)),
|
|
107
|
+
"behaviour": b["name"],
|
|
108
|
+
"behaviour_how": b.get("how", ""),
|
|
109
|
+
"objection": objections[rng.randrange(len(objections))],
|
|
110
|
+
"habit": habits[rng.randrange(len(habits))] if habits else "",
|
|
111
|
+
})
|
|
112
|
+
return cards
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# ── state ───────────────────────────────────────────────────────────────────────
|
|
116
|
+
def _path(d, *p):
|
|
117
|
+
return os.path.join(d, *p)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _read_json(path):
|
|
121
|
+
with open(path, encoding="utf-8") as fh:
|
|
122
|
+
return json.load(fh)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _write_json(path, obj):
|
|
126
|
+
os.makedirs(os.path.dirname(path) or ".", exist_ok=True)
|
|
127
|
+
with open(path, "w", encoding="utf-8") as fh:
|
|
128
|
+
json.dump(obj, fh, indent=1, ensure_ascii=False)
|
|
129
|
+
fh.write("\n")
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def init(d, customer_path, pitch_path, n=100, seed=None):
|
|
133
|
+
try:
|
|
134
|
+
customer = _read_json(customer_path)
|
|
135
|
+
except FileNotFoundError:
|
|
136
|
+
raise PanelError("no such file: %s" % customer_path)
|
|
137
|
+
try:
|
|
138
|
+
with open(pitch_path, encoding="utf-8") as fh:
|
|
139
|
+
pitch = fh.read().strip()
|
|
140
|
+
except FileNotFoundError:
|
|
141
|
+
raise PanelError("no such file: %s (write the pitch first: what you sell, the price, where)" % pitch_path)
|
|
142
|
+
if not pitch:
|
|
143
|
+
raise PanelError("the pitch is empty")
|
|
144
|
+
if seed is None:
|
|
145
|
+
seed = random.SystemRandom().randrange(1, 10 ** 6)
|
|
146
|
+
cards = deal(customer, n, seed)
|
|
147
|
+
_write_json(_path(d, "panel.json"), {"n": n, "seed": seed, "customer": customer, "pitch": pitch})
|
|
148
|
+
_write_json(_path(d, "personas.json"), cards)
|
|
149
|
+
os.makedirs(_path(d, "briefs"), exist_ok=True)
|
|
150
|
+
os.makedirs(_path(d, "answers"), exist_ok=True)
|
|
151
|
+
return cards
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def load_state(d):
|
|
155
|
+
try:
|
|
156
|
+
return _read_json(_path(d, "panel.json")), _read_json(_path(d, "personas.json"))
|
|
157
|
+
except FileNotFoundError:
|
|
158
|
+
raise PanelError("no panel in %s: run init first" % d)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
BRIEF = """You are a simulated buyer on a consumer panel. A founder wants to know, before spending any money, whether real people like you would buy. Your answer is only useful if it is honest: most people do not buy most things, and a polite yes is worse than a clear no.
|
|
162
|
+
|
|
163
|
+
=== WHO YOU ARE ===
|
|
164
|
+
{name}, {age}. {segment}. You earn about ${income:,} a year.
|
|
165
|
+
How you buy: {behaviour}. {behaviour_how}
|
|
166
|
+
{habit_line}The first thing that comes to mind when you hear an offer like this: "{objection}"
|
|
167
|
+
You are one of these people: {target}.
|
|
168
|
+
=== END ===
|
|
169
|
+
|
|
170
|
+
=== WHAT IS BEING OFFERED (you see it for the first time, the way a passer-by or a scroller would) ===
|
|
171
|
+
{pitch}
|
|
172
|
+
=== END ===
|
|
173
|
+
|
|
174
|
+
Decide as {name} would, with {name}'s money, habits and doubts, in a normal week. Do not be agreeable. Do not invent facts about the business beyond what is written above.
|
|
175
|
+
|
|
176
|
+
Create the file {out} with your file-writing tool (do not just print the answer in your reply) containing ONLY this JSON, no markdown fence, nothing else:
|
|
177
|
+
{{
|
|
178
|
+
"id": "{id}",
|
|
179
|
+
"buys": true or false,
|
|
180
|
+
"purchases_first_month": how many times you would buy in the first month (0 if you would not buy),
|
|
181
|
+
"reason_code": one of {reasons},
|
|
182
|
+
"reason": "why, in one or two sentences, in your own voice",
|
|
183
|
+
"objection": "the doubt that weighs most for you, in your own words",
|
|
184
|
+
"would_change_my_mind": "the one thing that would flip your answer, or empty",
|
|
185
|
+
"price_too_cheap": the price at which it would seem too cheap to be any good (a number),
|
|
186
|
+
"price_cheap": the price at which it would feel like a bargain (a number),
|
|
187
|
+
"price_expensive": the price at which it starts to feel expensive but you might still buy (a number),
|
|
188
|
+
"price_too_expensive": the price at which you would not buy it at all (a number)
|
|
189
|
+
}}
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def write_briefs(d, wave=WAVE):
|
|
194
|
+
state, cards = load_state(d)
|
|
195
|
+
target = state["customer"]["target"]
|
|
196
|
+
todo = []
|
|
197
|
+
for c in cards:
|
|
198
|
+
out = _path(d, "answers", c["id"] + ".json")
|
|
199
|
+
if _answer_ok(out, c["id"]) is None:
|
|
200
|
+
continue
|
|
201
|
+
brief = BRIEF.format(pitch=state["pitch"], target=target, out=os.path.abspath(out),
|
|
202
|
+
habit_line=("Your day: %s.\n" % c["habit"]) if c.get("habit") else "",
|
|
203
|
+
reasons=" / ".join(REASONS), **c)
|
|
204
|
+
bp = _path(d, "briefs", c["id"] + ".md")
|
|
205
|
+
with open(bp, "w", encoding="utf-8") as fh:
|
|
206
|
+
fh.write(brief)
|
|
207
|
+
todo.append((c["id"], os.path.abspath(bp)))
|
|
208
|
+
waves = [todo[i:i + wave] for i in range(0, len(todo), wave)]
|
|
209
|
+
return waves
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def _answer_ok(path, pid):
|
|
213
|
+
"""None if the answer file is good, else a short problem string."""
|
|
214
|
+
if not os.path.exists(path):
|
|
215
|
+
return "missing"
|
|
216
|
+
try:
|
|
217
|
+
a = _read_json(path)
|
|
218
|
+
except (json.JSONDecodeError, UnicodeDecodeError):
|
|
219
|
+
return "not valid JSON"
|
|
220
|
+
missing = ANSWER_FIELDS - set(a)
|
|
221
|
+
if missing:
|
|
222
|
+
return "missing " + ", ".join(sorted(missing))
|
|
223
|
+
if a.get("id") != pid:
|
|
224
|
+
return "id is %r, expected %s" % (a.get("id"), pid)
|
|
225
|
+
if not isinstance(a.get("buys"), bool):
|
|
226
|
+
return "'buys' must be true or false"
|
|
227
|
+
if a.get("reason_code") not in REASONS:
|
|
228
|
+
return "reason_code %r is not one of %s" % (a.get("reason_code"), ", ".join(REASONS))
|
|
229
|
+
return None
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def save(d, pid, text):
|
|
233
|
+
"""File a buyer's OWN answer that it printed instead of writing. Never used to answer for a buyer."""
|
|
234
|
+
_, cards = load_state(d)
|
|
235
|
+
if pid not in {c["id"] for c in cards}:
|
|
236
|
+
raise PanelError("no buyer %s on this panel" % pid)
|
|
237
|
+
start = text.find("{")
|
|
238
|
+
if start < 0:
|
|
239
|
+
raise PanelError("no JSON object in the reply")
|
|
240
|
+
try:
|
|
241
|
+
obj, _ = json.JSONDecoder().raw_decode(text[start:])
|
|
242
|
+
except json.JSONDecodeError as e:
|
|
243
|
+
raise PanelError("the reply's JSON does not parse: %s" % e)
|
|
244
|
+
path = _path(d, "answers", pid + ".json")
|
|
245
|
+
_write_json(path, obj)
|
|
246
|
+
prob = _answer_ok(path, pid)
|
|
247
|
+
if prob:
|
|
248
|
+
os.remove(path)
|
|
249
|
+
raise PanelError("%s's answer is not valid (%s); re-run its brief instead" % (pid, prob))
|
|
250
|
+
return path
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def check(d):
|
|
254
|
+
_, cards = load_state(d)
|
|
255
|
+
probs = []
|
|
256
|
+
for c in cards:
|
|
257
|
+
p = _answer_ok(_path(d, "answers", c["id"] + ".json"), c["id"])
|
|
258
|
+
if p:
|
|
259
|
+
probs.append((c["id"], p))
|
|
260
|
+
return probs
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
# ── tally ───────────────────────────────────────────────────────────────────────
|
|
264
|
+
def _rate(rows):
|
|
265
|
+
return (sum(1 for r in rows if r["buys"]) / len(rows)) if rows else 0.0
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _num(v):
|
|
269
|
+
try:
|
|
270
|
+
return float(v)
|
|
271
|
+
except (TypeError, ValueError):
|
|
272
|
+
return None
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def tally(d):
|
|
276
|
+
state, cards = load_state(d)
|
|
277
|
+
by_id = {c["id"]: c for c in cards}
|
|
278
|
+
rows, skipped = [], []
|
|
279
|
+
for c in cards:
|
|
280
|
+
path = _path(d, "answers", c["id"] + ".json")
|
|
281
|
+
p = _answer_ok(path, c["id"])
|
|
282
|
+
if p:
|
|
283
|
+
skipped.append((c["id"], p))
|
|
284
|
+
continue
|
|
285
|
+
a = _read_json(path)
|
|
286
|
+
rows.append(dict(by_id[c["id"]], **{k: v for k, v in a.items() if k != "id"}, id=c["id"]))
|
|
287
|
+
if not rows:
|
|
288
|
+
raise PanelError("no valid answers yet: run the briefs first (panel.py prompts)")
|
|
289
|
+
|
|
290
|
+
def group(key):
|
|
291
|
+
out = {}
|
|
292
|
+
for r in rows:
|
|
293
|
+
out.setdefault(r[key], []).append(r)
|
|
294
|
+
return sorted(((k, len(v), _rate(v)) for k, v in out.items()), key=lambda t: -t[2])
|
|
295
|
+
|
|
296
|
+
# income in thirds of the dealt range, so the bands mean the same thing every run
|
|
297
|
+
incomes = sorted(r["income"] for r in rows)
|
|
298
|
+
cut1, cut2 = incomes[len(incomes) // 3], incomes[2 * len(incomes) // 3]
|
|
299
|
+
for r in rows:
|
|
300
|
+
r["income_band"] = ("under $%s" % "{:,}".format(cut1)) if r["income"] < cut1 else (
|
|
301
|
+
("$%s and up" % "{:,}".format(cut2)) if r["income"] >= cut2 else "$%s to $%s" % ("{:,}".format(cut1), "{:,}".format(cut2)))
|
|
302
|
+
|
|
303
|
+
no = [r for r in rows if not r["buys"]]
|
|
304
|
+
yes = [r for r in rows if r["buys"]]
|
|
305
|
+
|
|
306
|
+
def reasons(rs):
|
|
307
|
+
out = {}
|
|
308
|
+
for r in rs:
|
|
309
|
+
out.setdefault(r["reason_code"], []).append(r)
|
|
310
|
+
return sorted(((k, v) for k, v in out.items()), key=lambda kv: -len(kv[1]))
|
|
311
|
+
|
|
312
|
+
def mean(vals):
|
|
313
|
+
vals = [v for v in vals if v is not None]
|
|
314
|
+
return sum(vals) / len(vals) if vals else None
|
|
315
|
+
|
|
316
|
+
res = {
|
|
317
|
+
"business": state["customer"]["business"], "seed": state["seed"], "dealt": len(cards),
|
|
318
|
+
"answered": len(rows), "skipped": skipped, "buys": len(yes), "passes": len(no),
|
|
319
|
+
"buy_rate": len(yes) / len(rows),
|
|
320
|
+
"by_segment": group("segment"), "by_behaviour": group("behaviour"), "by_income": group("income_band"),
|
|
321
|
+
"why_not": [(k, len(v), [r["reason"] for r in v[:2]], [r["id"] for r in v[:2]]) for k, v in reasons(no)],
|
|
322
|
+
"why_yes": [(k, len(v), [r["reason"] for r in v[:2]], [r["id"] for r in v[:2]]) for k, v in reasons(yes)],
|
|
323
|
+
"flip": [r["would_change_my_mind"] for r in no if (r.get("would_change_my_mind") or "").strip()],
|
|
324
|
+
"purchases_first_month_per_buyer": mean([_num(r.get("purchases_first_month")) for r in yes]),
|
|
325
|
+
"price_answers": sum(1 for r in rows if all(_num(r.get(k)) is not None for k in
|
|
326
|
+
("price_too_cheap", "price_cheap", "price_expensive", "price_too_expensive"))),
|
|
327
|
+
}
|
|
328
|
+
return res
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def results_md(res):
|
|
332
|
+
pct = lambda v: "%.0f%%" % (v * 100)
|
|
333
|
+
L = ["# Buyer panel: %s" % res["business"], ""]
|
|
334
|
+
L.append("**%d buy · %d pass** (%s buy) out of %d simulated buyers. Seed %s, so the same cards can be dealt again."
|
|
335
|
+
% (res["buys"], res["passes"], pct(res["buy_rate"]), res["answered"], res["seed"]))
|
|
336
|
+
if res["skipped"]:
|
|
337
|
+
L.append("")
|
|
338
|
+
L.append("%d of %d buyers have no valid answer and are left out: %s." % (
|
|
339
|
+
len(res["skipped"]), res["dealt"], ", ".join("%s (%s)" % s for s in res["skipped"][:10])))
|
|
340
|
+
L.append("")
|
|
341
|
+
L.append("These are simulated buyers, not customers. Use this to find objections and weak spots, then confirm the"
|
|
342
|
+
" big ones with real people before you spend.")
|
|
343
|
+
for title, key in (("By segment", "by_segment"), ("By buying behaviour", "by_behaviour"), ("By income", "by_income")):
|
|
344
|
+
L += ["", "## %s" % title, "", "| group | buyers | buy rate |", "| --- | ---: | ---: |"]
|
|
345
|
+
for k, n, r in res[key]:
|
|
346
|
+
L.append("| %s | %d | %s%s |" % (k, n, pct(r), " (thin)" if n < 8 else ""))
|
|
347
|
+
L += ["", "## Why they pass", "", "| reason | buyers | in their words |", "| --- | ---: | --- |"]
|
|
348
|
+
for k, n, quotes, ids in res["why_not"]:
|
|
349
|
+
L.append("| %s | %d | %s |" % (k, n, " · ".join('"%s" (%s)' % (q.replace("|", "/"), i) for q, i in zip(quotes, ids))))
|
|
350
|
+
L += ["", "## Why they buy", "", "| reason | buyers | in their words |", "| --- | ---: | --- |"]
|
|
351
|
+
for k, n, quotes, ids in res["why_yes"]:
|
|
352
|
+
L.append("| %s | %d | %s |" % (k, n, " · ".join('"%s" (%s)' % (q.replace("|", "/"), i) for q, i in zip(quotes, ids))))
|
|
353
|
+
if res["flip"]:
|
|
354
|
+
L += ["", "## What would flip a no", ""]
|
|
355
|
+
for f in res["flip"][:12]:
|
|
356
|
+
L.append("- %s" % f)
|
|
357
|
+
if res["purchases_first_month_per_buyer"] is not None:
|
|
358
|
+
L += ["", "Buyers say they would buy **%.1f times** in the first month on average." % res["purchases_first_month_per_buyer"]]
|
|
359
|
+
if res["price_answers"]:
|
|
360
|
+
L += ["", "%d buyers gave all four price answers. Run agemon-founder-pricing's van_westendorp.py on the answers folder." % res["price_answers"]]
|
|
361
|
+
return "\n".join(L) + "\n"
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def main(argv=None):
|
|
365
|
+
ap = argparse.ArgumentParser(description=__doc__.split("\n\n")[0])
|
|
366
|
+
ap.add_argument("--dir", default=os.path.join("founder", "panel"))
|
|
367
|
+
sub = ap.add_subparsers(dest="cmd", required=True)
|
|
368
|
+
i = sub.add_parser("init")
|
|
369
|
+
i.add_argument("--customer", required=True)
|
|
370
|
+
i.add_argument("--pitch", required=True)
|
|
371
|
+
i.add_argument("--n", type=int, default=100)
|
|
372
|
+
i.add_argument("--seed", type=int)
|
|
373
|
+
p = sub.add_parser("prompts")
|
|
374
|
+
p.add_argument("--wave", type=int, default=WAVE)
|
|
375
|
+
sub.add_parser("check")
|
|
376
|
+
sv = sub.add_parser("save")
|
|
377
|
+
sv.add_argument("id")
|
|
378
|
+
t = sub.add_parser("tally")
|
|
379
|
+
t.add_argument("--out")
|
|
380
|
+
sub.add_parser("status")
|
|
381
|
+
a = ap.parse_args(argv)
|
|
382
|
+
try:
|
|
383
|
+
if a.cmd == "init":
|
|
384
|
+
cards = init(a.dir, a.customer, a.pitch, a.n, a.seed)
|
|
385
|
+
st, _ = load_state(a.dir)
|
|
386
|
+
print("dealt %d buyers (seed %s) into %s. Next: panel.py prompts" % (len(cards), st["seed"], a.dir))
|
|
387
|
+
elif a.cmd == "prompts":
|
|
388
|
+
waves = write_briefs(a.dir, a.wave)
|
|
389
|
+
n = sum(len(w) for w in waves)
|
|
390
|
+
if not n:
|
|
391
|
+
print("every buyer has a valid answer. Next: panel.py tally")
|
|
392
|
+
else:
|
|
393
|
+
print("%d briefs in %d waves of up to %d. Launch one wave at a time:" % (n, len(waves), a.wave))
|
|
394
|
+
for k, w in enumerate(waves, 1):
|
|
395
|
+
print("wave %d: %s" % (k, " ".join("%s=%s" % job for job in w)))
|
|
396
|
+
elif a.cmd == "check":
|
|
397
|
+
probs = check(a.dir)
|
|
398
|
+
if not probs:
|
|
399
|
+
print("all answers present and valid")
|
|
400
|
+
for pid, prob in probs:
|
|
401
|
+
print("%s: %s" % (pid, prob))
|
|
402
|
+
return 1 if probs else 0
|
|
403
|
+
elif a.cmd == "save":
|
|
404
|
+
print("saved %s" % save(a.dir, a.id, sys.stdin.read()))
|
|
405
|
+
elif a.cmd == "tally":
|
|
406
|
+
res = tally(a.dir)
|
|
407
|
+
text = results_md(res)
|
|
408
|
+
out = a.out or _path(a.dir, "results.md")
|
|
409
|
+
with open(out, "w", encoding="utf-8") as fh:
|
|
410
|
+
fh.write(text)
|
|
411
|
+
_write_json(_path(a.dir, "results.json"), res)
|
|
412
|
+
print("%d buy · %d pass (%.0f%%). Wrote %s" % (res["buys"], res["passes"], res["buy_rate"] * 100, out))
|
|
413
|
+
elif a.cmd == "status":
|
|
414
|
+
st, cards = load_state(a.dir)
|
|
415
|
+
probs = check(a.dir)
|
|
416
|
+
print("%d buyers dealt (seed %s), %d answered, %d to go" % (len(cards), st["seed"], len(cards) - len(probs), len(probs)))
|
|
417
|
+
except PanelError as e:
|
|
418
|
+
print("error: %s" % e, file=sys.stderr)
|
|
419
|
+
return 2
|
|
420
|
+
return 0
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
if __name__ == "__main__":
|
|
424
|
+
sys.exit(main())
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jake Schincariol
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Vendored skill
|
|
2
|
+
|
|
3
|
+
- Source: https://github.com/Jakeschincariol/founder-skill
|
|
4
|
+
- Path in source: skills/founder-launch
|
|
5
|
+
- Commit: fd9385b0cfe1b96bebce3898fbd506d73eff5a9d
|
|
6
|
+
- Retrieved: 2026-11-05
|
|
7
|
+
- License: MIT — see `LICENSE` in this directory.
|
|
8
|
+
|
|
9
|
+
## agemon modifications
|
|
10
|
+
|
|
11
|
+
- Renamed from `founder-launch` to `agemon-founder-launch`, and updated every reference to the pack's other skills to their new names, in the Markdown and in the scripts.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agemon-founder-launch
|
|
3
|
+
description: >-
|
|
4
|
+
Your launch lead. Builds a dated, step-by-step launch plan: a cheap real-world
|
|
5
|
+
test first (a waitlist, a pre-sale or a pop-up with a real price, so real buyers
|
|
6
|
+
confirm what the simulated panel said), then the countdown to opening day with
|
|
7
|
+
owners and deadlines, the launch-day run sheet, and the first 30 days of what to
|
|
8
|
+
measure and what to change. Use when the user says "how do I launch", "launch
|
|
9
|
+
plan", "when can I open", "launch checklist", "go live", or "soft open".
|
|
10
|
+
argument-hint: "[target launch date]"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# agemon-founder-launch
|
|
14
|
+
|
|
15
|
+
Launching is a project with a date. This skill turns everything else in the pack
|
|
16
|
+
into a dated plan, and starts with the cheapest way to find out if real people
|
|
17
|
+
will pay before the big money goes out.
|
|
18
|
+
|
|
19
|
+
## Step 1: test before you spend
|
|
20
|
+
|
|
21
|
+
Pick the cheapest real test that fits the business, and run it before signing the
|
|
22
|
+
big costs in `founder/numbers.json`:
|
|
23
|
+
|
|
24
|
+
| business | the test |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| physical shop or café | a pop-up, a market stall or a pre-order list with a price and a date |
|
|
27
|
+
| online product | a landing page with the price and a "pre-order" or "join the waitlist" button |
|
|
28
|
+
| service or agency | three paid pilot clients at the planned price |
|
|
29
|
+
| subscription | a founding-member offer, paid up front |
|
|
30
|
+
|
|
31
|
+
Write the success line before running it (for example: 50 pre-orders in two weeks
|
|
32
|
+
at $6.50), and compare the result with the panel's buy rate. If real buyers fall
|
|
33
|
+
well short of the panel, trust the real buyers and go back to `/agemon-founder-offer` or
|
|
34
|
+
`/agemon-founder-pricing`.
|
|
35
|
+
|
|
36
|
+
## Step 2: the countdown
|
|
37
|
+
|
|
38
|
+
From today to launch day, with real dates (ask for the target date; default to the
|
|
39
|
+
earliest realistic one given lead times in `founder/ops.md`). Weekly blocks, each
|
|
40
|
+
task with an owner and a deadline:
|
|
41
|
+
|
|
42
|
+
- Legal and money: registration, bank account, permits from `founder/ops.md`.
|
|
43
|
+
- Build: fit-out or website, suppliers ordered by their lead times.
|
|
44
|
+
- Brand: sign, packaging, profiles from `founder/brand.md`.
|
|
45
|
+
- Marketing: the calendar in `founder/marketing.md` from launch minus 14 days.
|
|
46
|
+
- Team: hiring and training on the SOPs.
|
|
47
|
+
- A soft open or friends-and-family day before the public launch.
|
|
48
|
+
|
|
49
|
+
Mark the critical path: the tasks that move the launch date if they slip.
|
|
50
|
+
|
|
51
|
+
## Step 3: launch day
|
|
52
|
+
|
|
53
|
+
An hour-by-hour run sheet: who is where, what goes out on which channel, the
|
|
54
|
+
opening offer, what to do if something breaks (from the risk register).
|
|
55
|
+
|
|
56
|
+
## Step 4: the first 30 days
|
|
57
|
+
|
|
58
|
+
The weekly numbers to track (from the CFO: units a day against break-even; from
|
|
59
|
+
marketing: the channel numbers), the level that triggers a change, and a review on
|
|
60
|
+
days 7, 14 and 30 with the questions to answer.
|
|
61
|
+
|
|
62
|
+
## Output
|
|
63
|
+
|
|
64
|
+
`founder/launch.md` with the test, the countdown, the run sheet and the 30-day
|
|
65
|
+
review. Next: `/agemon-founder-plan` compiles everything into the business plan.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jake Schincariol
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Vendored skill
|
|
2
|
+
|
|
3
|
+
- Source: https://github.com/Jakeschincariol/founder-skill
|
|
4
|
+
- Path in source: skills/founder-marketing
|
|
5
|
+
- Commit: fd9385b0cfe1b96bebce3898fbd506d73eff5a9d
|
|
6
|
+
- Retrieved: 2026-11-05
|
|
7
|
+
- License: MIT — see `LICENSE` in this directory.
|
|
8
|
+
|
|
9
|
+
## agemon modifications
|
|
10
|
+
|
|
11
|
+
- Renamed from `founder-marketing` to `agemon-founder-marketing`, and updated every reference to the pack's other skills to their new names, in the Markdown and in the scripts.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agemon-founder-marketing
|
|
3
|
+
description: >-
|
|
4
|
+
Your marketing director. Turns the buyer panel and the competitor map into
|
|
5
|
+
positioning, the channels the target customer actually uses, a 30-day launch
|
|
6
|
+
campaign with dated posts and ads, the first ten hooks, a budget split and the
|
|
7
|
+
numbers to watch. Every message answers an objection real or simulated buyers
|
|
8
|
+
raised. Use when the user says "how do I market this", "marketing plan", "launch
|
|
9
|
+
campaign", "how do I get customers", "where do I advertise", "write my ads", or
|
|
10
|
+
"positioning".
|
|
11
|
+
argument-hint: "[budget]"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# agemon-founder-marketing
|
|
15
|
+
|
|
16
|
+
A business no one hears about does not exist. This skill plans how the first
|
|
17
|
+
customers hear about it, using what the rest of the pack already learned instead
|
|
18
|
+
of a generic playbook.
|
|
19
|
+
|
|
20
|
+
## Step 1: read the evidence
|
|
21
|
+
|
|
22
|
+
- `founder/panel/results.md`: who buys, who doesn't, and why. The segments with the
|
|
23
|
+
highest buy rate are the first audience. The top objections are what the
|
|
24
|
+
marketing must answer.
|
|
25
|
+
- `founder/competitors.md`: how competitors position themselves (so you do not
|
|
26
|
+
sound like them) and the gap.
|
|
27
|
+
- `founder/offer.md` and `founder/pricing.md`: what is being sold, at what price.
|
|
28
|
+
- `founder/numbers.json`: what a customer is worth, which caps what you can spend to
|
|
29
|
+
win one.
|
|
30
|
+
|
|
31
|
+
If none of these exist, say what is missing and offer to run `/agemon-founder-consumer
|
|
32
|
+
--quick` first. Do not invent an audience.
|
|
33
|
+
|
|
34
|
+
## Step 2: positioning
|
|
35
|
+
|
|
36
|
+
One line, then the reasons:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
For <the segment that buys most>, who <their problem in their words>,
|
|
40
|
+
<business> is the <category> that <the gap>, unlike <the nearest alternative>.
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Give three versions, recommend one, and say which panel evidence supports it.
|
|
44
|
+
|
|
45
|
+
## Step 3: channels
|
|
46
|
+
|
|
47
|
+
List where the first audience actually spends attention, specific to the business
|
|
48
|
+
type and place: foot traffic and window signage, Google Maps, Instagram and TikTok,
|
|
49
|
+
local creators, neighbourhood groups, partnerships with nearby businesses, email,
|
|
50
|
+
paid search, paid social. For each: why it fits this buyer, rough cost, and how you
|
|
51
|
+
will know it worked. Pick two or three to start; say what you are not doing and why.
|
|
52
|
+
|
|
53
|
+
## Step 4: the 30-day campaign
|
|
54
|
+
|
|
55
|
+
`founder/marketing.md` gets a dated calendar from launch minus 14 days to launch
|
|
56
|
+
plus 16: what goes out each day, on which channel, with the message. Include:
|
|
57
|
+
|
|
58
|
+
- **Ten hooks**, each answering one panel objection or using one buyer reason,
|
|
59
|
+
written for the format (a 3-second opening line for video, a headline for an ad,
|
|
60
|
+
a sign in the window).
|
|
61
|
+
- The launch-week offer from `founder/pricing.md` and when it ends.
|
|
62
|
+
- What to post when there is nothing new to say (behind the scenes, the making of).
|
|
63
|
+
|
|
64
|
+
## Step 5: budget and numbers
|
|
65
|
+
|
|
66
|
+
- The budget split across the chosen channels.
|
|
67
|
+
- The most you can pay to win a customer: from the CFO's contribution per unit and
|
|
68
|
+
the panel's purchases per buyer, show the sum.
|
|
69
|
+
- The three numbers to watch weekly and the level that means "change something".
|
|
70
|
+
|
|
71
|
+
## Rules
|
|
72
|
+
|
|
73
|
+
- No fake reviews, follower counts, testimonials, before/afters or "as seen on".
|
|
74
|
+
- Panel quotes are research; never use them as customer quotes in ads.
|
|
75
|
+
- Disclose paid partnerships. Follow the advertising rules for claims in the user's
|
|
76
|
+
market (health and earnings claims especially). Not legal advice.
|
|
77
|
+
|
|
78
|
+
## Output
|
|
79
|
+
|
|
80
|
+
`founder/marketing.md`. Next: `/agemon-founder-brand`, then `/agemon-founder-launch`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jake Schincariol
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|