wip: [01-stabilize] paused at task 1/1 - OCR Hallucination Immune logic via Semantic delta window and fret-isolation
This commit is contained in:
136
.agent/knowledge/awesome_claude/docs/CODE_OF_CONDUCT.md
Normal file
136
.agent/knowledge/awesome_claude/docs/CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||
identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the overall
|
||||
community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- The use of sexualized language or imagery, and sexual attention or advances of
|
||||
any kind
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email address,
|
||||
without their explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
- Use of this community resource for the purposes of:
|
||||
(i) spreading malware, spyware, and/or adware;
|
||||
(ii) attempting to promote proprietary, commercial offerings under the guise of,
|
||||
and at the expense of, the communal, informational purposes of this list.
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official email address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
awesome-conduct@hesreallyhim.com.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of
|
||||
actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or permanent
|
||||
ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||
community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.1, available at
|
||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
||||
|
||||
Community Impact Guidelines were inspired by
|
||||
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
||||
[https://www.contributor-covenant.org/translations][translations].
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||
[FAQ]: https://www.contributor-covenant.org/faq
|
||||
[translations]: https://www.contributor-covenant.org/translations
|
||||
108
.agent/knowledge/awesome_claude/docs/CONTRIBUTING.md
Normal file
108
.agent/knowledge/awesome_claude/docs/CONTRIBUTING.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Contributing to Awesome Claude Code
|
||||
|
||||
Please take a moment to read through this docoument if you plan to submit something for recommendation.
|
||||
|
||||
> [!WARNING]
|
||||
> Due to aggressive spamming of the repository's recommendation system, strict measures are in place to ensure that submissions are made accoring to the requirements stated in this document. The penalties are harsh, but compliance is very easy, and any well-meaning user who reads this document is unlikely to be affected. In additiion, please note that a temporary ban is also in place for any submissions relating to OpenClaw. I hope that these incidents were the result of a few irresponsible users, and not reflective of the OpenClaw community as a whole, and I'm sure this will be removed in the near future, but it is deemed necessary as a palliative measure.
|
||||
|
||||
- I am very grateful to receive recommendations from the visitors to this list. But be aware that there is no formal submission/review process at the moment. My responsibility is to share links to awesome things. One way I find out about awesome things is via the repo's issues, and I'm very grateful to everyone who shares their amazing work. But it's not the only way, and creating an issue does not represent any sort of contract.
|
||||
- Bear in mind that the point of an Awesome List is to be *selective* - I cannot recommend every single resource that is submitted.
|
||||
- Although many awesome resources are inter-operable, we especially welcome and invite recommendations of resources that focus on the unique features and functionality of Claude Code. This is not a hard requirement but it is a guideline.
|
||||
- I'm constantly trying to improve the way in which recommendations can be submitted, and to provide clear guidance to users who wish to share their work. Here are some of those guidelines:
|
||||
- security is of the utmost importance. I'm unlikely to install any software unless I have high confidence that it is free of malware, spyware, adware, or bloat. If a resource involves executing a shell script, for example, it is recommended to supply clear and thorough comments explaining exactly what it does.
|
||||
- If your library makes any network calls except to Anthropic servers; modifies shared system files; involves any form of telemetry; or requires "bypass-permissions" mode, this must be stated very clearly.
|
||||
- Do not submit resources that do not comply with the licensing rights of other developers. Make sure you understand what OSS licenses require.
|
||||
- I value _focused_ resources with a clear purpose and use value. Even if you have a marketplace full of awesome plugins, you are encouraged to select one, or a small subset.
|
||||
- Claims about what a resource does have to be evidence-based - and you should not expect me, or probably any user, to do the work of proving it themselves. If you can provide a video demonstrating the effectiveness of a skill, e.g., this is tremendously helpful. Otherwise, provide instructions for validating the claims made in the description, and make them as detailed as possible. "Install this library into your favorite project and watch the magic happen" - no. "Clone this demo repository and install the plugin; give Claude the following prompt: ..." - yes.
|
||||
- Put a tiny bit of time and effort into your README. It's a shame that developers will put so much effort into a project and then let an agent write the README and hardly give it any thought.
|
||||
|
||||
## How to Recommend a Resource
|
||||
|
||||
**NOTE: ALL RECOMMENDATIONS MUST BE MADE USING THE WEB UI ISSUE FORM TEMPLATE, OR YOU RISK BEING BANNED FROM INTERACTING WITH THIS REPOSITORY TEMPORARILY OR PERMANENTLY.**
|
||||
|
||||
First, make sure you've read the above information. Second, make sure you've read, and agree with, the [Code of Conduct](./CODE_OF_CONDUCT.md). Then:
|
||||
|
||||
### **[Click here to submit a new resource](https://github.com/hesreallyhim/awesome-claude-code/issues/new?template=recommend-resource.yml)**
|
||||
|
||||
Do not open a PR. Just fill out the form. If there are any issues with the form, the bot will notify you. (A notification from the bot that your recommendation needs some changes in formatting are not related to the warning above, which mainly applies to submissions that attempt to bypass the GitHub Web UI issue form entirely. You need not worry that formatting errors alone will incur a ban.)
|
||||
|
||||
> [!Warning]
|
||||
> It is **not** possible to submit a resource recommendation using the `gh` CLI.
|
||||
|
||||
Although resources themselves may be partially or entirely written by a coding agent, resource recommendations must be created by human beings.
|
||||
|
||||
### The Recommendation Process
|
||||
|
||||
The entire recommendation process is managed via automation - even the maintainer does not use PRs to add entries to the list. The bot is really good at it. Here's what happens when you submit a resource for recommendation:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[📝 Fill out recommendation form] --> B[🤖 Automated validation]
|
||||
B --> C{Valid?}
|
||||
C -->|❌ No| D[Bot comments with issues]
|
||||
D --> E[Edit your submission]
|
||||
E --> B
|
||||
C -->|✅ Yes| F[Awaits maintainer review]
|
||||
F --> G{Decision}
|
||||
G -->|👍 Approved| H[Bot creates PR automatically]
|
||||
G -->|🔄 Changes requested| I[Maintainer requests changes]
|
||||
G -->|👎 Rejected| J[Issue closed]
|
||||
I --> E
|
||||
H --> K[PR merged]
|
||||
K --> L[🎉 Resource goes live!]
|
||||
L --> M[You receive notification]
|
||||
```
|
||||
|
||||
### What the Bot Validates
|
||||
|
||||
When you submit a resource, the bot checks:
|
||||
|
||||
- All required fields are filled
|
||||
- URLs are valid and accessible
|
||||
- No duplicate resources exist
|
||||
- License information (when available)
|
||||
- Description length and quality
|
||||
|
||||
The bot's validation is not any sort of review. It's merely a formal check.
|
||||
|
||||
## Other Contributions
|
||||
|
||||
### Suggesting Improvements
|
||||
|
||||
For suggestions about the repository structure, new categories, or other enhancements:
|
||||
|
||||
1. **[Open a general issue](https://github.com/hesreallyhim/awesome-claude-code/issues/new)**
|
||||
2. Describe your suggestion clearly
|
||||
3. Explain the benefit to the community
|
||||
|
||||
Or, alternatively, start a thread in the [Discussions](https://github.com/hesreallyhim/awesome-claude-code/discussions) tab. All opinions are welcome in this repo so long as they are expressed in accordance with the Code of Conduct. It's very nice to interact with people who visit the list.
|
||||
|
||||
## Badges
|
||||
|
||||
If your submission is approved, you are invited to add a badge to your project's README:
|
||||
|
||||
[](https://github.com/hesreallyhim/awesome-claude-code)
|
||||
|
||||
```markdown
|
||||
[](https://github.com/hesreallyhim/awesome-claude-code)
|
||||
```
|
||||
|
||||
Or the flat version:
|
||||
|
||||
[](https://github.com/hesreallyhim/awesome-claude-code)
|
||||
|
||||
```markdown
|
||||
[](https://github.com/hesreallyhim/awesome-claude-code)
|
||||
```
|
||||
|
||||
## GitHub Repository Notifications
|
||||
|
||||
If your resource is on GitHub, our automated system will create a friendly notification issue on your repository informing you of the inclusion and providing badge options.
|
||||
|
||||
## Technical Details
|
||||
|
||||
For more information about how the repository works, including the automated systems, validation processes, the "multi-list design and technical architecture, see the documents in `docs/` - in particular `README_GENERATION`.
|
||||
|
||||
---
|
||||
|
||||
Thank you for taking the time to read this and to share your project (or any project).
|
||||
34
.agent/knowledge/awesome_claude/docs/COOLDOWN.md
Normal file
34
.agent/knowledge/awesome_claude/docs/COOLDOWN.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Cooldown Protocol
|
||||
|
||||
The following protocol exists to ensure fairness for all visitors that wish to be featured on the list, and to protect the repository from spam and other interactions which compromise the maintainer's ability to serve the needs of GitHub users.
|
||||
|
||||
## The GOLDEN Rule: Recommendations MUST be submitted by human beings using the Resource Recommendation Issue form template via the GitHub Web UI
|
||||
|
||||
Submissions that do not satisfy this very reasonable requirement violate the [CONRIBUTING](https://github.com/hesreallyhim/awesome-claude-code?tab=contributing-ov-file) guidelines and the corresponding [CODE_OF_CONDUCT](https://github.com/hesreallyhim/awesome-claude-code?tab=coc-ov-file). As maintainer, it is my [responsibility](https://github.com/hesreallyhim/awesome-claude-code?tab=coc-ov-file#enforcement-responsibilities) to make sure these guidelines are being upheld, and to do so in a way that reflects the [requirements](https://github.com/hesreallyhim/awesome-claude-code?tab=coc-ov-file#enforcement-guidelines) in the Code of Conduct.
|
||||
|
||||
The ones reading this are probably those least likely to be impacted by it. I'd like to thank everyone who supports this repository and makes a good-faith effort to contribute to it. If you believe that the automated processes that implement this protocol are unfairly or inaccurately affecting you, please leave a comment in the relevant issue (you don't need to re-open it), or contact the maintainer directly at awesome-conduct @ hesreallyhim.com
|
||||
|
||||
## Violations of The GOLDEN Rule
|
||||
|
||||
Violating "The GOLDEN Rule" will (a) cause the issue to be immediately closed; (b) initiate an automatically enforced "cooldown" policy for the account that created the issue. **Users are personally responsible for the activity of AI agents that they have instructed, or permitted, to act on their behalf.** This is something that is true in general, and is also a consequence of GitHub's policy regarding access tokens. Violations include:
|
||||
|
||||
* Submitting a resource recommendation without using the required Resource Recommendation issue template.
|
||||
* Submitting a resource via the `gh` CLI. Alas, the CLI does not presently supopport the creation of issues using issue templates, which carry the labels that are used to manage the processing of issues. If this happens to serve as a deterrent against bot submissions, I can't say I'm terribly despondent about that.
|
||||
* Although I have a lot of respect for some bots, only human beings are permitted to open issues in this repo. First of all, it's direspectful to Claude, who is supposed to be the star of the show; second of all, it is extremely obvious, and embarrassing.
|
||||
* You may not recommend a repo unless it is at least 7 days since the first public commit.
|
||||
|
||||
What happens if any of the above requirements are violated:
|
||||
|
||||
1st Time: 1-day cooldown period (no more posts during this time) \
|
||||
2nd Time: 2-day cooldown period \
|
||||
3rd TIme: 4-day cooldown period \
|
||||
4th Time: 8-day cooldown period \
|
||||
5th Time: 16-day cooldown period \
|
||||
5th Time: 32-day cooldown period \
|
||||
6th Time: Permanent Ban
|
||||
|
||||
**"Cooldown"** - no interactions with the respository during this time. It corresponds to a temporary ban such as described in the Code of Conduct, and reflects the seriousness of respecting the Community Guidelines and Contributing Guidelines of any repository whatsoever. The conditions I've laid out are not hard to comply with by anyone who has visited the repository and read the CONTRIBUTING doc, which is, as a matter of course, your obligation to do before enngaging with a repository. GitHub is a very nice place, where people are held to a somewhat higher standard, and it's my responsibility to follow the rules of conduct that I have set out.
|
||||
|
||||
Violating the cooldown protocol will result in a ban that is deemed appropriate given the circumstances.
|
||||
|
||||
I hope other visitors and developers will support this stance, and may have seen how disruptive it can be when basic standards of conduct are not met.
|
||||
11
.agent/knowledge/awesome_claude/docs/HOW_IT_LOOKS.md
Normal file
11
.agent/knowledge/awesome_claude/docs/HOW_IT_LOOKS.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# How It Looks (WIP)
|
||||
|
||||
Amazing, obviously. But there's more to it than pure visual stimulation - there's _numbers_ and... stuff.
|
||||
|
||||
## Why I Decided to Turn Awesome Claude Code into "90's MySpace Aesthetic"
|
||||
|
||||
Because it looks incredible, obviously.
|
||||
|
||||
**TODO:**
|
||||
|
||||
- [ ] Add to `.gitignore`
|
||||
331
.agent/knowledge/awesome_claude/docs/HOW_IT_WORKS.md
Normal file
331
.agent/knowledge/awesome_claude/docs/HOW_IT_WORKS.md
Normal file
@@ -0,0 +1,331 @@
|
||||
# How Awesome Claude Code Works
|
||||
|
||||
This document provides assorted technical details about the repository structure, automated systems, and processes that power Awesome Claude Code. It's mostly superceded by [README-GENERATION](./README-GENERATION.md), but, for one reason or another, it's still here, for now.
|
||||
|
||||
### GitHub Labels
|
||||
|
||||
The submission system uses several labels to track issue state:
|
||||
|
||||
#### Resource Submission Labels
|
||||
|
||||
- **`resource-submission`** - Applied automatically to issues created via the submission form
|
||||
- **`validation-passed`** - Applied when submission passes all validation checks
|
||||
- **`validation-failed`** - Applied when submission fails validation
|
||||
- **`approved`** - Applied when maintainer approves submission with `/approve`
|
||||
- **`pr-created`** - Applied after PR is successfully created
|
||||
- **`error-creating-pr`** - Applied if PR creation fails
|
||||
- **`rejected`** - Applied when maintainer rejects with `/reject`
|
||||
- **`changes-requested`** - Applied when maintainer requests changes with `/request-changes`
|
||||
|
||||
#### Other Labels
|
||||
|
||||
- **`broken-links`** - Applied by scheduled link validation when resources become unavailable
|
||||
- **`automated`** - Applied alongside `broken-links` to indicate automated detection
|
||||
- **`do-not-disturb`** - Apply to a resource PR before merging to skip the badge notification to the resource author's repository
|
||||
|
||||
#### Label State Transitions
|
||||
|
||||
1. New submission → `resource-submission`
|
||||
2. After validation → adds `validation-passed` OR `validation-failed`
|
||||
3. If changes requested → adds `changes-requested`
|
||||
4. When user edits and validation passes → removes `changes-requested`
|
||||
5. On approval → adds `approved` + `pr-created` (or `error-creating-pr`)
|
||||
6. On rejection → adds `rejected`
|
||||
|
||||
## The Submission Flow
|
||||
|
||||
### 1. User Submits Issue
|
||||
|
||||
When a user submits a resource via the issue form:
|
||||
|
||||
```yaml
|
||||
# .github/ISSUE_TEMPLATE/submit-resource.yml
|
||||
- Structured form with all required fields
|
||||
- Auto-labels with "resource-submission"
|
||||
- Validates input formats
|
||||
```
|
||||
|
||||
### 2. Automated Validation
|
||||
|
||||
The validation workflow triggers immediately:
|
||||
|
||||
```python
|
||||
# Simplified validation flow
|
||||
1. Parse issue body → extract form data
|
||||
2. Validate required fields
|
||||
3. Check URL accessibility
|
||||
4. Verify no duplicates exist
|
||||
5. Post results as comment
|
||||
6. Update issue labels
|
||||
```
|
||||
|
||||
**Validation includes:**
|
||||
- URL validation (200 OK response)
|
||||
- License detection from GitHub API
|
||||
- Duplicate checking against existing CSV
|
||||
- Field format validation
|
||||
|
||||
### 3. Maintainer Review
|
||||
|
||||
Once validation passes, maintainers can:
|
||||
|
||||
- `/approve` - Triggers PR creation
|
||||
- `/request-changes [reason]` - Asks for modifications
|
||||
- `/reject [reason]` - Closes the submission
|
||||
|
||||
**Notification System:**
|
||||
- When changes are requested, the maintainer is @-mentioned in the comment
|
||||
- When the user edits their issue, the maintainer receives a notification if:
|
||||
- It's the first edit after requesting changes
|
||||
- The validation status changes (pass→fail or fail→pass)
|
||||
- Multiple rapid edits won't spam the maintainer with notifications
|
||||
|
||||
### 4. Automated PR Creation
|
||||
|
||||
Upon approval:
|
||||
|
||||
```bash
|
||||
1. Checkout fresh main branch
|
||||
2. Create unique branch: add-resource/category/name-timestamp
|
||||
3. Add resource to CSV with generated ID
|
||||
4. Run generate_readme.py
|
||||
5. Commit changes
|
||||
6. Push branch
|
||||
7. Create PR via GitHub CLI
|
||||
8. Link back to original issue
|
||||
9. Close submission issue
|
||||
```
|
||||
|
||||
### 5. Final Steps
|
||||
|
||||
- Maintainer merges PR
|
||||
- Badge notification system runs (if enabled)
|
||||
- Submitter receives GitHub notifications
|
||||
|
||||
## Resource ID Generation
|
||||
|
||||
IDs follow the format: `{prefix}-{hash}`
|
||||
|
||||
```python
|
||||
prefixes = {
|
||||
"Agent Skills": "skill",
|
||||
"Slash-Commands": "cmd",
|
||||
"Workflows & Knowledge Guides": "wf",
|
||||
"Tooling": "tool",
|
||||
"CLAUDE.md Files": "claude",
|
||||
"Hooks": "hook",
|
||||
"Official Documentation": "doc",
|
||||
}
|
||||
|
||||
# Hash is first 8 chars of SHA256(display_name + primary_link)
|
||||
```
|
||||
|
||||
### Collapsible Sections
|
||||
|
||||
The generated README uses HTML `<details>` elements for improved navigation:
|
||||
- **Categories without subcategories**: Wrapped in `<details open>` (fully collapsible)
|
||||
- **Categories with subcategories**: Regular headers (subcategories are collapsible)
|
||||
- **All subcategories**: Wrapped in `<details open>` elements
|
||||
- **Table of Contents**: Collapsible with nested sections for categories with subcategories
|
||||
- All collapsible sections are open by default for easy browsing
|
||||
|
||||
**Design Note**: Initially attempted to make all categories collapsible with nested subcategories, but this caused anchor link navigation issues - links from the Table of Contents couldn't reach subcategories when their parent category was collapsed. The current design balances navigation functionality with collapsibility.
|
||||
|
||||
### GitHub Stats Integration
|
||||
|
||||
Each GitHub resource in the README automatically includes a collapsible statistics section:
|
||||
- **Automatic Detection**: The `parse_github_url` function from `validate_links.py` identifies GitHub repositories
|
||||
- **Stats Display**: Uses the GitHub Stats API to generate an SVG badge with repository metrics
|
||||
- **Collapsible Design**: Stats are hidden by default in a `<details>` element to keep the main list clean
|
||||
- **Universal Support**: Works with all GitHub URL formats (repository root, blob URLs, tree URLs, etc.)
|
||||
|
||||
Example output for a GitHub resource:
|
||||
```markdown
|
||||
[`resource-name`](https://github.com/owner/repo)
|
||||
Description of the resource
|
||||
|
||||
<details>
|
||||
<summary>📊 GitHub Stats</summary>
|
||||
<br>
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
```
|
||||
|
||||
## Alternative README Views
|
||||
|
||||
The repository offers multiple README styles to suit different preferences, all generated from the same CSV source of truth.
|
||||
|
||||
### Style Options
|
||||
|
||||
Users can switch between four presentation styles via navigation badges at the top of each page:
|
||||
|
||||
| Style | Description | Location |
|
||||
|-------|-------------|----------|
|
||||
| **Extra** | Visual/themed with SVG assets, collapsible sections, GitHub stats | `README_ALTERNATIVES/README_EXTRA.md` (and `README.md` when `root_style: extra`) |
|
||||
| **Classic** | Clean markdown, minimal styling, traditional awesome-list format | `README_ALTERNATIVES/README_CLASSIC.md` (and `README.md` when `root_style: classic`) |
|
||||
| **Awesome** | Clean awesome-list style with minimal embellishment | `README_ALTERNATIVES/README_AWESOME.md` (and `README.md` when `root_style: awesome`) |
|
||||
| **Flat** | Sortable/filterable table view with category filters | `README_ALTERNATIVES/README_FLAT_*.md` (and `README.md` when `root_style: flat`) |
|
||||
|
||||
### File Structure
|
||||
|
||||
Alternative views are in the `README_ALTERNATIVES/` folder to keep the root clean:
|
||||
|
||||
```
|
||||
README.md # Root README (root_style)
|
||||
README_ALTERNATIVES/
|
||||
├── README_EXTRA.md # Extra visual view
|
||||
├── README_CLASSIC.md # Classic markdown view
|
||||
├── README_AWESOME.md # Awesome list view
|
||||
├── README_FLAT_ALL_AZ.md # Flat: All resources, A-Z
|
||||
├── README_FLAT_ALL_UPDATED.md # Flat: All resources, by updated
|
||||
├── README_FLAT_ALL_CREATED.md # Flat: All resources, by created
|
||||
├── README_FLAT_ALL_RELEASES.md # Flat: All resources, recent releases
|
||||
├── README_FLAT_TOOLING_AZ.md # Flat: Tooling only, A-Z
|
||||
├── README_FLAT_HOOKS_UPDATED.md # Flat: Hooks only, by updated
|
||||
└── ... (44 flat views total: 11 categories × 4 sort types)
|
||||
```
|
||||
|
||||
### Flat List System
|
||||
|
||||
The flat view provides a searchable table with dual navigation:
|
||||
|
||||
#### Sort Options
|
||||
- **A-Z** - Alphabetical by resource name
|
||||
- **Updated** - By last modified date (most recent first)
|
||||
- **Created** - By repository creation date (newest first)
|
||||
- **Releases** - Resources with releases in past 30 days
|
||||
|
||||
#### Category Filters
|
||||
- **All** - All 164+ resources
|
||||
- **Tooling**, **Commands**, **CLAUDE.md**, **Workflows**, **Hooks**, **Skills**, **Styles**, **Status**, **Docs**, **Clients**
|
||||
|
||||
#### Table Format
|
||||
Resources are displayed with stacked name/author format to maximize description space:
|
||||
|
||||
```markdown
|
||||
| Resource | Category | Sub-Category | Description |
|
||||
|----------|----------|--------------|-------------|
|
||||
| [**Resource Name**](link)<br>by [Author](link) | Category | Sub-Cat | Full description... |
|
||||
```
|
||||
|
||||
### Release Detection
|
||||
|
||||
The "Releases" sort option shows resources with published releases in the past 30 days. Release information is fetched from GitHub Releases only.
|
||||
|
||||
### Generator Architecture
|
||||
|
||||
The `generate_readme.py` script uses generator classes under `scripts/readme/generators/`:
|
||||
|
||||
```python
|
||||
ReadmeGenerator (ABC)
|
||||
├── VisualReadmeGenerator # README_ALTERNATIVES/README_EXTRA.md
|
||||
├── MinimalReadmeGenerator # README_ALTERNATIVES/README_CLASSIC.md
|
||||
├── AwesomeReadmeGenerator # README_ALTERNATIVES/README_AWESOME.md
|
||||
└── ParameterizedFlatListGenerator # README_ALTERNATIVES/README_FLAT_*.md
|
||||
```
|
||||
|
||||
The `ParameterizedFlatListGenerator` takes `category_slug` and `sort_type` parameters, enabling generation of all 44 combinations from a single class. The configured `root_style` is additionally generated as `README.md`.
|
||||
|
||||
### Navigation Badges
|
||||
|
||||
SVG badges are generated dynamically in `assets/`:
|
||||
- `badge-style-*.svg` - Style selector (Extra, Classic, Awesome, Flat)
|
||||
- `badge-sort-*.svg` - Sort options (A-Z, Updated, Created, Releases)
|
||||
- `badge-cat-*.svg` - Category filters (All, Tooling, Hooks, etc.)
|
||||
|
||||
Current selections are highlighted with colored borders matching each badge's theme color.
|
||||
|
||||
### Adding/Removing Flat List Categories
|
||||
|
||||
To add a new category filter to flat list views:
|
||||
|
||||
1. **Update `FLAT_CATEGORIES`** in `scripts/readme/generators/flat.py`:
|
||||
```python
|
||||
FLAT_CATEGORIES = {
|
||||
# ... existing categories ...
|
||||
"new-category": ("CSV Category Value", "Display Name", "#hexcolor"),
|
||||
}
|
||||
```
|
||||
- First value: Exact match for the `Category` column in CSV (or `None` for "all")
|
||||
- Second value: Display name shown on badge
|
||||
- Third value: Hex color for badge accent and selection border
|
||||
|
||||
2. **Regenerate READMEs**: Run `python scripts/readme/generate_readme.py`
|
||||
- Creates new files: `README_ALTERNATIVES/README_FLAT_NEWCATEGORY_*.md`
|
||||
- Generates badge: `assets/badge-cat-new-category.svg`
|
||||
- Updates navigation in all 44+ flat views
|
||||
|
||||
To remove a category: Delete its entry from `FLAT_CATEGORIES` and run the generator. Manually delete the orphaned `.md` files from `README_ALTERNATIVES/`.
|
||||
|
||||
### Adding/Removing Sort Types
|
||||
|
||||
To add a new sort option:
|
||||
|
||||
1. **Update `FLAT_SORT_TYPES`** in `scripts/readme/generators/flat.py`:
|
||||
```python
|
||||
FLAT_SORT_TYPES = {
|
||||
# ... existing sorts ...
|
||||
"newsort": ("DISPLAY", "#hexcolor", "description for status text"),
|
||||
}
|
||||
```
|
||||
|
||||
2. **Implement sorting logic** in `ParameterizedFlatListGenerator.sort_resources()`:
|
||||
```python
|
||||
elif self.sort_type == "newsort":
|
||||
# Custom sorting logic
|
||||
return sorted(resources, key=lambda x: ...)
|
||||
```
|
||||
|
||||
3. **Regenerate READMEs**: Creates new views for all categories × new sort type.
|
||||
|
||||
### Adding/Removing README Styles
|
||||
|
||||
The main README styles are defined as generator classes:
|
||||
|
||||
| Style | Generator Class | Template | Output |
|
||||
|-------|----------------|----------|--------|
|
||||
| Extra | `VisualReadmeGenerator` | `README_EXTRA.template.md` | `README_ALTERNATIVES/README_EXTRA.md` |
|
||||
| Classic | `MinimalReadmeGenerator` | `README_CLASSIC.template.md` | `README_ALTERNATIVES/README_CLASSIC.md` |
|
||||
| Awesome | `AwesomeReadmeGenerator` | `README_AWESOME.template.md` | `README_ALTERNATIVES/README_AWESOME.md` |
|
||||
| Flat | `ParameterizedFlatListGenerator` | (built-in) | `README_ALTERNATIVES/README_FLAT_*.md` |
|
||||
|
||||
The configured `root_style` is additionally written to `README.md`.
|
||||
|
||||
**To add a new README style:**
|
||||
|
||||
1. **Create a generator class** extending `ReadmeGenerator` under `scripts/readme/generators/`:
|
||||
```python
|
||||
class NewStyleReadmeGenerator(ReadmeGenerator):
|
||||
@property
|
||||
def template_filename(self) -> str:
|
||||
return "README_NEWSTYLE.template.md"
|
||||
|
||||
@property
|
||||
def output_filename(self) -> str:
|
||||
return "README_ALTERNATIVES/README_NEWSTYLE.md"
|
||||
|
||||
# Implement abstract methods...
|
||||
```
|
||||
|
||||
2. **Create template** in `templates/README_NEWSTYLE.template.md` (include `{{STYLE_SELECTOR}}`).
|
||||
|
||||
3. **Register the generator** in `STYLE_GENERATORS` inside `scripts/readme/generate_readme.py`.
|
||||
|
||||
4. **Create style badge** `assets/badge-style-newstyle.svg`.
|
||||
|
||||
5. **Update config** in `acc-config.yaml`:
|
||||
- add a new entry under `styles:`
|
||||
- append the style ID to `style_order:`
|
||||
|
||||
**To remove a style:** Delete the generator class, template, badge asset, and config entry, then remove the style from `STYLE_GENERATORS` and `style_order`.
|
||||
|
||||
### Announcements System
|
||||
|
||||
Announcements are stored in `templates/announcements.yaml`:
|
||||
- YAML format for structured data
|
||||
- Renders as nested collapsible sections
|
||||
- Each date group is collapsible
|
||||
- Individual items can be simple text or collapsible with summary/text
|
||||
- Falls back to `.md` file if YAML doesn't exist
|
||||
615
.agent/knowledge/awesome_claude/docs/README-GENERATION.md
Normal file
615
.agent/knowledge/awesome_claude/docs/README-GENERATION.md
Normal file
@@ -0,0 +1,615 @@
|
||||
# README Generation & Asset Management
|
||||
|
||||
This document explains how the README and its visual assets are generated and maintained. It's mostly a reference document for development purposes, written and maintained by the coding agents who write most of the code, with some commentary sprinkled in.
|
||||
|
||||
## Overview
|
||||
|
||||
The repository implements a "multi-list" pattern, with one centralized "list" (which is effectively a kind of backend) and numerous "views" that are strictly generated from the central data source. In that sense, it's maybe the only "full-stack" Awesome list on GitHub - maybe that's a sign that it's a silly thing to do, but I figured if I was going to spend so much time maintaining a list, I had better do something interesting with it. To my knowledge, it's one of the few "full-stack applications" that's entirely hosted on GitHub.com (i.e. not a GitHub Pages site). (Yes, there are others. And yes, calling this an "application" is obviously a little bit of a stretch.)
|
||||
|
||||
- **`THE_RESOURCES_TABLE.csv`** - The master data file containing all resources (repo root)
|
||||
- **`acc-config.yaml`** - Global configuration (root style, style selector settings)
|
||||
- **`templates/categories.yaml`** - Category and subcategory definitions
|
||||
- **`scripts/readme/generate_readme.py`** - The generator script (class-based architecture)
|
||||
- **`scripts/readme/helpers/readme_config.py`** - Config loader and style path helpers
|
||||
- **`scripts/readme/helpers/readme_utils.py`** - Shared parsing/anchor utilities
|
||||
- **`scripts/readme/helpers/readme_assets.py`** - SVG asset writers (badges, TOC rows, headers)
|
||||
- **`scripts/readme/markup/`** - Markdown/HTML renderers by style
|
||||
- **`scripts/readme/svg_templates/`** - SVG renderers used by the generator
|
||||
- **`assets/`** - SVG visual assets (badges, headers, dividers, etc.)
|
||||
|
||||
The multi-list is maintained via a single source of truth, combined with generators that take templates (which implement the various styles), and generate all the READMEs. The complexity is mostly self-inflicted, and is an artefact of platform-specific features of GitHub.
|
||||
|
||||
### Generated README Styles
|
||||
|
||||
| Style | Primary Output | Template | Description |
|
||||
|-------|-------------|----------|-------------|
|
||||
| Extra (Visual) | `README_ALTERNATIVES/README_EXTRA.md` | `README_EXTRA.template.md` | Full visual theme with SVG badges, CRT-style TOC |
|
||||
| Classic | `README_ALTERNATIVES/README_CLASSIC.md` | `README_CLASSIC.template.md` | Plain markdown with collapsible sections |
|
||||
| Awesome | `README_ALTERNATIVES/README_AWESOME.md` | `README_AWESOME.template.md` | Clean awesome-list style |
|
||||
| Flat | `README_ALTERNATIVES/README_FLAT_*.md` | Built-in template (optional `templates/README_FLAT.template.md`) | 44 table views (category × sort combinations) |
|
||||
|
||||
All styles are always generated under `README_ALTERNATIVES/`. The `root_style` is additionally written to `README.md`.
|
||||
|
||||
#### Etymology
|
||||
|
||||
- **Classic:** The style of the list as it was initially maintained and iterated upon, before the "multi-list" pattern was adopted.
|
||||
- ***Extra:*** Heightened visual style, consisting almost entirely of SVG assets - "extra" does not mean "additional", it means _extra_.
|
||||
- **Flat:** Lacks internal structure or visual hierarchy; the "flat" views are basically just a dump of the CSV data with shields.io badges - information-dense and straightforward. This was implemented due to a single user's request, but it became a more interesting problem when the user asked for dynamic table features like sorting and filtering. This is "not possible" with Markdown, which is why I decided to do it - since you can't have any JavaScript on a README, the sorting and filtering functionality is simulated by generating every permutation of Sort x Filter as a separate file, and so the table operations become navigation.
|
||||
- **Awesome:** The style that is more or less compliant with the Awesome List style guide.
|
||||
|
||||
Generation runs in two phases:
|
||||
1. Generate all styles under `README_ALTERNATIVES/`.
|
||||
2. Generate `README.md` using the configured `root_style`.
|
||||
|
||||
If everything lived at the repo root, this would be a very easy thing to build, but then the user would have to scroll a lot before they even hit the first `h1`. So the whole complexity is due to the necessity of supporting multiple generated README files at two different paths. I'm not even sure if many people enjoy the "Flat" view, and without the 44 permutations, it probably wouldn't be a big deal at all to just put everything at the root... Hm. Nevertheless, I'm grateful to that user for giving me the opportunity to learn some new things, and to build this ridiculous Titanic just to host a list, and I hope the "curiosity" of it compensates for any aesthetic crimes that I've committed in building it.
|
||||
|
||||
## Configuration (`acc-config.yaml`)
|
||||
|
||||
The `acc-config.yaml` file at the repository root controls global README generation settings.
|
||||
|
||||
### Root Style
|
||||
|
||||
The `readme.root_style` setting determines which README style is additionally written to the repo root (`README.md`). All styles are always generated in `README_ALTERNATIVES/`.
|
||||
|
||||
```yaml
|
||||
readme:
|
||||
root_style: extra # Options: extra, classic, awesome, flat
|
||||
```
|
||||
|
||||
Changing this value and regenerating will:
|
||||
- Write the new root style to `README.md`
|
||||
- Keep all styles (including the root) in `README_ALTERNATIVES/`
|
||||
- Update the style selector links to reflect which style is root
|
||||
|
||||
### Style Selector Configuration
|
||||
|
||||
The `styles` section defines each README style's metadata for the style selector:
|
||||
|
||||
```yaml
|
||||
styles:
|
||||
extra:
|
||||
name: Extra # Display name for badge alt text
|
||||
badge: badge-style-extra.svg # Badge filename in assets/
|
||||
highlight_color: "#6a6a8a" # Border color when selected
|
||||
filename: README_EXTRA.md
|
||||
|
||||
classic:
|
||||
name: Classic
|
||||
badge: badge-style-classic.svg
|
||||
highlight_color: "#c9a227"
|
||||
filename: README_CLASSIC.md
|
||||
# ... other styles
|
||||
```
|
||||
|
||||
`filename` is the README variant filename under `README_ALTERNATIVES/` used for selector links and references.
|
||||
|
||||
The `style_order` list controls the left-to-right order of badges in the selector:
|
||||
|
||||
```yaml
|
||||
style_order:
|
||||
- extra
|
||||
- classic
|
||||
- flat
|
||||
- awesome
|
||||
```
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Task | Automated? | What to do |
|
||||
|------|------------|------------|
|
||||
| Add a new resource | Yes | Add row to CSV, run `make generate` |
|
||||
| Add a new category | Yes | Use `make add-category` or edit `categories.yaml` |
|
||||
| Add a new subcategory | Yes | Edit `categories.yaml`, run `make generate-toc-assets`, run generator |
|
||||
| Update resource info | Yes | Edit CSV, run `make generate` |
|
||||
| Customize asset style | Manual | Edit generator templates or asset files |
|
||||
|
||||
## Backups (README Outputs)
|
||||
|
||||
The README generators create a backup of the existing output file before overwriting it.
|
||||
|
||||
- Location: `.myob/backups/` at repo root
|
||||
- Naming: `{basename}.{YYYYMMDD_HHMMSS}.bak` (e.g., `README.md.20250105_154233.bak`)
|
||||
- Behavior: only created when the target file already exists
|
||||
- Coverage: applies to README outputs written by `scripts/readme/generate_readme.py`
|
||||
- Retention: keeps the most recent backup per output file; older backups are pruned
|
||||
|
||||
## Adding a New Resource
|
||||
|
||||
This process is now handled entirely by GitHub workflows. Due to the intricate, not-at-all-over-engineered design ~~mistakes~~ choices, having people submit PRs became unmanageable. Instead, all of the data that goes into a resource entry is processed as a "form" using GitHub's Issue form templates. That makes the shape of an Issue predictable, and the different fields are machine-readable. Since the resources table is the single source of truth for the list entries, the goal is just to get the necessary data points into the CSV, and everything else is controlled by the template/generator system. This eliminated any problems around merge conflicts, stale resource PRs, etc. (Trying to fix merge conflicts in a CSV file is not a good way to spend an afternoon.) The _state_ of resource recommendation Issues is managed by (i) labels (`pending-validation`, `validation-passed`, `approved`, etc.), which indicate the current state; (ii) "slash commands" (`/approve`, `/request-changes`, etc.), which trigger a workflow that transitions the state (if they're written by the maintainer). This is a simplified piecture of what the GitHub bot does once a resource is approved:
|
||||
|
||||
1. **Edit `THE_RESOURCES_TABLE.csv`** - Add a new row with these columns:
|
||||
- `Display Name` - The resource name shown in the README
|
||||
- `Primary Link` - URL to the resource (usually GitHub)
|
||||
- `Author Name` - Creator's name (optional but recommended)
|
||||
- `Author Link` - URL to author's profile
|
||||
- `Description` - Brief description of the resource
|
||||
- `Category` - Must match a category name in `categories.yaml`
|
||||
- `Sub-Category` - Must match a subcategory in `categories.yaml`
|
||||
- `Active` - Set to `TRUE` to include in README
|
||||
- `Removed From Origin` - Set to `TRUE` if the original repo/resource was deleted
|
||||
|
||||
The reason for the last field is due to the fact that (i) well, it's good to know if you're sharing a link that's dead; (ii) for a while, I was maintaing copies of the third-party authors' resources on the list (when it was licensed in a way that allowed me to do that), but that was when the resource were usually a bit of plaintext. Most entries are full repositories, and re-hosting entire repositories is out of scope. That directory is still present, but it's not currently maintained, and may become deprecated.
|
||||
|
||||
2. **Run the generator:**
|
||||
```bash
|
||||
make generate
|
||||
# or directly:
|
||||
python3 scripts/readme/generate_readme.py
|
||||
```
|
||||
|
||||
3. **What gets auto-generated:**
|
||||
- `assets/badge-{resource-name}.svg` - Theme-adaptive badge with initials box
|
||||
- Entry in all README styles
|
||||
|
||||
## Adding a New Category
|
||||
|
||||
1. **Use the interactive tool:**
|
||||
```bash
|
||||
make add-category
|
||||
# or with arguments:
|
||||
make add-category ARGS='--name "My Category" --prefix mycat --icon "🎯"'
|
||||
```
|
||||
|
||||
Note: `make add-category` uses `scripts/categories/add_category.py` (experimental). It rewrites
|
||||
`templates/categories.yaml` via PyYAML and updates `.github/ISSUE_TEMPLATE/recommend-resource.yml`,
|
||||
so review the diff after running it.
|
||||
|
||||
2. **Or manually edit `templates/categories.yaml`:**
|
||||
```yaml
|
||||
categories:
|
||||
- id: my-category
|
||||
name: My Category
|
||||
icon: "🎯"
|
||||
description: Description of this category
|
||||
order: 10
|
||||
subcategories:
|
||||
- id: general
|
||||
name: General
|
||||
```
|
||||
|
||||
3. **Run the generator:**
|
||||
```bash
|
||||
make generate
|
||||
```
|
||||
|
||||
4. **What gets auto-generated:**
|
||||
- `assets/header_{category}.svg` - Dark mode category header (CRT style)
|
||||
- `assets/header_{category}-light-v3.svg` - Light mode category header
|
||||
- `assets/subheader_{subcat}.svg` - Subcategory header (when resources exist)
|
||||
- Section in all README styles
|
||||
|
||||
5. **Regenerate subcategory TOC SVGs** (if subcategories were added):
|
||||
```bash
|
||||
make generate-toc-assets
|
||||
```
|
||||
This creates/updates `assets/toc-sub-{subcat}.svg` and `assets/toc-sub-{subcat}-light-anim-scanline.svg` files for all subcategories.
|
||||
|
||||
6. **What needs manual creation:**
|
||||
- `assets/toc-row-{category}.svg` and `assets/toc-row-{category}-light-anim-scanline.svg` - TOC row assets (category-level)
|
||||
- Card assets if using the EXTRA style navigation grid
|
||||
|
||||
## Adding a New Subcategory
|
||||
|
||||
Subcategories can be added to any category.
|
||||
|
||||
1. **Edit `templates/categories.yaml`:**
|
||||
```yaml
|
||||
categories:
|
||||
- id: tooling
|
||||
name: Tooling
|
||||
subcategories:
|
||||
- id: general
|
||||
name: General
|
||||
- id: my-new-subcat # Add new subcategory
|
||||
name: My New Subcat
|
||||
```
|
||||
|
||||
2. **Regenerate subcategory TOC SVGs:**
|
||||
```bash
|
||||
make generate-toc-assets
|
||||
```
|
||||
This creates/updates the `toc-sub-*.svg` and `toc-sub-*-light-anim-scanline.svg` files in `assets/` for all subcategories.
|
||||
|
||||
3. **Run the generator** - Subcategory headers are auto-generated alongside the README content
|
||||
|
||||
## If You Change Category IDs or Names
|
||||
|
||||
Update these locations:
|
||||
1. `templates/categories.yaml` - Category definitions
|
||||
2. Card-grid anchors in `templates/README_EXTRA.template.md` (they use trailing `-` anchors)
|
||||
3. Any static assets that embed text (for example, card SVGs)
|
||||
|
||||
## Adding a New README Style
|
||||
|
||||
1. Create a template file in `templates/` (for example, `README_NEWSTYLE.template.md`)
|
||||
2. Add a generator class extending `ReadmeGenerator` under `scripts/readme/generators/`
|
||||
3. Register the class in `STYLE_GENERATORS` in `scripts/readme/generate_readme.py`
|
||||
4. Create a style selector badge in `assets/badge-style-newstyle.svg`
|
||||
5. Add the style to `acc-config.yaml`:
|
||||
- Add an entry under `styles:` with name, badge, highlight_color, filename
|
||||
- Add the style ID to `style_order:`
|
||||
6. Ensure your template includes `{{STYLE_SELECTOR}}`
|
||||
|
||||
## Generator Architecture
|
||||
|
||||
The generator uses a class-based architecture with the Template Method pattern.
|
||||
Generator classes live under `scripts/readme/generators/` and are wired in
|
||||
`scripts/readme/generate_readme.py`:
|
||||
|
||||
```
|
||||
ReadmeGenerator (ABC)
|
||||
├── VisualReadmeGenerator → README_ALTERNATIVES/README_EXTRA.md
|
||||
├── MinimalReadmeGenerator → README_ALTERNATIVES/README_CLASSIC.md
|
||||
├── AwesomeReadmeGenerator → README_ALTERNATIVES/README_AWESOME.md
|
||||
└── ParameterizedFlatListGenerator → README_ALTERNATIVES/README_FLAT_*.md (44 files)
|
||||
|
||||
The `root_style` also gets an additional copy written to `README.md`.
|
||||
```
|
||||
|
||||
### Category Management
|
||||
|
||||
Categories can be managed via `scripts/categories/category_utils.py` (experimental):
|
||||
|
||||
```python
|
||||
from scripts.categories.category_utils import category_manager
|
||||
|
||||
# Get all categories
|
||||
categories = category_manager.get_categories_for_readme()
|
||||
|
||||
# Get category by name
|
||||
cat = category_manager.get_category_by_name("Tooling")
|
||||
```
|
||||
|
||||
### Template Placeholders
|
||||
|
||||
Templates use `{{PLACEHOLDER}}` syntax for dynamic content. Key placeholders:
|
||||
|
||||
| Placeholder | Description | Generator Method |
|
||||
|-------------|-------------|------------------|
|
||||
| `{{ASSET_PATH('file.svg')}}` | Tokenized asset path resolved per output location | `resolve_asset_tokens()` |
|
||||
| `{{STYLE_SELECTOR}}` | "Pick Your Style" badge row linking to all README variants | `get_style_selector()` |
|
||||
| `{{REPO_TICKER}}` | Animated SVG ticker showing featured projects | `generate_repo_ticker()` |
|
||||
| `{{ANNOUNCEMENTS}}` | Latest announcements from `templates/announcements.yaml` | `load_announcements()` |
|
||||
| `{{WEEKLY_SECTION}}` | Latest additions section | `generate_weekly_section()` |
|
||||
| `{{TABLE_OF_CONTENTS}}` | Table of contents | `generate_toc()` |
|
||||
| `{{BODY_SECTIONS}}` | Main resource listings | `generate_section_content()` |
|
||||
| `{{FOOTER}}` | Footer template content | `load_footer()` |
|
||||
|
||||
Template content outside these placeholders is treated as manual copy and is not regenerated.
|
||||
|
||||
Asset references use token placeholders (e.g. `{{ASSET_PATH('logo.svg')}}`) that are resolved after templating based on the destination README path. Resolution walks upward to the repo root (`pyproject.toml`) and computes a relative path to `/assets` for each output file.
|
||||
|
||||
Generated outputs are prefixed with `<!-- GENERATED FILE: do not edit directly -->` as a reminder that edits belong in templates and source data.
|
||||
|
||||
## Repo Ticker System
|
||||
|
||||
The repo ticker displays an animated scrolling banner of featured Claude Code projects with live GitHub stats.
|
||||
|
||||
### Components
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `scripts/ticker/fetch_repo_ticker_data.py` | Fetches GitHub stats for tracked repos |
|
||||
| `scripts/ticker/generate_ticker_svg.py` | Generates animated SVG tickers |
|
||||
| `data/repo-ticker.csv` | Current repo stats (stars, forks, deltas) |
|
||||
| `data/repo-ticker-previous.csv` | Previous stats for delta calculation |
|
||||
|
||||
### Generated Tickers
|
||||
|
||||
| Theme | Output File | Used By |
|
||||
|-------|-------------|---------|
|
||||
| Dark (CRT) | `assets/repo-ticker.svg` | Extra style (dark mode) |
|
||||
| Light (Vintage) | `assets/repo-ticker-light.svg` | Extra style (light mode) |
|
||||
| Awesome | `assets/repo-ticker-awesome.svg` | Awesome style |
|
||||
|
||||
### Ticker Generation
|
||||
|
||||
```bash
|
||||
# Fetch latest repo stats (requires GITHUB_TOKEN)
|
||||
python scripts/ticker/fetch_repo_ticker_data.py
|
||||
|
||||
# Generate ticker SVGs from current data
|
||||
python scripts/ticker/generate_ticker_svg.py
|
||||
```
|
||||
|
||||
The tickers:
|
||||
- Sample 10 random repos from the CSV
|
||||
- Display repo name, owner, stars, and daily delta
|
||||
- Animate with seamless horizontal scrolling
|
||||
- Use theme-appropriate styling (CRT glow for dark, muted colors for awesome)
|
||||
|
||||
## Asset Types
|
||||
|
||||
### Auto-Generated Assets
|
||||
|
||||
| Asset | Filename Pattern | Generator Function |
|
||||
|-------|------------------|-------------------|
|
||||
| Resource badges | `badge-{name}.svg` | `scripts/readme/svg_templates/badges.py:generate_resource_badge_svg()` |
|
||||
| Entry separators | `entry-separator-light-animated.svg` | `scripts/readme/svg_templates/dividers.py:generate_entry_separator_svg()` |
|
||||
| Category headers (dark/light) | `header_{cat}.svg`, `header_{cat}-light-v3.svg` | `scripts/readme/helpers/readme_assets.py:ensure_category_header_exists()` |
|
||||
| Subcategory headers | `subheader_{subcat}.svg` | `scripts/readme/helpers/readme_assets.py:create_h3_svg_file()` |
|
||||
| Section dividers (light) | `section-divider-light-manual-v{1,2,3}.svg` | `scripts/readme/svg_templates/dividers.py:generate_section_divider_light_svg()` |
|
||||
| Desc boxes (light) | `desc-box-{top,bottom}-light.svg` | `scripts/readme/svg_templates/dividers.py:generate_desc_box_light_svg()` |
|
||||
| Sort badges | `badge-sort-{type}.svg` | `scripts/readme/helpers/readme_assets.py:generate_flat_badges()` |
|
||||
| Category filter badges | `badge-cat-{slug}.svg` | `scripts/readme/helpers/readme_assets.py:generate_flat_badges()` |
|
||||
| Repo tickers | `repo-ticker*.svg` | `generate_ticker_svg()` / `generate_awesome_ticker_svg()` |
|
||||
| Subcategory TOC rows | `toc-sub-{subcat}.svg`, `toc-sub-{subcat}-light-anim-scanline.svg` | `scripts/readme/helpers/readme_assets.py:regenerate_sub_toc_svgs()` via `make generate-toc-assets` |
|
||||
| Style selector badges | `badge-style-{style}.svg` | Manual |
|
||||
|
||||
### Pre-Made Assets (Manual)
|
||||
|
||||
| Asset | Purpose |
|
||||
|-------|---------|
|
||||
| `section-divider-alt2.svg` | Dark mode section divider |
|
||||
| `desc-box-{top,bottom}.svg` | Dark mode description boxes |
|
||||
| `toc-row-*.svg` | Category-level TOC row assets (light variants use `-light-anim-scanline`) |
|
||||
| `toc-header*.svg` | TOC header assets (light variants use `-light-anim-scanline`) |
|
||||
| `card-*.svg` | Terminal Navigation grid cards |
|
||||
| `badge-style-*.svg` | Style selector badges |
|
||||
| Hero banners, logos | Top-of-README branding |
|
||||
|
||||
## Visual Styles
|
||||
|
||||
### Light Mode: "Vintage Technical Manual"
|
||||
- Muted brown/sepia tones (`#5c5247`, `#3d3530`)
|
||||
- Coral accent (`#c96442`)
|
||||
- "Layered drafts" effect - doubled lines, ghost shadows
|
||||
- L-shaped corner brackets
|
||||
- Tick marks and circle clusters
|
||||
|
||||
### Dark Mode: "CRT Terminal"
|
||||
- Green phosphor colors (`#33ff33`, `#66ff66`)
|
||||
- Scanline overlay effect
|
||||
- Subtle glow filter
|
||||
- Monospace fonts
|
||||
- Animated flicker effects
|
||||
|
||||
## Generator Functions
|
||||
|
||||
Key SVG renderers in `scripts/readme/svg_templates/`:
|
||||
|
||||
```python
|
||||
# Badge for each resource entry
|
||||
generate_resource_badge_svg(display_name, author_name)
|
||||
|
||||
# Category section header
|
||||
generate_category_header_light_svg(title, section_number)
|
||||
|
||||
# Horizontal dividers between sections
|
||||
generate_section_divider_light_svg(variant) # 1, 2, or 3
|
||||
|
||||
# Description box frames
|
||||
generate_desc_box_light_svg(position) # "top" or "bottom"
|
||||
|
||||
# TOC directory listing rows
|
||||
generate_toc_row_svg(directory_name, description)
|
||||
generate_toc_row_light_svg(directory_name, description)
|
||||
generate_toc_sub_svg(directory_name, description)
|
||||
```
|
||||
|
||||
Key markup helpers in `scripts/readme/markup/`:
|
||||
|
||||
```python
|
||||
# Style selector (dynamically generated)
|
||||
generate_style_selector(current_style, output_path, repo_root=None)
|
||||
```
|
||||
|
||||
Key asset writers in `scripts/readme/helpers/readme_assets.py`:
|
||||
|
||||
```python
|
||||
# Flat list badges (writes SVGs using scripts/readme/svg_templates/badges.py)
|
||||
generate_flat_badges(assets_dir, sort_types, categories)
|
||||
|
||||
# Regenerate subcategory TOC SVGs for the Visual (Extra) style
|
||||
regenerate_sub_toc_svgs(categories, assets_dir)
|
||||
```
|
||||
|
||||
Standalone TOC asset script (`scripts/readme/helpers/generate_toc_assets.py`):
|
||||
|
||||
```bash
|
||||
# Regenerate subcategory TOC SVGs from categories.yaml
|
||||
make generate-toc-assets
|
||||
# or directly:
|
||||
python -m scripts.readme.helpers.generate_toc_assets
|
||||
```
|
||||
|
||||
Key functions in `scripts/ticker/generate_ticker_svg.py`:
|
||||
|
||||
```python
|
||||
# Standard ticker (dark/light themes)
|
||||
generate_ticker_svg(repos, theme="dark") # or "light"
|
||||
|
||||
# Awesome-style ticker (clean, minimal)
|
||||
generate_awesome_ticker_svg(repos)
|
||||
```
|
||||
|
||||
## Animated Elements
|
||||
|
||||
### Entry Separator (`entry-separator-light-animated.svg`)
|
||||
- Pulsating dots that ripple outward then contract back in
|
||||
- 3 core dots always visible
|
||||
- 9 rings of dots animate with staggered timing
|
||||
- 2.5 second cycle
|
||||
|
||||
### TOC Rows
|
||||
- Subtle opacity flicker on directory names
|
||||
- Hover highlight pulse animation
|
||||
|
||||
## File Structure
|
||||
|
||||
This tree is auto-generated from `tools/readme_tree/config.yaml` (update with `make docs-tree`).
|
||||
|
||||
<!-- TREE:START -->
|
||||
```
|
||||
awesome-claude-code//
|
||||
├── THE_RESOURCES_TABLE.csv # Master data file
|
||||
├── acc-config.yaml # Root style + selector config
|
||||
├── README.md # Generated root README (root_style)
|
||||
├── README_ALTERNATIVES/ # All generated README variants
|
||||
│ ├── README_EXTRA.md # Generated (Extra style, always)
|
||||
│ ├── README_CLASSIC.md # Generated (Classic style)
|
||||
│ ├── README_AWESOME.md # Generated (Awesome list style)
|
||||
│ └── README_FLAT_*.md # Generated (44 flat list views)
|
||||
├── templates/ # README templates and supporting YAML
|
||||
│ ├── categories.yaml # Category definitions
|
||||
│ ├── announcements.yaml # Announcements content
|
||||
│ ├── README_EXTRA.template.md # Extra style template
|
||||
│ ├── README_CLASSIC.template.md # Classic style template
|
||||
│ ├── README_AWESOME.template.md # Awesome style template
|
||||
│ ├── footer.template.md # Shared footer
|
||||
│ └── resource-overrides.yaml # Manual resource overrides
|
||||
├── scripts/
|
||||
│ ├── readme/ # README generation pipeline
|
||||
│ │ ├── generate_readme.py # Generator entrypoint
|
||||
│ │ ├── generators/ # README generator classes by style
|
||||
│ │ │ ├── base.py # ReadmeGenerator base + shared helpers
|
||||
│ │ │ ├── visual.py # Extra (visual) README generator
|
||||
│ │ │ ├── minimal.py # Classic README generator
|
||||
│ │ │ ├── awesome.py # Awesome list README generator
|
||||
│ │ │ └── flat.py # Flat list README generator
|
||||
│ │ ├── helpers/ # Config/utils/assets helpers for README generation
|
||||
│ │ │ ├── readme_assets.py
|
||||
│ │ │ ├── readme_config.py
|
||||
│ │ │ ├── readme_utils.py
|
||||
│ │ │ ├── generate_toc_assets.py
|
||||
│ │ │ └── readme_paths.py
|
||||
│ │ ├── markup/ # Markdown/HTML renderers by style
|
||||
│ │ │ ├── awesome.py
|
||||
│ │ │ ├── flat.py
|
||||
│ │ │ ├── minimal.py
|
||||
│ │ │ ├── shared.py
|
||||
│ │ │ └── visual.py
|
||||
│ │ └── svg_templates/ # SVG renderers used by the generator
|
||||
│ │ ├── badges.py
|
||||
│ │ ├── dividers.py
|
||||
│ │ ├── headers.py
|
||||
│ │ └── toc.py
|
||||
│ ├── ticker/ # Repo ticker generation scripts
|
||||
│ │ ├── generate_ticker_svg.py # Repo ticker SVG generator
|
||||
│ │ └── fetch_repo_ticker_data.py # GitHub stats fetcher
|
||||
│ ├── categories/ # Category management scripts
|
||||
│ │ ├── category_utils.py # Category management
|
||||
│ │ └── add_category.py # Category addition tool
|
||||
│ └── resources/ # Resource maintenance scripts
|
||||
│ ├── sort_resources.py # CSV sorting (used by generator)
|
||||
│ ├── resource_utils.py # CSV append + PR content helpers
|
||||
│ ├── create_resource_pr.py
|
||||
│ ├── detect_informal_submission.py
|
||||
│ ├── download_resources.py
|
||||
│ └── parse_issue_form.py
|
||||
├── assets/ # SVG badges, headers, dividers
|
||||
│ ├── badge-*.svg # Resource badges (auto-generated)
|
||||
│ ├── header_*.svg # Category headers
|
||||
│ ├── section-divider-*.svg # Section dividers
|
||||
│ ├── desc-box-*.svg # Description boxes
|
||||
│ ├── toc-*.svg # TOC elements
|
||||
│ ├── subheader_*.svg # Subcategory headers
|
||||
│ ├── badge-sort-*.svg # Flat list sort badges
|
||||
│ ├── badge-cat-*.svg # Flat list category badges
|
||||
│ ├── badge-style-*.svg # Style selector badges
|
||||
│ ├── repo-ticker*.svg # Animated repo tickers
|
||||
│ └── entry-separator-*.svg # Entry separators
|
||||
├── data/ # Generated ticker data
|
||||
│ ├── repo-ticker.csv # Current repository stats
|
||||
│ └── repo-ticker-previous.csv # Previous stats (for deltas)
|
||||
└── docs/
|
||||
└── README-GENERATION.md # This file
|
||||
```
|
||||
<!-- TREE:END -->
|
||||
|
||||
## Makefile Commands
|
||||
|
||||
```bash
|
||||
make generate # Generate all READMEs (sorts CSV first)
|
||||
make generate-toc-assets # Regenerate subcategory TOC SVGs (after adding subcategories)
|
||||
make add-category # Interactive category addition
|
||||
make sort # Sort resources in CSV
|
||||
make validate # Validate all resource links
|
||||
make docs-tree # Update README-GENERATION tree block
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Purpose |
|
||||
|----------|---------|
|
||||
| `GITHUB_TOKEN` | Avoid GitHub API rate limiting during validation |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Badge not appearing
|
||||
- Check the resource name doesn't have special characters that break filenames
|
||||
- Verify the CSV row has all required columns
|
||||
- Ensure `Active` is set to `TRUE`
|
||||
|
||||
### New category not showing
|
||||
- Ensure category is added to `templates/categories.yaml`
|
||||
- Check for typos between CSV Category column and categories.yaml name
|
||||
- Run `make generate` after changes
|
||||
|
||||
### Assets look wrong after regeneration
|
||||
- The `ensure_*_exists()` functions only create files if they don't exist
|
||||
- To regenerate an asset, delete it first then run the generator
|
||||
- Or edit the generator template and manually update existing files
|
||||
|
||||
### Dark mode assets missing
|
||||
- Dark mode dividers, TOC header, and card assets are manual
|
||||
- Use existing dark mode assets as templates
|
||||
|
||||
### README style not generating
|
||||
- Check that the template file exists in `templates/`
|
||||
- Verify the generator class is registered in `STYLE_GENERATORS` in `scripts/readme/generate_readme.py`
|
||||
|
||||
## Path Resolution System
|
||||
|
||||
The generator uses a dynamic path resolution system to handle relative paths correctly across different README locations. This section documents the key assumptions and behaviors.
|
||||
|
||||
### Core Assumptions
|
||||
|
||||
These assumptions are tested in `tests/test_style_selector_paths.py`:
|
||||
|
||||
| Assumption | Description |
|
||||
|------------|-------------|
|
||||
| **Single root README** | Exactly one style is copied to `README.md` (the `root_style`) |
|
||||
| **Alternatives path is fixed** | `README_ALTERNATIVES/` is a fixed directory under the repo root |
|
||||
| **Assets at root** | The `assets/` folder is a direct child of the repo root |
|
||||
| **Repo root discovery** | Paths resolve from the repo root discovered by finding `pyproject.toml` |
|
||||
| **Flat entry point** | Flat style links to `README_FLAT_ALL_AZ.md` as its entry point |
|
||||
|
||||
### Path Prefix Rules
|
||||
|
||||
| Location | Asset Prefix | Link to Root | Link to Alternatives |
|
||||
|----------|--------------|--------------|----------------------|
|
||||
| Root (`README.md`) | `assets/` | `./` | `README_ALTERNATIVES/file.md` |
|
||||
| Alternatives | `../assets/` | `../` | `file.md` (same folder) |
|
||||
|
||||
### Key Properties
|
||||
|
||||
```python
|
||||
# In ReadmeGenerator base class:
|
||||
|
||||
is_root_style # True if this style matches config's root_style
|
||||
resolved_output_path # Default output path (under README_ALTERNATIVES/)
|
||||
alternative_output_path # Path under README_ALTERNATIVES/ for this style
|
||||
# Root generation uses generate(output_path="README.md")
|
||||
```
|
||||
|
||||
### How Root Style Changes Work
|
||||
|
||||
When `acc-config.yaml` changes from `root_style: extra` to `root_style: awesome`:
|
||||
|
||||
1. **Awesome README** is also written to `README.md`
|
||||
- Asset paths use `assets/`
|
||||
- Links to other styles use `README_ALTERNATIVES/file.md`
|
||||
|
||||
2. **All alternatives remain in `README_ALTERNATIVES/`**
|
||||
- Asset paths remain `../assets/`
|
||||
- Style selector links update to reflect the new root
|
||||
|
||||
### Breaking Changes to Avoid
|
||||
|
||||
These changes would break the path resolution system:
|
||||
|
||||
- **Changing `README_ALTERNATIVES/` location**: Output paths and selector targets are hardcoded to `README_ALTERNATIVES/`
|
||||
- **Renaming `assets/` folder**: All asset path prefixes would break
|
||||
- **Having multiple root READMEs**: Only one style can be `root_style`
|
||||
- **Nested alternative folders**: All alternatives must be in the same flat folder
|
||||
41
.agent/knowledge/awesome_claude/docs/REPO_TICKER.md
Normal file
41
.agent/knowledge/awesome_claude/docs/REPO_TICKER.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Awesome Claude Code - "Repo Ticker"
|
||||
|
||||
## What is this thing?
|
||||
|
||||
The repo displays an animated SVG, in the style of a "stock ticker", with the names of various Claude Code projects, their authors, and some stargazer data. You might be wondering - what is it?
|
||||
|
||||
The ticker is populated by repositories that are returned as search results for the query `claude code`/`claude-code` by the GitHub REST API. Periodically, a repository workflow queries the API for 100 results to this query - it then takes a random sample of those results and generates the animation for the ticker. The animation can be thought of as a long-ish strip of SVG text that "scrolls" from right to left over the area of the ticker container. It also displays the star count for each repository, and a small "delta" showing its change from the previous day.
|
||||
|
||||
The purpose of the ticker is: (i) to provide some exposure to projects that may or may not be on the list; (ii) to add some "fun" visual flair to the repo; (iii) markdown/SVG flex. (That's just a little joke - it was all Claude's idea to begin with.) You can inspect the aforementioned workflow/scripts yourself to verify what I just described - the ticker does not constitute any endorsement or advertisement of the projects that appear on it, which as I mentioned, are selected at random. If you see anything strange or malicious on the ticker, you may notify the maintainer.
|
||||
|
||||
## Technical Details
|
||||
|
||||
The "infinite scroll" effect is produced by an SVG animation that changes the horizontal coordinates of the group of SVG elements that constitute the ticker's "tape"; and in order to create a seamless, continuous scroll effect, the first few entries on the tape (enough to cover the first frame of the animation) are repeated at the end of the list of entries:
|
||||
|
||||
```
|
||||
---------|-----------------------|
|
||||
A B C | D E F G H A B C| <<--
|
||||
---------|-----------------------|
|
||||
|
||||
---------|-----------------------|
|
||||
F G H | A B C | <<--
|
||||
---------|-----------------------|
|
||||
|
||||
---------|-----------------------|
|
||||
A B C | | LOOP
|
||||
---------|-----------------------|
|
||||
```
|
||||
|
||||
So, when the duplicate elements have traversed the width of the visible window, the animation resets to the beginning, and the loop starts over.
|
||||
|
||||
I know that sounds kind of simple, but it's actually ridiculously clever.
|
||||
|
||||
### SVG Text
|
||||
|
||||
Working with SVG text is very annnoying. First, it doesn't have any word-wrapping properties, so you have to estimate the width based on character count. Second, what looks good on one screen may be illegible on another. My initial design did not adequately account for the GitHub mobile app. The text had some glow filters and other stuff that looked kind of decent on a monitor, but is terrible on mobile. If you want the text to be legible on the GitHub mobile app, it must be crisp, sharp, and have pretty large font-size. You cannot use media-queries or anything like that (not supported by GitHub renderer). I recommend avoiding any sort of filter and keeping it pretty simple.
|
||||
|
||||
In order to squeeze a little bit of additional headroom from the layout, I landed on this "two-level" design so that if the text overflowed, I didn't have to worry about it bleeding over into the next entry on the ticker. I've heard people say "If it bleeds, it leads", but I don't think they were talking about the text itself. More like - "if it bleeds, it's hard to read(s)"...
|
||||
|
||||
Wow, good one, Claude.
|
||||
|
||||
For more information about the tasteful artistic design of this repo, you may consult [HOW IT LOOKS](./HOW_IT_LOOKS.md).
|
||||
34
.agent/knowledge/awesome_claude/docs/SECURITY.md
Normal file
34
.agent/knowledge/awesome_claude/docs/SECURITY.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Security Policy
|
||||
|
||||
This repository does not export any executible software, and
|
||||
it is, at the end of the day, just a Markdown file with a
|
||||
lot of internal plumbing. No private information is collected
|
||||
or stored, except such as can be found on public GitHub
|
||||
repositories, or what is submitted by individual users
|
||||
when recommending a resource for inclusion on the list.
|
||||
|
||||
For these reasons, the surface area of vulnerability for a
|
||||
security incident is rather limited, and is almost entirely
|
||||
limited to the credentials of the maintainer.
|
||||
|
||||
That being said, if you do notice any security flaws, risks,
|
||||
or vulnerailities (even if they only potentially affect
|
||||
the maintainer), you are welcome and encouraged to open a
|
||||
private security advisory, which you can do so [here](https://github.com/hesreallyhim/awesome-claude-code/security/advisories/new).
|
||||
|
||||
## Security of Third-Party Resources
|
||||
|
||||
Any security vulnerabilities or incidents relating to any of the
|
||||
third-party resources that are featured on Awesome Claude Code
|
||||
should first and foremost be reported according to the security
|
||||
policy of the respective third-party repository.
|
||||
|
||||
However, in order to assist in ensuring the safety and security
|
||||
of the resources included here, you are strongly encouraged
|
||||
to _also_ report any such vulnerabilities to the maintainer
|
||||
of this repo. While it is outside of our capacity, or of our
|
||||
obligation, to enforce or investigate third-party security
|
||||
violations, we will take such reports seriously.
|
||||
|
||||
We take the same approach to any (undisclosed) risks
|
||||
to users' privacy.
|
||||
82
.agent/knowledge/awesome_claude/docs/TESTING.md
Normal file
82
.agent/knowledge/awesome_claude/docs/TESTING.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Testing & Coverage
|
||||
|
||||
This document covers how to run the test suite and generate coverage reports.
|
||||
|
||||
## Setup
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```bash
|
||||
make install
|
||||
```
|
||||
|
||||
## Running Tests
|
||||
|
||||
Run all tests with pytest:
|
||||
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
Note: Tests that exercise path resolution with temporary directories should create a
|
||||
minimal `pyproject.toml` in the temp repo root so repo-root discovery works as expected.
|
||||
|
||||
## Comprehensive Checks
|
||||
|
||||
Run formatting checks, mypy, and pytest:
|
||||
|
||||
```bash
|
||||
make ci
|
||||
```
|
||||
|
||||
Run type checks only:
|
||||
|
||||
```bash
|
||||
make mypy
|
||||
```
|
||||
|
||||
## Docs Tree Check
|
||||
|
||||
Verify the README generation file tree is up to date:
|
||||
|
||||
```bash
|
||||
make docs-tree-check
|
||||
```
|
||||
|
||||
Update the tree block:
|
||||
|
||||
```bash
|
||||
make docs-tree
|
||||
```
|
||||
|
||||
## Regeneration Cycle
|
||||
|
||||
Run the full regeneration integration check (root style + selector order changes):
|
||||
|
||||
```bash
|
||||
make test-regenerate-cycle
|
||||
```
|
||||
|
||||
This target runs `make test-regenerate` first, then exercises config changes using
|
||||
`make test-regenerate-allow-diff`, and finally restores the original config and reruns
|
||||
`make test-regenerate`.
|
||||
|
||||
Note: This integration test requires a clean working tree and will rewrite
|
||||
`acc-config.yaml` during the run before restoring it.
|
||||
Note: If the local date changes during the run (near midnight), regenerated READMEs
|
||||
may update their date stamps and cause a diff; rerun when the clock is stable.
|
||||
|
||||
## Coverage
|
||||
|
||||
Generate coverage reports (terminal + HTML + XML):
|
||||
|
||||
```bash
|
||||
make coverage
|
||||
```
|
||||
|
||||
Outputs:
|
||||
- `htmlcov/` for the HTML report
|
||||
- `coverage.xml` for CI integrations
|
||||
- Terminal summary via `term-missing`
|
||||
|
||||
Note: `scripts/archive/` is excluded from test discovery and coverage.
|
||||
@@ -0,0 +1,56 @@
|
||||
# Cooldown Enforcement
|
||||
|
||||
Automated rate-limiting for resource submissions. Applies to both issues and pull requests.
|
||||
|
||||
## How it works
|
||||
|
||||
Every submission is checked against a state file (`cooldown-state.json`) stored in the private ops repo. The state tracks each user's cooldown level, active cooldown expiry, and ban status.
|
||||
|
||||
**Violations** (each starts or extends a cooldown):
|
||||
|
||||
| Violation | Trigger |
|
||||
|---|---|
|
||||
| Missing form label | Issue opened without using the submission template |
|
||||
| Repo too young | Linked repository is less than 7 days old |
|
||||
| Submitted as PR | Pull request classified as a resource submission by Claude |
|
||||
| Submitted during cooldown | Any submission while an active cooldown is in effect |
|
||||
|
||||
**Escalation** — each violation doubles the cooldown period:
|
||||
|
||||
| Level | Duration |
|
||||
|---|---|
|
||||
| 0 → 1 | 24 hours |
|
||||
| 1 → 2 | 48 hours |
|
||||
| 2 → 3 | 4 days |
|
||||
| 3 → 4 | 8 days |
|
||||
| 4 → 5 | 16 days |
|
||||
| 5 → 6 | 32 days |
|
||||
| 6 | Permanent ban |
|
||||
|
||||
Submitting during an active cooldown is itself a violation — the cooldown extends and the level increments. Persistence is counterproductive.
|
||||
|
||||
## Maintainer controls
|
||||
|
||||
- **`excused` label** — apply to any issue to bypass cooldown checks entirely. The workflow skips enforcement and proceeds directly to validation.
|
||||
- **Manual state edits** — the state file lives in the private repo file `cooldown-state.json`. You can edit it directly to reduce a user's level, clear their cooldown, or remove a ban. Each entry looks like:
|
||||
|
||||
```json
|
||||
{
|
||||
"username": {
|
||||
"active_until": "2026-02-24T12:00:00.000Z",
|
||||
"cooldown_level": 2,
|
||||
"last_violation": "2026-02-22T12:00:00.000Z",
|
||||
"last_reason": "repo-too-young"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To unban someone, delete their entry or set `banned: false` and `cooldown_level: 0`.
|
||||
|
||||
## PR classification
|
||||
|
||||
Pull requests are classified by Claude (Haiku) as either `resource_submission` or `not_resource_submission` with a confidence level. Resource submissions are closed with a redirect to the issue template and trigger a cooldown violation. Non-resource PRs with low confidence get a `needs-review` label. API failures fail open — the PR stays untouched.
|
||||
|
||||
## Concurrency
|
||||
|
||||
Runs are serialized per-user (concurrent submissions from the same user queue). Different users process in parallel. The ops repo file uses optimistic locking (SHA-based) — if two concurrent writes race, the loser's violation isn't recorded but will be caught on the next submission.
|
||||
@@ -0,0 +1,10 @@
|
||||
# Don't Forget
|
||||
|
||||
Some important but easy-to-forget assumptions and gotchas that can cause headaches:
|
||||
|
||||
- `python -m` uses dot notation (for example, `python -m scripts.resources.parse_issue_form`), not slash paths or `.py` suffixes.
|
||||
- `python -m` only works for modules with a CLI entrypoint (`if __name__ == "__main__":`).
|
||||
- GitHub Actions with sparse checkout must include `pyproject.toml` so `find_repo_root()` can locate the repo root.
|
||||
- If a workflow runs scripts that import `scripts.*`, either run from the repo root or set `PYTHONPATH` to the repo root.
|
||||
- Sparse checkout must include any data files the script reads (for example, `THE_RESOURCES_TABLE.csv`, `templates/`).
|
||||
- GitHub Actions using sparse checkout must include `pyproject.toml` so scripts can locate the repo root (via `find_repo_root()`).
|
||||
@@ -0,0 +1,45 @@
|
||||
# Path Resolution Migration Plan
|
||||
|
||||
This plan describes the concrete work needed to migrate README generation to the
|
||||
final path-resolution strategy (relative asset paths resolved per output file).
|
||||
|
||||
## Scope
|
||||
|
||||
- Keep style-specific templates intact (extra/classic/awesome/flat).
|
||||
- Remove all path-specific assumptions from templates and markup.
|
||||
- Centralize asset path resolution in the generator.
|
||||
|
||||
## Plan
|
||||
|
||||
1. **Audit templates and markup**
|
||||
- Inventory all occurrences of `{{ASSET_PREFIX}}`, `{{ASSET_PATH(...)}}`, `assets/`, `../assets`, `/assets`.
|
||||
- Identify every generator/markup call site that injects or assumes a prefix.
|
||||
- Map all output locations (root README, README_ALTERNATIVES, .github, etc.).
|
||||
|
||||
2. **Introduce a single asset token scheme**
|
||||
- Choose one token format (e.g., `asset:foo.png` or `{{ASSET_PATH('foo.png')}}`).
|
||||
- Implement a resolver that:
|
||||
- finds `repo_root` via `pyproject.toml`
|
||||
- computes a relative path from the output file’s directory to `/assets`
|
||||
- replaces tokens with correct POSIX paths
|
||||
- Remove `ASSET_PREFIX` and `is_root_readme` assumptions from templates.
|
||||
|
||||
3. **Wire the resolver into generation**
|
||||
- Apply the resolver after template substitution but before writing files.
|
||||
- Update markup helpers to emit tokenized asset references instead of prefixes.
|
||||
- Ensure style selector and repo ticker resolve through the same mechanism.
|
||||
|
||||
4. **Add generated-file header**
|
||||
- Insert `<!-- GENERATED FILE: do not edit directly -->` into all outputs.
|
||||
- Ensure templates or generator handle this consistently.
|
||||
|
||||
5. **Update tests and docs**
|
||||
- Add/adjust tests to validate asset paths for all output locations.
|
||||
- Ensure `test-regenerate` remains the canonical drift check.
|
||||
- Update docs to reflect the new token scheme and remove obsolete guidance.
|
||||
|
||||
## Completion Criteria
|
||||
|
||||
- No templates or markup contain concrete asset prefixes.
|
||||
- Outputs render correctly in-place and on GitHub across all locations.
|
||||
- `make test-regenerate` passes with a clean working tree.
|
||||
@@ -0,0 +1,109 @@
|
||||
# Strategy: Generated, Location-Correct Relative Asset Paths
|
||||
|
||||
This repo treats all Markdown READMEs as generated artifacts. The generator is responsible for making every output Markdown file render correctly both (a) on GitHub when viewed in-place and (b) in local Markdown previews that expect standard relative paths.
|
||||
|
||||
## Goals
|
||||
|
||||
- Any generated file like `/README.md`, `/foo/bar/README.md`, `/.github/README.md`, `README_ALTERNATIVES/*.md` renders correctly in its own directory.
|
||||
- Local preview works without special editor configuration.
|
||||
- GitHub rendering works without relying on repo-root /assets/... semantics.
|
||||
- “Swaps” never copy pre-generated Markdown between locations; they regenerate for the destination path.
|
||||
|
||||
---
|
||||
|
||||
## Rules
|
||||
|
||||
### Rule 1: Single source of truth for assets
|
||||
|
||||
- Assets live only in: /assets/*
|
||||
- No duplicated asset directories are required for this strategy.
|
||||
|
||||
### Rule 2: Templates never contain concrete relative prefixes
|
||||
|
||||
Templates must not hardcode ./assets, ../assets, /assets, etc.
|
||||
|
||||
Instead, templates use one of:
|
||||
|
||||
- a placeholder token: {{ASSET_PATH("foo.png")}} (single quotes are also supported)
|
||||
- or a canonical pseudo-URL: asset:foo.png
|
||||
|
||||
Only the generator resolves these into real paths.
|
||||
|
||||
### Rule 3: Generator anchors on repo root
|
||||
|
||||
The generator must discover repo_root deterministically by walking upward from the executing script (or from the template file) until it finds pyproject.toml.
|
||||
|
||||
Definition:
|
||||
|
||||
- repo_root is the directory containing pyproject.toml.
|
||||
|
||||
### Rule 4: Resolve assets relative to each output file
|
||||
|
||||
For each output Markdown file at path out_md:
|
||||
|
||||
- Let base_dir = out_md.parent
|
||||
- Let assets_dir = repo_root / "assets"
|
||||
- Compute rel_assets = relative_path(from=base_dir, to=assets_dir) using POSIX separators (/) for Markdown
|
||||
- Emit image references as: rel_assets + "/<asset-file>"
|
||||
|
||||
Examples:
|
||||
|
||||
- Output /README.md → assets/foo.png
|
||||
- Output /.github/README.md → ../assets/foo.png
|
||||
- Output /foo/bar/README.md → ../../assets/foo.png
|
||||
|
||||
### Rule 5: Swaps are selection + generation, never copying contents
|
||||
|
||||
A “swap” means:
|
||||
|
||||
- Choose a variant/source template (e.g. language/style)
|
||||
- Regenerate the destination file(s) in their final location(s)
|
||||
|
||||
Never:
|
||||
|
||||
- Copy or move pre-generated Markdown from one directory to another (paths will break).
|
||||
|
||||
### Rule 6: Generated files are not manually edited
|
||||
|
||||
- Generated READMEs must carry a header comment like:
|
||||
|
||||
```markdown
|
||||
<!-- GENERATED FILE: do not edit directly -->
|
||||
```
|
||||
|
||||
- Manual edits go into the template/source inputs only.
|
||||
|
||||
### Rule 7: CI validates generation is up-to-date
|
||||
|
||||
CI must:
|
||||
|
||||
1. run the generator
|
||||
2. fail if the working tree changed
|
||||
|
||||
Canonical check:
|
||||
|
||||
- git diff --exit-code
|
||||
|
||||
This ensures no drift between committed generated READMEs and what templates would produce.
|
||||
|
||||
---
|
||||
|
||||
## Operational Guidance
|
||||
|
||||
### Editing Files
|
||||
|
||||
- Edit: templates + data inputs only
|
||||
- Do not edit: generated Markdown outputs
|
||||
- Assume: manual changes to Markdown files will be overridden by the generators
|
||||
|
||||
### Link checking
|
||||
|
||||
Run link/image checks only on:
|
||||
|
||||
- the generated Markdown outputs (post-generation) not on templates or source markdown fragments.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
This strategy makes local preview easy by using standard relative paths, while keeping GitHub rendering correct everywhere. The generator is the only component allowed to decide how assets/ is referenced, and swaps are implemented exclusively as “regenerate for destination path,” not file copying.
|
||||
@@ -0,0 +1,22 @@
|
||||
## GitHub README collapsible subcategory cheat sheet
|
||||
|
||||
Context: GitHub’s Markdown renderer wraps loose content in `<p>` tags and modifies markup inside `<summary>`. These tweaks keep the caret aligned and prevent broken first items in collapsible sections.
|
||||
|
||||
- Keep `<summary>` contents on one line with no leading/trailing whitespace; GitHub inserts `<p>` if it sees blank lines.
|
||||
- Wrap the SVG in a `<picture>` to stop the image from becoming a link target via camo wrapping.
|
||||
- Use `align="absmiddle"` on the `<img>` to nudge the caret arrow to midline (works on GitHub).
|
||||
- Put the back-to-top link immediately after the picture inside the same `<span>`; avoid extra spaces or newlines between them.
|
||||
- Add exactly one blank line after the `<summary>` line so the first resource renders as Markdown, not as raw text.
|
||||
|
||||
Minimal pattern that renders correctly on GitHub:
|
||||
|
||||
```html
|
||||
<details id="some-subcategory-">
|
||||
<summary><span><picture><img src="assets/subheader_some.svg" alt="Some Subcat" align="absmiddle"></picture><a href="#awesome-claude-code">🔝</a></span></summary>
|
||||
|
||||
[`Example`](https://example.com) by [Author](https://author.example)
|
||||
|
||||
</details>
|
||||
```
|
||||
|
||||
Verification tip: use GitHub’s `/markdown` API with mode `gfm` to preview the rendered HTML without pushing commits. One request per variant is usually enough.***
|
||||
@@ -0,0 +1,3 @@
|
||||
Really Him: Claude, this file is empty
|
||||
|
||||
Claude: You're absolutely right.
|
||||
@@ -0,0 +1,157 @@
|
||||
# TOC Anchor Generation
|
||||
|
||||
## GitHub Anchor Generation Rules
|
||||
|
||||
GitHub generates heading anchors by:
|
||||
1. Lowercasing the heading text
|
||||
2. Replacing spaces with `-`
|
||||
3. Removing special characters
|
||||
4. Stripping emojis (each emoji leaves a `-` in its place)
|
||||
5. Appending `-N` suffix for duplicate anchors (where N = 1, 2, 3...)
|
||||
|
||||
## Style-Specific Heading Formats
|
||||
|
||||
### AWESOME Style
|
||||
```markdown
|
||||
## Agent Skills 🤖
|
||||
### General
|
||||
```
|
||||
- Category anchor: `#agent-skills-` (one dash from emoji)
|
||||
- Subcategory anchor: `#general` (no trailing dash)
|
||||
|
||||
### CLASSIC Style
|
||||
```markdown
|
||||
## Agent Skills 🤖 [🔝](#awesome-claude-code)
|
||||
<h3>General <a href="#awesome-claude-code">🔝</a></h3>
|
||||
```
|
||||
- Category anchor: `#agent-skills--` (two dashes: one from 🤖, one from 🔝)
|
||||
- Subcategory anchor: `#general-` (one dash from 🔝)
|
||||
|
||||
### EXTRA/VISUAL Style
|
||||
Uses explicit `id` attributes on headings, controlling anchors directly.
|
||||
|
||||
## Duplicate "General" Subcategory Handling
|
||||
|
||||
Multiple "General" subcategories across categories generate:
|
||||
- First: `#general` (AWESOME) or `#general-` (CLASSIC)
|
||||
- Second: `#general-1` (AWESOME) or `#general--1` (CLASSIC)
|
||||
- Third: `#general-2` (AWESOME) or `#general--2` (CLASSIC)
|
||||
|
||||
Note: GitHub uses double-dash before the counter in CLASSIC due to the 🔝 emoji.
|
||||
|
||||
## Relevant Source Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `scripts/readme/markup/awesome.py` | AWESOME style TOC generation |
|
||||
| `scripts/readme/markup/minimal.py` | CLASSIC style TOC generation |
|
||||
| `scripts/readme/markup/visual.py` | EXTRA style TOC generation |
|
||||
| `scripts/readme/helpers/readme_utils.py` | `get_anchor_suffix_for_icon()` helper |
|
||||
| `scripts/testing/validate_toc_anchors.py` | Validation utility |
|
||||
|
||||
## Validation
|
||||
|
||||
### Manual Validation
|
||||
```bash
|
||||
# Validate root README (AWESOME style)
|
||||
make validate-toc
|
||||
|
||||
# Validate CLASSIC style
|
||||
python3 -m scripts.testing.validate_toc_anchors \
|
||||
--html .claude/readme-body-html-non-root-readme.html \
|
||||
--readme README_ALTERNATIVES/README_CLASSIC.md
|
||||
```
|
||||
|
||||
### Obtaining GitHub HTML
|
||||
1. Push README to GitHub
|
||||
2. View rendered README page
|
||||
3. Open browser dev tools (F12)
|
||||
4. Find `<article>` element containing README content
|
||||
5. Copy inner HTML to `.claude/root-readme-html-article-body.html`
|
||||
|
||||
### Automated Tests
|
||||
```bash
|
||||
make test # Includes TOC anchor validation tests
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
1. **Extra dash before suffix**: `#{anchor}-{suffix}` when `suffix` already contains `-`
|
||||
2. **Missing back-to-top dash**: CLASSIC style headings include 🔝 which adds a dash
|
||||
3. **Wrong General counter format**: CLASSIC uses `general--N`, AWESOME uses `general-N`
|
||||
|
||||
## HTML Fixture Storage
|
||||
|
||||
GitHub-rendered HTML fixtures are stored in `tests/fixtures/github-html/` (version controlled).
|
||||
Fixture filenames indicate root vs non-root placement to detect potential rendering differences:
|
||||
|
||||
| Style | README Path | HTML Fixture | Placement |
|
||||
|-------|-------------|--------------|-----------|
|
||||
| AWESOME | `README.md` | `awesome-root.html` | Root |
|
||||
| CLASSIC | `README_ALTERNATIVES/README_CLASSIC.md` | `classic-non-root.html` | Non-root |
|
||||
| EXTRA | `README_ALTERNATIVES/README_EXTRA.md` | `extra-non-root.html` | Non-root |
|
||||
| FLAT | `README_ALTERNATIVES/README_FLAT_ALL_AZ.md` | `flat-non-root.html` | Non-root |
|
||||
|
||||
Validation commands:
|
||||
```bash
|
||||
# AWESOME (default)
|
||||
python3 -m scripts.testing.validate_toc_anchors
|
||||
|
||||
# Other styles
|
||||
python3 -m scripts.testing.validate_toc_anchors --style classic
|
||||
python3 -m scripts.testing.validate_toc_anchors --style extra
|
||||
python3 -m scripts.testing.validate_toc_anchors --style flat
|
||||
```
|
||||
|
||||
## Validation Status
|
||||
|
||||
| Style | Status | Notes |
|
||||
|-------|--------|-------|
|
||||
| AWESOME | ✅ | Root README, 30 TOC anchors verified |
|
||||
| CLASSIC | ✅ | Different anchor format due to 🔝 in headings |
|
||||
| EXTRA | ✅ | Uses explicit `id` attributes; template anchor fixed |
|
||||
| FLAT | ✅ | No TOC anchors (flat list format) |
|
||||
|
||||
## Future Work
|
||||
|
||||
- [ ] Unify anchor generation logic into shared helper with parameterized flags
|
||||
- [ ] Add CI job to validate TOC anchors on README changes
|
||||
|
||||
---
|
||||
|
||||
## Architectural Decision: Anchor Generation Unification
|
||||
|
||||
**Date**: 2026-01-09
|
||||
|
||||
**Context**: TOC anchor generation logic is duplicated across three files (`awesome.py`, `minimal.py`, `visual.py`) with subtle differences due to each style's heading format.
|
||||
|
||||
**Options Considered**:
|
||||
|
||||
1. **Parameterized flags** - Create shared helper with semantic flags like `has_back_to_top_in_heading`
|
||||
2. **Unify to ID-based** - Migrate all styles to use explicit `<h2 id="...">` like EXTRA
|
||||
|
||||
**Decision**: Option 1 (parameterized flags)
|
||||
|
||||
**Rationale**:
|
||||
- Lower risk: heading markup remains unchanged
|
||||
- AWESOME style intentionally uses clean markdown (`## Title`) for aesthetic reasons
|
||||
- ID-based approach would require CLASSIC to restructure its `[🔝](#...)` links
|
||||
- Parameterized flags are self-documenting and decouple anchor logic from style names
|
||||
|
||||
**Proposed API**:
|
||||
```python
|
||||
def generate_toc_anchor(
|
||||
title: str,
|
||||
icon: str | None = None,
|
||||
has_back_to_top_in_heading: bool = False,
|
||||
) -> str:
|
||||
"""Generate TOC anchor for a heading.
|
||||
|
||||
Args:
|
||||
title: The heading text (e.g., "Agent Skills")
|
||||
icon: Optional trailing emoji icon (e.g., "🤖")
|
||||
has_back_to_top_in_heading: True if heading contains 🔝 back-to-top link
|
||||
"""
|
||||
```
|
||||
|
||||
**Trade-off**: If a style changes its heading format (e.g., CLASSIC removes 🔝), only the flag value changes—not the shared logic.
|
||||
@@ -0,0 +1,487 @@
|
||||
# Vintage Manual Animation Style Guide
|
||||
|
||||
A comprehensive guide to the animation effects developed for the light mode "vintage technical manual" theme. These animations are designed to evoke 70s-80s computer documentation, printing, and paper-based media while remaining subtle and professional.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Design Principles](#design-principles)
|
||||
2. [Color Palette](#color-palette)
|
||||
3. [Typography](#typography)
|
||||
4. [Animation Patterns](#animation-patterns)
|
||||
- [Typewriter Reveal](#1-typewriter-reveal)
|
||||
- [Print Scan](#2-print-scan)
|
||||
- [Stamp Press](#3-stamp-press)
|
||||
- [Registration Shift](#4-registration-shift)
|
||||
- [Line Printer](#5-line-printer)
|
||||
5. [Parameterization Guide](#parameterization-guide)
|
||||
6. [Implementation Examples](#implementation-examples)
|
||||
|
||||
---
|
||||
|
||||
## Design Principles
|
||||
|
||||
1. **Paper-like Motion**: Animations should feel physical - like ink, paper, and mechanical processes
|
||||
2. **Warm Aesthetics**: Use sepia tones that suggest aged paper and vintage printing
|
||||
3. **Purposeful Timing**: Each animation should have clear phases (anticipation, action, settle)
|
||||
4. **Loopable**: Animations should loop seamlessly without jarring resets
|
||||
|
||||
---
|
||||
|
||||
## Color Palette
|
||||
|
||||
```css
|
||||
/* Primary Colors */
|
||||
--ink-dark: #2d251f; /* Main text, darkest ink */
|
||||
--ink-medium: #3d3530; /* Secondary text */
|
||||
--ink-light: #5c5247; /* Tertiary, rules, borders */
|
||||
--ink-faded: #6b5b4f; /* Subtle text, descriptions */
|
||||
--ink-ghost: #7a6b5f; /* Very light text */
|
||||
--ink-muted: #8a7b6f; /* Metadata, timestamps */
|
||||
|
||||
/* Accent Colors */
|
||||
--accent-terracotta: #c96442; /* Section numbers, highlights */
|
||||
--accent-warm: #9a8b7f; /* Warm gray accent */
|
||||
|
||||
/* Paper Colors */
|
||||
--paper-light: #faf8f3; /* Lightest paper */
|
||||
--paper-cream: #f5f0e6; /* Standard paper */
|
||||
--paper-aged: #f2ede4; /* Slightly aged */
|
||||
--paper-shadow: #e8e3d9; /* Paper shadow/fold */
|
||||
|
||||
/* Border Colors */
|
||||
--border-light: #c4baa8; /* Light borders */
|
||||
--border-medium: #b0a696; /* Medium borders */
|
||||
|
||||
/* Print Effects */
|
||||
--greenbar: #4a7c4a; /* Green bar paper stripe */
|
||||
--perf-hole: #d4cfc5; /* Perforation holes */
|
||||
--cyan-offset: #6b8a8a; /* Registration cyan layer */
|
||||
--magenta-offset: #8a6b6b; /* Registration magenta layer */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Typography
|
||||
|
||||
```css
|
||||
/* Primary Heading - Serif */
|
||||
font-family: Georgia, 'Times New Roman', serif;
|
||||
font-size: 38px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 8px;
|
||||
|
||||
/* Secondary Heading - Monospace */
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
font-size: 12px;
|
||||
letter-spacing: 3px;
|
||||
|
||||
/* Body/Tagline - Serif Italic */
|
||||
font-family: Georgia, 'Times New Roman', serif;
|
||||
font-size: 13px;
|
||||
font-style: italic;
|
||||
|
||||
/* Technical/Metadata - Monospace */
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
font-size: 9px;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Animation Patterns
|
||||
|
||||
### 1. Typewriter Reveal
|
||||
|
||||
**Concept**: Characters appear sequentially, mimicking a typewriter or teletype machine.
|
||||
|
||||
**Timing**: 6 second cycle
|
||||
- Characters appear every 0.3s
|
||||
- Cursor follows and blinks
|
||||
- Subtitle/tagline fade in after title completes
|
||||
|
||||
**Core Technique**:
|
||||
```xml
|
||||
<!-- Each character has staggered opacity animation -->
|
||||
<text x="100" y="50" opacity="0">A
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
values="0;0;1;1;1;1;1;1;1;1"
|
||||
dur="6s"
|
||||
repeatCount="indefinite"/>
|
||||
</text>
|
||||
|
||||
<text x="120" y="50" opacity="0">W
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
values="0;0;0;1;1;1;1;1;1;1"
|
||||
dur="6s"
|
||||
repeatCount="indefinite"/>
|
||||
</text>
|
||||
|
||||
<!-- Cursor follows typing position -->
|
||||
<rect width="4" height="28" fill="#2d251f">
|
||||
<animate
|
||||
attributeName="x"
|
||||
values="100;120;140;160;180"
|
||||
dur="6s"
|
||||
repeatCount="indefinite"
|
||||
calcMode="discrete"/>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
values="1;0"
|
||||
dur="0.5s"
|
||||
repeatCount="indefinite"/>
|
||||
</rect>
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
- `charDelay`: Time between each character (default: 0.3s)
|
||||
- `cursorBlinkRate`: Cursor blink speed (default: 0.5s)
|
||||
- `holdTime`: Time to display complete text before reset
|
||||
|
||||
**Generator Function** (JavaScript):
|
||||
```javascript
|
||||
function generateTypewriterText(text, x, y, options = {}) {
|
||||
const {
|
||||
charWidth = 24,
|
||||
charDelay = 0.3,
|
||||
cycleDuration = 6,
|
||||
fontSize = 36
|
||||
} = options;
|
||||
|
||||
const chars = text.split('');
|
||||
const totalChars = chars.length;
|
||||
|
||||
return chars.map((char, i) => {
|
||||
const charX = x + (i * charWidth);
|
||||
const appearTime = (i * charDelay) / cycleDuration;
|
||||
const values = Array(20).fill('1');
|
||||
const appearIndex = Math.floor(appearTime * 20);
|
||||
for (let j = 0; j < appearIndex; j++) values[j] = '0';
|
||||
|
||||
return `
|
||||
<text x="${charX}" y="${y}" opacity="0">${char}
|
||||
<animate attributeName="opacity"
|
||||
values="${values.join(';')}"
|
||||
dur="${cycleDuration}s"
|
||||
repeatCount="indefinite"/>
|
||||
</text>`;
|
||||
}).join('\n');
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Print Scan
|
||||
|
||||
**Concept**: A glowing scan bar sweeps across, simulating a print head or scanner.
|
||||
|
||||
**Timing**: 4 second cycle (continuous)
|
||||
|
||||
**Core Technique**:
|
||||
```xml
|
||||
<defs>
|
||||
<!-- Gradient for scan bar glow -->
|
||||
<linearGradient id="scanGlow" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" style="stop-color:#c96442;stop-opacity:0"/>
|
||||
<stop offset="50%" style="stop-color:#c96442;stop-opacity:0.6"/>
|
||||
<stop offset="100%" style="stop-color:#c96442;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- Scan bar that moves across -->
|
||||
<rect x="-100" y="0" width="100" height="180" fill="url(#scanGlow)">
|
||||
<animate
|
||||
attributeName="x"
|
||||
values="-100;950"
|
||||
dur="4s"
|
||||
repeatCount="indefinite"/>
|
||||
</rect>
|
||||
|
||||
<!-- Optional: Print head indicator dot -->
|
||||
<circle r="3" fill="#c96442" opacity="0.8">
|
||||
<animate attributeName="cx" values="-50;900" dur="4s" repeatCount="indefinite"/>
|
||||
<animate attributeName="cy" values="10;10;170;170;10" dur="4s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
- `scanDuration`: Time for full sweep (default: 4s)
|
||||
- `barWidth`: Width of scan bar (default: 100px)
|
||||
- `glowColor`: Scan bar color (default: #c96442)
|
||||
- `direction`: 'ltr' | 'rtl' | 'ttb' | 'btt'
|
||||
|
||||
---
|
||||
|
||||
### 3. Stamp Press
|
||||
|
||||
**Concept**: Elements drop from above and "press" into the paper with a bounce and ink spread.
|
||||
|
||||
**Timing**: 5 second cycle
|
||||
- Elements start offset above
|
||||
- Drop with slight overshoot
|
||||
- Bounce back to final position
|
||||
- Ink spread effect at moment of impact
|
||||
|
||||
**Core Technique**:
|
||||
```xml
|
||||
<defs>
|
||||
<!-- Shadow that animates with press -->
|
||||
<filter id="stampShadow">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="2" flood-color="#3d3530" flood-opacity="0.2">
|
||||
<animate attributeName="dy" values="4;0;0;0;0;0" dur="5s" repeatCount="indefinite"/>
|
||||
<animate attributeName="stdDeviation" values="4;1;1;1;1;1" dur="5s" repeatCount="indefinite"/>
|
||||
</feDropShadow>
|
||||
</filter>
|
||||
|
||||
<!-- Ink spread filter -->
|
||||
<filter id="inkSpread">
|
||||
<feMorphology operator="dilate" radius="0">
|
||||
<animate attributeName="radius" values="0;0.5;0" dur="3s" repeatCount="indefinite"/>
|
||||
</feMorphology>
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
<!-- Element with stamp animation -->
|
||||
<text filter="url(#stampShadow)" opacity="0">
|
||||
TITLE TEXT
|
||||
<animate attributeName="opacity" values="0;0;0;1;1;1" dur="5s" repeatCount="indefinite"/>
|
||||
<animateTransform
|
||||
attributeName="transform"
|
||||
type="translate"
|
||||
values="0,-15;0,-15;0,-15;0,3;0,0;0,0"
|
||||
dur="5s"
|
||||
repeatCount="indefinite"/>
|
||||
</text>
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
- `dropDistance`: How far above element starts (default: 15px)
|
||||
- `bounceAmount`: Overshoot distance (default: 3px)
|
||||
- `stampDelay`: Stagger between elements (default: 0.5s)
|
||||
- `inkSpreadRadius`: Maximum ink spread (default: 0.5)
|
||||
|
||||
---
|
||||
|
||||
### 4. Registration Shift
|
||||
|
||||
**Concept**: Color layers start misaligned and shift into registration, like offset printing.
|
||||
|
||||
**Timing**: 4 second cycle
|
||||
- Cyan and magenta layers offset by ~3px
|
||||
- Shift to aligned position
|
||||
- Hold aligned
|
||||
- Quick reset
|
||||
|
||||
**Core Technique**:
|
||||
```xml
|
||||
<!-- Cyan offset layer (behind) -->
|
||||
<text x="450" y="85" fill="#6b8a8a" opacity="0.15">
|
||||
TITLE TEXT
|
||||
<animate attributeName="x" values="447;450;450;450" dur="4s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0.25;0.1;0.1;0.1" dur="4s" repeatCount="indefinite"/>
|
||||
</text>
|
||||
|
||||
<!-- Magenta offset layer (behind) -->
|
||||
<text x="450" y="85" fill="#8a6b6b" opacity="0.15">
|
||||
TITLE TEXT
|
||||
<animate attributeName="x" values="453;450;450;450" dur="4s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0.25;0.1;0.1;0.1" dur="4s" repeatCount="indefinite"/>
|
||||
</text>
|
||||
|
||||
<!-- Main layer (on top) -->
|
||||
<text x="450" y="85" fill="#2d251f">
|
||||
TITLE TEXT
|
||||
<animate attributeName="y" values="83;85;85;85" dur="4s" repeatCount="indefinite"/>
|
||||
</text>
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
- `offsetDistance`: How far layers are misaligned (default: 3px)
|
||||
- `cyanOffset`: Direction of cyan layer (default: -3, 0)
|
||||
- `magentaOffset`: Direction of magenta layer (default: +3, 0)
|
||||
- `settleTime`: Time to reach alignment (default: 25% of cycle)
|
||||
|
||||
---
|
||||
|
||||
### 5. Line Printer
|
||||
|
||||
**Concept**: Content reveals top-to-bottom like continuous form paper feeding through a printer.
|
||||
|
||||
**Timing**: 8 second cycle (with pause)
|
||||
- Paper feeds down revealing content (2s)
|
||||
- Hold/pause (4s)
|
||||
- Rapid wipe up to reset (1s)
|
||||
- Brief blank (1s)
|
||||
|
||||
**Core Technique**:
|
||||
```xml
|
||||
<defs>
|
||||
<!-- Clip path for line reveal -->
|
||||
<clipPath id="lineReveal">
|
||||
<rect x="0" y="0" width="900" height="0">
|
||||
<!-- Down (reveal) - pause - up (hide) - pause -->
|
||||
<animate
|
||||
attributeName="height"
|
||||
values="0;180;180;180;180;180;0;0"
|
||||
keyTimes="0;0.25;0.3;0.7;0.75;0.8;0.9;1"
|
||||
dur="8s"
|
||||
repeatCount="indefinite"/>
|
||||
</rect>
|
||||
</clipPath>
|
||||
|
||||
<!-- Green bar paper pattern -->
|
||||
<pattern id="greenBar" width="60" height="60" patternUnits="userSpaceOnUse">
|
||||
<rect width="60" height="30" fill="#4a7c4a" opacity="0.08"/>
|
||||
</pattern>
|
||||
|
||||
<!-- Perforation pattern -->
|
||||
<pattern id="perfEdge" width="10" height="20" patternUnits="userSpaceOnUse">
|
||||
<circle cx="5" cy="10" r="2" fill="#d4cfc5"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<!-- Perforated edges -->
|
||||
<rect x="0" y="0" width="12" height="180" fill="url(#perfEdge)" opacity="0.5"/>
|
||||
<rect x="888" y="0" width="12" height="180" fill="url(#perfEdge)" opacity="0.5"/>
|
||||
|
||||
<!-- Green bar stripes -->
|
||||
<rect x="20" y="0" width="860" height="180" fill="url(#greenBar)"/>
|
||||
|
||||
<!-- Content with clip -->
|
||||
<g clip-path="url(#lineReveal)">
|
||||
<!-- All content here -->
|
||||
</g>
|
||||
|
||||
<!-- Print head line -->
|
||||
<line x1="20" y1="0" x2="880" y2="0" stroke="#c96442" stroke-width="2">
|
||||
<animate
|
||||
attributeName="y1"
|
||||
values="0;180;180;180;180;180;0;0"
|
||||
keyTimes="0;0.25;0.3;0.7;0.75;0.8;0.9;1"
|
||||
dur="8s"
|
||||
repeatCount="indefinite"/>
|
||||
</line>
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
- `revealSpeed`: Time to reveal content (default: 2s)
|
||||
- `holdTime`: Pause duration (default: 4s)
|
||||
- `wipeSpeed`: Time to wipe up (default: 1s)
|
||||
- `showGreenBar`: Boolean for green bar paper effect
|
||||
- `showPerforations`: Boolean for feed holes
|
||||
|
||||
---
|
||||
|
||||
## Parameterization Guide
|
||||
|
||||
### Creating a Generator Function
|
||||
|
||||
```javascript
|
||||
function generateVintageManualSVG(options) {
|
||||
const {
|
||||
width = 900,
|
||||
height = 180,
|
||||
title = 'TITLE',
|
||||
subtitle = 'Subtitle',
|
||||
tagline = 'Tagline text here',
|
||||
animation = 'lineprint', // typewriter|printscan|stamp|registration|lineprint
|
||||
colors = {
|
||||
ink: '#2d251f',
|
||||
accent: '#c96442',
|
||||
paper: '#faf8f3'
|
||||
},
|
||||
timing = {
|
||||
cycleDuration: 8,
|
||||
revealDuration: 2,
|
||||
holdDuration: 4
|
||||
}
|
||||
} = options;
|
||||
|
||||
// Generate SVG based on animation type
|
||||
switch(animation) {
|
||||
case 'typewriter':
|
||||
return generateTypewriterSVG(options);
|
||||
case 'printscan':
|
||||
return generatePrintScanSVG(options);
|
||||
case 'stamp':
|
||||
return generateStampSVG(options);
|
||||
case 'registration':
|
||||
return generateRegistrationSVG(options);
|
||||
case 'lineprint':
|
||||
return generateLinePrintSVG(options);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CSS Custom Properties Approach
|
||||
|
||||
```css
|
||||
:root {
|
||||
--manual-cycle-duration: 8s;
|
||||
--manual-reveal-duration: 2s;
|
||||
--manual-hold-duration: 4s;
|
||||
--manual-ink-color: #2d251f;
|
||||
--manual-accent-color: #c96442;
|
||||
--manual-paper-color: #faf8f3;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Examples
|
||||
|
||||
### React Component
|
||||
|
||||
```jsx
|
||||
const VintageHeader = ({
|
||||
title,
|
||||
subtitle,
|
||||
animation = 'lineprint',
|
||||
cycleDuration = 8
|
||||
}) => {
|
||||
return (
|
||||
<svg viewBox="0 0 900 180" className="vintage-header">
|
||||
{/* SVG content with dynamic values */}
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
### Web Component
|
||||
|
||||
```javascript
|
||||
class VintageManualHeader extends HTMLElement {
|
||||
static get observedAttributes() {
|
||||
return ['title', 'subtitle', 'animation', 'duration'];
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
}
|
||||
|
||||
render() {
|
||||
const animation = this.getAttribute('animation') || 'lineprint';
|
||||
// Generate appropriate SVG
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('vintage-header', VintageManualHeader);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Reference
|
||||
|
||||
| Animation | File | Cycle | Best For |
|
||||
|-----------|------|-------|----------|
|
||||
| Typewriter | `terminal-header-light-anim-typewriter.svg` | 6s | One-time reveals, loading states |
|
||||
| Print Scan | `terminal-header-light-anim-printscan.svg` | 4s | Continuous ambient animation |
|
||||
| Stamp Press | `terminal-header-light-anim-stamp.svg` | 5s | Dramatic entrances, hero sections |
|
||||
| Registration | `terminal-header-light-anim-registration.svg` | 4s | Subtle ambient animation |
|
||||
| Line Printer | `terminal-header-light-anim-lineprint.svg` | 8s | Headers, document-style layouts |
|
||||
|
||||
---
|
||||
|
||||
*Style Guide Version 1.0 - Created for Awesome Claude Code*
|
||||
Reference in New Issue
Block a user