docs: sweep em dashes out of the active published surface
Em dashes crept back into examples, docs/platform-native.md, several READMEs,
the ponytail-debt skill, and a command file since 88431de. Replaced with plain
punctuation (commas, matching the house convention), .openclaw mirror
regenerated. Follows 88431de's scope: leaves untouched the vendored caveman
SKILL.md and the dated benchmarks/results/ writeups (historical records).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
bd6176a9b3
commit
426ffd0b36
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Examples
|
||||
|
||||
Real model output, verbatim from benchmark runs — the same task answered by the same model
|
||||
Real model output, verbatim from benchmark runs, the same task answered by the same model
|
||||
with no skill (`## Without Ponytail`) and with ponytail (`## With Ponytail`), so you can
|
||||
compare side by side. Model: Claude Haiku 4.5, temperature 1, source `benchmarks/output.json`.
|
||||
|
||||
|
||||
+5
-5
@@ -2,9 +2,9 @@
|
||||
|
||||
**Task:** "Write Python code that reads sales.csv and sums the 'amount' column."
|
||||
|
||||
Verbatim model output from a benchmark run — Claude Haiku 4.5, no-skill arm vs ponytail arm, temperature 1, source `benchmarks/output.json`. Reproduce: `npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml`.
|
||||
Verbatim model output from a benchmark run, Claude Haiku 4.5, no-skill arm vs ponytail arm, temperature 1, source `benchmarks/output.json`. Reproduce: `npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml`.
|
||||
|
||||
## Without Ponytail — 20 lines of code
|
||||
## Without Ponytail, 20 lines of code
|
||||
|
||||
# Python code to read sales.csv and sum the 'amount' column
|
||||
|
||||
@@ -57,7 +57,7 @@ except KeyError:
|
||||
- Provides built-in error handling
|
||||
- Efficient for large files
|
||||
|
||||
## With Ponytail — 3 lines of code
|
||||
## With Ponytail, 3 lines of code
|
||||
|
||||
```python
|
||||
import csv
|
||||
@@ -66,6 +66,6 @@ total = sum(float(row['amount']) for row in csv.DictReader(open('sales.csv')))
|
||||
print(total)
|
||||
```
|
||||
|
||||
Skipped: pandas, error handling, file closing — add when the CSV is large, malformed, or you need more analysis.
|
||||
Skipped: pandas, error handling, file closing, add when the CSV is large, malformed, or you need more analysis.
|
||||
|
||||
**20 → 3 lines of code** — same model, same prompt.
|
||||
**20 → 3 lines of code**, same model, same prompt.
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
**Task:** "Add debounce to a search input in vanilla JavaScript. It currently fires an API call on every keystroke."
|
||||
|
||||
Verbatim model output from a benchmark run — Claude Haiku 4.5, no-skill arm vs ponytail arm, temperature 1, source `benchmarks/output.json`. Reproduce: `npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml`.
|
||||
Verbatim model output from a benchmark run, Claude Haiku 4.5, no-skill arm vs ponytail arm, temperature 1, source `benchmarks/output.json`. Reproduce: `npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml`.
|
||||
|
||||
## Without Ponytail — 116 lines of code
|
||||
## Without Ponytail, 116 lines of code
|
||||
|
||||
# Debounce Search Input
|
||||
|
||||
@@ -190,7 +190,7 @@ searchInput.addEventListener('blur', () => {
|
||||
|
||||
**Typical keystroke reduction:** 10 characters = 10 API calls → 1-2 API calls with debounce ✅
|
||||
|
||||
## With Ponytail — 10 lines of code
|
||||
## With Ponytail, 10 lines of code
|
||||
|
||||
```javascript
|
||||
const searchInput = document.querySelector('input[type="search"]');
|
||||
@@ -206,6 +206,6 @@ searchInput.addEventListener('input', (e) => {
|
||||
});
|
||||
```
|
||||
|
||||
Skipped: debounce utility function, class wrapper, config object — `setTimeout` + `clearTimeout` is the debounce. Add a utility when you need it on 3+ inputs.
|
||||
Skipped: debounce utility function, class wrapper, config object, `setTimeout` + `clearTimeout` is the debounce. Add a utility when you need it on 3+ inputs.
|
||||
|
||||
**116 → 10 lines of code** — same model, same prompt.
|
||||
**116 → 10 lines of code**, same model, same prompt.
|
||||
|
||||
@@ -28,4 +28,4 @@ const copy = JSON.parse(JSON.stringify(original));
|
||||
const copy = structuredClone(original);
|
||||
```
|
||||
|
||||
**1 dependency (or a fragile hack) → 1 built-in.** `structuredClone` handles `Date`, `Map`, `Set`, `ArrayBuffer`, `RegExp`, circular references, and more — everything `JSON.parse/stringify` silently drops. Available in every browser since 2022 and Node.js since v17. Pull lodash in when you need the rest of it, not for one function.
|
||||
**1 dependency (or a fragile hack) → 1 built-in.** `structuredClone` handles `Date`, `Map`, `Set`, `ArrayBuffer`, `RegExp`, circular references, and more, everything `JSON.parse/stringify` silently drops. Available in every browser since 2022 and Node.js since v17. Pull lodash in when you need the rest of it, not for one function.
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
**Task:** "Write me a Python function that validates email addresses."
|
||||
|
||||
Verbatim model output from a benchmark run — Claude Haiku 4.5, no-skill arm vs ponytail arm, temperature 1, source `benchmarks/output.json`. Reproduce: `npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml`.
|
||||
Verbatim model output from a benchmark run, Claude Haiku 4.5, no-skill arm vs ponytail arm, temperature 1, source `benchmarks/output.json`. Reproduce: `npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml`.
|
||||
|
||||
## Without Ponytail — 75 lines of code
|
||||
## Without Ponytail, 75 lines of code
|
||||
|
||||
# Email Validation Function
|
||||
|
||||
@@ -142,7 +142,7 @@ if __name__ == "__main__":
|
||||
|
||||
**Recommendation**: Use the `email-validator` library for production applications, as it properly handles RFC 5321/5322 standards. Use the simple regex version for quick scripts or when you want to avoid dependencies.
|
||||
|
||||
## With Ponytail — 3 lines of code
|
||||
## With Ponytail, 3 lines of code
|
||||
|
||||
```python
|
||||
import re
|
||||
@@ -151,6 +151,6 @@ def is_valid_email(email: str) -> bool:
|
||||
return bool(re.match(r'^[^@]+@[^@]+\.[^@]+$', email))
|
||||
```
|
||||
|
||||
Skipped: RFC 5322 parser, DNS MX lookup, confirmation email. Add when you actually need to reject `user+tag@sub.domain.co.uk` or catch typos — until then, this catches 99% of "oops I fat-fingered it" cases.
|
||||
Skipped: RFC 5322 parser, DNS MX lookup, confirmation email. Add when you actually need to reject `user+tag@sub.domain.co.uk` or catch typos, until then, this catches 99% of "oops I fat-fingered it" cases.
|
||||
|
||||
**75 → 3 lines of code** — same model, same prompt.
|
||||
**75 → 3 lines of code**, same model, same prompt.
|
||||
|
||||
@@ -32,4 +32,4 @@ const byStatus = Object.groupBy(orders, order => order.status);
|
||||
// → { pending: [...], shipped: [...], delivered: [...] }
|
||||
```
|
||||
|
||||
**1 dependency (or a reduce) → 1 built-in.** `Object.groupBy` shipped in Chrome 117, Firefox 119, Safari 17.4, Node.js 21. If you need a `Map` instead of a plain object: `Map.groupBy(orders, o => o.status)`. Check your target runtime; if you need IE11 or old Node, the `reduce` one-liner is still the right call — not lodash.
|
||||
**1 dependency (or a reduce) → 1 built-in.** `Object.groupBy` shipped in Chrome 117, Firefox 119, Safari 17.4, Node.js 21. If you need a `Map` instead of a plain object: `Map.groupBy(orders, o => o.status)`. Check your target runtime; if you need IE11 or old Node, the `reduce` one-liner is still the right call, not lodash.
|
||||
|
||||
@@ -55,4 +55,4 @@ export function Feed({ items, fetchMore, hasMore }) {
|
||||
}
|
||||
```
|
||||
|
||||
**1 dependency → 0 dependencies.** `IntersectionObserver` fires only when the sentinel enters the viewport — no scroll event, no throttling, no jank. Ships in every browser. The library wraps exactly this API.
|
||||
**1 dependency → 0 dependencies.** `IntersectionObserver` fires only when the sentinel enters the viewport, no scroll event, no throttling, no jank. Ships in every browser. The library wraps exactly this API.
|
||||
|
||||
@@ -37,7 +37,7 @@ export function DeleteModal({ onConfirm, onCancel }) {
|
||||
}
|
||||
```
|
||||
|
||||
A dependency, a portal, an overlay, a root, a trigger, a content wrapper — to show a box with two buttons.
|
||||
A dependency, a portal, an overlay, a root, a trigger, a content wrapper, to show a box with two buttons.
|
||||
|
||||
## With Ponytail
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
**Task:** "Add rate limiting to my FastAPI endpoint so users can't spam it."
|
||||
|
||||
Verbatim model output from a benchmark run — Claude Haiku 4.5, no-skill arm vs ponytail arm, temperature 1, source `benchmarks/output.json`. Reproduce: `npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml`.
|
||||
Verbatim model output from a benchmark run, Claude Haiku 4.5, no-skill arm vs ponytail arm, temperature 1, source `benchmarks/output.json`. Reproduce: `npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml`.
|
||||
|
||||
## Without Ponytail — 128 lines of code
|
||||
## Without Ponytail, 128 lines of code
|
||||
|
||||
# Rate Limiting in FastAPI
|
||||
|
||||
@@ -248,9 +248,9 @@ async def test_rate_limit():
|
||||
# First 5 should be 200, 6th should be 429
|
||||
```
|
||||
|
||||
**Recommendation:** Use `slowapi` for most cases—it's the most popular and easiest to implement! 🚀
|
||||
**Recommendation:** Use `slowapi` for most cases, it's the most popular and easiest to implement! 🚀
|
||||
|
||||
## With Ponytail — 10 lines of code
|
||||
## With Ponytail, 10 lines of code
|
||||
|
||||
```python
|
||||
from fastapi import FastAPI, HTTPException
|
||||
@@ -267,6 +267,6 @@ async def my_endpoint(request):
|
||||
return {"status": "ok"}
|
||||
```
|
||||
|
||||
Skipped: custom rate limit logic, Redis, sliding windows — `slowapi` handles it. Add when: you need distributed rate limiting across multiple servers (swap `Limiter` for Redis backend) or per-user limits (add `key_func=lambda r: r.headers.get("authorization")`).
|
||||
Skipped: custom rate limit logic, Redis, sliding windows, `slowapi` handles it. Add when: you need distributed rate limiting across multiple servers (swap `Limiter` for Redis backend) or per-user limits (add `key_func=lambda r: r.headers.get("authorization")`).
|
||||
|
||||
**128 → 10 lines of code** — same model, same prompt.
|
||||
**128 → 10 lines of code**, same model, same prompt.
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
**Task:** "Build me a countdown timer component in React that counts down from a given number of seconds."
|
||||
|
||||
Verbatim model output from a benchmark run — Claude Haiku 4.5, no-skill arm vs ponytail arm, temperature 1, source `benchmarks/output.json`. Reproduce: `npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml`.
|
||||
Verbatim model output from a benchmark run, Claude Haiku 4.5, no-skill arm vs ponytail arm, temperature 1, source `benchmarks/output.json`. Reproduce: `npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml`.
|
||||
|
||||
## Without Ponytail — 267 lines of code
|
||||
## Without Ponytail, 267 lines of code
|
||||
|
||||
# React Countdown Timer Component
|
||||
|
||||
@@ -369,7 +369,7 @@ export function StyledCountdownTimer({ initialSeconds = 60 }) {
|
||||
|
||||
Choose the version that best fits your needs!
|
||||
|
||||
## With Ponytail — 9 lines of code
|
||||
## With Ponytail, 9 lines of code
|
||||
|
||||
```jsx
|
||||
export function CountdownTimer({ seconds }) {
|
||||
@@ -385,6 +385,6 @@ export function CountdownTimer({ seconds }) {
|
||||
}
|
||||
```
|
||||
|
||||
Skipped: pause/resume, formatted display (mm:ss), sound on zero, styling — add when needed.
|
||||
Skipped: pause/resume, formatted display (mm:ss), sound on zero, styling, add when needed.
|
||||
|
||||
**267 → 9 lines of code** — same model, same prompt.
|
||||
**267 → 9 lines of code**, same model, same prompt.
|
||||
|
||||
Reference in New Issue
Block a user