mindforge-cc 11.5.0 → 11.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/mindforge/skill-tdd.md +53 -0
- package/.agent/mindforge/skills-index.md +118 -0
- package/.agent/mindforge/systematic-debug.md +60 -0
- package/.agent/skills/1password-skill/SKILL.md +156 -0
- package/.agent/skills/1password-skill/references/cli-examples.md +31 -0
- package/.agent/skills/1password-skill/references/get-started.md +21 -0
- package/.agent/skills/article-illustrator/SKILL.md +199 -0
- package/.agent/skills/article-illustrator/references/prompt-construction.md +426 -0
- package/.agent/skills/article-illustrator/references/style-presets.md +80 -0
- package/.agent/skills/article-illustrator/references/styles.md +224 -0
- package/.agent/skills/article-illustrator/references/usage.md +50 -0
- package/.agent/skills/article-illustrator/references/workflow.md +332 -0
- package/.agent/skills/arxiv/SKILL.md +275 -0
- package/.agent/skills/blogwatcher/SKILL.md +130 -0
- package/.agent/skills/code-wiki/SKILL.md +438 -0
- package/.agent/skills/code-wiki/templates/README.md +31 -0
- package/.agent/skills/code-wiki/templates/architecture.md +30 -0
- package/.agent/skills/code-wiki/templates/getting-started.md +47 -0
- package/.agent/skills/code-wiki/templates/module.md +38 -0
- package/.agent/skills/codebase-inspection/SKILL.md +109 -0
- package/.agent/skills/comic-creator/SKILL.md +240 -0
- package/.agent/skills/comic-creator/references/analysis-framework.md +176 -0
- package/.agent/skills/comic-creator/references/auto-selection.md +71 -0
- package/.agent/skills/comic-creator/references/base-prompt.md +98 -0
- package/.agent/skills/comic-creator/references/character-template.md +180 -0
- package/.agent/skills/comic-creator/references/ohmsha-guide.md +85 -0
- package/.agent/skills/comic-creator/references/partial-workflows.md +106 -0
- package/.agent/skills/comic-creator/references/storyboard-template.md +143 -0
- package/.agent/skills/comic-creator/references/workflow.md +401 -0
- package/.agent/skills/concept-diagrams/SKILL.md +355 -0
- package/.agent/skills/concept-diagrams/references/dashboard-patterns.md +43 -0
- package/.agent/skills/concept-diagrams/references/infrastructure-patterns.md +144 -0
- package/.agent/skills/concept-diagrams/references/physical-shape-cookbook.md +42 -0
- package/.agent/skills/creative-ideation/SKILL.md +144 -0
- package/.agent/skills/creative-ideation/references/full-prompt-library.md +110 -0
- package/.agent/skills/devops-cli/SKILL.md +149 -0
- package/.agent/skills/devops-cli/references/app-discovery.md +112 -0
- package/.agent/skills/devops-cli/references/authentication.md +59 -0
- package/.agent/skills/devops-cli/references/cli-reference.md +104 -0
- package/.agent/skills/devops-cli/references/running-apps.md +171 -0
- package/.agent/skills/devops-watchers/SKILL.md +103 -0
- package/.agent/skills/docker-management/SKILL.md +273 -0
- package/.agent/skills/domain-intel/SKILL.md +96 -0
- package/.agent/skills/duckduckgo-search/SKILL.md +230 -0
- package/.agent/skills/github-auth/SKILL.md +240 -0
- package/.agent/skills/github-code-review/SKILL.md +474 -0
- package/.agent/skills/github-code-review/references/review-output-template.md +74 -0
- package/.agent/skills/github-issues/SKILL.md +363 -0
- package/.agent/skills/github-issues/templates/bug-report.md +35 -0
- package/.agent/skills/github-issues/templates/feature-request.md +31 -0
- package/.agent/skills/github-pr-workflow/SKILL.md +360 -0
- package/.agent/skills/github-pr-workflow/references/ci-troubleshooting.md +183 -0
- package/.agent/skills/github-pr-workflow/references/conventional-commits.md +71 -0
- package/.agent/skills/github-pr-workflow/templates/pr-body-bugfix.md +35 -0
- package/.agent/skills/github-pr-workflow/templates/pr-body-feature.md +33 -0
- package/.agent/skills/github-repo-management/SKILL.md +509 -0
- package/.agent/skills/github-repo-management/references/github-api-cheatsheet.md +161 -0
- package/.agent/skills/godmode/SKILL.md +396 -0
- package/.agent/skills/godmode/references/jailbreak-templates.md +128 -0
- package/.agent/skills/godmode/references/refusal-detection.md +142 -0
- package/.agent/skills/hyperframes/SKILL.md +182 -0
- package/.agent/skills/hyperframes/references/cli.md +185 -0
- package/.agent/skills/hyperframes/references/composition.md +129 -0
- package/.agent/skills/hyperframes/references/features.md +289 -0
- package/.agent/skills/hyperframes/references/gsap.md +136 -0
- package/.agent/skills/hyperframes/references/troubleshooting.md +137 -0
- package/.agent/skills/hyperframes/references/website-to-video.md +145 -0
- package/.agent/skills/jupyter-live-kernel/SKILL.md +160 -0
- package/.agent/skills/kanban-orchestrator/SKILL.md +209 -0
- package/.agent/skills/kanban-worker/SKILL.md +188 -0
- package/.agent/skills/llm-wiki/SKILL.md +499 -0
- package/.agent/skills/meme-generation/SKILL.md +122 -0
- package/.agent/skills/node-inspect-debugger/SKILL.md +312 -0
- package/.agent/skills/obsidian/SKILL.md +60 -0
- package/.agent/skills/osint-investigation/SKILL.md +269 -0
- package/.agent/skills/osint-investigation/templates/source-template.md +59 -0
- package/.agent/skills/oss-forensics/SKILL.md +422 -0
- package/.agent/skills/oss-forensics/references/evidence-types.md +89 -0
- package/.agent/skills/oss-forensics/references/github-archive-guide.md +184 -0
- package/.agent/skills/oss-forensics/references/investigation-templates.md +131 -0
- package/.agent/skills/oss-forensics/references/recovery-techniques.md +164 -0
- package/.agent/skills/oss-forensics/templates/forensic-report.md +151 -0
- package/.agent/skills/oss-forensics/templates/malicious-package-report.md +43 -0
- package/.agent/skills/parallel-cli/SKILL.md +384 -0
- package/.agent/skills/pinggy-tunnel/SKILL.md +302 -0
- package/.agent/skills/pixel-art/SKILL.md +209 -0
- package/.agent/skills/pixel-art/references/palettes.md +49 -0
- package/.agent/skills/plan/SKILL.md +331 -0
- package/.agent/skills/polymarket/SKILL.md +75 -0
- package/.agent/skills/polymarket/references/api-endpoints.md +220 -0
- package/.agent/skills/python-debugpy/SKILL.md +368 -0
- package/.agent/skills/requesting-code-review/SKILL.md +273 -0
- package/.agent/skills/research-paper-writing/SKILL.md +2367 -0
- package/.agent/skills/research-paper-writing/references/autoreason-methodology.md +394 -0
- package/.agent/skills/research-paper-writing/references/checklists.md +434 -0
- package/.agent/skills/research-paper-writing/references/citation-workflow.md +563 -0
- package/.agent/skills/research-paper-writing/references/experiment-patterns.md +728 -0
- package/.agent/skills/research-paper-writing/references/human-evaluation.md +476 -0
- package/.agent/skills/research-paper-writing/references/paper-types.md +481 -0
- package/.agent/skills/research-paper-writing/references/reviewer-guidelines.md +433 -0
- package/.agent/skills/research-paper-writing/references/sources.md +191 -0
- package/.agent/skills/research-paper-writing/references/writing-guide.md +474 -0
- package/.agent/skills/research-paper-writing/templates/README.md +251 -0
- package/.agent/skills/rest-graphql-debug/SKILL.md +507 -0
- package/.agent/skills/s6-container-supervision/SKILL.md +171 -0
- package/.agent/skills/scrapling/SKILL.md +328 -0
- package/.agent/skills/sherlock/SKILL.md +186 -0
- package/.agent/skills/simplify-code/SKILL.md +168 -0
- package/.agent/skills/skill-authoring/SKILL.md +158 -0
- package/.agent/skills/spike/SKILL.md +190 -0
- package/.agent/skills/subagent-driven-development/SKILL.md +345 -0
- package/.agent/skills/subagent-driven-development/references/context-budget-discipline.md +53 -0
- package/.agent/skills/subagent-driven-development/references/gates-taxonomy.md +93 -0
- package/.agent/skills/systematic-debugging/SKILL.md +360 -0
- package/.agent/skills/test-driven-development/SKILL.md +336 -0
- package/.agent/skills/video-orchestrator/SKILL.md +194 -0
- package/.agent/skills/video-orchestrator/references/examples.md +227 -0
- package/.agent/skills/video-orchestrator/references/intake.md +166 -0
- package/.agent/skills/video-orchestrator/references/kanban-setup.md +278 -0
- package/.agent/skills/video-orchestrator/references/monitoring.md +180 -0
- package/.agent/skills/video-orchestrator/references/role-archetypes.md +298 -0
- package/.agent/skills/video-orchestrator/references/tool-matrix.md +317 -0
- package/.agent/skills/web-pentest/SKILL.md +332 -0
- package/.agent/skills/web-pentest/references/bypass-techniques.md +133 -0
- package/.agent/skills/web-pentest/references/exploitation-techniques.md +204 -0
- package/.agent/skills/web-pentest/references/scope-enforcement.md +110 -0
- package/.agent/skills/web-pentest/references/vuln-taxonomy.md +81 -0
- package/.agent/skills/web-pentest/templates/authorization.md +69 -0
- package/.agent/skills/web-pentest/templates/pentest-report.md +178 -0
- package/.claude/commands/mindforge/skill-tdd.md +53 -0
- package/.claude/commands/mindforge/skills-index.md +118 -0
- package/.claude/commands/mindforge/systematic-debug.md +60 -0
- package/.mindforge/config.json +2 -2
- package/.mindforge/memory/sync-manifest.json +1 -1
- package/.mindforge/skills/arxiv/SKILL.md +294 -0
- package/.mindforge/skills/blogwatcher/SKILL.md +147 -0
- package/.mindforge/skills/code-wiki/SKILL.md +457 -0
- package/.mindforge/skills/codebase-inspection/SKILL.md +126 -0
- package/.mindforge/skills/concept-diagrams/SKILL.md +373 -0
- package/.mindforge/skills/creative-ideation/SKILL.md +162 -0
- package/.mindforge/skills/domain-intel/SKILL.md +116 -0
- package/.mindforge/skills/duckduckgo-search/SKILL.md +249 -0
- package/.mindforge/skills/github-code-review/SKILL.md +493 -0
- package/.mindforge/skills/github-issues/SKILL.md +382 -0
- package/.mindforge/skills/github-pr-workflow/SKILL.md +379 -0
- package/.mindforge/skills/jupyter-live-kernel/SKILL.md +179 -0
- package/.mindforge/skills/kanban-orchestrator/SKILL.md +227 -0
- package/.mindforge/skills/kanban-worker/SKILL.md +206 -0
- package/.mindforge/skills/meme-generation/SKILL.md +141 -0
- package/.mindforge/skills/obsidian/SKILL.md +80 -0
- package/.mindforge/skills/osint-investigation/SKILL.md +288 -0
- package/.mindforge/skills/oss-forensics/SKILL.md +421 -0
- package/.mindforge/skills/pixel-art/SKILL.md +228 -0
- package/.mindforge/skills/plan/SKILL.md +350 -0
- package/.mindforge/skills/requesting-code-review/SKILL.md +292 -0
- package/.mindforge/skills/research-paper-writing/SKILL.md +2384 -0
- package/.mindforge/skills/scrapling/SKILL.md +345 -0
- package/.mindforge/skills/sherlock/SKILL.md +203 -0
- package/.mindforge/skills/simplify-code/SKILL.md +187 -0
- package/.mindforge/skills/spike/SKILL.md +209 -0
- package/.mindforge/skills/subagent-driven-development/SKILL.md +364 -0
- package/.mindforge/skills/systematic-debugging/SKILL.md +379 -0
- package/.mindforge/skills/test-driven-development/SKILL.md +355 -0
- package/.mindforge/skills/web-pentest/SKILL.md +327 -0
- package/CHANGELOG.md +88 -0
- package/MINDFORGE.md +3 -3
- package/README.md +38 -3
- package/RELEASENOTES.md +100 -0
- package/bin/dashboard/api-router.js +10 -1
- package/bin/governance/approve.js +5 -1
- package/bin/memory/federated-sync.js +11 -2
- package/bin/memory/knowledge-capture.js +10 -1
- package/bin/memory/pillar-health-tracker.js +9 -1
- package/bin/review/ads-engine.js +2 -2
- package/bin/security/trust-boundaries.js +5 -0
- package/docs/getting-started.md +42 -5
- package/package.json +1 -1
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: oss-forensics
|
|
3
|
+
description: "Supply chain investigation, evidence recovery, and forensic analysis for GitHub repositories — deleted commit recovery, force-push detection, IOC extraction, and structured forensic reporting."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
status: stable
|
|
6
|
+
min_mindforge_version: 11.5.1
|
|
7
|
+
triggers: OSS forensics, open source forensics, dependency security, supply chain audit, package audit, open source security, supply chain investigation, github forensics, repository forensics, oss security, audit dependencies, supply chain compromise
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# OSS Security Forensics Skill
|
|
11
|
+
|
|
12
|
+
A 7-phase multi-agent investigation framework for researching open-source supply chain attacks.
|
|
13
|
+
Adapted from RAPTOR's forensics system. Covers GitHub Archive, Wayback Machine, GitHub API,
|
|
14
|
+
local git analysis, IOC extraction, evidence-backed hypothesis formation and validation,
|
|
15
|
+
and final forensic report generation.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## ⚠️ Anti-Hallucination Guardrails
|
|
20
|
+
|
|
21
|
+
Read these before every investigation step. Violating them invalidates the report.
|
|
22
|
+
|
|
23
|
+
1. **Evidence-First Rule**: Every claim in any report, hypothesis, or summary MUST cite at least one evidence ID (`EV-XXXX`). Assertions without citations are forbidden.
|
|
24
|
+
2. **STAY IN YOUR LANE**: Each sub-agent (investigator) has a single data source. Do NOT mix sources. The GH Archive investigator does not query the GitHub API, and vice versa. Role boundaries are hard.
|
|
25
|
+
3. **Fact vs. Hypothesis Separation**: Mark all unverified inferences with `[HYPOTHESIS]`. Only statements verified against original sources may be stated as facts.
|
|
26
|
+
4. **No Evidence Fabrication**: The hypothesis validator MUST mechanically check that every cited evidence ID actually exists in the evidence store before accepting a hypothesis.
|
|
27
|
+
5. **Proof-Required Disproval**: A hypothesis cannot be dismissed without a specific, evidence-backed counter-argument. "No evidence found" is not sufficient to disprove—it only makes a hypothesis inconclusive.
|
|
28
|
+
6. **SHA/URL Double-Verification**: Any commit SHA, URL, or external identifier cited as evidence must be independently confirmed from at least two sources before being marked as verified.
|
|
29
|
+
7. **Suspicious Code Rule**: Never run code found inside the investigated repository locally. Analyze statically only, or use `execute_code` in a sandboxed environment.
|
|
30
|
+
8. **Secret Redaction**: Any API keys, tokens, or credentials discovered during investigation must be redacted in the final report. Log them internally only.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Example Scenarios
|
|
35
|
+
|
|
36
|
+
- **Scenario A: Dependency Confusion**: A malicious package `internal-lib-v2` is uploaded to NPM with a higher version than the internal one. The investigator must track when this package was first seen and if any PushEvents in the target repo updated `package.json` to this version.
|
|
37
|
+
- **Scenario B: Maintainer Takeover**: A long-term contributor's account is used to push a backdoored `.github/workflows/build.yml`. The investigator looks for PushEvents from this user after a long period of inactivity or from a new IP/location (if detectable via BigQuery).
|
|
38
|
+
- **Scenario C: Force-Push Hide**: A developer accidentally commits a production secret, then force-pushes to "fix" it. The investigator uses `git fsck` and GH Archive to recover the original commit SHA and verify what was leaked.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
> **Path convention**: Throughout this skill, `SKILL_DIR` refers to the root of this skill's
|
|
43
|
+
> installation directory (the folder containing this `SKILL.md`). When the skill is loaded,
|
|
44
|
+
> resolve `SKILL_DIR` to the actual path — e.g. `~/.hermes/skills/security/oss-forensics/`
|
|
45
|
+
> or the `optional-skills/` equivalent. All script and template references are relative to it.
|
|
46
|
+
|
|
47
|
+
## Phase 0: Initialization
|
|
48
|
+
|
|
49
|
+
1. Create investigation working directory:
|
|
50
|
+
```bash
|
|
51
|
+
mkdir investigation_$(echo "REPO_NAME" | tr '/' '_')
|
|
52
|
+
cd investigation_$(echo "REPO_NAME" | tr '/' '_')
|
|
53
|
+
```
|
|
54
|
+
2. Initialize the evidence store:
|
|
55
|
+
```bash
|
|
56
|
+
python3 SKILL_DIR/scripts/evidence-store.py --store evidence.json list
|
|
57
|
+
```
|
|
58
|
+
3. Copy the forensic report template:
|
|
59
|
+
```bash
|
|
60
|
+
cp SKILL_DIR/templates/forensic-report.md ./investigation-report.md
|
|
61
|
+
```
|
|
62
|
+
4. Create an `iocs.md` file to track Indicators of Compromise as they are discovered.
|
|
63
|
+
5. Record the investigation start time, target repository, and stated investigation goal.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Phase 1: Prompt Parsing and IOC Extraction
|
|
68
|
+
|
|
69
|
+
**Goal**: Extract all structured investigative targets from the user's request.
|
|
70
|
+
|
|
71
|
+
**Actions**:
|
|
72
|
+
- Parse the user prompt and extract:
|
|
73
|
+
- Target repository (`owner/repo`)
|
|
74
|
+
- Target actors (GitHub handles, email addresses)
|
|
75
|
+
- Time window of interest (commit date ranges, PR timestamps)
|
|
76
|
+
- Provided Indicators of Compromise: commit SHAs, file paths, package names, IP addresses, domains, API keys/tokens, malicious URLs
|
|
77
|
+
- Any linked vendor security reports or blog posts
|
|
78
|
+
|
|
79
|
+
**Tools**: Reasoning only, or `execute_code` for regex extraction from large text blocks.
|
|
80
|
+
|
|
81
|
+
**Output**: Populate `iocs.md` with extracted IOCs. Each IOC must have:
|
|
82
|
+
- Type (from: COMMIT_SHA, FILE_PATH, API_KEY, SECRET, IP_ADDRESS, DOMAIN, PACKAGE_NAME, ACTOR_USERNAME, MALICIOUS_URL, OTHER)
|
|
83
|
+
- Value
|
|
84
|
+
- Source (user-provided, inferred)
|
|
85
|
+
|
|
86
|
+
**Reference**: See [evidence-types.md](./references/evidence-types.md) for IOC taxonomy.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Phase 2: Parallel Evidence Collection
|
|
91
|
+
|
|
92
|
+
Spawn up to 5 specialist investigator sub-agents using `delegate_task` (batch mode, max 3 concurrent). Each investigator has a **single data source** and must not mix sources.
|
|
93
|
+
|
|
94
|
+
> **Orchestrator note**: Pass the IOC list from Phase 1 and the investigation time window in the `context` field of each delegated task.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
### Investigator 1: Local Git Investigator
|
|
99
|
+
|
|
100
|
+
**ROLE BOUNDARY**: You query the LOCAL GIT REPOSITORY ONLY. Do not call any external APIs.
|
|
101
|
+
|
|
102
|
+
**Actions**:
|
|
103
|
+
```bash
|
|
104
|
+
# Clone repository
|
|
105
|
+
git clone https://github.com/OWNER/REPO.git target_repo && cd target_repo
|
|
106
|
+
|
|
107
|
+
# Full commit log with stats
|
|
108
|
+
git log --all --full-history --stat --format="%H|%ae|%an|%ai|%s" > ../git_log.txt
|
|
109
|
+
|
|
110
|
+
# Detect force-push evidence (orphaned/dangling commits)
|
|
111
|
+
git fsck --lost-found --unreachable 2>&1 | grep commit > ../dangling_commits.txt
|
|
112
|
+
|
|
113
|
+
# Check reflog for rewritten history
|
|
114
|
+
git reflog --all > ../reflog.txt
|
|
115
|
+
|
|
116
|
+
# List ALL branches including deleted remote refs
|
|
117
|
+
git branch -a -v > ../branches.txt
|
|
118
|
+
|
|
119
|
+
# Find suspicious large binary additions
|
|
120
|
+
git log --all --diff-filter=A --name-only --format="%H %ai" -- "*.so" "*.dll" "*.exe" "*.bin" > ../binary_additions.txt
|
|
121
|
+
|
|
122
|
+
# Check for GPG signature anomalies
|
|
123
|
+
git log --show-signature --format="%H %ai %aN" > ../signature_check.txt 2>&1
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Evidence to collect** (add via `python3 SKILL_DIR/scripts/evidence-store.py add`):
|
|
127
|
+
- Each dangling commit SHA → type: `git`
|
|
128
|
+
- Force-push evidence (reflog showing history rewrite) → type: `git`
|
|
129
|
+
- Unsigned commits from verified contributors → type: `git`
|
|
130
|
+
- Suspicious binary file additions → type: `git`
|
|
131
|
+
|
|
132
|
+
**Reference**: See [recovery-techniques.md](./references/recovery-techniques.md) for accessing force-pushed commits.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
### Investigator 2: GitHub API Investigator
|
|
137
|
+
|
|
138
|
+
**ROLE BOUNDARY**: You query the GITHUB REST API ONLY. Do not run git commands locally.
|
|
139
|
+
|
|
140
|
+
**Actions**:
|
|
141
|
+
```bash
|
|
142
|
+
# Commits (paginated)
|
|
143
|
+
curl -s "https://api.github.com/repos/OWNER/REPO/commits?per_page=100" > api_commits.json
|
|
144
|
+
|
|
145
|
+
# Pull Requests including closed/deleted
|
|
146
|
+
curl -s "https://api.github.com/repos/OWNER/REPO/pulls?state=all&per_page=100" > api_prs.json
|
|
147
|
+
|
|
148
|
+
# Issues
|
|
149
|
+
curl -s "https://api.github.com/repos/OWNER/REPO/issues?state=all&per_page=100" > api_issues.json
|
|
150
|
+
|
|
151
|
+
# Contributors and collaborator changes
|
|
152
|
+
curl -s "https://api.github.com/repos/OWNER/REPO/contributors" > api_contributors.json
|
|
153
|
+
|
|
154
|
+
# Repository events (last 300)
|
|
155
|
+
curl -s "https://api.github.com/repos/OWNER/REPO/events?per_page=100" > api_events.json
|
|
156
|
+
|
|
157
|
+
# Check specific suspicious commit SHA details
|
|
158
|
+
curl -s "https://api.github.com/repos/OWNER/REPO/git/commits/SHA" > commit_detail.json
|
|
159
|
+
|
|
160
|
+
# Releases
|
|
161
|
+
curl -s "https://api.github.com/repos/OWNER/REPO/releases?per_page=100" > api_releases.json
|
|
162
|
+
|
|
163
|
+
# Check if a specific commit exists (force-pushed commits may 404 on commits/ but succeed on git/commits/)
|
|
164
|
+
curl -s "https://api.github.com/repos/OWNER/REPO/commits/SHA" | jq .sha
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Cross-reference targets** (flag discrepancies as evidence):
|
|
168
|
+
- PR exists in archive but missing from API → evidence of deletion
|
|
169
|
+
- Contributor in archive events but not in contributors list → evidence of permission revocation
|
|
170
|
+
- Commit in archive PushEvents but not in API commit list → evidence of force-push/deletion
|
|
171
|
+
|
|
172
|
+
**Reference**: See [evidence-types.md](./references/evidence-types.md) for GH event types.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
### Investigator 3: Wayback Machine Investigator
|
|
177
|
+
|
|
178
|
+
**ROLE BOUNDARY**: You query the WAYBACK MACHINE CDX API ONLY. Do not use the GitHub API.
|
|
179
|
+
|
|
180
|
+
**Goal**: Recover deleted GitHub pages (READMEs, issues, PRs, releases, wiki pages).
|
|
181
|
+
|
|
182
|
+
**Actions**:
|
|
183
|
+
```bash
|
|
184
|
+
# Search for archived snapshots of the repo main page
|
|
185
|
+
curl -s "https://web.archive.org/cdx/search/cdx?url=github.com/OWNER/REPO&output=json&limit=100&from=YYYYMMDD&to=YYYYMMDD" > wayback_main.json
|
|
186
|
+
|
|
187
|
+
# Search for a specific deleted issue
|
|
188
|
+
curl -s "https://web.archive.org/cdx/search/cdx?url=github.com/OWNER/REPO/issues/NUM&output=json&limit=50" > wayback_issue_NUM.json
|
|
189
|
+
|
|
190
|
+
# Search for a specific deleted PR
|
|
191
|
+
curl -s "https://web.archive.org/cdx/search/cdx?url=github.com/OWNER/REPO/pull/NUM&output=json&limit=50" > wayback_pr_NUM.json
|
|
192
|
+
|
|
193
|
+
# Fetch the best snapshot of a page
|
|
194
|
+
# Use the Wayback Machine URL: https://web.archive.org/web/TIMESTAMP/ORIGINAL_URL
|
|
195
|
+
# Example: https://web.archive.org/web/20240101000000*/github.com/OWNER/REPO
|
|
196
|
+
|
|
197
|
+
# Advanced: Search for deleted releases/tags
|
|
198
|
+
curl -s "https://web.archive.org/cdx/search/cdx?url=github.com/OWNER/REPO/releases/tag/*&output=json" > wayback_tags.json
|
|
199
|
+
|
|
200
|
+
# Advanced: Search for historical wiki changes
|
|
201
|
+
curl -s "https://web.archive.org/cdx/search/cdx?url=github.com/OWNER/REPO/wiki/*&output=json" > wayback_wiki.json
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Evidence to collect**:
|
|
205
|
+
- Archived snapshots of deleted issues/PRs with their content
|
|
206
|
+
- Historical README versions showing changes
|
|
207
|
+
- Evidence of content present in archive but missing from current GitHub state
|
|
208
|
+
|
|
209
|
+
**Reference**: See [github-archive-guide.md](./references/github-archive-guide.md) for CDX API parameters.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
### Investigator 4: GH Archive / BigQuery Investigator
|
|
214
|
+
|
|
215
|
+
**ROLE BOUNDARY**: You query GITHUB ARCHIVE via BIGQUERY ONLY. This is a tamper-proof record of all public GitHub events.
|
|
216
|
+
|
|
217
|
+
> **Prerequisites**: Requires Google Cloud credentials with BigQuery access (`gcloud auth application-default login`). If unavailable, skip this investigator and note it in the report.
|
|
218
|
+
|
|
219
|
+
**Cost Optimization Rules** (MANDATORY):
|
|
220
|
+
1. ALWAYS run a `--dry_run` before every query to estimate cost.
|
|
221
|
+
2. Use `_TABLE_SUFFIX` to filter by date range and minimize scanned data.
|
|
222
|
+
3. Only SELECT the columns you need.
|
|
223
|
+
4. Add a LIMIT unless aggregating.
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
# Template: safe BigQuery query for PushEvents to OWNER/REPO
|
|
227
|
+
bq query --use_legacy_sql=false --dry_run "
|
|
228
|
+
SELECT created_at, actor.login, payload.commits, payload.before, payload.head,
|
|
229
|
+
payload.size, payload.distinct_size
|
|
230
|
+
FROM \`githubarchive.month.*\`
|
|
231
|
+
WHERE _TABLE_SUFFIX BETWEEN 'YYYYMM' AND 'YYYYMM'
|
|
232
|
+
AND type = 'PushEvent'
|
|
233
|
+
AND repo.name = 'OWNER/REPO'
|
|
234
|
+
LIMIT 1000
|
|
235
|
+
"
|
|
236
|
+
# If cost is acceptable, re-run without --dry_run
|
|
237
|
+
|
|
238
|
+
# Detect force-pushes: zero-distinct_size PushEvents mean commits were force-erased
|
|
239
|
+
# payload.distinct_size = 0 AND payload.size > 0 → force push indicator
|
|
240
|
+
|
|
241
|
+
# Check for deleted branch events
|
|
242
|
+
bq query --use_legacy_sql=false "
|
|
243
|
+
SELECT created_at, actor.login, payload.ref, payload.ref_type
|
|
244
|
+
FROM \`githubarchive.month.*\`
|
|
245
|
+
WHERE _TABLE_SUFFIX BETWEEN 'YYYYMM' AND 'YYYYMM'
|
|
246
|
+
AND type = 'DeleteEvent'
|
|
247
|
+
AND repo.name = 'OWNER/REPO'
|
|
248
|
+
LIMIT 200
|
|
249
|
+
"
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**Evidence to collect**:
|
|
253
|
+
- Force-push events (payload.size > 0, payload.distinct_size = 0)
|
|
254
|
+
- DeleteEvents for branches/tags
|
|
255
|
+
- WorkflowRunEvents for suspicious CI/CD automation
|
|
256
|
+
- PushEvents that precede a "gap" in the git log (evidence of rewrite)
|
|
257
|
+
|
|
258
|
+
**Reference**: See [github-archive-guide.md](./references/github-archive-guide.md) for all 12 event types and query patterns.
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
### Investigator 5: IOC Enrichment Investigator
|
|
263
|
+
|
|
264
|
+
**ROLE BOUNDARY**: You enrich EXISTING IOCs from Phase 1 using passive public sources ONLY. Do not execute any code from the target repository.
|
|
265
|
+
|
|
266
|
+
**Actions**:
|
|
267
|
+
- For each commit SHA: attempt recovery via direct GitHub URL (`github.com/OWNER/REPO/commit/SHA.patch`)
|
|
268
|
+
- For each domain/IP: check passive DNS, WHOIS records (via `web_extract` on public WHOIS services)
|
|
269
|
+
- For each package name: check npm/PyPI for matching malicious package reports
|
|
270
|
+
- For each actor username: check GitHub profile, contribution history, account age
|
|
271
|
+
- Recover force-pushed commits using 3 methods (see [recovery-techniques.md](./references/recovery-techniques.md))
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Phase 3: Evidence Consolidation
|
|
276
|
+
|
|
277
|
+
After all investigators complete:
|
|
278
|
+
|
|
279
|
+
1. Run `python3 SKILL_DIR/scripts/evidence-store.py --store evidence.json list` to see all collected evidence.
|
|
280
|
+
2. For each piece of evidence, verify the `content_sha256` hash matches the original source.
|
|
281
|
+
3. Group evidence by:
|
|
282
|
+
- **Timeline**: Sort all timestamped evidence chronologically
|
|
283
|
+
- **Actor**: Group by GitHub handle or email
|
|
284
|
+
- **IOC**: Link evidence to the IOC it relates to
|
|
285
|
+
4. Identify **discrepancies**: items present in one source but absent in another (key deletion indicators).
|
|
286
|
+
5. Flag evidence as `[VERIFIED]` (confirmed from 2+ independent sources) or `[UNVERIFIED]` (single source only).
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Phase 4: Hypothesis Formation
|
|
291
|
+
|
|
292
|
+
A hypothesis must:
|
|
293
|
+
- State a specific claim (e.g., "Actor X force-pushed to BRANCH on DATE to erase commit SHA")
|
|
294
|
+
- Cite at least 2 evidence IDs that support it (`EV-XXXX`, `EV-YYYY`)
|
|
295
|
+
- Identify what evidence would disprove it
|
|
296
|
+
- Be labeled `[HYPOTHESIS]` until validated
|
|
297
|
+
|
|
298
|
+
**Common hypothesis templates** (see [investigation-templates.md](./references/investigation-templates.md)):
|
|
299
|
+
- Maintainer Compromise: legitimate account used post-takeover to inject malicious code
|
|
300
|
+
- Dependency Confusion: package name squatting to intercept installs
|
|
301
|
+
- CI/CD Injection: malicious workflow changes to run code during builds
|
|
302
|
+
- Typosquatting: near-identical package name targeting misspellers
|
|
303
|
+
- Credential Leak: token/key accidentally committed then force-pushed to erase
|
|
304
|
+
|
|
305
|
+
For each hypothesis, spawn a `delegate_task` sub-agent to attempt to find disconfirming evidence before confirming.
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Phase 5: Hypothesis Validation
|
|
310
|
+
|
|
311
|
+
The validator sub-agent MUST mechanically check:
|
|
312
|
+
|
|
313
|
+
1. For each hypothesis, extract all cited evidence IDs.
|
|
314
|
+
2. Verify each ID exists in `evidence.json` (hard failure if any ID is missing → hypothesis rejected as potentially fabricated).
|
|
315
|
+
3. Verify each `[VERIFIED]` piece of evidence was confirmed from 2+ sources.
|
|
316
|
+
4. Check logical consistency: does the timeline depicted by the evidence support the hypothesis?
|
|
317
|
+
5. Check for alternative explanations: could the same evidence pattern arise from a benign cause?
|
|
318
|
+
|
|
319
|
+
**Output**:
|
|
320
|
+
- `VALIDATED`: All evidence cited, verified, logically consistent, no plausible alternative explanation.
|
|
321
|
+
- `INCONCLUSIVE`: Evidence supports hypothesis but alternative explanations exist or evidence is insufficient.
|
|
322
|
+
- `REJECTED`: Missing evidence IDs, unverified evidence cited as fact, logical inconsistency detected.
|
|
323
|
+
|
|
324
|
+
Rejected hypotheses feed back into Phase 4 for refinement (max 3 iterations).
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Phase 6: Final Report Generation
|
|
329
|
+
|
|
330
|
+
Populate `investigation-report.md` using the template in [forensic-report.md](./templates/forensic-report.md).
|
|
331
|
+
|
|
332
|
+
**Mandatory sections**:
|
|
333
|
+
- Executive Summary: one-paragraph verdict (Compromised / Clean / Inconclusive) with confidence level
|
|
334
|
+
- Timeline: chronological reconstruction of all significant events with evidence citations
|
|
335
|
+
- Validated Hypotheses: each with status and supporting evidence IDs
|
|
336
|
+
- Evidence Registry: table of all `EV-XXXX` entries with source, type, and verification status
|
|
337
|
+
- IOC List: all extracted and enriched Indicators of Compromise
|
|
338
|
+
- Chain of Custody: how evidence was collected, from what sources, at what timestamps
|
|
339
|
+
- Recommendations: immediate mitigations if compromise detected; monitoring recommendations
|
|
340
|
+
|
|
341
|
+
**Report rules**:
|
|
342
|
+
- Every factual claim must have at least one `[EV-XXXX]` citation
|
|
343
|
+
- Executive Summary must state confidence level (High / Medium / Low)
|
|
344
|
+
- All secrets/credentials must be redacted to `[REDACTED]`
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## Phase 7: Completion
|
|
349
|
+
|
|
350
|
+
1. Run final evidence count: `python3 SKILL_DIR/scripts/evidence-store.py --store evidence.json list`
|
|
351
|
+
2. Archive the full investigation directory.
|
|
352
|
+
3. If compromise is confirmed:
|
|
353
|
+
- List immediate mitigations (rotate credentials, pin dependency hashes, notify affected users)
|
|
354
|
+
- Identify affected versions/packages
|
|
355
|
+
- Note disclosure obligations (if a public package: coordinate with the package registry)
|
|
356
|
+
4. Present the final `investigation-report.md` to the user.
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Ethical Use Guidelines
|
|
361
|
+
|
|
362
|
+
This skill is designed for **defensive security investigation** — protecting open-source software from supply chain attacks. It must not be used for:
|
|
363
|
+
|
|
364
|
+
- **Harassment or stalking** of contributors or maintainers
|
|
365
|
+
- **Doxing** — correlating GitHub activity to real identities for malicious purposes
|
|
366
|
+
- **Competitive intelligence** — investigating proprietary or internal repositories without authorization
|
|
367
|
+
- **False accusations** — publishing investigation results without validated evidence (see anti-hallucination guardrails)
|
|
368
|
+
|
|
369
|
+
Investigations should be conducted with the principle of **minimal intrusion**: collect only the evidence necessary to validate or refute the hypothesis. When publishing results, follow responsible disclosure practices and coordinate with affected maintainers before public disclosure.
|
|
370
|
+
|
|
371
|
+
If the investigation reveals a genuine compromise, follow the coordinated vulnerability disclosure process:
|
|
372
|
+
1. Notify the repository maintainers privately first
|
|
373
|
+
2. Allow reasonable time for remediation (typically 90 days)
|
|
374
|
+
3. Coordinate with package registries (npm, PyPI, etc.) if published packages are affected
|
|
375
|
+
4. File a CVE if appropriate
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## API Rate Limiting
|
|
380
|
+
|
|
381
|
+
GitHub REST API enforces rate limits that will interrupt large investigations if not managed.
|
|
382
|
+
|
|
383
|
+
**Authenticated requests**: 5,000/hour (requires `GITHUB_TOKEN` env var or `gh` CLI auth)
|
|
384
|
+
**Unauthenticated requests**: 60/hour (unusable for investigations)
|
|
385
|
+
|
|
386
|
+
**Best practices**:
|
|
387
|
+
- Always authenticate: `export GITHUB_TOKEN=ghp_...` or use `gh` CLI (auto-authenticates)
|
|
388
|
+
- Use conditional requests (`If-None-Match` / `If-Modified-Since` headers) to avoid consuming quota on unchanged data
|
|
389
|
+
- For paginated endpoints, fetch all pages in sequence — don't parallelize against the same endpoint
|
|
390
|
+
- Check `X-RateLimit-Remaining` header; if below 100, pause for `X-RateLimit-Reset` timestamp
|
|
391
|
+
- BigQuery has its own quotas (10 TiB/day free tier) — always dry-run first
|
|
392
|
+
- Wayback Machine CDX API: no formal rate limit, but be courteous (1-2 req/sec max)
|
|
393
|
+
|
|
394
|
+
If rate-limited mid-investigation, record the partial results in the evidence store and note the limitation in the report.
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## Reference Materials
|
|
399
|
+
|
|
400
|
+
- [github-archive-guide.md](./references/github-archive-guide.md) — BigQuery queries, CDX API, 12 event types
|
|
401
|
+
- [evidence-types.md](./references/evidence-types.md) — IOC taxonomy, evidence source types, observation types
|
|
402
|
+
- [recovery-techniques.md](./references/recovery-techniques.md) — Recovering deleted commits, PRs, issues
|
|
403
|
+
- [investigation-templates.md](./references/investigation-templates.md) — Pre-built hypothesis templates per attack type
|
|
404
|
+
- [evidence-store.py](./scripts/evidence-store.py) — CLI tool for managing the evidence JSON store
|
|
405
|
+
- [forensic-report.md](./templates/forensic-report.md) — Structured report template
|
|
406
|
+
|
|
407
|
+
## Mandatory actions when this skill is active
|
|
408
|
+
|
|
409
|
+
Before applying this skill:
|
|
410
|
+
- [ ] Read the task requirements fully before acting
|
|
411
|
+
- [ ] Confirm you understand the goal and constraints
|
|
412
|
+
- [ ] Check for existing work or prior context in the codebase
|
|
413
|
+
|
|
414
|
+
While working:
|
|
415
|
+
- [ ] Follow the methodology described above step by step
|
|
416
|
+
- [ ] Document any decisions or findings as you go
|
|
417
|
+
|
|
418
|
+
After completing:
|
|
419
|
+
- [ ] Self-check: does the output satisfy the original requirement?
|
|
420
|
+
- [ ] Verify no regressions or unintended side effects
|
|
421
|
+
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pixel-art
|
|
3
|
+
description: "Pixel art w/ era palettes (NES, Game Boy, PICO-8)."
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
status: stable
|
|
6
|
+
min_mindforge_version: 11.5.1
|
|
7
|
+
triggers: pixel art, create pixel art, sprite design, pixel graphics, make pixel art, pixel character, pixel sprite, retro pixel art, pixel game art, 8-bit art, pixel illustration, pixel image
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Pixel Art
|
|
11
|
+
|
|
12
|
+
Convert any image into retro pixel art, then optionally animate it into a short
|
|
13
|
+
MP4 or GIF with era-appropriate effects (rain, fireflies, snow, embers).
|
|
14
|
+
|
|
15
|
+
Two scripts ship with this skill:
|
|
16
|
+
|
|
17
|
+
- `scripts/pixel_art.py` — photo → pixel-art PNG (Floyd-Steinberg dithering)
|
|
18
|
+
- `scripts/pixel_art_video.py` — pixel-art PNG → animated MP4 (+ optional GIF)
|
|
19
|
+
|
|
20
|
+
Each is importable or runnable directly. Presets snap to hardware palettes
|
|
21
|
+
when you want era-accurate colors (NES, Game Boy, PICO-8, etc.), or use
|
|
22
|
+
adaptive N-color quantization for arcade/SNES-style looks.
|
|
23
|
+
|
|
24
|
+
## When to Use
|
|
25
|
+
|
|
26
|
+
- User wants retro pixel art from a source image
|
|
27
|
+
- User asks for NES / Game Boy / PICO-8 / C64 / arcade / SNES styling
|
|
28
|
+
- User wants a short looping animation (rain scene, night sky, snow, etc.)
|
|
29
|
+
- Posters, album covers, social posts, sprites, characters, avatars
|
|
30
|
+
|
|
31
|
+
## Workflow
|
|
32
|
+
|
|
33
|
+
Before generating, confirm the style with the user. Different presets produce
|
|
34
|
+
very different outputs and regenerating is costly.
|
|
35
|
+
|
|
36
|
+
### Step 1 — Offer a style
|
|
37
|
+
|
|
38
|
+
Call `clarify` with 4 representative presets. Pick the set based on what the
|
|
39
|
+
user asked for — don't just dump all 14.
|
|
40
|
+
|
|
41
|
+
Default menu when the user's intent is unclear:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
clarify(
|
|
45
|
+
question="Which pixel-art style do you want?",
|
|
46
|
+
choices=[
|
|
47
|
+
"arcade — bold, chunky 80s cabinet feel (16 colors, 8px)",
|
|
48
|
+
"nes — Nintendo 8-bit hardware palette (54 colors, 8px)",
|
|
49
|
+
"gameboy — 4-shade green Game Boy DMG",
|
|
50
|
+
"snes — cleaner 16-bit look (32 colors, 4px)",
|
|
51
|
+
],
|
|
52
|
+
)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
When the user already named an era (e.g. "80s arcade", "Gameboy"), skip
|
|
56
|
+
`clarify` and use the matching preset directly.
|
|
57
|
+
|
|
58
|
+
### Step 2 — Offer animation (optional)
|
|
59
|
+
|
|
60
|
+
If the user asked for a video/GIF, or the output might benefit from motion,
|
|
61
|
+
ask which scene:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
clarify(
|
|
65
|
+
question="Want to animate it? Pick a scene or skip.",
|
|
66
|
+
choices=[
|
|
67
|
+
"night — stars + fireflies + leaves",
|
|
68
|
+
"urban — rain + neon pulse",
|
|
69
|
+
"snow — falling snowflakes",
|
|
70
|
+
"skip — just the image",
|
|
71
|
+
],
|
|
72
|
+
)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Do NOT call `clarify` more than twice in a row. One for style, one for scene if
|
|
76
|
+
animation is on the table. If the user explicitly asked for a specific style
|
|
77
|
+
and scene in their message, skip `clarify` entirely.
|
|
78
|
+
|
|
79
|
+
### Step 3 — Generate
|
|
80
|
+
|
|
81
|
+
Run `pixel_art()` first; if animation was requested, chain into
|
|
82
|
+
`pixel_art_video()` on the result.
|
|
83
|
+
|
|
84
|
+
## Preset Catalog
|
|
85
|
+
|
|
86
|
+
| Preset | Era | Palette | Block | Best for |
|
|
87
|
+
|--------|-----|---------|-------|----------|
|
|
88
|
+
| `arcade` | 80s arcade | adaptive 16 | 8px | Bold posters, hero art |
|
|
89
|
+
| `snes` | 16-bit | adaptive 32 | 4px | Characters, detailed scenes |
|
|
90
|
+
| `nes` | 8-bit | NES (54) | 8px | True NES look |
|
|
91
|
+
| `gameboy` | DMG handheld | 4 green shades | 8px | Monochrome Game Boy |
|
|
92
|
+
| `gameboy_pocket` | Pocket handheld | 4 grey shades | 8px | Mono GB Pocket |
|
|
93
|
+
| `pico8` | PICO-8 | 16 fixed | 6px | Fantasy-console look |
|
|
94
|
+
| `c64` | Commodore 64 | 16 fixed | 8px | 8-bit home computer |
|
|
95
|
+
| `apple2` | Apple II hi-res | 6 fixed | 10px | Extreme retro, 6 colors |
|
|
96
|
+
| `teletext` | BBC Teletext | 8 pure | 10px | Chunky primary colors |
|
|
97
|
+
| `mspaint` | Windows MS Paint | 24 fixed | 8px | Nostalgic desktop |
|
|
98
|
+
| `mono_green` | CRT phosphor | 2 green | 6px | Terminal/CRT aesthetic |
|
|
99
|
+
| `mono_amber` | CRT amber | 2 amber | 6px | Amber monitor look |
|
|
100
|
+
| `neon` | Cyberpunk | 10 neons | 6px | Vaporwave/cyber |
|
|
101
|
+
| `pastel` | Soft pastel | 10 pastels | 6px | Kawaii / gentle |
|
|
102
|
+
|
|
103
|
+
Named palettes live in `scripts/palettes.py` (see `references/palettes.md` for
|
|
104
|
+
the complete list — 28 named palettes total). Any preset can be overridden:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
pixel_art("in.png", "out.png", preset="snes", palette="PICO_8", block=6)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Scene Catalog (for video)
|
|
111
|
+
|
|
112
|
+
| Scene | Effects |
|
|
113
|
+
|-------|---------|
|
|
114
|
+
| `night` | Twinkling stars + fireflies + drifting leaves |
|
|
115
|
+
| `dusk` | Fireflies + sparkles |
|
|
116
|
+
| `tavern` | Dust motes + warm sparkles |
|
|
117
|
+
| `indoor` | Dust motes |
|
|
118
|
+
| `urban` | Rain + neon pulse |
|
|
119
|
+
| `nature` | Leaves + fireflies |
|
|
120
|
+
| `magic` | Sparkles + fireflies |
|
|
121
|
+
| `storm` | Rain + lightning |
|
|
122
|
+
| `underwater` | Bubbles + light sparkles |
|
|
123
|
+
| `fire` | Embers + sparkles |
|
|
124
|
+
| `snow` | Snowflakes + sparkles |
|
|
125
|
+
| `desert` | Heat shimmer + dust |
|
|
126
|
+
|
|
127
|
+
## Invocation Patterns
|
|
128
|
+
|
|
129
|
+
### Python (import)
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
import sys
|
|
133
|
+
sys.path.insert(0, "/home/teknium/.hermes/skills/creative/pixel-art/scripts")
|
|
134
|
+
from pixel_art import pixel_art
|
|
135
|
+
from pixel_art_video import pixel_art_video
|
|
136
|
+
|
|
137
|
+
# 1. Convert to pixel art
|
|
138
|
+
pixel_art("/path/to/photo.jpg", "/tmp/pixel.png", preset="nes")
|
|
139
|
+
|
|
140
|
+
# 2. Animate (optional)
|
|
141
|
+
pixel_art_video(
|
|
142
|
+
"/tmp/pixel.png",
|
|
143
|
+
"/tmp/pixel.mp4",
|
|
144
|
+
scene="night",
|
|
145
|
+
duration=6,
|
|
146
|
+
fps=15,
|
|
147
|
+
seed=42,
|
|
148
|
+
export_gif=True,
|
|
149
|
+
)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### CLI
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
cd /home/teknium/.hermes/skills/creative/pixel-art/scripts
|
|
156
|
+
|
|
157
|
+
python pixel_art.py in.jpg out.png --preset gameboy
|
|
158
|
+
python pixel_art.py in.jpg out.png --preset snes --palette PICO_8 --block 6
|
|
159
|
+
|
|
160
|
+
python pixel_art_video.py out.png out.mp4 --scene night --duration 6 --gif
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Pipeline Rationale
|
|
164
|
+
|
|
165
|
+
**Pixel conversion:**
|
|
166
|
+
1. Boost contrast/color/sharpness (stronger for smaller palettes)
|
|
167
|
+
2. Posterize to simplify tonal regions before quantization
|
|
168
|
+
3. Downscale by `block` with `Image.NEAREST` (hard pixels, no interpolation)
|
|
169
|
+
4. Quantize with Floyd-Steinberg dithering — against either an adaptive
|
|
170
|
+
N-color palette OR a named hardware palette
|
|
171
|
+
5. Upscale back with `Image.NEAREST`
|
|
172
|
+
|
|
173
|
+
Quantizing AFTER downscale keeps dithering aligned with the final pixel grid.
|
|
174
|
+
Quantizing before would waste error-diffusion on detail that disappears.
|
|
175
|
+
|
|
176
|
+
**Video overlay:**
|
|
177
|
+
- Copies the base frame each tick (static background)
|
|
178
|
+
- Overlays stateless-per-frame particle draws (one function per effect)
|
|
179
|
+
- Encodes via ffmpeg `libx264 -pix_fmt yuv420p -crf 18`
|
|
180
|
+
- Optional GIF via `palettegen` + `paletteuse`
|
|
181
|
+
|
|
182
|
+
## Dependencies
|
|
183
|
+
|
|
184
|
+
- Python 3.9+
|
|
185
|
+
- Pillow (`pip install Pillow`)
|
|
186
|
+
- ffmpeg on PATH (only needed for video — install this package)
|
|
187
|
+
|
|
188
|
+
## Pitfalls
|
|
189
|
+
|
|
190
|
+
- Pallet keys are case-sensitive (`"NES"`, `"PICO_8"`, `"GAMEBOY_ORIGINAL"`).
|
|
191
|
+
- Very small sources (<100px wide) collapse under 8-10px blocks. Upscale the
|
|
192
|
+
source first if it's tiny.
|
|
193
|
+
- Fractional `block` or `palette` will break quantization — keep them positive ints.
|
|
194
|
+
- Animation particle counts are tuned for ~640x480 canvases. On very large
|
|
195
|
+
images you may want a second pass with a different seed for density.
|
|
196
|
+
- `mono_green` / `mono_amber` force `color=0.0` (desaturate). If you override
|
|
197
|
+
and keep chroma, the 2-color palette can produce stripes on smooth regions.
|
|
198
|
+
- `clarify` loop: call it at most twice per turn (style, then scene). Don't
|
|
199
|
+
pepper the user with more picks.
|
|
200
|
+
|
|
201
|
+
## Verification
|
|
202
|
+
|
|
203
|
+
- PNG is created at the output path
|
|
204
|
+
- Clear square pixel blocks visible at the preset's block size
|
|
205
|
+
- Color count matches preset (eyeball the image or run `Image.open(p).getcolors()`)
|
|
206
|
+
- Video is a valid MP4 (`ffprobe` can open it) with non-zero size
|
|
207
|
+
|
|
208
|
+
## Attribution
|
|
209
|
+
|
|
210
|
+
Named hardware palettes and the procedural animation loops in `pixel_art_video.py`
|
|
211
|
+
are ported from [pixel-art-studio](https://github.com/Synero/pixel-art-studio)
|
|
212
|
+
(MIT). See `ATTRIBUTION.md` in this skill directory for details.
|
|
213
|
+
|
|
214
|
+
## Mandatory actions when this skill is active
|
|
215
|
+
|
|
216
|
+
Before applying this skill:
|
|
217
|
+
- [ ] Read the task requirements fully before acting
|
|
218
|
+
- [ ] Confirm you understand the goal and constraints
|
|
219
|
+
- [ ] Check for existing work or prior context in the codebase
|
|
220
|
+
|
|
221
|
+
While working:
|
|
222
|
+
- [ ] Follow the methodology described above step by step
|
|
223
|
+
- [ ] Document any decisions or findings as you go
|
|
224
|
+
|
|
225
|
+
After completing:
|
|
226
|
+
- [ ] Self-check: does the output satisfy the original requirement?
|
|
227
|
+
- [ ] Verify no regressions or unintended side effects
|
|
228
|
+
|