@softspark/ai-toolkit 3.1.1 → 3.2.1
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/AGENTS.md +3 -3
- package/CHANGELOG.md +40 -0
- package/README.md +7 -8
- package/app/.claude-plugin/plugin.json +1 -1
- package/app/ARCHITECTURE.md +47 -0
- package/app/agents/seo-specialist.md +86 -3
- package/app/hooks/ai-toolkit-statusline.sh +200 -0
- package/app/hooks.json +5 -0
- package/app/skills/brand-voice/SKILL.md +38 -2
- package/app/skills/brand-voice/modes/concise.md +67 -0
- package/app/skills/brand-voice/modes/strict.md +91 -0
- package/app/skills/brand-voice/scripts/measure.py +246 -0
- package/app/skills/briefing/SKILL.md +61 -0
- package/app/skills/swarm/SKILL.md +83 -1
- package/benchmarks/ecosystem-doctor-snapshot.json +17 -13
- package/bin/ai-toolkit.js +2 -0
- package/kb/history/completed/f2-mcp-trim-spike-20260504.md +117 -0
- package/kb/history/completed/output-token-discipline-plan-20260504.md +261 -0
- package/kb/planning/mcp-context-trim-v4-prd.md +158 -0
- package/kb/procedures/release-verification-sop.md +8 -5
- package/kb/reference/architecture-overview.md +2 -2
- package/kb/reference/skills-catalog.md +3 -3
- package/llms-full.txt +569 -12
- package/llms.txt +3 -0
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/scripts/install_steps/hooks.py +33 -0
- package/scripts/merge-hooks.py +17 -0
- package/scripts/pack_codebase.py +362 -0
- package/scripts/session_token_stats.py +264 -0
package/AGENTS.md
CHANGED
|
@@ -348,7 +348,7 @@ Security expert. Use for OWASP Top 10, CVE analysis, security audits, penetratio
|
|
|
348
348
|
|
|
349
349
|
### `seo-specialist`
|
|
350
350
|
|
|
351
|
-
Search engine optimization specialist. Trigger words: SEO, search engine, meta tags, structured data, Core Web Vitals, sitemap, robots.txt, schema.org
|
|
351
|
+
Search engine + generative engine optimization specialist. Trigger words: SEO, GEO, AEO, search engine, meta tags, structured data, Core Web Vitals, sitemap, robots.txt, schema.org, llms.txt, ChatGPT visibility, Claude citation, Perplexity ranking, AI Overviews
|
|
352
352
|
|
|
353
353
|
**Tools:** `Read, Write, Edit, Bash, Grep, Glob`
|
|
354
354
|
|
|
@@ -436,7 +436,7 @@ Specialized agent personas — apply their expertise for relevant tasks:
|
|
|
436
436
|
- **search-specialist**: Information retrieval and search optimization specialist. Trigger words: search, query, semantic search, information retrieval, relevance, ranking, search optimization
|
|
437
437
|
- **security-architect**: Proactive security design expert. Use for Threat Modeling, architecture security reviews, and designing secure systems (AuthN/AuthZ, Crypto).
|
|
438
438
|
- **security-auditor**: Security expert. Use for OWASP Top 10, CVE analysis, security audits, penetration testing, vulnerability assessment, hardening. Triggers: security, owasp, cve, vulnerability, audit, hardening, penetration, pentest, injection test, api security.
|
|
439
|
-
- **seo-specialist**: Search engine optimization specialist. Trigger words: SEO, search engine, meta tags, structured data, Core Web Vitals, sitemap, robots.txt, schema.org
|
|
439
|
+
- **seo-specialist**: Search engine + generative engine optimization specialist. Trigger words: SEO, GEO, AEO, search engine, meta tags, structured data, Core Web Vitals, sitemap, robots.txt, schema.org, llms.txt, ChatGPT visibility, Claude citation, Perplexity ranking, AI Overviews
|
|
440
440
|
- **system-governor**: The Guardian of the Constitution. Validates all evolutionary changes and enforces immutable rules. Has VETO power.
|
|
441
441
|
- **tech-lead**: Technical authority for code quality, architecture patterns, and stack decisions. Use for code reviews, technological disputes, and standards enforcement.
|
|
442
442
|
- **technical-researcher**: Deep technical investigation and multi-source research synthesis specialist. Trigger words: technical research, feasibility study, root cause analysis, API investigation, compatibility research, comparison matrix, synthesize, aggregate, report, executive summary, gap analysis, findings, multi-source, cross-reference
|
|
@@ -454,7 +454,7 @@ Skills are invocable commands or auto-loaded knowledge sources:
|
|
|
454
454
|
- **architecture-audit**: Explore codebase organically for architectural friction, discover shallow modules, and propose module-deepening refactors as GitHub issue RFCs using parallel sub-agent interface designs. Use when user wants to improve architecture, find shallow modules, deepen modules, or reduce coupling. Codex-adapted: uses native subagents and plan tracking.
|
|
455
455
|
- **architecture-decision**: Architecture decision making via trade-off analysis in RFC/RFD/ADR format: context, constraints, 3+ options, comparison, recommendation. Triggers: architecture decision, ADR, RFC, RFD, trade-offs, options comparison, design choice, pick between, should we use, evaluate approach. Load when weighing 2+ architectural options or writing decision records.
|
|
456
456
|
- **biz-scan**: Scans codebase for business opportunities by analyzing database schemas, API endpoints, tracking events, and feature flags to surface underutilized capabilities, missing KPIs, and monetization gaps. Use when the user asks about revenue opportunities, business metrics, KPI coverage, analytics gaps, or monetization analysis of a codebase.
|
|
457
|
-
- **brand-voice**: Loaded when writing documentation, content, README, or user-facing text. Prevents generic LLM rhetoric
|
|
457
|
+
- **brand-voice**: Loaded when writing documentation, content, README, or user-facing text, AND when an output-mode is set for conversational responses. Prevents generic LLM rhetoric, enforces direct technical voice, and supplies optional concise/strict response modes.
|
|
458
458
|
- **briefing**: Generate an executive daily briefing that aggregates reports from all agents into a short, decision-focused summary. Use when the user asks for a status update across the whole system — not for one-agent activity reports.
|
|
459
459
|
- **build**: Build the project with auto-detected toolchain (npm, poetry, cargo, go, flutter, Docker). Use when the user asks to compile, bundle, or produce artifacts — not to run tests or deploy.
|
|
460
460
|
- **chaos**: Inject controlled faults for resilience testing on non-production targets. Use when the user explicitly asks for a chaos experiment, latency injection, or dependency kill — never implicit.
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,46 @@ Versioning follows [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## v3.2.1 — Statusline shellcheck cleanup (2026-05-04)
|
|
11
|
+
|
|
12
|
+
Patch release. Lint-only fix in the default status line hook — no behavior change.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **`app/hooks/ai-toolkit-statusline.sh` shellcheck warnings** — removed the unused `C_GRAY` color variable (SC2034) and replaced the deprecated `[ p -o q ]` form with `{ [ p ] || [ q ]; }` (SC2166). CI shellcheck gate at `--severity=warning` now passes clean across `app/hooks/*.sh`.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## v3.2.0 — Output discipline & token-aware status line (2026-05-04)
|
|
21
|
+
|
|
22
|
+
Minor release. Two coordinated additions: per-response output discipline and a real-token status line installed by default.
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- **`brand-voice` output modes** — `concise` (≤60% tokens) and `strict` (≤40% tokens) extend the existing brand-voice skill with response-length governance. Activate via `output-mode: concise` in project `CLAUDE.md` or `/brand-voice concise`. Mode rules in `app/skills/brand-voice/modes/`.
|
|
27
|
+
- **`measure.py` token evaluator** — fixture-driven before/after comparison at `app/skills/brand-voice/scripts/measure.py`. Asserts budget compliance and load-bearing fact preservation via optional `must_contain.txt` per fixture. JSON and human report formats.
|
|
28
|
+
- **`session_token_stats.py`** — stdlib-only Claude Code session JSONL parser at `scripts/session_token_stats.py`. Reports real input/output/cache token counts per session, supports `--since`, `--baseline`, `--statusline`, and `--json` modes.
|
|
29
|
+
- **Comprehensive default status line** — new `app/hooks/ai-toolkit-statusline.sh` renders a single line with cwd, git branch + dirty marker, context-window as a 10-cell progress bar (green <70% / orange 70–89% / red ≥90%), upload arrow `↑` (input tokens, green) + download arrow `↓` (output tokens, red), effort level, and model name. All token + cost data is read directly from Claude Code's statusLine stdin (`context_window.total_input_tokens`, `total_output_tokens`, `cost.total_cost_usd`, `effort.level`) — no JSONL parsing in the hot path, ~50ms cold start. Installed automatically into `~/.claude/settings.json` by `ai-toolkit install` (and `update`). User-customized statusLine entries (without the ai-toolkit `_source` tag) are preserved untouched. Cost-estimate segment is opt-in via `AI_TOOLKIT_STATUSLINE_SHOW_COST=1`.
|
|
30
|
+
- **`merge-hooks.py` statusLine support** — `inject` writes the toolkit statusLine only when the target has none or has a stale toolkit-installed one. `strip` removes only toolkit-installed entries.
|
|
31
|
+
- **`briefing` skill `--tokens` mode** — `/briefing --tokens [--since 7d]` for explicit reporting and baseline capture. Includes wire-up docs for the status-line hook and `AI_TOOLKIT_STATUSLINE_*` opt-out env vars.
|
|
32
|
+
- **Hook runtime scripts deployed alongside hooks** — `scripts/install_steps/hooks.py` now copies a curated allowlist of Python helpers (`session_token_stats.py`, `version_check.py`) to `~/.softspark/ai-toolkit/scripts/`, so hooks work on a fresh install before the npm-global package catches up. Hook resolution order: `AI_TOOLKIT_DIR` → `~/.softspark/ai-toolkit/` → npm global → walk up from script (dev fallback).
|
|
33
|
+
|
|
34
|
+
### Opt-out
|
|
35
|
+
|
|
36
|
+
- `AI_TOOLKIT_STATUSLINE_DISABLE=1` silences output entirely
|
|
37
|
+
- `AI_TOOLKIT_STATUSLINE_NO_TOKENS=1` hides token arrows segment
|
|
38
|
+
- `AI_TOOLKIT_STATUSLINE_NO_GIT=1` hides git segment
|
|
39
|
+
- `AI_TOOLKIT_STATUSLINE_NO_EFFORT=1` hides effort level segment
|
|
40
|
+
- `AI_TOOLKIT_STATUSLINE_NO_COLOR=1` disables ANSI colors
|
|
41
|
+
- `AI_TOOLKIT_STATUSLINE_SHOW_COST=1` appends Claude Code's reported `cost.total_cost_usd` (off by default — long Opus sessions show alarming numbers)
|
|
42
|
+
- `AI_TOOLKIT_STATUSLINE_DUMP=1` writes received stdin to `/tmp/cc-statusline-input.json` (debug only)
|
|
43
|
+
|
|
44
|
+
### Tests
|
|
45
|
+
|
|
46
|
+
- 38 new bats tests across `tests/test_brand_voice.bats`, `tests/test_session_token_stats.bats`, `tests/test_statusline_hook.bats`, `tests/test_merge_hooks_statusline.bats`, plus install-step assertion in `tests/test_install.bats`.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
10
50
|
## v3.1.1 — Windows install fix (2026-04-29)
|
|
11
51
|
|
|
12
52
|
Patch release. `ai-toolkit install --local` crashed on Windows before doing any work because `scripts/install_steps/project_registry.py` imported `fcntl` (POSIX-only) at module load, raising `ModuleNotFoundError: No module named 'fcntl'`.
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
[](app/skills/)
|
|
8
8
|
[](app/agents/)
|
|
9
|
-
[](tests/)
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<img src="assets/ai-toolkit-readme-hero.png" alt="ai-toolkit 3 README hero showing one toolkit for 12 AI editors" width="900">
|
|
@@ -14,12 +14,11 @@
|
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
-
## What's New in v3.
|
|
17
|
+
## What's New in v3.2.1
|
|
18
18
|
|
|
19
|
-
Patch release
|
|
19
|
+
Patch release. Shellcheck cleanup of the default status line hook — no behavior change.
|
|
20
20
|
|
|
21
|
-
- **
|
|
22
|
-
- **Regression test on POSIX CI** — `tests/test_windows_support.bats` simulates the missing-`fcntl` scenario and exercises the Windows lock branch via a stubbed `msvcrt`, so this regression is caught without a Windows runner.
|
|
21
|
+
- **Statusline lint cleanup** — `app/hooks/ai-toolkit-statusline.sh` now passes `shellcheck --severity=warning`: removed the unused `C_GRAY` color variable (SC2034) and replaced the deprecated `[ p -o q ]` form with `{ [ p ] || [ q ]; }` (SC2166).
|
|
23
22
|
|
|
24
23
|
See [CHANGELOG.md](CHANGELOG.md) for full history.
|
|
25
24
|
|
|
@@ -126,8 +125,8 @@ See [CLI Reference](kb/reference/cli-reference.md) for all commands and options.
|
|
|
126
125
|
| Component | Count | Description |
|
|
127
126
|
|-----------|-------|-------------|
|
|
128
127
|
| `skills/` (task) | 32 | Slash commands: `/commit`, `/build`, `/deploy`, `/test`, `/mcp-builder`, ... |
|
|
129
|
-
| `skills/` (hybrid) |
|
|
130
|
-
| `skills/` (knowledge) |
|
|
128
|
+
| `skills/` (hybrid) | 32 | Slash commands with agent knowledge base |
|
|
129
|
+
| `skills/` (knowledge) | 48 | Domain knowledge auto-loaded by agents (includes 13 `<lang>-rules` skills) |
|
|
131
130
|
| `agents/` | 44 | Specialized agents across 10 categories |
|
|
132
131
|
| `hooks/` | 21 global + 5 skill-scoped | Quality gates, path safety, prompt governance, session lifecycle |
|
|
133
132
|
| `plugins/` | 11 packs | Opt-in domain bundles (security, research, frontend, enterprise, 6 language packs) |
|
|
@@ -152,7 +151,7 @@ ai-toolkit/
|
|
|
152
151
|
│ └── ARCHITECTURE.md # Full system design
|
|
153
152
|
├── kb/ # Reference docs, procedures, plans
|
|
154
153
|
├── scripts/ # Validation, install, evaluation scripts
|
|
155
|
-
├── tests/ # Bats test suite (
|
|
154
|
+
├── tests/ # Bats test suite (1038 tests)
|
|
156
155
|
└── CHANGELOG.md
|
|
157
156
|
```
|
|
158
157
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-toolkit",
|
|
3
3
|
"description": "Professional-grade Claude Code toolkit with persona presets, skill security auditor, expanded lifecycle hooks, experimental opt-in plugin packs, benchmark harvesting, and multi-tool support.",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.2.1",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "SoftSpark",
|
|
7
7
|
"url": "https://github.com/softspark"
|
package/app/ARCHITECTURE.md
CHANGED
|
@@ -12,6 +12,53 @@ Universal multi-agent system for software development. Works across all reposito
|
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
+
## Layered Model (the five-layer mental model)
|
|
16
|
+
|
|
17
|
+
The toolkit is organised as five stacked layers. Higher layers depend on lower layers, never the other way around. Treat this as the canonical mental model when adding features — pick the lowest layer that fits.
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
21
|
+
│ Layer 5 — Plugins (distribution) │
|
|
22
|
+
│ Bundles for npm / marketplace / ai-toolkit eject │
|
|
23
|
+
│ Files: app/plugins/, plugin.json, package.json │
|
|
24
|
+
├─────────────────────────────────────────────────────────────┤
|
|
25
|
+
│ Layer 4 — Subagents (delegation) │
|
|
26
|
+
│ Specialised personas spawned via Agent / Teams │
|
|
27
|
+
│ Files: app/agents/, .claude/agents/ │
|
|
28
|
+
├─────────────────────────────────────────────────────────────┤
|
|
29
|
+
│ Layer 3 — Hooks (the guardrail layer) │
|
|
30
|
+
│ Lifecycle events: SessionStart, PreToolUse, Stop, … │
|
|
31
|
+
│ Files: app/hooks/*.sh, settings.json hooks block │
|
|
32
|
+
├─────────────────────────────────────────────────────────────┤
|
|
33
|
+
│ Layer 2 — Skills (the knowledge layer) │
|
|
34
|
+
│ Slash-commands, knowledge skills, hybrid skills │
|
|
35
|
+
│ Files: app/skills/<name>/SKILL.md │
|
|
36
|
+
├─────────────────────────────────────────────────────────────┤
|
|
37
|
+
│ Layer 1 — CLAUDE.md (the memory layer) │
|
|
38
|
+
│ Persistent rules + auto-memory loaded into every session │
|
|
39
|
+
│ Files: CLAUDE.md (global / project / .claude) │
|
|
40
|
+
└─────────────────────────────────────────────────────────────┘
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Where does my new feature go?
|
|
44
|
+
|
|
45
|
+
| If the feature is… | Add it at | Examples |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| A persistent rule the model must always know | Layer 1 (CLAUDE.md) | "always sync_tasks first", commit conventions |
|
|
48
|
+
| A reusable workflow / domain knowledge | Layer 2 (Skills) | `/debug`, `/review`, `python-rules` |
|
|
49
|
+
| Behavior the harness must enforce automatically | Layer 3 (Hooks) | block destructive `rm -rf`, run lint on Stop |
|
|
50
|
+
| A specialised role for delegation | Layer 4 (Subagents) | `security-auditor`, `database-architect` |
|
|
51
|
+
| A shippable bundle for other repos | Layer 5 (Plugins) | `app/plugins/python-stack/` |
|
|
52
|
+
|
|
53
|
+
### Cross-cutting rules
|
|
54
|
+
|
|
55
|
+
- A skill MAY trigger an agent (`agent: <name>` frontmatter) — that's Layer 2 calling Layer 4.
|
|
56
|
+
- A hook MUST NOT call a skill — hooks are deterministic shell, skills are LLM-driven.
|
|
57
|
+
- A plugin MAY bundle skills + agents + hooks, but never the inverse.
|
|
58
|
+
- CLAUDE.md is read by every layer; it is the only layer everyone reads.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
15
62
|
## Agents
|
|
16
63
|
|
|
17
64
|
### Orchestration & Planning (4)
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: seo-specialist
|
|
3
|
-
description: "Search engine optimization specialist. Trigger words: SEO, search engine, meta tags, structured data, Core Web Vitals, sitemap, robots.txt, schema.org"
|
|
3
|
+
description: "Search engine + generative engine optimization specialist. Trigger words: SEO, GEO, AEO, search engine, meta tags, structured data, Core Web Vitals, sitemap, robots.txt, schema.org, llms.txt, ChatGPT visibility, Claude citation, Perplexity ranking, AI Overviews"
|
|
4
4
|
tools: Read, Write, Edit, Bash, Grep, Glob
|
|
5
5
|
model: sonnet
|
|
6
6
|
color: cyan
|
|
7
7
|
skills: clean-code, seo-validate
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
# SEO Specialist
|
|
10
|
+
# SEO + GEO Specialist
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Optimization for both classical search engines AND generative engines (ChatGPT, Claude, Perplexity, Google AI Overviews, Gemini).
|
|
13
13
|
|
|
14
14
|
## Expertise
|
|
15
15
|
- Technical SEO
|
|
@@ -17,6 +17,7 @@ Search engine optimization specialist.
|
|
|
17
17
|
- Core Web Vitals
|
|
18
18
|
- Structured data (Schema.org)
|
|
19
19
|
- SEO auditing
|
|
20
|
+
- **Generative Engine Optimization (GEO)** — being cited by LLM-based answer engines
|
|
20
21
|
|
|
21
22
|
## Responsibilities
|
|
22
23
|
|
|
@@ -108,4 +109,86 @@ Sitemap: https://example.com/sitemap.xml
|
|
|
108
109
|
```python
|
|
109
110
|
smart_query("SEO optimization patterns")
|
|
110
111
|
hybrid_search_kb("technical SEO checklist")
|
|
112
|
+
smart_query("GEO generative engine optimization")
|
|
111
113
|
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Generative Engine Optimization (GEO)
|
|
118
|
+
|
|
119
|
+
Goal: get cited by ChatGPT, Claude, Perplexity, Gemini, and Google AI Overviews — not just rank in classical SERPs.
|
|
120
|
+
|
|
121
|
+
### When to use SEO vs GEO
|
|
122
|
+
- **SEO**: a user types a query and clicks a link → optimise for click-through.
|
|
123
|
+
- **GEO**: a user asks an LLM and reads the synthesis → optimise for **inclusion in the answer + named source attribution**.
|
|
124
|
+
- They overlap on technical foundations (crawlability, structured data, authority) and diverge on content shape and citability.
|
|
125
|
+
|
|
126
|
+
### Citability checklist (the 12 things LLM crawlers reward)
|
|
127
|
+
1. **One claim per sentence.** LLMs extract sentence-level snippets — long compound sentences get dropped.
|
|
128
|
+
2. **Lead with the answer.** Inverted-pyramid structure — definition / number / decision in the first sentence of each section.
|
|
129
|
+
3. **Stable, descriptive H2/H3 headings phrased as questions.** Mirrors how users prompt LLMs.
|
|
130
|
+
4. **Unique data, numbers, dates, version strings.** Verifiable facts get cited; opinion does not.
|
|
131
|
+
5. **Named author + author bio with credentials.** Authority signal that survives synthesis.
|
|
132
|
+
6. **Original quotes from named experts.** Quotation blocks are over-represented in LLM citations.
|
|
133
|
+
7. **Comparison tables with explicit labels.** Tables are extracted whole; vague prose is summarised away.
|
|
134
|
+
8. **Schema.org `Article`, `FAQPage`, `HowTo`, `QAPage`, `Person`.** Mandatory for entity disambiguation.
|
|
135
|
+
9. **`llms.txt` at site root.** Curated index of canonical pages for LLM crawlers (Anthropic-proposed convention).
|
|
136
|
+
10. **Stable URLs with semantic slugs.** LLMs cache citations — URL changes erase your authority overnight.
|
|
137
|
+
11. **Cross-linking with descriptive anchors.** "this article" is dead anchor text; use the actual claim.
|
|
138
|
+
12. **Date stamps on every page.** Recency is a top-3 ranking factor for AI Overviews and Perplexity.
|
|
139
|
+
|
|
140
|
+
### `llms.txt` template
|
|
141
|
+
```
|
|
142
|
+
# Brand Name
|
|
143
|
+
> One-sentence description of what the site is and who it's for.
|
|
144
|
+
|
|
145
|
+
## Core docs
|
|
146
|
+
- [Title](/url): one-line summary the LLM should remember
|
|
147
|
+
- [Title](/url): one-line summary
|
|
148
|
+
|
|
149
|
+
## API reference
|
|
150
|
+
- [Endpoint](/url): purpose, auth, response shape
|
|
151
|
+
|
|
152
|
+
## Optional
|
|
153
|
+
- [Changelog](/changelog): recent updates
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### GEO audit checklist
|
|
157
|
+
- [ ] First sentence of every page answers the page's title as a question
|
|
158
|
+
- [ ] At least one comparison table OR numbered list per long-form page
|
|
159
|
+
- [ ] Author block with name + role + LinkedIn / GitHub / ORCID
|
|
160
|
+
- [ ] Schema.org `Article` with `author`, `datePublished`, `dateModified`
|
|
161
|
+
- [ ] Schema.org `FAQPage` for any page with Q/A structure
|
|
162
|
+
- [ ] `llms.txt` at site root with curated canonical URLs
|
|
163
|
+
- [ ] Page contains at least 3 unique data points (numbers, dates, version strings)
|
|
164
|
+
- [ ] Date visible to the user, not just in metadata
|
|
165
|
+
- [ ] No paywall / login wall on indexable content
|
|
166
|
+
- [ ] No JavaScript-only content for primary value (LLM crawlers often skip JS)
|
|
167
|
+
- [ ] Internal links use claim-as-anchor, not "click here"
|
|
168
|
+
- [ ] Brand and product names are consistent across the entire site
|
|
169
|
+
|
|
170
|
+
### Measuring GEO outcomes
|
|
171
|
+
GEO has no Search Console equivalent. Substitutes:
|
|
172
|
+
- **Manual prompt testing**: query each target prompt monthly in ChatGPT / Claude / Perplexity / AI Overviews; record whether your domain appears in the citation footer.
|
|
173
|
+
- **Referrer analysis**: filter analytics by `Referer` containing `chat.openai.com`, `perplexity.ai`, `claude.ai`, `gemini.google.com`.
|
|
174
|
+
- **Brand-mention monitoring**: tools that scrape LLM outputs for mentions (Otterly, Profound, AthenaHQ).
|
|
175
|
+
- **Server logs**: identify and welcome crawler user-agents (`GPTBot`, `ClaudeBot`, `PerplexityBot`, `Google-Extended`, `OAI-SearchBot`).
|
|
176
|
+
|
|
177
|
+
### `robots.txt` for AI crawlers (allow by default)
|
|
178
|
+
```
|
|
179
|
+
User-agent: GPTBot
|
|
180
|
+
Allow: /
|
|
181
|
+
|
|
182
|
+
User-agent: ClaudeBot
|
|
183
|
+
Allow: /
|
|
184
|
+
|
|
185
|
+
User-agent: PerplexityBot
|
|
186
|
+
Allow: /
|
|
187
|
+
|
|
188
|
+
User-agent: Google-Extended
|
|
189
|
+
Allow: /
|
|
190
|
+
|
|
191
|
+
User-agent: OAI-SearchBot
|
|
192
|
+
Allow: /
|
|
193
|
+
```
|
|
194
|
+
Disallow only what you would disallow for Googlebot. Blocking AI crawlers wholesale erases you from generative answers — the trade-off is rarely worth it for content sites.
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ai-toolkit-statusline.sh — comprehensive Claude Code status line.
|
|
3
|
+
#
|
|
4
|
+
# Renders one line. Left side: cwd, git, ctx%, i/o token split.
|
|
5
|
+
# Right side (right-aligned): effort level, model name.
|
|
6
|
+
# Optional cost segment is opt-in via AI_TOOLKIT_STATUSLINE_SHOW_COST=1.
|
|
7
|
+
#
|
|
8
|
+
# All token + cost data is read directly from Claude Code's statusLine stdin
|
|
9
|
+
# (context_window.total_input_tokens, total_output_tokens, cost.total_cost_usd,
|
|
10
|
+
# effort.level). No JSONL parsing in the hot path.
|
|
11
|
+
#
|
|
12
|
+
# Wire-up: ai-toolkit installer adds this as default `statusLine` in
|
|
13
|
+
# ~/.claude/settings.json. Manual config:
|
|
14
|
+
# {
|
|
15
|
+
# "statusLine": {
|
|
16
|
+
# "type": "command",
|
|
17
|
+
# "command": "bash ~/.softspark/ai-toolkit/hooks/ai-toolkit-statusline.sh"
|
|
18
|
+
# }
|
|
19
|
+
# }
|
|
20
|
+
#
|
|
21
|
+
# Env vars (all optional):
|
|
22
|
+
# AI_TOOLKIT_DIR — toolkit install location (auto-detected)
|
|
23
|
+
# AI_TOOLKIT_STATUSLINE_DISABLE — "1" silences output entirely
|
|
24
|
+
# AI_TOOLKIT_STATUSLINE_NO_COLOR — "1" disables ANSI colors
|
|
25
|
+
# AI_TOOLKIT_STATUSLINE_NO_TOKENS — "1" hides i/o segment
|
|
26
|
+
# AI_TOOLKIT_STATUSLINE_NO_GIT — "1" hides git segment
|
|
27
|
+
# AI_TOOLKIT_STATUSLINE_NO_EFFORT — "1" hides effort segment
|
|
28
|
+
# AI_TOOLKIT_STATUSLINE_SHOW_COST — "1" appends Claude Code's reported cost
|
|
29
|
+
# AI_TOOLKIT_STATUSLINE_DUMP — "1" writes stdin to /tmp/cc-statusline-input.json
|
|
30
|
+
#
|
|
31
|
+
# Performance: ~50ms (single python3 parse of stdin, one git invocation).
|
|
32
|
+
|
|
33
|
+
set -u
|
|
34
|
+
|
|
35
|
+
[ "${AI_TOOLKIT_STATUSLINE_DISABLE:-0}" = "1" ] && exit 0
|
|
36
|
+
|
|
37
|
+
# ── Colors ───────────────────────────────────────────────────────────────────
|
|
38
|
+
# Claude Code captures stdout via pipe but interprets ANSI escapes when it
|
|
39
|
+
# renders the statusline. So always emit colors unless explicitly disabled.
|
|
40
|
+
if [ "${AI_TOOLKIT_STATUSLINE_NO_COLOR:-0}" = "1" ]; then
|
|
41
|
+
C_RESET="" C_GREEN="" C_BOLD_GREEN="" C_CYAN="" C_BLUE="" C_RED=""
|
|
42
|
+
C_YELLOW="" C_MAGENTA="" C_DIM="" C_BOLD_YELLOW="" C_ORANGE=""
|
|
43
|
+
else
|
|
44
|
+
C_RESET=$'\033[0m'
|
|
45
|
+
C_GREEN=$'\033[0;32m'
|
|
46
|
+
C_BOLD_GREEN=$'\033[1;32m'
|
|
47
|
+
C_CYAN=$'\033[0;36m'
|
|
48
|
+
C_BLUE=$'\033[1;34m'
|
|
49
|
+
C_RED=$'\033[0;31m'
|
|
50
|
+
C_YELLOW=$'\033[0;33m'
|
|
51
|
+
C_BOLD_YELLOW=$'\033[1;33m'
|
|
52
|
+
C_MAGENTA=$'\033[0;35m'
|
|
53
|
+
C_DIM=$'\033[2m'
|
|
54
|
+
C_ORANGE=$'\033[38;5;208m'
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# ── Parse stdin in one python3 invocation ────────────────────────────────────
|
|
58
|
+
INPUT="$(cat 2>/dev/null || true)"
|
|
59
|
+
|
|
60
|
+
if [ "${AI_TOOLKIT_STATUSLINE_DUMP:-0}" = "1" ] && [ -n "$INPUT" ]; then
|
|
61
|
+
printf '%s' "$INPUT" > /tmp/cc-statusline-input.json 2>/dev/null
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
PARSED="$(printf '%s' "$INPUT" | python3 -c '
|
|
65
|
+
import json, sys
|
|
66
|
+
def get(d, path):
|
|
67
|
+
for k in path.split("."):
|
|
68
|
+
d = d.get(k) if isinstance(d, dict) else None
|
|
69
|
+
if d is None:
|
|
70
|
+
return ""
|
|
71
|
+
return d if d is not None else ""
|
|
72
|
+
def fmt_tokens(n):
|
|
73
|
+
try:
|
|
74
|
+
n = int(n)
|
|
75
|
+
except (TypeError, ValueError):
|
|
76
|
+
return "0"
|
|
77
|
+
if n >= 1000:
|
|
78
|
+
return f"{n/1000:.1f}k"
|
|
79
|
+
return str(n)
|
|
80
|
+
try:
|
|
81
|
+
d = json.loads(sys.stdin.read() or "{}")
|
|
82
|
+
except Exception:
|
|
83
|
+
d = {}
|
|
84
|
+
cwd = get(d, "cwd") or ""
|
|
85
|
+
model = get(d, "model.display_name") or get(d, "model.id") or ""
|
|
86
|
+
ctx_pct = get(d, "context_window.used_percentage")
|
|
87
|
+
in_tok = fmt_tokens(get(d, "context_window.total_input_tokens"))
|
|
88
|
+
out_tok = fmt_tokens(get(d, "context_window.total_output_tokens"))
|
|
89
|
+
cost = get(d, "cost.total_cost_usd")
|
|
90
|
+
try:
|
|
91
|
+
cost_str = f"{float(cost):.2f}" if cost != "" else ""
|
|
92
|
+
except (TypeError, ValueError):
|
|
93
|
+
cost_str = ""
|
|
94
|
+
effort = get(d, "effort.level") or ""
|
|
95
|
+
print(f"{cwd}\t{model}\t{ctx_pct}\t{in_tok}\t{out_tok}\t{cost_str}\t{effort}")
|
|
96
|
+
' 2>/dev/null)"
|
|
97
|
+
|
|
98
|
+
IFS=$'\t' read -r CWD MODEL_NAME CTX_USED IN_TOK OUT_TOK COST EFFORT <<< "$PARSED"
|
|
99
|
+
[ -z "$CWD" ] && CWD="$PWD"
|
|
100
|
+
|
|
101
|
+
# ── Segment: prompt + dir ────────────────────────────────────────────────────
|
|
102
|
+
DIR_BASENAME="$(basename "$CWD" 2>/dev/null || echo '~')"
|
|
103
|
+
SEG_PROMPT="${C_BOLD_GREEN}\xe2\x9e\x9c${C_RESET} ${C_CYAN}${DIR_BASENAME}${C_RESET}"
|
|
104
|
+
|
|
105
|
+
# ── Segment: git ────────────────────────────────────────────────────────────
|
|
106
|
+
SEG_GIT=""
|
|
107
|
+
if [ "${AI_TOOLKIT_STATUSLINE_NO_GIT:-0}" != "1" ] && \
|
|
108
|
+
git -C "$CWD" rev-parse --git-dir >/dev/null 2>&1; then
|
|
109
|
+
BRANCH="$(git -C "$CWD" -c core.fsmonitor=false symbolic-ref --short HEAD 2>/dev/null)"
|
|
110
|
+
if [ -n "$BRANCH" ]; then
|
|
111
|
+
DIRTY=""
|
|
112
|
+
if git -C "$CWD" -c core.fsmonitor=false status --porcelain 2>/dev/null | grep -q .; then
|
|
113
|
+
DIRTY=" ${C_RED}\xe2\x9c\x97${C_RESET}"
|
|
114
|
+
fi
|
|
115
|
+
SEG_GIT=" ${C_BLUE}git:(${C_RED}${BRANCH}${C_BLUE})${C_RESET}${DIRTY}"
|
|
116
|
+
fi
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# ── Segment: context window as progress bar ────────────────────────────────
|
|
120
|
+
# 10-cell bar with usage-shaded color: green <50%, yellow 50-79%, red ≥80%.
|
|
121
|
+
build_ctx_bar() {
|
|
122
|
+
local pct=$1
|
|
123
|
+
local cells=10
|
|
124
|
+
local filled=$(( (pct * cells + 50) / 100 ))
|
|
125
|
+
[ "$filled" -gt "$cells" ] && filled=$cells
|
|
126
|
+
[ "$filled" -lt 0 ] && filled=0
|
|
127
|
+
local color
|
|
128
|
+
if [ "$pct" -ge 90 ]; then
|
|
129
|
+
color="$C_RED"
|
|
130
|
+
elif [ "$pct" -ge 70 ]; then
|
|
131
|
+
color="$C_ORANGE"
|
|
132
|
+
else
|
|
133
|
+
color="$C_GREEN"
|
|
134
|
+
fi
|
|
135
|
+
local bar=""
|
|
136
|
+
local i=0
|
|
137
|
+
while [ "$i" -lt "$filled" ]; do
|
|
138
|
+
bar+="\xe2\x96\x88" # █ FULL BLOCK
|
|
139
|
+
i=$((i+1))
|
|
140
|
+
done
|
|
141
|
+
local empty=""
|
|
142
|
+
while [ "$i" -lt "$cells" ]; do
|
|
143
|
+
empty+="\xe2\x96\x91" # ░ LIGHT SHADE
|
|
144
|
+
i=$((i+1))
|
|
145
|
+
done
|
|
146
|
+
printf '%b' "${color}${bar}${C_DIM}${empty}${C_RESET}"
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
SEG_CTX=""
|
|
150
|
+
if [ -n "$CTX_USED" ]; then
|
|
151
|
+
CTX_INT="$(printf '%.0f' "$CTX_USED" 2>/dev/null || echo "$CTX_USED")"
|
|
152
|
+
case "$CTX_INT" in
|
|
153
|
+
''|*[!0-9]*) CTX_INT=0 ;;
|
|
154
|
+
esac
|
|
155
|
+
SEG_CTX=" $(build_ctx_bar "$CTX_INT") ${C_DIM}${CTX_INT}%${C_RESET}"
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
# ── Segment: tokens with up/down arrows ─────────────────────────────────────
|
|
159
|
+
# ↑ green = upload (input tokens sent to model)
|
|
160
|
+
# ↓ red = download (output tokens received from model)
|
|
161
|
+
SEG_TOKENS=""
|
|
162
|
+
if [ "${AI_TOOLKIT_STATUSLINE_NO_TOKENS:-0}" != "1" ] && [ -n "$IN_TOK" ] && \
|
|
163
|
+
{ [ "$IN_TOK" != "0" ] || [ "$OUT_TOK" != "0" ]; }; then
|
|
164
|
+
SEG_TOKENS=" ${C_BOLD_GREEN}\xe2\x86\x91${IN_TOK}${C_RESET} ${C_RED}\xe2\x86\x93${OUT_TOK}${C_RESET}"
|
|
165
|
+
if [ "${AI_TOOLKIT_STATUSLINE_SHOW_COST:-0}" = "1" ] && [ -n "$COST" ]; then
|
|
166
|
+
SEG_TOKENS+=" ${C_BOLD_GREEN}\$${COST}${C_RESET}"
|
|
167
|
+
fi
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
# ── Right-aligned segments: effort + model ───────────────────────────────────
|
|
171
|
+
SEG_EFFORT=""
|
|
172
|
+
if [ "${AI_TOOLKIT_STATUSLINE_NO_EFFORT:-0}" != "1" ] && [ -n "$EFFORT" ]; then
|
|
173
|
+
case "$EFFORT" in
|
|
174
|
+
xhigh|high) E_COLOR="$C_BOLD_YELLOW" ;;
|
|
175
|
+
medium) E_COLOR="$C_YELLOW" ;;
|
|
176
|
+
*) E_COLOR="$C_DIM" ;;
|
|
177
|
+
esac
|
|
178
|
+
SEG_EFFORT="${C_DIM}effort:${C_RESET}${E_COLOR}${EFFORT}${C_RESET}"
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
SEG_MODEL=""
|
|
182
|
+
if [ -n "$MODEL_NAME" ]; then
|
|
183
|
+
SEG_MODEL="${C_MAGENTA}${MODEL_NAME}${C_RESET}"
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
# ── Render (left-aligned, single line) ───────────────────────────────────────
|
|
187
|
+
# Right-align was attempted earlier but Claude Code reserves variable-width
|
|
188
|
+
# space on the right of the rendered statusline for its own UI overlay,
|
|
189
|
+
# truncating any content right-padded near COLUMNS. Left-align with effort
|
|
190
|
+
# and model as trailing segments avoids the truncation.
|
|
191
|
+
SEG_TRAILER=""
|
|
192
|
+
[ -n "$SEG_EFFORT" ] && SEG_TRAILER+=" $SEG_EFFORT"
|
|
193
|
+
[ -n "$SEG_MODEL" ] && SEG_TRAILER+=" $SEG_MODEL"
|
|
194
|
+
|
|
195
|
+
printf "%b%b%b%b%b\n" \
|
|
196
|
+
"$SEG_PROMPT" \
|
|
197
|
+
"${SEG_GIT:-}" \
|
|
198
|
+
"${SEG_CTX:-}" \
|
|
199
|
+
"${SEG_TOKENS:-}" \
|
|
200
|
+
"${SEG_TRAILER}"
|
package/app/hooks.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: brand-voice
|
|
3
|
-
description: "Loaded when writing documentation, content, README, or user-facing text. Prevents generic LLM rhetoric
|
|
3
|
+
description: "Loaded when writing documentation, content, README, or user-facing text, AND when an output-mode is set for conversational responses. Prevents generic LLM rhetoric, enforces direct technical voice, and supplies optional concise/strict response modes."
|
|
4
4
|
effort: medium
|
|
5
|
-
user-invocable:
|
|
5
|
+
user-invocable: true
|
|
6
6
|
allowed-tools: Read
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -10,6 +10,8 @@ allowed-tools: Read
|
|
|
10
10
|
|
|
11
11
|
Auto-loaded when writing documentation, content, or user-facing text. Enforces consistent, direct voice and eliminates LLM rhetoric.
|
|
12
12
|
|
|
13
|
+
Also loaded when a project sets `output-mode: concise` or `output-mode: strict` in `CLAUDE.md`, to govern conversational response length and structure (see [Output Modes](#output-modes)).
|
|
14
|
+
|
|
13
15
|
## Anti-Trope List (Banned Phrases)
|
|
14
16
|
|
|
15
17
|
### Opening Tropes (Never Start With)
|
|
@@ -119,6 +121,40 @@ install takes under 30 seconds on a local disk.
|
|
|
119
121
|
- **CRITICAL**: one idea per sentence. If you write "and" linking two distinct ideas, split the sentence
|
|
120
122
|
- **MANDATORY**: technical claims include a concrete number, name, or example — never assert quality without evidence
|
|
121
123
|
|
|
124
|
+
## Output Modes
|
|
125
|
+
|
|
126
|
+
Three modes govern conversational response length. Default applies always; `concise` and `strict` activate per-project or per-session.
|
|
127
|
+
|
|
128
|
+
| Mode | Token target vs default | Used when |
|
|
129
|
+
|------|-------------------------|-----------|
|
|
130
|
+
| `default` | 100% (no extra constraints) | No `output-mode` configured |
|
|
131
|
+
| `concise` | ≤60% | Daily work, short Q&A, code edits, short reviews |
|
|
132
|
+
| `strict` | ≤40% | Long sessions, expensive models, batch operations, code-only tasks |
|
|
133
|
+
|
|
134
|
+
Mode rules live in this skill's `modes/` directory. Read the file matching the active mode:
|
|
135
|
+
|
|
136
|
+
- `modes/concise.md` — bullet-first, no preamble, max 3-sentence prose blocks
|
|
137
|
+
- `modes/strict.md` — telegraphic, no prose blocks, only lists/tables/code
|
|
138
|
+
|
|
139
|
+
### Activation
|
|
140
|
+
|
|
141
|
+
1. **Project-level (preferred):** add `output-mode: concise` to project `CLAUDE.md` frontmatter or `.claude/settings.json` under `aiToolkit.outputMode`
|
|
142
|
+
2. **Session-level:** user types `/brand-voice concise` or `/brand-voice strict` to switch for the current session
|
|
143
|
+
3. **Reset:** `/brand-voice default` or remove the project setting
|
|
144
|
+
|
|
145
|
+
### What modes do NOT change
|
|
146
|
+
|
|
147
|
+
- Code blocks (always full, never truncated)
|
|
148
|
+
- File paths, line numbers, error messages (always exact)
|
|
149
|
+
- Lists of items the user must see (file lists, test failures, security findings)
|
|
150
|
+
- Plan documents and ADRs (always full structure)
|
|
151
|
+
|
|
152
|
+
Modes change *prose*, not *data*. If you cut a fact to fit a length budget, you have failed the mode, not honored it.
|
|
153
|
+
|
|
154
|
+
### Measurement
|
|
155
|
+
|
|
156
|
+
Run `python3 app/skills/brand-voice/scripts/measure.py --fixtures tests/fixtures/output-modes/` to compare baseline vs mode tokens on the fixture set. Report shows per-fixture deltas and an aggregate ratio.
|
|
157
|
+
|
|
122
158
|
## When NOT to Load
|
|
123
159
|
|
|
124
160
|
- For code or technical specs with no user-facing prose — the voice rules do not apply
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Concise Mode
|
|
2
|
+
|
|
3
|
+
Active when project sets `output-mode: concise` or user invokes `/brand-voice concise`.
|
|
4
|
+
|
|
5
|
+
## Targets
|
|
6
|
+
|
|
7
|
+
- Token output ≤60% of default
|
|
8
|
+
- No response longer than 12 lines unless data requires it (file list, test failures, code)
|
|
9
|
+
- No response shorter than 1 sentence — never reply with just "Done." or "OK"
|
|
10
|
+
|
|
11
|
+
## Hard Rules
|
|
12
|
+
|
|
13
|
+
1. **No preamble.** Start with the answer or the action result, not "I'll now..." or "Let me explain..."
|
|
14
|
+
2. **No closing summary.** Don't restate what you just did unless asked.
|
|
15
|
+
3. **Bullets over prose** for any list ≥3 items. Each bullet = one fact, ≤80 chars.
|
|
16
|
+
4. **One paragraph max** per topic. If you need two, split into bullets.
|
|
17
|
+
5. **No filler transitions:** drop "Additionally," "Moreover," "It's worth noting," "Importantly."
|
|
18
|
+
6. **No hedging stacks:** "I think we could potentially maybe try" → "Try X."
|
|
19
|
+
7. **Quote facts, not framing:** show file paths, line numbers, exact error text. Cut the explanation around them if the user can read them.
|
|
20
|
+
|
|
21
|
+
## What to Cut First
|
|
22
|
+
|
|
23
|
+
| Pattern | Action |
|
|
24
|
+
|---------|--------|
|
|
25
|
+
| "Let me check..." / "I'll look at..." | Delete — just do the action |
|
|
26
|
+
| "It looks like..." / "It seems..." | Delete and state the fact directly |
|
|
27
|
+
| "As you can see..." | Delete — the user can see |
|
|
28
|
+
| "Now that we've ... let's ..." | Delete — start the next action |
|
|
29
|
+
| "Great question!" / "Good point!" | Delete always |
|
|
30
|
+
| Restating the user's question | Delete — answer it |
|
|
31
|
+
| "In summary," / "Overall," | Delete the summary entirely |
|
|
32
|
+
|
|
33
|
+
## What to Keep
|
|
34
|
+
|
|
35
|
+
- Concrete file paths, line numbers, command output
|
|
36
|
+
- Exact error messages and stack frames
|
|
37
|
+
- Trade-offs when the user has to decide
|
|
38
|
+
- Warnings about destructive actions
|
|
39
|
+
- Numbers (timings, sizes, counts, percentages)
|
|
40
|
+
|
|
41
|
+
## Examples
|
|
42
|
+
|
|
43
|
+
**Bad (verbose):**
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
Let me check the brand-voice skill for you. I'll read the SKILL.md file
|
|
47
|
+
to understand its current structure and then look at how it integrates
|
|
48
|
+
with the rest of the system. Now that I've examined it, I can see that
|
|
49
|
+
the skill currently has 130 lines and uses YAML frontmatter. As you can
|
|
50
|
+
see, it has a clear structure with sections for anti-tropes, voice
|
|
51
|
+
principles, and rules. In summary, the skill is well-organized.
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Good (concise):**
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
brand-voice/SKILL.md: 130 lines, YAML frontmatter, sections for anti-tropes,
|
|
58
|
+
voice principles, rules. Structure is clean.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Token ratio: 76 → 25 = 33%.
|
|
62
|
+
|
|
63
|
+
## Boundary Behavior
|
|
64
|
+
|
|
65
|
+
- If a question genuinely needs 30 lines to answer, write 30. Don't truncate facts to hit the budget.
|
|
66
|
+
- If the user asks "explain", give one solid paragraph, not a one-liner.
|
|
67
|
+
- If unsure whether the user wants depth, ask. One question is cheaper than a wrong-length response.
|