luckiest-co 1.0.47 → 1.0.48
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/skills/ab-testing/CHANGELOG.md +5 -0
- package/skills/ab-testing/SKILL.md +12 -9
- package/skills/ab-testing/evals/evals.json +18 -7
- package/skills/ab-testing/references/sample-size-guide.md +2 -2
- package/skills/ads/CHANGELOG.md +5 -0
- package/skills/ads/SKILL.md +4 -4
- package/skills/ai-seo/CHANGELOG.md +7 -0
- package/skills/ai-seo/SKILL.md +27 -20
- package/skills/analytics/CHANGELOG.md +6 -0
- package/skills/analytics/SKILL.md +4 -3
- package/skills/analytics/evals/evals.json +27 -0
- package/skills/analytics/references/ga4-implementation.md +7 -3
- package/skills/analytics/references/gtm-implementation.md +8 -2
- package/skills/aso/CHANGELOG.md +5 -0
- package/skills/aso/SKILL.md +4 -4
- package/skills/aso/evals/evals.json +15 -2
- package/skills/aso/references/benchmarks.md +4 -2
- package/skills/aso/references/google-play-specs.md +5 -1
- package/skills/brainstorm/SKILL.md +59 -16
- package/skills/brainstorm/builder-check-prompt.md +23 -0
- package/skills/churn-prevention/CHANGELOG.md +5 -0
- package/skills/churn-prevention/SKILL.md +3 -3
- package/skills/churn-prevention/evals/evals.json +14 -0
- package/skills/churn-prevention/references/dunning-playbook.md +6 -1
- package/skills/coder-brainstorming/CHANGELOG.md +10 -0
- package/skills/coder-brainstorming/SKILL.md +62 -20
- package/skills/coder-brainstorming/builder-check-prompt.md +23 -0
- package/skills/coder-brainstorming/scripts/server.cjs +1 -1
- package/skills/coder-debugging/CHANGELOG.md +4 -0
- package/skills/coder-debugging/SKILL.md +5 -5
- package/skills/coder-requesting-code-review/CHANGELOG.md +4 -0
- package/skills/coder-requesting-code-review/SKILL.md +4 -4
- package/skills/coder-subagent-driven-development/CHANGELOG.md +4 -0
- package/skills/coder-subagent-driven-development/SKILL.md +3 -3
- package/skills/coder-subagent-driven-development/scripts/sdd-workspace +3 -1
- package/skills/cold-email/CHANGELOG.md +7 -0
- package/skills/cold-email/SKILL.md +27 -7
- package/skills/cold-email/evals/evals.json +30 -0
- package/skills/cold-email/references/benchmarks.md +15 -11
- package/skills/cold-email/references/deliverability.md +110 -0
- package/skills/cold-email/references/linkedin-outreach.md +91 -0
- package/skills/cold-email/references/multichannel-cadence.md +79 -0
- package/skills/cold-email/references/outbound-plays.md +88 -0
- package/skills/cold-email/references/personalization.md +11 -0
- package/skills/cold-email/references/reply-handling.md +65 -0
- package/skills/competitor-profiling/CHANGELOG.md +5 -0
- package/skills/competitor-profiling/SKILL.md +4 -4
- package/skills/content-strategy/CHANGELOG.md +5 -0
- package/skills/content-strategy/SKILL.md +5 -3
- package/skills/copy-editing/CHANGELOG.md +5 -0
- package/skills/copy-editing/SKILL.md +5 -5
- package/skills/copy-editing/references/content-refresh.md +33 -0
- package/skills/cro/CHANGELOG.md +5 -0
- package/skills/cro/SKILL.md +14 -3
- package/skills/cro/references/form.md +1 -1
- package/skills/directory-submissions/CHANGELOG.md +5 -0
- package/skills/directory-submissions/SKILL.md +13 -4
- package/skills/directory-submissions/evals/evals.json +15 -1
- package/skills/directory-submissions/references/directory-list.md +2 -4
- package/skills/emails/CHANGELOG.md +5 -0
- package/skills/emails/SKILL.md +14 -4
- package/skills/launch/CHANGELOG.md +7 -0
- package/skills/launch/SKILL.md +8 -4
- package/skills/launch/evals/evals.json +29 -0
- package/skills/launch/references/shipped-changes.md +84 -0
- package/skills/launch/references/site-launch-qa.md +55 -0
- package/skills/lead-magnets/CHANGELOG.md +5 -0
- package/skills/lead-magnets/SKILL.md +6 -4
- package/skills/lead-magnets/evals/evals.json +18 -0
- package/skills/lead-magnets/references/content-to-skill-corpus-design.md +89 -0
- package/skills/lead-magnets/references/content-to-skill-release.md +71 -0
- package/skills/lead-magnets/references/content-to-skill.md +108 -0
- package/skills/marketing-plan/CHANGELOG.md +5 -0
- package/skills/marketing-plan/SKILL.md +3 -3
- package/skills/marketing-plan/evals/evals.json +13 -0
- package/skills/marketing-plan/references/budget-planning.md +26 -17
- package/skills/pricing/CHANGELOG.md +5 -0
- package/skills/pricing/SKILL.md +4 -4
- package/skills/pricing/evals/evals.json +12 -0
- package/skills/pricing/references/research-methods.md +8 -4
- package/skills/programmatic-seo/CHANGELOG.md +5 -0
- package/skills/programmatic-seo/SKILL.md +8 -4
- package/skills/programmatic-seo/evals/evals.json +13 -0
- package/skills/programmatic-seo/references/implementation-platforms.md +37 -0
- package/skills/prospecting/CHANGELOG.md +7 -0
- package/skills/prospecting/SKILL.md +27 -13
- package/skills/prospecting/evals/evals.json +41 -0
- package/skills/prospecting/references/account-research.md +59 -0
- package/skills/prospecting/references/b2b-prospecting.md +1 -1
- package/skills/prospecting/references/compliance.md +44 -6
- package/skills/prospecting/references/data-sources.md +13 -15
- package/skills/prospecting/references/enrichment-playbook.md +61 -0
- package/skills/prospecting/references/saas-prospecting.md +1 -1
- package/skills/prospecting/references/signal-plays.md +99 -0
- package/skills/prospecting/references/sourcing-and-enrichment.md +89 -0
- package/skills/referrals/CHANGELOG.md +5 -0
- package/skills/referrals/SKILL.md +10 -4
- package/skills/referrals/evals/evals.json +99 -0
- package/skills/referrals/references/affiliate-operations.md +64 -0
- package/skills/referrals/references/affiliate-programs.md +2 -2
- package/skills/referrals/references/program-examples.md +14 -6
- package/skills/referrals/references/review-platform-rules.md +36 -0
- package/skills/referrals/references/review-program-operations.md +62 -0
- package/skills/referrals/references/review-programs.md +96 -0
- package/skills/revops/CHANGELOG.md +5 -0
- package/skills/revops/SKILL.md +10 -6
- package/skills/revops/evals/evals.json +13 -0
- package/skills/revops/references/automation-playbooks.md +1 -1
- package/skills/revops/references/inbound-routing.md +43 -0
- package/skills/revops/references/lifecycle-definitions.md +31 -0
- package/skills/sales-enablement/CHANGELOG.md +5 -0
- package/skills/sales-enablement/SKILL.md +6 -4
- package/skills/sales-enablement/evals/evals.json +14 -0
- package/skills/sales-enablement/references/cold-call-scripts.md +68 -0
- package/skills/schema/CHANGELOG.md +5 -0
- package/skills/schema/SKILL.md +20 -8
- package/skills/schema/evals/evals.json +40 -0
- package/skills/schema/references/schema-examples.md +9 -15
- package/skills/seo-audit/CHANGELOG.md +5 -0
- package/skills/seo-audit/SKILL.md +10 -16
- package/skills/seo-audit/evals/evals.json +68 -0
- package/skills/seo-audit/references/international-seo.md +9 -11
- package/skills/seo-audit/references/local-seo-pages-and-measurement.md +39 -0
- package/skills/seo-audit/references/local-seo-profile-and-citations.md +41 -0
- package/skills/seo-audit/references/local-seo.md +86 -0
- package/skills/seo-audit/references/rankings-push.md +62 -0
- package/skills/seo-audit/references/title-tags.md +89 -0
- package/skills/signup/CHANGELOG.md +5 -0
- package/skills/signup/SKILL.md +7 -3
- package/skills/site-architecture/CHANGELOG.md +5 -0
- package/skills/site-architecture/SKILL.md +5 -4
- package/skills/site-architecture/evals/evals.json +25 -0
- package/skills/site-architecture/references/platforms-and-migration.md +84 -0
- package/skills/social/CHANGELOG.md +5 -0
- package/skills/social/SKILL.md +4 -4
- package/skills/trends/.skillignore +3 -0
- package/skills/trends/CHANGELOG.md +20 -0
- package/skills/trends/SKILL.md +12 -8
- package/skills/trends/references/agent-mode.md +36 -0
- package/skills/trends/references/category-peers.md +38 -0
- package/skills/trends/references/comparison.md +227 -0
- package/skills/trends/references/competitors.md +29 -0
- package/skills/trends/references/discovery.md +90 -0
- package/skills/trends/references/engine-contract.md +111 -1889
- package/skills/trends/references/followups.md +112 -0
- package/skills/trends/references/grok-bot-x.md +55 -0
- package/skills/trends/references/hiring-signals.md +19 -0
- package/skills/trends/references/library-queue.md +33 -0
- package/skills/trends/references/recommendations.md +86 -0
- package/skills/trends/references/research-runbook.md +781 -0
- package/skills/trends/references/runtime.md +165 -0
- package/skills/trends/references/save-html-brief.md +39 -20
- package/skills/trends/references/setup-wizard.md +253 -0
- package/skills/trends/references/synthesis.md +289 -0
- package/skills/trends/scripts/box_chrome_login.py +209 -0
- package/skills/trends/scripts/briefing.py +9 -17
- package/skills/trends/scripts/last30days.py +3247 -280
- package/skills/trends/scripts/lib/agentcookie.py +196 -0
- package/skills/trends/scripts/lib/amazon.py +877 -0
- package/skills/trends/scripts/lib/arxiv.py +42 -8
- package/skills/trends/scripts/lib/backends.py +769 -0
- package/skills/trends/scripts/lib/bird_x.py +340 -57
- package/skills/trends/scripts/lib/bluesky.py +84 -10
- package/skills/trends/scripts/lib/bounded_get.py +156 -0
- package/skills/trends/scripts/lib/brightdata.py +291 -0
- package/skills/trends/scripts/lib/categories.py +7 -1
- package/skills/trends/scripts/lib/chrome_cdp.py +455 -0
- package/skills/trends/scripts/lib/chrome_cookies.py +132 -39
- package/skills/trends/scripts/lib/cluster.py +31 -54
- package/skills/trends/scripts/lib/competitors.py +10 -1
- package/skills/trends/scripts/lib/cookie_extract.py +221 -44
- package/skills/trends/scripts/lib/cookie_paths.py +27 -0
- package/skills/trends/scripts/lib/corpus.py +439 -0
- package/skills/trends/scripts/lib/devto.py +313 -0
- package/skills/trends/scripts/lib/discovery_handoff.py +988 -0
- package/skills/trends/scripts/lib/doctor.py +2166 -0
- package/skills/trends/scripts/lib/dripstack.py +203 -0
- package/skills/trends/scripts/lib/entity_extract.py +37 -0
- package/skills/trends/scripts/lib/env.py +1092 -138
- package/skills/trends/scripts/lib/fanout.py +11 -1
- package/skills/trends/scripts/lib/feed.py +61 -0
- package/skills/trends/scripts/lib/fetch_memo.py +135 -0
- package/skills/trends/scripts/lib/freshness.py +566 -0
- package/skills/trends/scripts/lib/fusion.py +314 -28
- package/skills/trends/scripts/lib/github.py +438 -24
- package/skills/trends/scripts/lib/grok_x.py +1237 -0
- package/skills/trends/scripts/lib/grounding.py +129 -11
- package/skills/trends/scripts/lib/hackernews.py +61 -4
- package/skills/trends/scripts/lib/health.py +373 -0
- package/skills/trends/scripts/lib/hosted.py +333 -0
- package/skills/trends/scripts/lib/html_publish.py +34 -0
- package/skills/trends/scripts/lib/html_render.py +169 -3
- package/skills/trends/scripts/lib/http.py +1215 -70
- package/skills/trends/scripts/lib/instagram.py +132 -9
- package/skills/trends/scripts/lib/jobs.py +4 -2
- package/skills/trends/scripts/lib/library.py +308 -0
- package/skills/trends/scripts/lib/library_index.py +477 -0
- package/skills/trends/scripts/lib/linkedin.py +271 -24
- package/skills/trends/scripts/lib/log.py +5 -2
- package/skills/trends/scripts/lib/meta_ads.py +982 -0
- package/skills/trends/scripts/lib/normalize.py +382 -28
- package/skills/trends/scripts/lib/parallel_mcp.py +234 -0
- package/skills/trends/scripts/lib/permission_preflight.py +42 -3
- package/skills/trends/scripts/lib/perplexity.py +1080 -468
- package/skills/trends/scripts/lib/pipeline.py +5079 -211
- package/skills/trends/scripts/lib/planner.py +396 -53
- package/skills/trends/scripts/lib/polymarket.py +285 -23
- package/skills/trends/scripts/lib/prescriptions.py +432 -0
- package/skills/trends/scripts/lib/private_files.py +21 -0
- package/skills/trends/scripts/lib/providers.py +231 -10
- package/skills/trends/scripts/lib/quality_nudge.py +122 -37
- package/skills/trends/scripts/lib/reddit.py +177 -12
- package/skills/trends/scripts/lib/reddit_arctic.py +146 -5
- package/skills/trends/scripts/lib/reddit_keyless.py +121 -60
- package/skills/trends/scripts/lib/reddit_listing.py +215 -14
- package/skills/trends/scripts/lib/reddit_public.py +12 -13
- package/skills/trends/scripts/lib/reddit_search.py +304 -0
- package/skills/trends/scripts/lib/reddit_shreddit.py +51 -7
- package/skills/trends/scripts/lib/registers.py +134 -0
- package/skills/trends/scripts/lib/relevance.py +17 -0
- package/skills/trends/scripts/lib/render.py +2161 -271
- package/skills/trends/scripts/lib/rerank.py +623 -55
- package/skills/trends/scripts/lib/resolve.py +50 -1
- package/skills/trends/scripts/lib/safari_cookies.py +42 -15
- package/skills/trends/scripts/lib/schema.py +782 -1
- package/skills/trends/scripts/lib/setup_wizard.py +779 -120
- package/skills/trends/scripts/lib/signals.py +206 -7
- package/skills/trends/scripts/lib/stocktwits.py +374 -0
- package/skills/trends/scripts/lib/subproc.py +307 -53
- package/skills/trends/scripts/lib/techmeme.py +89 -64
- package/skills/trends/scripts/lib/telegram.py +317 -0
- package/skills/trends/scripts/lib/tiktok.py +13 -9
- package/skills/trends/scripts/lib/topic_shape.py +340 -0
- package/skills/trends/scripts/lib/transcribe.py +12 -3
- package/skills/trends/scripts/lib/trustpilot.py +256 -5
- package/skills/trends/scripts/lib/truthsocial.py +9 -1
- package/skills/trends/scripts/lib/ui.py +6 -0
- package/skills/trends/scripts/lib/usage.py +132 -0
- package/skills/trends/scripts/lib/web_search_keyless.py +63 -4
- package/skills/trends/scripts/lib/windows_job.py +138 -0
- package/skills/trends/scripts/lib/x_api.py +824 -0
- package/skills/trends/scripts/lib/x_envelope.py +733 -0
- package/skills/trends/scripts/lib/x_judge.py +292 -0
- package/skills/trends/scripts/lib/xai_x.py +26 -3
- package/skills/trends/scripts/lib/xquik.py +89 -15
- package/skills/trends/scripts/lib/xurl_x.py +284 -91
- package/skills/trends/scripts/lib/youtube_yt.py +570 -119
- package/skills/trends/scripts/setup-keychain.sh +12 -4
- package/skills/trends/scripts/setup-pass.sh +3 -0
- package/skills/trends/scripts/store.py +444 -50
- package/skills/trends/scripts/watchlist.py +38 -11
- package/skills/trends/scripts/x_lane_parity.py +107 -0
- package/skills/video-studio/CHANGELOG.md +4 -0
- package/skills/video-studio/SKILL.md +4 -4
- package/skills/video-studio/references/styles/product-flight.md +45 -0
- package/skills/video-studio/references/styles.md +3 -1
- package/skills/video-studio-motion/ATTRIBUTION.md +1 -1
- package/skills/video-studio-motion/CHANGELOG.md +4 -0
- package/skills/video-studio-motion/SKILL.md +8 -5
- package/skills/coder-brainstorming/spec-document-reviewer-prompt.md +0 -49
- package/skills/trends/scripts/lib/reddit_rss.py +0 -224
|
@@ -5,9 +5,11 @@ from __future__ import annotations
|
|
|
5
5
|
|
|
6
6
|
import argparse
|
|
7
7
|
import json
|
|
8
|
+
import os
|
|
8
9
|
import subprocess
|
|
9
10
|
import sys
|
|
10
11
|
import time
|
|
12
|
+
import tempfile
|
|
11
13
|
import urllib.parse
|
|
12
14
|
from pathlib import Path
|
|
13
15
|
|
|
@@ -15,7 +17,7 @@ SCRIPT_DIR = Path(__file__).parent.resolve()
|
|
|
15
17
|
sys.path.insert(0, str(SCRIPT_DIR))
|
|
16
18
|
|
|
17
19
|
import store
|
|
18
|
-
from lib import http, schema
|
|
20
|
+
from lib import env as envlib, http, schema, usage
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
# --- Webhook Delivery Functions ---
|
|
@@ -121,6 +123,7 @@ def cmd_list(args):
|
|
|
121
123
|
"topics": topics,
|
|
122
124
|
"budget_used": budget_used,
|
|
123
125
|
"budget_limit": budget_limit,
|
|
126
|
+
"budget_unknown_runs": store.get_daily_unknown_cost_runs(),
|
|
124
127
|
}, default=str))
|
|
125
128
|
|
|
126
129
|
|
|
@@ -137,7 +140,7 @@ def cmd_run_one(args):
|
|
|
137
140
|
if not topic:
|
|
138
141
|
print(json.dumps({"error": f'Topic not found: "{args.topic}"'}))
|
|
139
142
|
sys.exit(1)
|
|
140
|
-
print(json.dumps(_run_topic(topic), default=str))
|
|
143
|
+
print(json.dumps(_budget_skip(topic) or _run_topic(topic), default=str))
|
|
141
144
|
|
|
142
145
|
|
|
143
146
|
def cmd_run_all(args):
|
|
@@ -150,27 +153,49 @@ def cmd_run_all(args):
|
|
|
150
153
|
budget_limit = float(store.get_setting("daily_budget", "5.00"))
|
|
151
154
|
results = []
|
|
152
155
|
for topic in topics:
|
|
153
|
-
|
|
154
|
-
results.append({
|
|
155
|
-
"topic": topic["name"],
|
|
156
|
-
"status": "skipped",
|
|
157
|
-
"reason": f"Budget exceeded: ${store.get_daily_cost():.2f}/${budget_limit:.2f}",
|
|
158
|
-
})
|
|
159
|
-
continue
|
|
160
|
-
results.append(_run_topic(topic))
|
|
156
|
+
results.append(_budget_skip(topic) or _run_topic(topic))
|
|
161
157
|
|
|
162
158
|
print(json.dumps({
|
|
163
159
|
"action": "run_all",
|
|
164
160
|
"results": results,
|
|
165
161
|
"budget_used": store.get_daily_cost(),
|
|
166
162
|
"budget_limit": budget_limit,
|
|
163
|
+
"budget_unknown_runs": store.get_daily_unknown_cost_runs(),
|
|
167
164
|
}, default=str))
|
|
168
165
|
|
|
169
166
|
|
|
167
|
+
def _budget_skip(topic: dict) -> dict | None:
|
|
168
|
+
limit = float(store.get_setting("daily_budget", "5.00"))
|
|
169
|
+
cost = store.get_daily_cost()
|
|
170
|
+
unknown = store.get_daily_unknown_cost_runs()
|
|
171
|
+
if cost >= limit:
|
|
172
|
+
reason = f"Budget exceeded: ${cost:.2f}/${limit:.2f}"
|
|
173
|
+
elif unknown:
|
|
174
|
+
reason = f"Budget unknown: {unknown} run(s) today have unreported provider charges"
|
|
175
|
+
else:
|
|
176
|
+
return None
|
|
177
|
+
return {"topic": topic["name"], "status": "skipped", "reason": reason}
|
|
178
|
+
|
|
179
|
+
|
|
170
180
|
def _run_topic(topic: dict) -> dict:
|
|
181
|
+
topic_id = topic["id"]
|
|
182
|
+
with tempfile.TemporaryDirectory(prefix="last30days-usage-") as temp_dir:
|
|
183
|
+
journal = Path(temp_dir) / "usage.db"
|
|
184
|
+
usage.create_journal(journal)
|
|
185
|
+
child_env = dict(os.environ, **{usage.JOURNAL_ENV: str(journal), "LAST30DAYS_STORE": "0"})
|
|
186
|
+
run_id = store.record_run(topic_id, source_mode="v3", status="running")
|
|
187
|
+
try:
|
|
188
|
+
result = _research_topic(topic, run_id, child_env)
|
|
189
|
+
finally:
|
|
190
|
+
costs = usage.read_journal(journal)
|
|
191
|
+
store.update_run(run_id, **costs)
|
|
192
|
+
result.update(costs)
|
|
193
|
+
return result
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _research_topic(topic: dict, run_id: int, child_env: dict) -> dict:
|
|
171
197
|
start_time = time.time()
|
|
172
198
|
topic_id = topic["id"]
|
|
173
|
-
run_id = store.record_run(topic_id, source_mode="v3", status="running")
|
|
174
199
|
|
|
175
200
|
try:
|
|
176
201
|
search_queries = json.loads(topic["search_queries"]) if topic.get("search_queries") else None
|
|
@@ -181,6 +206,7 @@ def _run_topic(topic: dict) -> dict:
|
|
|
181
206
|
str(SCRIPT_DIR / "last30days.py"),
|
|
182
207
|
search_term,
|
|
183
208
|
"--emit=json",
|
|
209
|
+
"--json-profile=raw",
|
|
184
210
|
"--quick",
|
|
185
211
|
"--lookback-days",
|
|
186
212
|
"90",
|
|
@@ -193,6 +219,7 @@ def _run_topic(topic: dict) -> dict:
|
|
|
193
219
|
capture_output=True,
|
|
194
220
|
text=True,
|
|
195
221
|
timeout=300,
|
|
222
|
+
env={**child_env, envlib.ALLOW_ENGINE_PLAN_VAR: "1"},
|
|
196
223
|
)
|
|
197
224
|
duration = time.time() - start_time
|
|
198
225
|
if result.returncode != 0:
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Compare the X results of two saved last30days report JSON files.
|
|
3
|
+
|
|
4
|
+
Dev tool for checking one X lane against another on the same topic and
|
|
5
|
+
window. Each input is the output of ``last30days.py <topic> --emit=json
|
|
6
|
+
--json-profile=raw``; the optional envelope is the candidate's ``--x-posts``
|
|
7
|
+
file, so a baseline post the candidate fetched but did not keep still counts
|
|
8
|
+
toward recall.
|
|
9
|
+
|
|
10
|
+
python3 scripts/x_lane_parity.py baseline.json candidate.json [--envelope x-posts.json]
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import argparse
|
|
16
|
+
import json
|
|
17
|
+
import re
|
|
18
|
+
import sys
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
_STATUS_RE = re.compile(r"/status/(\d+)")
|
|
22
|
+
_METRICS = ("likes", "reposts", "replies", "quotes")
|
|
23
|
+
TOP_N = 10
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _load(path: str) -> dict:
|
|
27
|
+
return json.loads(Path(path).read_text(encoding="utf-8"))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _x_items(report: dict) -> list[dict]:
|
|
31
|
+
return list((report.get("items_by_source") or {}).get("x") or [])
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _require_same_run_shape(base: dict, cand: dict, envelope: dict | None) -> None:
|
|
35
|
+
"""Refuse to compare reports that cover different topics or windows."""
|
|
36
|
+
for key in ("topic", "range_from", "range_to"):
|
|
37
|
+
if base.get(key) != cand.get(key):
|
|
38
|
+
raise ValueError(f"reports differ on {key}: {base.get(key)!r} vs {cand.get(key)!r}")
|
|
39
|
+
if envelope is not None and envelope.get("topic") != cand.get("topic"):
|
|
40
|
+
raise ValueError(
|
|
41
|
+
f"envelope topic {envelope.get('topic')!r} does not match the candidate report {cand.get('topic')!r}"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _post_id(item: dict) -> str | None:
|
|
46
|
+
match = _STATUS_RE.search(str(item.get("url") or ""))
|
|
47
|
+
return match.group(1) if match else None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _likes(item: dict) -> int:
|
|
51
|
+
value = (item.get("engagement") or {}).get("likes")
|
|
52
|
+
return int(value) if isinstance(value, (int, float)) else 0
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _envelope_ids(payload: dict | None) -> set[str]:
|
|
56
|
+
if not payload:
|
|
57
|
+
return set()
|
|
58
|
+
return {
|
|
59
|
+
str(post.get("id"))
|
|
60
|
+
for call in payload.get("calls") or []
|
|
61
|
+
for post in call.get("posts") or []
|
|
62
|
+
if post.get("id")
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _ratio(numerator: float, denominator: float) -> float:
|
|
67
|
+
return round(numerator / denominator, 3) if denominator else 0.0
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def compare(baseline: str, candidate: str, *, envelope: str | None = None) -> dict:
|
|
71
|
+
"""Counts, top-liked recall, field completeness, and author spread."""
|
|
72
|
+
base, cand = _load(baseline), _load(candidate)
|
|
73
|
+
env = _load(envelope) if envelope else None
|
|
74
|
+
_require_same_run_shape(base, cand, env)
|
|
75
|
+
base_items = _x_items(base)
|
|
76
|
+
cand_items = _x_items(cand)
|
|
77
|
+
cand_ids = {pid for pid in map(_post_id, cand_items) if pid} | _envelope_ids(env)
|
|
78
|
+
top = sorted(base_items, key=_likes, reverse=True)[:TOP_N]
|
|
79
|
+
top_ids = [pid for pid in map(_post_id, top) if pid]
|
|
80
|
+
complete = sum(
|
|
81
|
+
1 for item in cand_items
|
|
82
|
+
if all(isinstance((item.get("engagement") or {}).get(m), (int, float)) for m in _METRICS)
|
|
83
|
+
)
|
|
84
|
+
return {
|
|
85
|
+
"baseline_count": len(base_items),
|
|
86
|
+
"candidate_count": len(cand_items),
|
|
87
|
+
"count_ratio": _ratio(len(cand_items), len(base_items)),
|
|
88
|
+
"top_liked_recall": _ratio(sum(1 for pid in top_ids if pid in cand_ids), len(top_ids)),
|
|
89
|
+
"candidate_field_completeness": _ratio(complete, len(cand_items)),
|
|
90
|
+
"baseline_authors": len({item.get("author") for item in base_items}),
|
|
91
|
+
"candidate_authors": len({item.get("author") for item in cand_items}),
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def main(argv: list[str] | None = None) -> int:
|
|
96
|
+
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
|
97
|
+
parser.add_argument("baseline")
|
|
98
|
+
parser.add_argument("candidate")
|
|
99
|
+
parser.add_argument("--envelope")
|
|
100
|
+
args = parser.parse_args(argv)
|
|
101
|
+
json.dump(compare(args.baseline, args.candidate, envelope=args.envelope), sys.stdout, indent=2)
|
|
102
|
+
sys.stdout.write("\n")
|
|
103
|
+
return 0
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
if __name__ == "__main__":
|
|
107
|
+
raise SystemExit(main())
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog — luckiest-video-studio
|
|
2
2
|
|
|
3
|
+
## 1.19.0 — 2026-10-15
|
|
4
|
+
|
|
5
|
+
- New motion-design style card `product-flight` (Continuous Product Flight): one camera flight around one hero object, speed ramps between stops on downbeats, side captions, glass callouts with pointer lines, one procedural VFX peak. Distilled from the approved PSA slab film and its review corrections. Offered for collectible and single premium product reveals. 39 styles.
|
|
6
|
+
|
|
3
7
|
## 1.18.0 — 2026-10-13
|
|
4
8
|
|
|
5
9
|
- New QA gate `node qa.mjs logo <run-dir> [--svg path] [--max 8]`: for every logo scene it takes the clip's last frame, finds the mark's box, draws the logo SVG (default `brand/logo.svg`) into the same box on the same background with HyperFrames, and fails when they differ. Enforces the "resolve frame equals the master logo" rule in the style cards' Logo construction sections.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: luckiest-video-studio
|
|
3
|
-
description: "Make product launch videos, product demos with motion design between demo shots, and logo showcases, all editable after render, in
|
|
3
|
+
description: "Make product launch videos, product demos with motion design between demo shots, and logo showcases, all editable after render, in 39 named styles. Starts with a short context interview, plans a scripted storyboard the user approves scene by scene in a review player before anything renders, builds motion scenes with HyperFrames, records or places demo footage, renders each scene as its own clip, then hands back an MP4 plus a storyboard.json that re-renders one scene at a time, a review player for edits and notes (Concat, OpenScreen, or Diffusion Studio on request), and optional After Effects compositions. Use for 'make a launch video', 'product demo video', 'demo with motion graphics', 'logo animation', 'logo reveal', 'portfolio reel', 'animate my logos', 'brand reel', 'turn my talking-head recording into a reel', 'add graphics over me talking', or 'change scene 3 of the video'. For AI-generated footage, avatars, and text-to-video models use luckiest-video. For what to post and when use luckiest-social."
|
|
4
4
|
license: See ATTRIBUTION.md
|
|
5
5
|
allowed-tools: Bash, Read, Write, Edit, Glob, Grep, AskUserQuestion
|
|
6
6
|
metadata:
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.19.0"
|
|
8
8
|
listing_id: luckiest-video-studio
|
|
9
9
|
author: luckiest
|
|
10
10
|
---
|
|
@@ -25,7 +25,7 @@ further if `upToDate: true`. Never block on this check; if the tool is unavailab
|
|
|
25
25
|
proceed.
|
|
26
26
|
|
|
27
27
|
When the skill's work is done, call the Luckiest MCP `report_usage` tool once with
|
|
28
|
-
`{ listing_id: "luckiest-video-studio", skill_version: "1.
|
|
28
|
+
`{ listing_id: "luckiest-video-studio", skill_version: "1.19.0", matched: true, success: <true if the skill completed, false otherwise> }`.
|
|
29
29
|
Metadata only, never prompt text. Never block on it; if the tool is unavailable,
|
|
30
30
|
skip silently.
|
|
31
31
|
|
|
@@ -69,7 +69,7 @@ in `<skill-dir>/assets/sfx/`. Resolve it; never assume an install path.
|
|
|
69
69
|
|---|---|---|
|
|
70
70
|
| `--mode` | `launch`, `demo`, `logos` | inferred |
|
|
71
71
|
| `--tone` | preset or freeform ([references/tones.md](references/tones.md)) | inferred |
|
|
72
|
-
| `--style` | a style id from [references/styles.md](references/styles.md); its card is `references/styles/<id>.md`.
|
|
72
|
+
| `--style` | a style id from [references/styles.md](references/styles.md); its card is `references/styles/<id>.md`. 39 looks (flat vector, synthwave, whiteboard explainer, paper collage, ink wash...) plus era styles | named in the request, else asked |
|
|
73
73
|
| `--format` | `landscape`, `vertical`, `square`: the master size scenes are designed at | `landscape` |
|
|
74
74
|
| `--formats` | comma list of `landscape`, `vertical`, `square`: render the same video once per format, one file each | master only |
|
|
75
75
|
| `--duration` | seconds | per mode |
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Continuous Product Flight
|
|
2
|
+
|
|
3
|
+
- id: `product-flight`
|
|
4
|
+
- Source: Luckiest, from the approved PSA slab film (2026-10-14), a remake of the whatships.com OneKey Pro 2 film. Rules come from the user's Motion OS review notes on that run.
|
|
5
|
+
- Best for: collectible and premium single-object reveals (graded cards, watches, sneakers, devices, bottles), music-timed hero films, launch teasers, 9:16 and 4:5 cutdowns of the same flight
|
|
6
|
+
- Not for: product lineups, UI walkthroughs, voiceover explainers, anything that needs more than one product on screen
|
|
7
|
+
- Triggers: continuous shot, one take, oner, camera flight, fly around, orbit the product, speed ramp, speed ramps, transparent case, clear acrylic, acrylic slab, graded card, PSA slab, collectible, trading card, whatships
|
|
8
|
+
- Tone cell: calm-sharp
|
|
9
|
+
- Clock: smooth 30 fps, motion blur only on fast stretches
|
|
10
|
+
|
|
11
|
+
## Look
|
|
12
|
+
One hero object on a near-black ground (#0B0B0F, never pure #000, which bands after recompression). Clear material where the product has one: transmission with IOR about 1.49 for acrylic, a thin edge glow, raised lips and wells modeled, not painted. Textures are cut from the user's own photos; the product's art, labels and text are never redrawn. One warm rim light is the only accent and carries one meaning. Bold side captions (about 64px at 1080p, heavy grotesk) sit beside the subject, never over it. Feature beats get a frosted glass callout with a drawn pointer line to the exact detail. The real brand logo file, never a typed stand-in.
|
|
13
|
+
|
|
14
|
+
## Motion
|
|
15
|
+
One continuous camera flight around one object, no cuts. Each line of the script is a camera stop: a slow drift while the caption reads, then a speed ramp (cubic in-out, fast middle) to the next stop, so the energy comes from velocity changes, not edits. Motion blur scales with pose speed, so drifts stay crisp and whips smear. Feature stops are angled and wide enough to tease, then reveal; tight macros read as cropped. Set pieces, at most one each: a whip-around reveal of the full product, the case drifting apart then slamming shut, a whip-flip to the back, and one procedural VFX peak (cloud, smoke and fire shader) that fills the frame behind the hero.
|
|
16
|
+
|
|
17
|
+
## Signature features (judged against these)
|
|
18
|
+
- One product on screen at all times, one continuous camera, zero hard cuts.
|
|
19
|
+
- Stops joined by speed ramps: slow drift, whip, slow drift.
|
|
20
|
+
- Ramps start on downbeats. The reveal lands on the music's bass entry and the VFX peak on the drop.
|
|
21
|
+
- Captions beside the subject, never over it, readable at phone size.
|
|
22
|
+
- A glass callout with a pointer line on every feature beat.
|
|
23
|
+
- Real photos and real brand assets only. No AI redraw of the product, its art or its label.
|
|
24
|
+
- The edge light pulses on the beat only in sections with drums.
|
|
25
|
+
|
|
26
|
+
## 10-second beat seed
|
|
27
|
+
- 0-1.5s: product dark, a sliver of rim light, one word of setup.
|
|
28
|
+
- 1.5-4s: slow drift past a detail at an angle, caption beside it.
|
|
29
|
+
- 4-5s (on a downbeat): ramp into a whip-around.
|
|
30
|
+
- 5-7.5s (hero at 50-75%, on the bass entry): land front-on, the whole product seen for the first time, name it.
|
|
31
|
+
- 7.5-10s: callout with a line to the one feature that matters, slow push, hold the last 1s.
|
|
32
|
+
|
|
33
|
+
## Sound
|
|
34
|
+
A licensed track or the user's own, cut on downbeats so film time 0 is a downbeat and every join falls on one. Splice only at the song's natural transitions or with beat-aligned crossfades; a hard swap skips audibly. Anchor the reveal, the flip and the VFX peak to the song's own entries and drop. Master near -13 LUFS. No whooshes stacked on every ramp; the music already carries them.
|
|
35
|
+
|
|
36
|
+
## Build it in HyperFrames
|
|
37
|
+
Three.js (WebGL2) with MeshPhysicalMaterial (transmission, thickness, ior 1.49, clearcoat) for the case, the photo textures on planes inside it, and an edge-light shader for the glow. The camera is an orbit pose (azimuth, elevation, distance, target) interpolated over a key list of `[end time, pose, ease]`, with closed-form eases (`in`, `out`, `ramp`, `sin`) so any frame renders alone from `?at=<seconds>`: no stateful animation. Captions, callouts and the logo are canvas or SVG textures drawn in the same frame. Motion blur is a sub-frame average whose count follows pose speed. The VFX peak is a raymarched or noise-driven fragment shader, not generated plates. Reels re-use the same keys: 9:16 moves captions clear of the platform buttons, 4:5 pulls the camera back about 1.2x.
|
|
38
|
+
|
|
39
|
+
## Logo construction
|
|
40
|
+
Rule from logo-design (MIT, kaankiziltug): the entrance is built from the mark's own construction, and the resolve frame equals the master logo. Before animating, write the mark's construction in one line in `plan.md` (its primitives, strokes or modules, and the order they would be drawn). The resolve frame is the real logo file (`brand/logo.svg` or the SVG the user supplied), never a styled stand-in or an invented wordmark: render the last frame and the logo SVG at the same size and position, and any visible difference is a Block. Sting length 1 to 3 seconds, easing from this card.
|
|
41
|
+
- Construction: the logo SVG's own paths are flat planes in the scene, and the camera flies to them as its last stop. They build in construction order (outer shape first, then cuts and counters) during the final ramp, lit by the same rim light.
|
|
42
|
+
- Resolve: the ramp lands front-on and orthographic-matched; in the last 0.3s blur, glow and depth flatten so the hold frame is the flat logo SVG in brand colors.
|
|
43
|
+
|
|
44
|
+
## Watch out
|
|
45
|
+
Transmission in headless WebGL is slow and goes flat on a weak GPU: check the renderer logs a real GPU, and cap sub-frames. Too many stops makes the flight feel like a slideshow; keep 2.5 to 4s per stop. Several products, a second accent color, or a numeric claim the user did not give all break the card. Callout lines must point at the real detail in the texture, so check them on stills at each stop before the full render.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Style library
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
39 visual styles plus 18 era styles, each a card in `styles/`. A style decides the
|
|
4
4
|
renderer, texture, motion signature, clock and transition family. The brand still
|
|
5
5
|
decides the colors and faces when it has a design system (art director section 0):
|
|
6
6
|
map the card's palette roles onto the brand palette instead of replacing it.
|
|
@@ -28,6 +28,7 @@ map the card's palette roles onto the brand palette instead of replacing it.
|
|
|
28
28
|
| Hype, gaming, dev tools | `synthwave`, `hud`, `pixel` |
|
|
29
29
|
| Vertical social (9:16) | `variety-show`, `kinetic-type`, `collage` |
|
|
30
30
|
| Logo showcase | `morph`, `liquid`, `bauhaus` |
|
|
31
|
+
| Collectible, single premium product reveal | `product-flight`, `3d-render`, `aurora-glass` |
|
|
31
32
|
|
|
32
33
|
When all three offers are polished looks, swap the third for one hand-made style
|
|
33
34
|
(`collage`, `cel-boil`, `line-art`, `whiteboard`, `cut-paper`): in 2026 feeds full
|
|
@@ -72,6 +73,7 @@ the concept. Brand names in seeds are placeholders: use the real product.
|
|
|
72
73
|
| [`liquid`](styles/liquid.md) | Liquid Metaball Motion | kinetic-soft | music video packaging, food and drink ads, logo genesis, transition packs | liquid, fluid, metaball, goo, gooey, paint splash, drip, melt, blob, ink flood, liquid transition, logo reveal |
|
|
73
74
|
| [`morph`](styles/morph.md) | Shape Morph Chain | calm-sharp | keynote-grade storytelling, icon sequences, feature walkthroughs, brand reveal built from meaningful symbols | morph, morphing, shape transition, icon morph, shape shifting, one shape becomes another, Apple keynote, visual storytelling, flubber |
|
|
74
75
|
| [`pixel`](styles/pixel.md) | Pixel Art 8-bit | kinetic-sharp | game trailers and attract screens, 8-bit music videos, nostalgic brand marketing, indie game promos | pixel art, 8-bit, 16-bit, retro game, sprite, chiptune, side scroller, CRT, dithering, PICO-8, Aseprite, Minecraft, Terraria |
|
|
76
|
+
| [`product-flight`](styles/product-flight.md) | Continuous Product Flight | calm-sharp | collectible and premium single-object reveals (graded cards, watches, sneakers, devices, bottles), music-timed hero films, launch teasers, 9:16 and 4:5 cutdowns of the same flight | continuous shot, one take, oner, camera flight, fly around, orbit the product, speed ramp, speed ramps, transparent case, clear acrylic, acrylic slab, graded card, PSA slab, collectible, trading card, whatships |
|
|
75
77
|
| [`sticker-explainer`](styles/sticker-explainer.md) | Sticker Knowledge Explainer | calm-sharp | hard-core science explainers, finance and knowledge channels, corporate documentary explainers, data-rich narration videos | sticker, knowledge video, science explainer, infographic video, big canvas, camera pan and zoom, photo cutouts with white outline, periodic table, PaperClip, Lin Chao, explainer channel |
|
|
76
78
|
| [`synthwave`](styles/synthwave.md) | Synthwave VHS Retro | kinetic-sharp | retro title sequences, music videos, trend brand films, gaming and nostalgia content, Y2K chrome revivals | synthwave, outrun, 80s, retro, neon, VHS, vaporwave, Y2K, chrome text, scanlines, grid horizon, retrowave |
|
|
77
79
|
| [`variety-show`](styles/variety-show.md) | Variety Show Kinetic Captions | kinetic-soft | 9:16 vlogs, pet and lifestyle shorts, interview and reaction edits, comedic re-edits, caption-heavy social video | variety show, hanazi, Chinese variety captions, kinetic captions, sticker text, fancy text, reaction text, vlog captions, burst box, outlined text, TikTok captions, Douyin, bilibili |
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
| Source | License | What this sub-skill uses | License file |
|
|
6
6
|
|---|---|---|---|
|
|
7
|
-
| **skills** by Emil Kowalski (`emilkowalski/skills`) | MIT | The animation decision order, easing and duration rules, physicality and origin rules, blur-masked transitions, stagger, asymmetric timing, and the strict review posture from `emil-design-eng`, `animate`, `review-animations`, and `find-animation-opportunities`; type and material rules from `apple-design`; the glossary from `animation-vocabulary` | `LICENSE-emil` |
|
|
7
|
+
| **skills** by Emil Kowalski (`emilkowalski/skills`) | MIT | The animation decision order, easing and duration rules, physicality and origin rules, blur-masked transitions, stagger, asymmetric timing, and the strict review posture from `emil-design-eng`, `animate`, `review-animations`, and `find-animation-opportunities`; type and material rules from `apple-design`; the glossary from `animation-vocabulary`; shadow, CSS-variable and `transition: all` rules from `animation-performance` | `LICENSE-emil` |
|
|
8
8
|
| **motionmaxxing** by Tejas Makwana (`Tejashmakwana/motionmaxxing`, FinalMotion, finalmotion.video), commit 8c8ec0f2 | Apache-2.0 | Frame-measured durations, ease roles, stagger and camera values, handoff and transition recipes, and the numbers in `references/kinetic-type.md` and `references/ui-demo.md`. Rewritten in our own words; no code, runtime, media, studies or `library/` rows are copied | `LICENSE-motionmaxxing` |
|
|
9
9
|
|
|
10
10
|
## Changes in this edition
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog — luckiest-video-studio-motion
|
|
2
2
|
|
|
3
|
+
## 1.3.1 — 2026-10-16
|
|
4
|
+
|
|
5
|
+
- Transform rule now covers shadows (`drop-shadow` over `box-shadow`), tweening transforms directly instead of an inherited CSS variable, and no `transition: all`. From emilkowalski/skills animation-performance at 2d22863 (MIT).
|
|
6
|
+
|
|
3
7
|
## 1.3.0 — 2026-10-12
|
|
4
8
|
|
|
5
9
|
- Camera as punctuation: three questions before each move, a move table (slow push, pull, glide, snap, whip, slam), accents at most a third of shots, no three push-ins in a row, enter slow and exit fast, reveals landed on beats or words (from huashu-art-motion, MIT).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: video-studio-motion
|
|
3
3
|
description: >-
|
|
4
4
|
Motion taste for luckiest-video-studio. Decides whether a beat should move,
|
|
5
5
|
then picks the easing, duration, origin, stagger, and transition for HyperFrames
|
|
@@ -16,7 +16,7 @@ user-invocable: true
|
|
|
16
16
|
license: MIT. See ATTRIBUTION.md
|
|
17
17
|
allowed-tools: Bash, Read, Write, Edit, Glob, Grep
|
|
18
18
|
metadata:
|
|
19
|
-
version: "1.3.
|
|
19
|
+
version: "1.3.1"
|
|
20
20
|
listing_id: luckiest-video-studio-motion
|
|
21
21
|
author: luckiest
|
|
22
22
|
---
|
|
@@ -32,11 +32,11 @@ interruption, and how often a user triggers something.
|
|
|
32
32
|
## Staying current
|
|
33
33
|
|
|
34
34
|
On activation, call the Luckiest MCP `check_updates` tool with
|
|
35
|
-
`{ listingId: "luckiest-video-studio-motion", installedSemver: "1.3.
|
|
35
|
+
`{ listingId: "luckiest-video-studio-motion", installedSemver: "1.3.1" }`. If
|
|
36
36
|
`upToDate: false`, surface the `notice` once and continue. Never block on it.
|
|
37
37
|
|
|
38
38
|
When done, call `report_usage` once with
|
|
39
|
-
`{ listing_id: "luckiest-video-studio-motion", skill_version: "1.3.
|
|
39
|
+
`{ listing_id: "luckiest-video-studio-motion", skill_version: "1.3.1", matched: true, success: <true|false> }`.
|
|
40
40
|
Metadata only, never prompt text. Skip silently if unavailable.
|
|
41
41
|
|
|
42
42
|
## Modes
|
|
@@ -151,7 +151,10 @@ change about every 0.8 seconds.
|
|
|
151
151
|
for fades, wipes, and linear fills.
|
|
152
152
|
- **Transform, not layout.** Animate `x`, `y`, `scale`, `rotate`, `autoAlpha`,
|
|
153
153
|
`clipPath`, and `filter`. `width`, `height`, `top`, and `left` snap to whole
|
|
154
|
-
pixels and shimmer in the render.
|
|
154
|
+
pixels and shimmer in the render. Animate a shadow with `filter: drop-shadow()`,
|
|
155
|
+
not `box-shadow`. Tween `transform` on the element itself, never a CSS variable
|
|
156
|
+
on a parent: every child restyles each frame and long scenes render slowly.
|
|
157
|
+
Name the tweened properties; no `transition: all`.
|
|
155
158
|
- **Fast moves strobe.** At 30fps, an element crossing more than about a tenth of
|
|
156
159
|
the frame per frame reads as jumps. Shorten the distance, lengthen the move, or
|
|
157
160
|
make it a deliberate whip with a blur.
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# Spec Document Reviewer Prompt Template
|
|
2
|
-
|
|
3
|
-
Use this template when dispatching a spec document reviewer subagent.
|
|
4
|
-
|
|
5
|
-
**Purpose:** Verify the spec is complete, consistent, and ready for implementation planning.
|
|
6
|
-
|
|
7
|
-
**Dispatch after:** Spec document is written to docs/luckiest-coder/specs/
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
Subagent (general-purpose):
|
|
11
|
-
description: "Review spec document"
|
|
12
|
-
prompt: |
|
|
13
|
-
You are a spec document reviewer. Verify this spec is complete and ready for planning.
|
|
14
|
-
|
|
15
|
-
**Spec to review:** [SPEC_FILE_PATH]
|
|
16
|
-
|
|
17
|
-
## What to Check
|
|
18
|
-
|
|
19
|
-
| Category | What to Look For |
|
|
20
|
-
|----------|------------------|
|
|
21
|
-
| Completeness | TODOs, placeholders, "TBD", incomplete sections |
|
|
22
|
-
| Consistency | Internal contradictions, conflicting requirements |
|
|
23
|
-
| Clarity | Requirements ambiguous enough to cause someone to build the wrong thing |
|
|
24
|
-
| Scope | Focused enough for a single plan — not covering multiple independent subsystems |
|
|
25
|
-
| YAGNI | Unrequested features, over-engineering |
|
|
26
|
-
|
|
27
|
-
## Calibration
|
|
28
|
-
|
|
29
|
-
**Only flag issues that would cause real problems during implementation planning.**
|
|
30
|
-
A missing section, a contradiction, or a requirement so ambiguous it could be
|
|
31
|
-
interpreted two different ways — those are issues. Minor wording improvements,
|
|
32
|
-
stylistic preferences, and "sections less detailed than others" are not.
|
|
33
|
-
|
|
34
|
-
Approve unless there are serious gaps that would lead to a flawed plan.
|
|
35
|
-
|
|
36
|
-
## Output Format
|
|
37
|
-
|
|
38
|
-
## Spec Review
|
|
39
|
-
|
|
40
|
-
**Status:** Approved | Issues Found
|
|
41
|
-
|
|
42
|
-
**Issues (if any):**
|
|
43
|
-
- [Section X]: [specific issue] - [why it matters for planning]
|
|
44
|
-
|
|
45
|
-
**Recommendations (advisory, do not block approval):**
|
|
46
|
-
- [suggestions for improvement]
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
**Reviewer returns:** Status, Issues (if any), Recommendations
|