claude-mcp-workflow 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +4 -2
- package/README.md +37 -0
- package/build/engine.d.ts +13 -1
- package/build/engine.d.ts.map +1 -1
- package/build/engine.js +41 -2
- package/build/engine.js.map +1 -1
- package/build/types.d.ts +20 -20
- package/build/types.js +1 -1
- package/build/types.js.map +1 -1
- package/hooks/hooks.json +4 -2
- package/hooks/workflow-cleanup.sh +8 -4
- package/hooks/workflow-start.sh +60 -32
- package/package.json +1 -1
- package/templates/bug-fix.yaml +98 -16
- package/templates/code-review.yaml +30 -12
- package/templates/coding.yaml +49 -4
- package/templates/debugging.yaml +39 -14
- package/templates/explore.yaml +48 -14
- package/templates/file-code.yaml +13 -4
- package/templates/file-review.yaml +25 -6
- package/templates/github-init.yaml +24 -8
- package/templates/investigate.yaml +13 -4
- package/templates/master.yaml +16 -13
- package/templates/new-feature.yaml +24 -26
- package/templates/planning.yaml +34 -7
- package/templates/reflection.yaml +11 -4
- package/templates/review-push.yaml +26 -7
- package/templates/skills/architecture/SKILL.md +131 -1
- package/templates/skills/aws-lambda/SKILL.md +9 -9
- package/templates/skills/browser-verify/SKILL.md +58 -0
- package/templates/skills/build-cmake/SKILL.md +24 -8
- package/templates/skills/ci-github-actions/SKILL.md +34 -18
- package/templates/skills/claude-code-config/SKILL.md +41 -19
- package/templates/skills/cleanup/SKILL.md +57 -0
- package/templates/skills/coding-skill-selector/SKILL.md +2 -1
- package/templates/skills/debug-bridge-scaffold/SKILL.md +98 -0
- package/templates/skills/domain-gamedev/SKILL.md +56 -6
- package/templates/skills/domain-pixi/SKILL.md +256 -7
- package/templates/skills/domain-reid/SKILL.md +39 -5
- package/templates/skills/domain-yolo/SKILL.md +18 -7
- package/templates/skills/ide-zed/SKILL.md +23 -0
- package/templates/skills/lang-as3/SKILL.md +7 -5
- package/templates/skills/lang-haxe/SKILL.md +538 -19
- package/templates/skills/lang-python/SKILL.md +6 -2
- package/templates/skills/math/SKILL.md +64 -2
- package/templates/skills/mcp-setup/SKILL.md +14 -2
- package/templates/skills/preferences/SKILL.md +10 -10
- package/templates/skills/skill-manager/SKILL.md +264 -0
- package/templates/skills/target-openfl-native/SKILL.md +52 -17
- package/templates/skills/target-openfl-native/references/build-and-versions.md +7 -4
- package/templates/skills/task-delegation/SKILL.md +76 -4
- package/templates/skills/web-reading/SKILL.md +33 -25
- package/templates/skills/workflow-authoring/SKILL.md +47 -12
- package/templates/subagent.yaml +29 -8
- package/templates/testing.yaml +64 -10
- package/templates/web-research.yaml +23 -13
|
@@ -9,8 +9,12 @@ description: Python language gotchas
|
|
|
9
9
|
|
|
10
10
|
```python
|
|
11
11
|
results = [c for raw in data if (c := normalize(raw)) is not None]
|
|
12
|
-
# c IS accessible outside the comprehension
|
|
12
|
+
# c IS accessible outside the comprehension (PEP 572 design) —
|
|
13
|
+
# but only if the walrus actually ran: with an empty `data`, reading c
|
|
14
|
+
# raises NameError. It runs even for filtered-out elements (the walrus
|
|
15
|
+
# sits in the condition), so c holds the last *evaluated* value, not the
|
|
16
|
+
# last *kept* one.
|
|
13
17
|
# Unlike regular loop variables, := leaks to enclosing scope
|
|
14
18
|
```
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
The common confident claim "c is NOT accessible outside" is wrong — the walrus operator in comprehensions intentionally binds in the containing scope.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: math
|
|
3
|
-
description: Math overflow
|
|
3
|
+
description: Math gotchas — integer overflow boundaries, cross-runtime float parity (tan/pow ULP drift), FP modulo-wrap pitfalls
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Math — Verified Gotchas
|
|
@@ -10,5 +10,67 @@ description: Math overflow boundary gotchas
|
|
|
10
10
|
| Type | Last fits | First overflow |
|
|
11
11
|
|------|-----------|----------------|
|
|
12
12
|
| Int64 | C(66, 33) = 7,219,428,434,016,265,740 | C(67, 33) |
|
|
13
|
+
| UInt64 | C(67, 33) = 14,226,520,737,620,288,370 | C(68, 34) |
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
Models consistently underestimate this boundary (a common wrong answer is n=62; correct is n=66 for Int64).
|
|
16
|
+
|
|
17
|
+
**Result vs computation**: the table bounds the RESULT. Intermediate products in the usual `res = res * (n-k+i) / i` loop overflow earlier (the multiply happens before the divide) — the last few safe n need 128-bit intermediates or a divide-first formulation.
|
|
18
|
+
|
|
19
|
+
## Cross-runtime trig: V8 `Math.tan` ≠ CPython `math.tan` by 1 ULP
|
|
20
|
+
|
|
21
|
+
When building bit-exact parity between TS/JS and Python implementations of
|
|
22
|
+
the same math, **`tan` is the single biggest offender**. V8 and CPython do
|
|
23
|
+
not share a single implementation (V8 ships its own fdlibm-derived routines;
|
|
24
|
+
CPython calls platform libm), and `tan`'s range reduction produces a
|
|
25
|
+
different LSB from naive `sin(x)/cos(x)` for some angles — which layer is
|
|
26
|
+
responsible varies by platform.
|
|
27
|
+
|
|
28
|
+
**Fix**: compute `tan(x)` as `sin(x) / cos(x)` in BOTH languages. `sin` and
|
|
29
|
+
`cos` round-tripped bit-identically across the tested runtimes.
|
|
30
|
+
|
|
31
|
+
| Op | V8 `Math.X` vs CPython `math.X` | Use? |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| `sin`, `cos` | bit-identical (observed) | yes |
|
|
34
|
+
| `sqrt` | bit-identical (IEEE-754 mandates correctly-rounded) | yes |
|
|
35
|
+
| `tan` | **1 ULP drift possible** | avoid — use `sin/cos` |
|
|
36
|
+
| `**` (pow) | 1-2 ULP drift possible | accept tolerance |
|
|
37
|
+
| `atan`, `atan2`, `exp`, `log` | 1-2 ULP drift possible | accept tolerance |
|
|
38
|
+
|
|
39
|
+
**Even after sin/cos swap**, `pow(x, y)` (e.g. `step_mult = floor + norm**exp`)
|
|
40
|
+
can still produce 1-ULP-different doubles between V8 and CPython for some
|
|
41
|
+
inputs. If the math identity is preserved (same algorithm, same constants,
|
|
42
|
+
sin/cos for tan), `math.isclose(rel_tol=1e-12, abs_tol=1e-9)` covers ~2 ULP
|
|
43
|
+
at typical magnitudes and is the right tolerance for "bit-exact in spirit".
|
|
44
|
+
|
|
45
|
+
**Concrete example**: a projectile-apex derivation
|
|
46
|
+
`apexAboveMidline = (range/4) * tan(angleRad)`. V8 emitted
|
|
47
|
+
`tan=0.32130439756415801744`; CPython emitted `tan=0.32130439756415796193`.
|
|
48
|
+
After swapping both to `sin(x)/cos(x)`, both emitted the second value.
|
|
49
|
+
Remaining rare failures (9/1000 seeds) came from `**1.8` in the step
|
|
50
|
+
multiplier — those needed the `isclose` tolerance.
|
|
51
|
+
|
|
52
|
+
## Modulo-wrap round-trip is NOT identity for in-range floats — never gate "did it wrap?" on FP equality
|
|
53
|
+
|
|
54
|
+
`wrapped = lo + (((x - lo) % span) + span) % span` for `x` ALREADY in
|
|
55
|
+
`[lo, hi)` returns a value that differs from `x` by ~1 ULP(span) on a large
|
|
56
|
+
fraction of inputs. The `%` ops themselves are exact — `%` is
|
|
57
|
+
truncated-division remainder (C `fmod` semantics), which IEEE 754 requires
|
|
58
|
+
to be exact; note it is NOT the IEEE `remainder()` operation (round-nearest
|
|
59
|
+
quotient), a different op. The error comes from the surrounding `x-lo`,
|
|
60
|
+
`+span`, `lo+m` adds, each of which rounds. Measured: 41–67% of in-range
|
|
61
|
+
values fail `wrapped === x` depending on the window; with `lo` and `x` of
|
|
62
|
+
matching magnitude the subtraction is Sterbenz-exact and the identity HOLDS
|
|
63
|
+
(0/1e6 failures) — so the spurious rate silently depends on runtime state
|
|
64
|
+
(camera position), making it look fine in one regime and fire constantly in
|
|
65
|
+
another.
|
|
66
|
+
|
|
67
|
+
**Failure mode**: `if (wrapped !== x) onWrap()` as a "teleport happened"
|
|
68
|
+
detector fired the callback ~60 Hz for every entity instead of once per
|
|
69
|
+
recycle — and a simulation harness with the same window shape "validated"
|
|
70
|
+
the degenerate behavior convincingly.
|
|
71
|
+
|
|
72
|
+
**Right**: detect the wrap by RANGE, then normalize:
|
|
73
|
+
```js
|
|
74
|
+
if (x < lo || x >= hi) { x = lo + (((x - lo) % span) + span) % span; onWrap(); }
|
|
75
|
+
```
|
|
76
|
+
Also skips the modulo (and its FP noise re-write) in the common in-range case.
|
|
@@ -6,9 +6,16 @@ description: MCP server setup and troubleshooting
|
|
|
6
6
|
## Rules
|
|
7
7
|
|
|
8
8
|
1. **NEVER guess package names** → `npm info <name>` to verify before installing
|
|
9
|
-
2. **Validate before adding** → `npm info` → `npx -y <pkg> --help` → `claude mcp add`
|
|
9
|
+
2. **Validate before adding** → `npm info` → `npx -y <pkg> --help` → `claude mcp add`. Caveat: many MCP servers don't implement `--help` and just wait on stdio — wrap validation in `timeout 10 …` so it can't hang.
|
|
10
10
|
3. **Think UX upfront** → headless mode, timeouts, flags — ask user BEFORE installing
|
|
11
|
-
4. **
|
|
11
|
+
4. **Restarts**: `/mcp` can reconnect already-registered servers, but registering a NEW server requires a session restart. Get the config right the first time.
|
|
12
|
+
|
|
13
|
+
## Quick Facts
|
|
14
|
+
|
|
15
|
+
- Python servers: `claude mcp add <name> -- uvx <pkg>` — uvx launches PyPI packages over stdio, no venv management.
|
|
16
|
+
- Remote servers: `claude mcp add --transport http <name> <url>` (also `--transport sse` for legacy SSE servers).
|
|
17
|
+
- Scopes: `project` scope lives in `.mcp.json` at the repo root (checked in); `local` scope lives in `~/.claude.json` under that project's entry (NOT in the repo); `user` scope is global in `~/.claude.json`.
|
|
18
|
+
- Plugin-bundled servers get tool names `mcp__plugin_<plugin>_<server>__<tool>` — the full name must stay under the 64-char API limit, so keep plugin/server names short.
|
|
12
19
|
|
|
13
20
|
## Troubleshooting
|
|
14
21
|
|
|
@@ -16,3 +23,8 @@ description: MCP server setup and troubleshooting
|
|
|
16
23
|
2. Run command manually to see error
|
|
17
24
|
3. `npm whoami` — fix stale token if needed
|
|
18
25
|
4. `npm info <pkg> deprecated` — check if abandoned
|
|
26
|
+
|
|
27
|
+
## Browser MCP (playwright/chrome-devtools)
|
|
28
|
+
|
|
29
|
+
- **"Browser is already in use … use --isolated"** = the persistent Chrome profile (`~/Library/Caches/ms-playwright-mcp/mcp-chrome-*` on macOS, `~/.cache/ms-playwright-mcp/mcp-chrome-*` on Linux) is locked by a stale `SingletonLock` symlink (often pointing at an unrelated regular Chrome pid). The MCP server refuses even after `browser_close`.
|
|
30
|
+
- **Fix without killing the user's Chrome**: if more than one browser MCP server is configured, each has its own profile — switch to the other server rather than `kill`ing the pid the lock points at (it may be the user's real browser). Stay with ONE browser server per session; alternating between two hits the lock again.
|
|
@@ -5,11 +5,11 @@ description: User's general coding preferences
|
|
|
5
5
|
|
|
6
6
|
## User's personal coding preferences
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
They ALWAYS take priority over base skills.
|
|
8
|
+
Rules in this file ALWAYS take priority over base skills.
|
|
10
9
|
|
|
11
|
-
<!--
|
|
12
|
-
<!--
|
|
10
|
+
<!-- Customize this file to match your coding style: the uncommented -->
|
|
11
|
+
<!-- rules below are shipped defaults — keep, edit, or delete them. -->
|
|
12
|
+
<!-- Commented rules are examples to uncomment and adapt. -->
|
|
13
13
|
|
|
14
14
|
### Model usage
|
|
15
15
|
|
|
@@ -38,9 +38,9 @@ They ALWAYS take priority over base skills.
|
|
|
38
38
|
### Naming
|
|
39
39
|
|
|
40
40
|
- Private fields (variables) must start with `_` prefix: `_count`, `_items`
|
|
41
|
+
- This applies to instance variables, NOT to methods or constants
|
|
42
|
+
- Public fields do NOT use underscore prefix
|
|
41
43
|
<!-- - Event listener methods: use `Handler` suffix, not `on` prefix -->
|
|
42
|
-
<!-- - This applies to instance variables, NOT to methods or constants -->
|
|
43
|
-
<!-- - Public fields do NOT use underscore prefix -->
|
|
44
44
|
|
|
45
45
|
### Comments and documentation
|
|
46
46
|
|
|
@@ -53,10 +53,10 @@ They ALWAYS take priority over base skills.
|
|
|
53
53
|
<!-- - No curly braces for single-line bodies -->
|
|
54
54
|
<!-- - Combine `for` + `if` into `for (...) if (...) {` — preferred over `if (!cond) continue;` -->
|
|
55
55
|
|
|
56
|
-
### Error handling
|
|
57
|
-
|
|
58
|
-
- Never silently swallow invalid state — throw exceptions instead of returning quietly
|
|
59
|
-
|
|
60
56
|
### Magic numbers
|
|
61
57
|
|
|
62
58
|
<!-- - No magic number literals in logic — extract into a named constant -->
|
|
59
|
+
|
|
60
|
+
### Error handling
|
|
61
|
+
|
|
62
|
+
- Never silently swallow invalid state — throw exceptions instead of returning quietly
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-manager
|
|
3
|
+
description: Create, install, update, optimize skills
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Skill lifecycle manager
|
|
7
|
+
|
|
8
|
+
This skill is HEAVY. Always run via subagent (Task tool), never in main context.
|
|
9
|
+
|
|
10
|
+
### Model policy
|
|
11
|
+
|
|
12
|
+
- Use **Opus** or **Sonnet** for subagents
|
|
13
|
+
- **NEVER use Haiku** — insufficient for quality work
|
|
14
|
+
- Skills are optimized for Opus/Sonnet reasoning capabilities
|
|
15
|
+
|
|
16
|
+
**Model selection by task:**
|
|
17
|
+
- **OPTIMIZE skills** → Sonnet (filtering/editing, doesn't need deep reasoning)
|
|
18
|
+
- **CREATE skill from research** → Sonnet (research + writing)
|
|
19
|
+
- **Complex code generation** → Opus (when quality is critical)
|
|
20
|
+
|
|
21
|
+
### ⛔ PROTECTED skills — NEVER modify or overwrite
|
|
22
|
+
|
|
23
|
+
Skills matching `preferences*` (`preferences/`, `preferences-<lang>/`,
|
|
24
|
+
any other `preferences-*` variant) are user-owned personal rules.
|
|
25
|
+
|
|
26
|
+
These are ONLY updated when the user gives direct feedback.
|
|
27
|
+
skill-manager must NEVER touch, overwrite, or regenerate them without
|
|
28
|
+
an explicit user request.
|
|
29
|
+
|
|
30
|
+
### 1. FIND an existing skill
|
|
31
|
+
|
|
32
|
+
Search order:
|
|
33
|
+
A) Check awesome-agent-skills: https://github.com/VoltAgent/awesome-agent-skills
|
|
34
|
+
B) Check awesome-claude-code: https://github.com/hesreallyhim/awesome-claude-code
|
|
35
|
+
C) Check anthropics/skills: https://github.com/anthropics/skills
|
|
36
|
+
D) Search npm: `npm search claude skill <keyword>`
|
|
37
|
+
E) Search GitHub: `gh search repos "claude skill <keyword>"`
|
|
38
|
+
|
|
39
|
+
**IMPORTANT:** Subagents don't have access to skills. When launching a research subagent, include these web-reading rules in the prompt:
|
|
40
|
+
|
|
41
|
+
1. For GitHub repos/issues/PRs → use `gh` CLI, not web fetch
|
|
42
|
+
2. Fetch web pages via Jina Reader: `WebFetch("https://r.jina.ai/<url>", "<precise extraction prompt>")`
|
|
43
|
+
3. If Jina fails → direct `WebFetch` with prompt: "Extract ONLY main article content as clean markdown. Ignore navigation, sidebars, headers, footers, ads."
|
|
44
|
+
4. If page inaccessible → `WebSearch` for mirrors, docs, cached versions
|
|
45
|
+
5. ALWAYS specify exactly what to extract — never "get the page" or "summarize"
|
|
46
|
+
|
|
47
|
+
### 2. INSTALL an existing skill
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# From known repos
|
|
51
|
+
npx -y openskills install <owner/repo/skill-name> -g
|
|
52
|
+
|
|
53
|
+
# Or manually
|
|
54
|
+
# 1. Fetch the SKILL.md content
|
|
55
|
+
# 2. Write to ~/.claude/skills/<skill-name>/SKILL.md
|
|
56
|
+
# 3. Copy any scripts/, references/, assets/ if present
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
After install, verify:
|
|
60
|
+
- SKILL.md has valid frontmatter (name, description)
|
|
61
|
+
- Description doesn't overlap with existing skills
|
|
62
|
+
- Fits the layered architecture: universal → lang → domain → target
|
|
63
|
+
|
|
64
|
+
### 3. CREATE a new skill from scratch
|
|
65
|
+
|
|
66
|
+
Follow Anthropic's skill-creator principles:
|
|
67
|
+
|
|
68
|
+
A) **Size = f(content)** — can be 10 lines or 500, depends on how much Claude DOESN'T know
|
|
69
|
+
B) **CRITICAL: Don't teach what Claude already knows!**
|
|
70
|
+
C) **When in doubt — EXCLUDE** (easier to add later than to remove)
|
|
71
|
+
D) **Minimal code examples** — only to illustrate a gotcha, not full solutions
|
|
72
|
+
E) **Always add `description` to frontmatter** — max 5-6 words, as short as possible. Without it Claude won't load the skill.
|
|
73
|
+
F) **Do NOT add `disable-model-invocation`** — skills must be callable via Skill() tool. Discovery chain: workflow `think` state → domain mapping → `Skill(name)`.
|
|
74
|
+
G) Use progressive disclosure:
|
|
75
|
+
- SKILL.md body (<5k words) = loaded when triggered via Skill()
|
|
76
|
+
- references/ = loaded on demand
|
|
77
|
+
|
|
78
|
+
### ⚠️ What to include vs exclude in skills
|
|
79
|
+
|
|
80
|
+
**NEVER include** (Claude already knows this):
|
|
81
|
+
- Basic syntax of mainstream languages
|
|
82
|
+
- Standard library functions that are well-documented
|
|
83
|
+
- Common design patterns (singleton, factory, observer)
|
|
84
|
+
- General programming principles (DRY, SOLID)
|
|
85
|
+
- Popular framework basics (React, ASP.NET, Django)
|
|
86
|
+
- **Well-known patterns with full examples** (multi-stage Docker builds, async/await)
|
|
87
|
+
- **Obvious best practices** (use .gitignore, validate input)
|
|
88
|
+
- **Standard CLI commands** (docker run, git commit, npm install)
|
|
89
|
+
|
|
90
|
+
**ALWAYS include** (Claude needs this):
|
|
91
|
+
- **Gotchas and pitfalls** — things Claude commonly gets wrong
|
|
92
|
+
- **Subtle differences** — from similar languages/frameworks
|
|
93
|
+
- **Non-obvious conventions** — that differ from common patterns
|
|
94
|
+
- **Version-specific changes** — recent updates Claude may not know
|
|
95
|
+
- **Integration quirks** — how things work together in practice
|
|
96
|
+
- **User's preferences** — always in preferences-* skills
|
|
97
|
+
- **Niche topics** — obscure APIs, legacy systems, specialized domains
|
|
98
|
+
|
|
99
|
+
**Process for creating a lang-* or domain-* skill:**
|
|
100
|
+
|
|
101
|
+
1. Start with EMPTY file
|
|
102
|
+
2. Research web for "gotchas", "common mistakes", "pitfalls" in this domain
|
|
103
|
+
3. For each finding — two-model filter (Opus + Sonnet):
|
|
104
|
+
- Both models know it → SKIP (water)
|
|
105
|
+
- At least one doesn't know → INCLUDE
|
|
106
|
+
4. Specific numbers/boundaries → always verify by computation, record exact values
|
|
107
|
+
5. If nothing passes the filter → maybe this skill isn't needed
|
|
108
|
+
|
|
109
|
+
**Two-model consensus** (mirrors water-removal):
|
|
110
|
+
- Remove what BOTH models know
|
|
111
|
+
- Add what at LEAST ONE model doesn't know
|
|
112
|
+
|
|
113
|
+
**Gotcha vs Pattern — examples:**
|
|
114
|
+
```
|
|
115
|
+
✗ EXCLUDE: "Use multi-stage builds to reduce image size"
|
|
116
|
+
(well-known pattern, Claude knows this)
|
|
117
|
+
|
|
118
|
+
✓ INCLUDE: "COPY --from=0 uses stage INDEX, not name — breaks if stages reordered"
|
|
119
|
+
(gotcha, easy to miss)
|
|
120
|
+
|
|
121
|
+
✗ EXCLUDE: "Use async/await for asynchronous code"
|
|
122
|
+
(basic syntax)
|
|
123
|
+
|
|
124
|
+
✓ INCLUDE: "ConfigureAwait(false) in library code — otherwise deadlock in UI"
|
|
125
|
+
(subtle gotcha, context-dependent)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Structure:
|
|
129
|
+
```
|
|
130
|
+
~/.claude/skills/<skill-name>/
|
|
131
|
+
├── SKILL.md # Required: frontmatter + instructions
|
|
132
|
+
├── references/ # Optional: detailed docs, schemas
|
|
133
|
+
├── scripts/ # Optional: executable helpers
|
|
134
|
+
└── assets/ # Optional: templates, samples
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Naming for layered architecture:
|
|
138
|
+
- Universal: `code-writing`, `architecture`, `testing`, `refactoring`
|
|
139
|
+
- Language: `lang-csharp`, `lang-haxe`, `lang-python`
|
|
140
|
+
- Domain: `domain-unity`, `domain-dotnet`, `domain-gamedev`
|
|
141
|
+
- Target: `target-hashlink`, `target-aspnet`, `target-webgl`
|
|
142
|
+
|
|
143
|
+
### 4. CONVERT documentation into a skill
|
|
144
|
+
|
|
145
|
+
For turning language/framework docs into a skill:
|
|
146
|
+
|
|
147
|
+
A) Fetch documentation using web-reading chain
|
|
148
|
+
B) Extract:
|
|
149
|
+
- Core idioms and conventions
|
|
150
|
+
- Common patterns and anti-patterns
|
|
151
|
+
- API quick reference (signatures, not full docs)
|
|
152
|
+
- Gotchas and common mistakes
|
|
153
|
+
C) Structure as SKILL.md — focus on what Claude wouldn't know
|
|
154
|
+
D) Move detailed API references to references/ directory
|
|
155
|
+
E) Write precise description for auto-invocation
|
|
156
|
+
|
|
157
|
+
### 5. ENRICH skill from observed error
|
|
158
|
+
|
|
159
|
+
Triggered by reflection when Claude makes a verifiable mistake.
|
|
160
|
+
|
|
161
|
+
1. Identify the error and the skill it belongs to
|
|
162
|
+
2. Research the correct answer: code verification → web docs → web search
|
|
163
|
+
3. Verify the correct answer by running code (if possible)
|
|
164
|
+
4. Add ONLY the verified correction to the existing skill
|
|
165
|
+
5. Format: show the wrong thing and the right thing with exact values
|
|
166
|
+
|
|
167
|
+
Example flow: Claude writes `Fib(46) overflows Int32` → verification shows Fib(46) fits,
|
|
168
|
+
Fib(47) overflows → add verified table to math skill with exact numbers.
|
|
169
|
+
|
|
170
|
+
### 6. UPDATE an existing skill (manual)
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# Via openskills (if installed from repo)
|
|
174
|
+
npx -y openskills update <skill-name>
|
|
175
|
+
|
|
176
|
+
# Or manually
|
|
177
|
+
# 1. Read current ~/.claude/skills/<skill-name>/SKILL.md
|
|
178
|
+
# 2. Identify what's missing or wrong
|
|
179
|
+
# 3. Edit with improvements
|
|
180
|
+
# 4. Verify description still fits
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 7. LIST and AUDIT current skills
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
ls ~/.claude/skills/
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Check for:
|
|
190
|
+
- Overlapping descriptions between skills
|
|
191
|
+
- Skills that are too large (>500 lines)
|
|
192
|
+
- Missing skills for languages/domains being used
|
|
193
|
+
- Outdated information
|
|
194
|
+
|
|
195
|
+
### 8. OPTIMIZE skills (on model version change)
|
|
196
|
+
|
|
197
|
+
When Claude version changes (e.g., 4.5 → 5.0), run optimization:
|
|
198
|
+
|
|
199
|
+
**Trigger:** User says "optimize skills" or new model version detected.
|
|
200
|
+
|
|
201
|
+
**Process for each skill:**
|
|
202
|
+
|
|
203
|
+
1. Read the skill content
|
|
204
|
+
2. For each piece of information, ask:
|
|
205
|
+
- "Does the NEW model already know this?" → REMOVE if yes
|
|
206
|
+
- "Is this a gotcha/pitfall that's still relevant?" → KEEP
|
|
207
|
+
- "Is this user's preference?" → NEVER TOUCH (preferences-*)
|
|
208
|
+
- "Has this API/convention changed?" → UPDATE from fresh research
|
|
209
|
+
3. Re-test: does the skill still add value?
|
|
210
|
+
4. If skill becomes nearly empty → consider deleting it
|
|
211
|
+
|
|
212
|
+
**What to keep regardless of model version:**
|
|
213
|
+
- User preferences (preferences-*)
|
|
214
|
+
- Behavioral/meta skills (reflection)
|
|
215
|
+
- Infrastructure skills (web-reading, mcp-setup)
|
|
216
|
+
- Recent version-specific changes (last 6-12 months)
|
|
217
|
+
- Niche domains (ANE, Re-ID pipelines)
|
|
218
|
+
|
|
219
|
+
**What to aggressively prune:**
|
|
220
|
+
- Basic syntax of mainstream languages
|
|
221
|
+
- Well-documented standard library functions
|
|
222
|
+
- General programming principles
|
|
223
|
+
- Popular framework basics
|
|
224
|
+
|
|
225
|
+
**Deduplicate with preferences:**
|
|
226
|
+
During optimization, check preferences-* skills for this language/domain.
|
|
227
|
+
If a rule exists in preferences-*, REMOVE it from the base skill.
|
|
228
|
+
User preferences always win — no need to duplicate.
|
|
229
|
+
|
|
230
|
+
Example: if preferences-haxe says "use final class", remove any mention
|
|
231
|
+
of final class conventions from lang-haxe.
|
|
232
|
+
|
|
233
|
+
**Log optimizations:**
|
|
234
|
+
After optimization, note in MEMORY.md:
|
|
235
|
+
- Date optimized
|
|
236
|
+
- Model version optimized for
|
|
237
|
+
- What was removed/kept/updated
|
|
238
|
+
|
|
239
|
+
### 9. UPDATE selector domain mappings after creating new skills
|
|
240
|
+
|
|
241
|
+
**MANDATORY:** After creating or installing any new skill, update the domain mapping
|
|
242
|
+
in `~/.claude/skills/coding-skill-selector/SKILL.md` — one place.
|
|
243
|
+
|
|
244
|
+
Add the new skill to the appropriate section (by extension or by domain), e.g.:
|
|
245
|
+
```
|
|
246
|
+
- NewDomain → `Skill("domain-newdomain")`
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**This single skill is loaded at the skill-gate states of all code-related workflows (coding, debugging, bug-fix, code-review, etc.).**
|
|
250
|
+
|
|
251
|
+
### Language rule
|
|
252
|
+
|
|
253
|
+
All skills MUST be written in English only. Never mix languages in skill files.
|
|
254
|
+
|
|
255
|
+
### Validation checklist
|
|
256
|
+
|
|
257
|
+
Before finishing any skill operation:
|
|
258
|
+
- [ ] Frontmatter has `name` + short `description` (no disable-model-invocation)
|
|
259
|
+
- [ ] Name is hyphen-case, max 64 chars
|
|
260
|
+
- [ ] SKILL.md ≤500 lines (size driven by content, not arbitrary target)
|
|
261
|
+
- [ ] Follows layered architecture (universal/lang/domain/target)
|
|
262
|
+
- [ ] Only gotchas/pitfalls — no basic patterns Claude already knows
|
|
263
|
+
- [ ] If skill is nearly empty → maybe it's not needed
|
|
264
|
+
- [ ] **selector domain mapping updated** (coding-skill-selector skill)
|
|
@@ -129,8 +129,10 @@ while (!_worker.isStopped() && waited < TIMEOUT_MS) {
|
|
|
129
129
|
Sys.sleep(0.1);
|
|
130
130
|
waited += 100;
|
|
131
131
|
}
|
|
132
|
-
if (
|
|
133
|
-
// Thread stopped cleanly — safe to close resources
|
|
132
|
+
if (_worker.isStopped()) {
|
|
133
|
+
// Thread stopped cleanly — safe to close resources.
|
|
134
|
+
// Re-check the flag, NOT the timer: the worker may have stopped
|
|
135
|
+
// during the final sleep, right as the timeout expired.
|
|
134
136
|
try db.close() catch (e:Dynamic) {};
|
|
135
137
|
}
|
|
136
138
|
// Always null out regardless
|
|
@@ -143,11 +145,11 @@ _worker = null;
|
|
|
143
145
|
|
|
144
146
|
```haxe
|
|
145
147
|
// WRONG — parent field nulled but still in __children → main thread renders it
|
|
146
|
-
|
|
148
|
+
child.parent = null;
|
|
147
149
|
|
|
148
150
|
// RIGHT — remove from __children, then null parent
|
|
149
|
-
@:privateAccess parent.__children.remove(
|
|
150
|
-
|
|
151
|
+
@:privateAccess parent.__children.remove(child);
|
|
152
|
+
child.parent = null;
|
|
151
153
|
```
|
|
152
154
|
|
|
153
155
|
To restore, save the child index before removing and re-insert at the same position:
|
|
@@ -169,6 +171,39 @@ child.parent = savedParent;
|
|
|
169
171
|
|
|
170
172
|
`Sys.exit()` calls C `exit()`. In worker threads, stdout buffer may not flush. Always call `Sys.stdout().flush()` before `Sys.exit()`.
|
|
171
173
|
|
|
174
|
+
### Sys.exit() races hxcpp GC mutex destruction → `mutex lock failed: Invalid argument`
|
|
175
|
+
|
|
176
|
+
`Sys.exit()` → libc `exit()` → runs C++ static destructors, including hxcpp's GC mutexes (`sThreadPoolLock` in `hx::gc::Immix.cpp`, `g_threadInfoMutex` in `hx::Thread.cpp`). The GC worker thread is NOT stopped by `exit()`. Its next `pthread_mutex_lock` on a now-destroyed mutex returns EINVAL → libc++abi terminates with `mutex lock failed: Invalid argument`. Manifests differently per platform: Linux shows `terminate ... std::system_error ... Invalid argument`, Windows is silent or AV, macOS crashes at unit test exit.
|
|
177
|
+
|
|
178
|
+
Fix: after cooperative cleanup, skip C++ static destructors by calling `_Exit` (see below).
|
|
179
|
+
|
|
180
|
+
### `_exit` from `<unistd.h>` is NOT available; use `_Exit` from `<cstdlib>`
|
|
181
|
+
|
|
182
|
+
hxcpp does NOT auto-include `<unistd.h>`. `untyped __cpp__("::_exit({0})", code)` fails with `error: no type named '_exit' in the global namespace`.
|
|
183
|
+
|
|
184
|
+
Use C99 `_Exit` (capital E) from `<cstdlib>` — skips C++ static destructors and atexit handlers, identical to `_exit` in effect, portable across Darwin/Linux/Windows MSVC.
|
|
185
|
+
|
|
186
|
+
```haxe
|
|
187
|
+
// WRONG — <unistd.h> not included by hxcpp; compile error
|
|
188
|
+
untyped __cpp__("::_exit({0})", code);
|
|
189
|
+
|
|
190
|
+
// RIGHT — <cstdlib> is safe; _Exit skips static destructors
|
|
191
|
+
@:cppFileCode("#include <cstdlib>")
|
|
192
|
+
final class CleanExit {
|
|
193
|
+
public static function exit(code:Int):Void {
|
|
194
|
+
try Sys.stdout().flush() catch (_:Exception) {} // see "doesn't flush stdout" above
|
|
195
|
+
try Sys.stderr().flush() catch (_:Exception) {}
|
|
196
|
+
#if cpp
|
|
197
|
+
untyped __cpp__("std::_Exit({0})", code);
|
|
198
|
+
#else
|
|
199
|
+
Sys.exit(code);
|
|
200
|
+
#end
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Warning**: `_Exit` skips ALL atexit handlers. Any pending writes (DB flushes, file saves) are lost. Only call after cooperative cleanup. Keep this as a small shared utility class.
|
|
206
|
+
|
|
172
207
|
## Extern Patterns (@:native)
|
|
173
208
|
|
|
174
209
|
### Pointer suffix for heap-allocated types
|
|
@@ -225,7 +260,7 @@ Including `<OpenGLES/EAGL.h>` or any header that pulls in `Foundation.h` inside
|
|
|
225
260
|
#include <objc/runtime.h>
|
|
226
261
|
#include <objc/message.h>
|
|
227
262
|
|
|
228
|
-
static void*
|
|
263
|
+
static void* get_eagl_context() {
|
|
229
264
|
Class cls = objc_getClass("EAGLContext");
|
|
230
265
|
SEL sel = sel_registerName("currentContext");
|
|
231
266
|
return ((void* (*)(id, SEL))objc_msgSend)((id)cls, sel);
|
|
@@ -279,25 +314,25 @@ No leading slashes in asset paths — `"/manifest/default.json"` crashes on some
|
|
|
279
314
|
|
|
280
315
|
**GlowFilter on Label/Sprite container** — apply to the parent container (Label, Sprite), NOT to TextField directly. `label.filters = [new GlowFilter(...)]` works. `textField.filters` inside a Label wrapper does NOT produce visible results.
|
|
281
316
|
|
|
282
|
-
**BitmapData.draw() does NOT capture filters** — `bmd.draw(stage)` uses the software renderer and skips GPU filters. Use `window.readPixels()` instead — reads from the GPU framebuffer and captures everything including filters.
|
|
317
|
+
**BitmapData.draw() does NOT capture filters** — `bmd.draw(stage)` uses the software renderer and skips GPU filters. Use `window.readPixels()` instead — reads from the GPU framebuffer and captures everything including filters. Screenshot tooling (e.g. a debug bridge) should use readPixels with draw() as fallback.
|
|
283
318
|
|
|
284
319
|
**Search codebase first** — before implementing text outlines, shadows, or effects, grep for existing `GlowFilter`/`DropShadowFilter` usage in the project. Likely already solved with correct params.
|
|
285
320
|
|
|
286
321
|
**`DisplayObject.filters != null` forces `cacheAsBitmap = true`** — the getter is `return (__filters == null ? __cacheAsBitmap : true)`. Any non-null filters array (even a filter with alpha=0 or zero-radius) causes the object to render through the intermediate bitmap-cache path. Symptoms:
|
|
287
322
|
|
|
288
323
|
- Setting `obj.cacheAsBitmap = false` has NO effect when `filters != null` — the getter still returns `true`.
|
|
289
|
-
- At high render scales (video export, offscreen `BitmapData.draw` with large matrix), the intermediate cache bitmap can be sized wrong for the target, visually clipping the right/bottom of content (
|
|
324
|
+
- At high render scales (video export, offscreen `BitmapData.draw` with large matrix), the intermediate cache bitmap can be sized wrong for the target, visually clipping the right/bottom of content (elements near those edges silently disappear from the output).
|
|
290
325
|
|
|
291
326
|
```haxe
|
|
292
327
|
// WRONG — unselected state keeps a zero-alpha filter "to avoid allocations"
|
|
293
|
-
override function set_isSelected(value:Bool):Bool {
|
|
328
|
+
override private function set_isSelected(value:Bool):Bool {
|
|
294
329
|
final alpha:Float = value ? 1 : 0;
|
|
295
330
|
obj.filters = [new GlowFilter(color, alpha, 4, 4, 1)]; // still forces cacheAsBitmap
|
|
296
331
|
return isSelected = value;
|
|
297
332
|
}
|
|
298
333
|
|
|
299
334
|
// RIGHT — null out filters when not needed
|
|
300
|
-
override function set_isSelected(value:Bool):Bool {
|
|
335
|
+
override private function set_isSelected(value:Bool):Bool {
|
|
301
336
|
obj.filters = value ? [new GlowFilter(color, 1, 4, 4, 1)] : null;
|
|
302
337
|
return isSelected = value;
|
|
303
338
|
}
|
|
@@ -343,7 +378,7 @@ bytes.blit(botOff, tmp, 0, rowStride); // tmp → bottom
|
|
|
343
378
|
|
|
344
379
|
### BitmapData.draw pixelRatio vs cache bitmaps (text blur on Windows)
|
|
345
380
|
|
|
346
|
-
`BitmapData.draw()` sets `renderer.__pixelRatio = window.scale`. TextFields with filters (GlowFilter, DropShadowFilter) go through `__updateCacheBitmap` which creates the cache bitmap at `pixelRatio` resolution. On Windows (`window.scale=1`), cache bitmaps are 1x — if the draw matrix scales up (e.g. video
|
|
381
|
+
`BitmapData.draw()` sets `renderer.__pixelRatio = window.scale`. TextFields with filters (GlowFilter, DropShadowFilter) go through `__updateCacheBitmap` which creates the cache bitmap at `pixelRatio` resolution. On Windows (`window.scale=1`), cache bitmaps are 1x — if the draw matrix scales up (e.g. a ~2x video-export draw matrix), the 1x cache is upscaled → blurry text.
|
|
347
382
|
|
|
348
383
|
**Fix**: set `pixelRatio = max(window.scale, transform_scale)` in `BitmapData.draw()` so cache bitmaps are rasterized at the final output resolution. This fixes BOTH code paths — text with filters (cache bitmap) and text without filters (Context3DTextField.render).
|
|
349
384
|
|
|
@@ -391,7 +426,7 @@ graphics.endFill();
|
|
|
391
426
|
shape.x = containerWidth - FADE_WIDTH; // gradient at edge, solid extends past it
|
|
392
427
|
```
|
|
393
428
|
|
|
394
|
-
Key: solid rect goes PAST `containerWidth`, not before it. Parent mask clips the visual excess, but the fill covers any children that overshoot the boundary (e.g. scrollbar offset by `barPad`). Verify
|
|
429
|
+
Key: solid rect goes PAST `containerWidth`, not before it. Parent mask clips the visual excess, but the fill covers any children that overshoot the boundary (e.g. scrollbar offset by `barPad`). Verify by inspecting the display tree (debug-bridge query, runtime trace) — check child positions and widths to confirm the cover extends past all children.
|
|
395
430
|
|
|
396
431
|
## Actuate (Tween Library)
|
|
397
432
|
|
|
@@ -442,7 +477,7 @@ OpenFL provides utility methods that are easy to miss. Use them instead of writi
|
|
|
442
477
|
| `HXCPP_STACK_LINE` | Line numbers (implies above) | Medium |
|
|
443
478
|
| `-debug` | All above + no optimization | ~80% |
|
|
444
479
|
|
|
445
|
-
**Crash investigation builds**: When
|
|
480
|
+
**Crash investigation builds**: When building a binary to reproduce a crash, always add `-DHXCPP_CHECK_POINTER` to the build flags. Without it, a Null Object Reference is a silent segfault with no stack trace — useless for diagnosis. `-debug` includes it automatically, but if already building with `-debug`, you're covered.
|
|
446
481
|
|
|
447
482
|
**Null function pointer = hard crash**: `var f:Void->Void = null; f();` → C++ NULL dereference, not catchable. Check before calling.
|
|
448
483
|
|
|
@@ -515,8 +550,8 @@ this.stage.addEventListener(Event.RESIZE, handler); // if 'this' is a DisplayOb
|
|
|
515
550
|
Logical coords → `stage.__onMouse()` requires display-matrix input space, NOT stage coordinates:
|
|
516
551
|
|
|
517
552
|
```haxe
|
|
518
|
-
// logical (
|
|
519
|
-
final globalPoint:Point =
|
|
553
|
+
// logical (app coordinate space) → stage global → display input
|
|
554
|
+
final globalPoint:Point = contentRoot.localToGlobal(new Point(logicalX, logicalY));
|
|
520
555
|
final inputPoint:Point = stage.__displayMatrix.transformPoint(globalPoint);
|
|
521
556
|
stage.__onMouse(MouseEvent.MOUSE_DOWN, inputPoint.x, inputPoint.y, 0);
|
|
522
557
|
```
|
|
@@ -531,9 +566,9 @@ Display list hit-test order: **highest index first** (front-to-back). If a trans
|
|
|
531
566
|
|
|
532
567
|
### Scroll events bypass OS natural-scrolling inversion
|
|
533
568
|
|
|
534
|
-
Real scroll events: OS/SDL applies natural scrolling → Lime → OpenFL.
|
|
569
|
+
Real scroll events: OS/SDL applies natural scrolling → Lime → OpenFL. Apps typically compensate with their own inversion flag on the scroll component.
|
|
535
570
|
|
|
536
|
-
Synthetic `stage.__onMouseWheel(deltaX, deltaY, mode)` bypasses OS/SDL, so the app's compensation causes **double inversion**. Fix:
|
|
571
|
+
Synthetic `stage.__onMouseWheel(deltaX, deltaY, mode)` bypasses OS/SDL, so the app's compensation causes **double inversion**. Fix: when the app's inversion flag is active, negate the delta before passing it to `__onMouseWheel`.
|
|
537
572
|
|
|
538
573
|
### __onMouseWheel needs __mouseX/Y set first
|
|
539
574
|
|
|
@@ -25,10 +25,13 @@
|
|
|
25
25
|
|
|
26
26
|
## Cross-compilation
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
|
31
|
-
|
|
28
|
+
hxcpp selects the toolchain via defines (`-D ...`). Haxe's `-cpp <dir>` only sets the C++ output directory — it is not a cross-compilation flag.
|
|
29
|
+
|
|
30
|
+
| From → To | Define |
|
|
31
|
+
|-----------|--------|
|
|
32
|
+
| macOS → Linux | `-D linux` (needs a Linux cross-toolchain, e.g. via Homebrew) |
|
|
33
|
+
| Linux → Windows | `-D windows` (selects the MinGW-w64 cross toolchain) |
|
|
34
|
+
| Windows: MSVC → MinGW | `-D mingw` |
|
|
32
35
|
|
|
33
36
|
## CI/CD gotchas
|
|
34
37
|
|