mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-02 07:03:28 +08:00
Compare commits
607 Commits
7713ceeec0
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
401966bc18 | ||
|
|
1abeff9be7 | ||
|
|
975100db55 | ||
|
|
6833454778 | ||
|
|
e134e492cb | ||
|
|
f3db349984 | ||
|
|
5194d2000a | ||
|
|
43ac81f1ac | ||
|
|
e1bc08fa6e | ||
|
|
03c4a90ffa | ||
|
|
d4b5ca7483 | ||
|
|
51a87d86d9 | ||
|
|
a273c62f35 | ||
|
|
b41b2cb554 | ||
|
|
1744e1ef0e | ||
|
|
f056952e50 | ||
|
|
97d9607be5 | ||
|
|
44dfc35b16 | ||
|
|
e85bc5fe87 | ||
|
|
d0e5caebd4 | ||
|
|
9908610221 | ||
|
|
a2b3cc1600 | ||
|
|
0f40fd030c | ||
|
|
c02d6e9f94 | ||
|
|
f90f269b92 | ||
|
|
95e606fb81 | ||
|
|
eacf3a9fb4 | ||
|
|
87363f0e59 | ||
|
|
6b82abeaf1 | ||
|
|
c38bc799fd | ||
|
|
477d23a34f | ||
|
|
4cdfe709ab | ||
|
|
0c9b024746 | ||
|
|
a41a07363f | ||
|
|
a1cebd29f7 | ||
|
|
09398b42c2 | ||
|
|
e86d3dbe02 | ||
|
|
99a44f6a54 | ||
|
|
9b611f1b37 | ||
|
|
30ab9e2cd7 | ||
|
|
fade657338 | ||
|
|
5596159a83 | ||
|
|
d1e2209a52 | ||
|
|
cfb3476f02 | ||
|
|
5e7f657a5a | ||
|
|
6cc85ef2ed | ||
|
|
f7f91d9e43 | ||
|
|
e68233cd5d | ||
|
|
656cf4c94a | ||
|
|
0220202a61 | ||
|
|
5a2c9f5558 | ||
|
|
7ff2f0748e | ||
|
|
3f6a14acde | ||
|
|
d6c7f8fb0a | ||
|
|
7253d0ca98 | ||
|
|
118e57e14b | ||
|
|
a4d4b1d756 | ||
|
|
c90566f9be | ||
|
|
b9a01d3c32 | ||
|
|
fab80c99b7 | ||
|
|
8846210ca2 | ||
|
|
cff28efb34 | ||
|
|
b575f2e3eb | ||
|
|
0f065af311 | ||
|
|
ded5d826a4 | ||
|
|
ae272da28d | ||
|
|
c39aa22c5a | ||
|
|
7483d646e4 | ||
|
|
432a45274e | ||
|
|
866d9ebb53 | ||
|
|
dd675d4258 | ||
|
|
db12d3d838 | ||
|
|
46f37ae4fb | ||
|
|
0c166e14da | ||
|
|
527c79350c | ||
|
|
0ebcfc368e | ||
|
|
bec1ebf76d | ||
|
|
be76918850 | ||
|
|
99a154a908 | ||
|
|
ebf0f135bb | ||
|
|
2d27da52e2 | ||
|
|
65c4a0f6ba | ||
|
|
ab49c9adf5 | ||
|
|
b7a82cf240 | ||
|
|
9a55fd069b | ||
|
|
d9e8305aa1 | ||
|
|
f2bf72c005 | ||
|
|
3ae0df781f | ||
|
|
a346a304b0 | ||
|
|
81acf0c928 | ||
|
|
06a77911e6 | ||
|
|
9406f35fab | ||
|
|
c5e3658ba6 | ||
|
|
eeeea506a6 | ||
|
|
fc1ea4fbea | ||
|
|
00787d68e4 | ||
|
|
1e3572becf | ||
|
|
7462168377 | ||
|
|
3c3781ca43 | ||
|
|
27d71c9548 | ||
|
|
6f16e75f9d | ||
|
|
0d30da1fc7 | ||
|
|
e686bcbc82 | ||
|
|
25c8a5de08 | ||
|
|
ec104c94c5 | ||
|
|
14a51404c0 | ||
|
|
666c639206 | ||
|
|
a8e088a54e | ||
|
|
eac0228f88 | ||
|
|
b6e3434ff4 | ||
|
|
4eaee83448 | ||
|
|
1e43639cc7 | ||
|
|
766f846478 | ||
|
|
dd38518afe | ||
|
|
c1d98b071e | ||
|
|
70b98f3178 | ||
|
|
dcc4d914d2 | ||
|
|
71219ff656 | ||
|
|
e815f0d05c | ||
|
|
b3a43f34e6 | ||
|
|
0d26f5295d | ||
|
|
9181382065 | ||
|
|
9434e07749 | ||
|
|
9cde3427e2 | ||
|
|
c6b4c719b2 | ||
|
|
f98207feea | ||
|
|
52e9bd58f1 | ||
|
|
4257c093ca | ||
|
|
23d743b92c | ||
|
|
414ea90e11 | ||
|
|
d473cf87e6 | ||
|
|
64847d0a21 | ||
|
|
c865d4c676 | ||
|
|
72de19effd | ||
|
|
56076edd48 | ||
|
|
04d7eeb16f | ||
|
|
4e7773c2ce | ||
|
|
a3fc90f7ac | ||
|
|
55efeb7f20 | ||
|
|
1e7c299706 | ||
|
|
47aa415b06 | ||
|
|
d7e6bb242a | ||
|
|
9f37a5d8c7 | ||
|
|
d9ec51c9e9 | ||
|
|
9033f2a997 | ||
|
|
67660540ac | ||
|
|
432788d0b5 | ||
|
|
6a7a115e18 | ||
|
|
1181d93498 | ||
|
|
80d6a89f12 | ||
|
|
28a1fbc3f2 | ||
|
|
4fcaaf8a89 | ||
|
|
7a4cb8c570 | ||
|
|
4b4f077d18 | ||
|
|
78c98dd4fd | ||
|
|
f07797533d | ||
|
|
87d883eb1b | ||
|
|
652f87c5b6 | ||
|
|
70b65a9d06 | ||
|
|
24674a7bd6 | ||
|
|
d49c95a5ec | ||
|
|
70a96bd363 | ||
|
|
8f7445a260 | ||
|
|
9ad4351f53 | ||
|
|
451732164f | ||
|
|
ebd14cde7d | ||
|
|
ae21a8df85 | ||
|
|
d8e3b9d593 | ||
|
|
7148d9006f | ||
|
|
c14765e701 | ||
|
|
194bc0000b | ||
|
|
1e44475458 | ||
|
|
31af1adcc8 | ||
|
|
c80631fc1d | ||
|
|
00f8628b83 | ||
|
|
ba09a34432 | ||
|
|
27e0d53f6d | ||
|
|
8b6140dedc | ||
|
|
7633386e04 | ||
|
|
b4296c7095 | ||
|
|
17f6f95090 | ||
|
|
1e226ba556 | ||
|
|
cc60bf6b65 | ||
|
|
160624d0ed | ||
|
|
73c10122fe | ||
|
|
9b24bedf85 | ||
|
|
e3f2bda9fc | ||
|
|
fe6a6fc106 | ||
|
|
63737544a1 | ||
|
|
dafc9bcd60 | ||
|
|
2d0fddf174 | ||
|
|
f471f27658 | ||
|
|
925d830c53 | ||
|
|
2243f15581 | ||
|
|
6408511611 | ||
|
|
9348751b8e | ||
|
|
c96c4d2742 | ||
|
|
da74f85c10 | ||
|
|
c146fae2ce | ||
|
|
3f5e042b40 | ||
|
|
b5148f184a | ||
|
|
b44ba7096f | ||
|
|
45baaa1ea5 | ||
|
|
4da1fb388c | ||
|
|
917c35bb6f | ||
|
|
ee3f348dcb | ||
|
|
e6eb99271f | ||
|
|
7cabf77142 | ||
|
|
9cfcfac665 | ||
|
|
0284f60871 | ||
|
|
7a17ec9b14 | ||
|
|
243fae8476 | ||
|
|
dc92b5c62b | ||
|
|
3fbfd7f7ff | ||
|
|
a6a81490f6 | ||
|
|
d170cdd175 | ||
|
|
57e9983c88 | ||
|
|
d952a07c73 | ||
|
|
369f66297a | ||
|
|
9cc5d085e1 | ||
|
|
678fb6f0d3 | ||
|
|
401e26a45a | ||
|
|
eb934afbb5 | ||
|
|
8303970258 | ||
|
|
319f9efafb | ||
|
|
6c2a3a2bae | ||
|
|
adaeab9dba | ||
|
|
8981dd6067 | ||
|
|
7229e09df1 | ||
|
|
4105a2f36c | ||
|
|
0166231ddb | ||
|
|
cf439dd481 | ||
|
|
9903ae528b | ||
|
|
44c2bf6f7b | ||
|
|
e78c092499 | ||
|
|
61f70de479 | ||
|
|
776ac439f3 | ||
|
|
b19b4c6b5e | ||
|
|
b5157f4ed1 | ||
|
|
2d1e384eef | ||
|
|
9c5ca92e6e | ||
|
|
7b510c886e | ||
|
|
c1b47ac9db | ||
|
|
3f02fa439a | ||
|
|
f6b10481f3 | ||
|
|
d3699f9010 | ||
|
|
445ae5099d | ||
|
|
00bc7f30be | ||
|
|
1d0aa5ac2a | ||
|
|
7f7e319d9f | ||
|
|
d7bcc92007 | ||
|
|
e883385ab0 | ||
|
|
e7d827548c | ||
|
|
bf7ed1fce2 | ||
|
|
fee93f2dab | ||
|
|
a61947bb5c | ||
|
|
3c59d8dc60 | ||
|
|
46f6e3644b | ||
|
|
39a34e46db | ||
|
|
95a1435f61 | ||
|
|
e57ad5c33d | ||
|
|
f7d589ce21 | ||
|
|
2787b8e92f | ||
|
|
2166d80d58 | ||
|
|
67306c22cd | ||
|
|
b2407ab3f5 | ||
|
|
00dce30d3b | ||
|
|
9c381b4469 | ||
|
|
e3510f62a8 | ||
|
|
1d0f64a14d | ||
|
|
7726c25e46 | ||
|
|
df4f2df297 | ||
|
|
6af7ca1afc | ||
|
|
d6061cf937 | ||
|
|
ec921e5202 | ||
|
|
d016e68cee | ||
|
|
aed18eb571 | ||
|
|
f3cf808814 | ||
|
|
e22cb57718 | ||
|
|
bacc585b87 | ||
|
|
535120d6b1 | ||
|
|
bf4a22f082 | ||
|
|
2c23ff54d1 | ||
|
|
a411da9122 | ||
|
|
264396a616 | ||
|
|
a2e465c74d | ||
|
|
4811e8c73b | ||
|
|
0f22cb4450 | ||
|
|
6f13b057af | ||
|
|
0e733753e0 | ||
|
|
4f5665c7f0 | ||
|
|
83d3279fd8 | ||
|
|
0c7deb26a3 | ||
|
|
fdb10ba116 | ||
|
|
401dca07d0 | ||
|
|
4df960c9d5 | ||
|
|
09efd68228 | ||
|
|
4e6b5cc19f | ||
|
|
4f6f587700 | ||
|
|
fd2a8edb53 | ||
|
|
bb1efad7c7 | ||
|
|
57fa3b56c0 | ||
|
|
c3769b5c13 | ||
|
|
d54b57e77d | ||
|
|
82e842ad69 | ||
|
|
408a208086 | ||
|
|
bb1c625b30 | ||
|
|
900c9836fb | ||
|
|
6b2de1baff | ||
|
|
f55dc50435 | ||
|
|
dae25a15b3 | ||
|
|
4dafacaa8b | ||
|
|
9b24173867 | ||
|
|
91dcb31886 | ||
|
|
be6d7f314a | ||
|
|
1ef8bc1e72 | ||
|
|
5fb3bca5fd | ||
|
|
29c0434eb3 | ||
|
|
0195465234 | ||
|
|
0d2828cc00 | ||
|
|
c1847bec5d | ||
|
|
4b01c8eef5 | ||
|
|
e73c2ffa34 | ||
|
|
0af0fbf40b | ||
|
|
af30ae63c5 | ||
|
|
fc4e5d654b | ||
|
|
7ccfda9e25 | ||
|
|
2643e0c72f | ||
|
|
1975a576c5 | ||
|
|
f563fe2a3b | ||
|
|
e8495aa3fc | ||
|
|
35071150b7 | ||
|
|
40f18885b1 | ||
|
|
b77f49569b | ||
|
|
bea68549c5 | ||
|
|
b981c765ae | ||
|
|
b61f549444 | ||
|
|
162236f463 | ||
|
|
04ad4737de | ||
|
|
8ebb47bdd1 | ||
|
|
e70c43bcd4 | ||
|
|
cbccb7fdc0 | ||
|
|
a2df9397ff | ||
|
|
47f508ec21 | ||
|
|
ce828c1c3c | ||
|
|
c8f631b046 | ||
|
|
8511d84042 | ||
|
|
8a57894394 | ||
|
|
68484da2fc | ||
|
|
0b0b66c02f | ||
|
|
28de7cc420 | ||
|
|
9a478ad676 | ||
|
|
52e949a85b | ||
|
|
07f6156d8a | ||
|
|
29277ac273 | ||
|
|
6836e9875d | ||
|
|
cfb3370df8 | ||
|
|
d697f2ebac | ||
|
|
0efd6ed914 | ||
|
|
72c013d212 | ||
|
|
27234fb790 | ||
|
|
a6bd90713d | ||
|
|
9c58d1edb5 | ||
|
|
04f8675624 | ||
|
|
f37c92cfe2 | ||
|
|
fec871e1cb | ||
|
|
1b21e082fa | ||
|
|
beb11f8d02 | ||
|
|
90c3486e03 | ||
|
|
9ceb699e9a | ||
|
|
a9edf54d2f | ||
|
|
4bdbf57d98 | ||
|
|
fce4513d58 | ||
|
|
7cf07cac17 | ||
|
|
b6595974c2 | ||
|
|
f12bb90924 | ||
|
|
f0b394a151 | ||
|
|
01585ab8a3 | ||
|
|
0be6455fca | ||
|
|
f03db8278c | ||
|
|
93a78f1847 | ||
|
|
5bd183f4a7 | ||
|
|
89044e8c33 | ||
|
|
10879da823 | ||
|
|
609a0f4fd1 | ||
|
|
f9e8287346 | ||
|
|
bb27dde116 | ||
|
|
3b2e1745e9 | ||
|
|
9fcbe9751c | ||
|
|
b57b573085 | ||
|
|
01ed1b3b03 | ||
|
|
ac53fbcd0e | ||
|
|
e4cb5a14b3 | ||
|
|
8676d3af1d | ||
|
|
c2f2f9517c | ||
|
|
113119dc6f | ||
|
|
17a6ef4edb | ||
|
|
cd82517b90 | ||
|
|
888132263d | ||
|
|
0ff1b594d0 | ||
|
|
ebd8c8c6fa | ||
|
|
b48930974b | ||
|
|
426fc54456 | ||
|
|
bae1129209 | ||
|
|
d5371d28aa | ||
|
|
131f977841 | ||
|
|
1e0238de96 | ||
|
|
8878c6d6b0 | ||
|
|
c53bba9e02 | ||
|
|
2b2777915e | ||
|
|
fcaf78e449 | ||
|
|
4e028bd2d2 | ||
|
|
fdea3085a7 | ||
|
|
4c0107a322 | ||
|
|
f548ca3e19 | ||
|
|
5e481879ca | ||
|
|
cc9b11d163 | ||
|
|
bfc802204e | ||
|
|
fb7b73a962 | ||
|
|
4de5da2f8f | ||
|
|
1c1a9ef73e | ||
|
|
e043a2824a | ||
|
|
3010f75297 | ||
|
|
99d443b16e | ||
|
|
bc21e7adba | ||
|
|
240d553443 | ||
|
|
e692a2886c | ||
|
|
a6f380fde0 | ||
|
|
c52a28ace9 | ||
|
|
83f6d5679c | ||
|
|
c5acb5ac32 | ||
|
|
8ed2fb21b2 | ||
|
|
d994e0503b | ||
|
|
2d43541f0e | ||
|
|
c5b8a0783e | ||
|
|
af318b8f04 | ||
|
|
0d96876505 | ||
|
|
52daf17cb5 | ||
|
|
ca33419c52 | ||
|
|
ddab6f1190 | ||
|
|
fe9f8772ad | ||
|
|
9359e46951 | ||
|
|
ad4ef58a8e | ||
|
|
4d4ba25d11 | ||
|
|
d3f4fd5061 | ||
|
|
424f3b3729 | ||
|
|
bdf4befb3e | ||
|
|
2349e21731 | ||
|
|
bfc73866c9 | ||
|
|
cb43402d7d | ||
|
|
51eec12764 | ||
|
|
c1bff00d1f | ||
|
|
27b537d568 | ||
|
|
2c726244ca | ||
|
|
2856b79591 | ||
|
|
b0bc3dc0c9 | ||
|
|
db89e7bcd0 | ||
|
|
8627cd07e7 | ||
|
|
96708e5d45 | ||
|
|
8079d354d1 | ||
|
|
da4db99c94 | ||
|
|
dba4c462c4 | ||
|
|
135eb4c98d | ||
|
|
192d2b63f2 | ||
|
|
70449a1cd7 | ||
|
|
82f9f58d28 | ||
|
|
16b33eecb1 | ||
|
|
db2bf16427 | ||
|
|
47a5d4b459 | ||
|
|
062956311d | ||
|
|
2581bebfd9 | ||
|
|
ed366bddbb | ||
|
|
6c8f425ae2 | ||
|
|
e0f8f914ee | ||
|
|
b0c2e77bd8 | ||
|
|
b8ab34e362 | ||
|
|
22816651c2 | ||
|
|
0326442969 | ||
|
|
7433610105 | ||
|
|
f6a470de63 | ||
|
|
ab693f7b8a | ||
|
|
2d5dc62ad0 | ||
|
|
8961f24821 | ||
|
|
f10d638bfa | ||
|
|
16bc7436c5 | ||
|
|
2b8eca3ae9 | ||
|
|
5a5d647825 | ||
|
|
9c1e8dd1e4 | ||
|
|
034835073c | ||
|
|
78a56174b1 | ||
|
|
36bcf20588 | ||
|
|
b2a7bae5db | ||
|
|
ae5c9243c9 | ||
|
|
d239d873d8 | ||
|
|
8f87a5408f | ||
|
|
b365ce861a | ||
|
|
b39e25a58f | ||
|
|
81022fdcfe | ||
|
|
e71024c4bd | ||
|
|
043b3cd9a9 | ||
|
|
6937491d2a | ||
|
|
0c2954565d | ||
|
|
02d754ba67 | ||
|
|
973be02aa6 | ||
|
|
5929db9b23 | ||
|
|
32e11b8701 | ||
|
|
4fa817cd7d | ||
|
|
b0a6847007 | ||
|
|
327c2e97d8 | ||
|
|
7705051910 | ||
|
|
a50349181a | ||
|
|
c883289abb | ||
|
|
65cb240e88 | ||
|
|
77f38955b3 | ||
|
|
7c82aebc76 | ||
|
|
205fa72809 | ||
|
|
13fe21c5b7 | ||
|
|
f809bdd049 | ||
|
|
678ee7dc32 | ||
|
|
5644415767 | ||
|
|
b7bafb40cb | ||
|
|
4de776341e | ||
|
|
708c265b4f | ||
|
|
67841042d6 | ||
|
|
0a3afbe38f | ||
|
|
66498ae9ac | ||
|
|
9ea415c037 | ||
|
|
e30109829b | ||
|
|
68fc85ea49 | ||
|
|
0405ade5f4 | ||
|
|
6c56e541dd | ||
|
|
44dc96d2c6 | ||
|
|
e5d02000c3 | ||
|
|
f331d3ecc9 | ||
|
|
526a9070e6 | ||
|
|
af51fcacb7 | ||
|
|
1c5e07ff77 | ||
|
|
d66bd6439b | ||
|
|
440178d697 | ||
|
|
3144b96faa | ||
|
|
3e9c207c25 | ||
|
|
cbe2e68c26 | ||
|
|
b3f8206d47 | ||
|
|
a693d2e023 | ||
|
|
540f738cc7 | ||
|
|
0f416b0b9d | ||
|
|
b390fd141d | ||
|
|
cb56d1a22d | ||
|
|
6090401ccd | ||
|
|
e3314f41e4 | ||
|
|
036d8e872c | ||
|
|
27ee3a449b | ||
|
|
b994a076c2 | ||
|
|
e2d78d6def | ||
|
|
9b69dd0d03 | ||
|
|
abcf38b085 | ||
|
|
da17d33ac3 | ||
|
|
177dd36e23 | ||
|
|
7bed751db0 | ||
|
|
e9577e34f1 | ||
|
|
9661a6f042 | ||
|
|
03b3e0d0da | ||
|
|
1797e79129 | ||
|
|
1f8b3eaba7 | ||
|
|
d1f44e89e2 | ||
|
|
5fe40f4a63 | ||
|
|
c4a5a69dbd | ||
|
|
5e1472263d | ||
|
|
61485f91ad | ||
|
|
57eb9361db | ||
|
|
98643ef6e6 | ||
|
|
f94707d429 | ||
|
|
48b883d741 | ||
|
|
32e9c293f0 | ||
|
|
cd129edef0 | ||
|
|
9dc76fd27b | ||
|
|
3260c7449e | ||
|
|
66143eaf74 | ||
|
|
9dfe149310 | ||
|
|
179a0272d1 | ||
|
|
cff0308568 | ||
|
|
ada4cd75a3 | ||
|
|
adc0f67008 | ||
|
|
3bfd29bb46 | ||
|
|
1df0a53f22 | ||
|
|
912df24f4a | ||
|
|
e000bbe5e4 | ||
|
|
bc64712b5d | ||
|
|
5818e8adc7 | ||
|
|
2d3be88bb5 | ||
|
|
87a2ed51dc | ||
|
|
b68558d749 | ||
|
|
1fa22efd90 | ||
|
|
dc8455dd10 | ||
|
|
c1954aee72 | ||
|
|
c26ba60003 | ||
|
|
b3d3eac532 | ||
|
|
706ee80069 | ||
|
|
87fc2d5089 | ||
|
|
2d9cc5c336 | ||
|
|
b21596de20 | ||
|
|
fb94c645f7 | ||
|
|
6e48f43e4e | ||
|
|
82fa0bc03d | ||
|
|
1cda15440a | ||
|
|
264b44f617 | ||
|
|
2652578aa4 |
20
.agents/plugins/marketplace.json
Normal file
20
.agents/plugins/marketplace.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "everything-claude-code",
|
||||||
|
"interface": {
|
||||||
|
"displayName": "Everything Claude Code"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "everything-claude-code",
|
||||||
|
"source": {
|
||||||
|
"source": "local",
|
||||||
|
"path": "../.."
|
||||||
|
},
|
||||||
|
"policy": {
|
||||||
|
"installation": "AVAILABLE",
|
||||||
|
"authentication": "ON_INSTALL"
|
||||||
|
},
|
||||||
|
"category": "Productivity"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
106
.agents/skills/article-writing/SKILL.md
Normal file
106
.agents/skills/article-writing/SKILL.md
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
---
|
||||||
|
name: article-writing
|
||||||
|
description: Write articles, guides, blog posts, tutorials, newsletter issues, and other long-form content in a distinctive voice derived from supplied examples or brand guidance. Use when the user wants polished written content longer than a paragraph, especially when voice consistency, structure, and credibility matter.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Article Writing
|
||||||
|
|
||||||
|
Write long-form content that sounds like an actual person with a point of view, not an LLM smoothing itself into paste.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- drafting blog posts, essays, launch posts, guides, tutorials, or newsletter issues
|
||||||
|
- turning notes, transcripts, or research into polished articles
|
||||||
|
- matching an existing founder, operator, or brand voice from examples
|
||||||
|
- tightening structure, pacing, and evidence in already-written long-form copy
|
||||||
|
|
||||||
|
## Core Rules
|
||||||
|
|
||||||
|
1. Lead with the concrete thing: artifact, example, output, anecdote, number, screenshot, or code.
|
||||||
|
2. Explain after the example, not before.
|
||||||
|
3. Keep sentences tight unless the source voice is intentionally expansive.
|
||||||
|
4. Use proof instead of adjectives.
|
||||||
|
5. Never invent facts, credibility, or customer evidence.
|
||||||
|
|
||||||
|
## Voice Capture Workflow
|
||||||
|
|
||||||
|
If the user wants a specific voice, collect one or more of:
|
||||||
|
- published articles
|
||||||
|
- newsletters
|
||||||
|
- X posts or threads
|
||||||
|
- docs or memos
|
||||||
|
- launch notes
|
||||||
|
- a style guide
|
||||||
|
|
||||||
|
Then extract:
|
||||||
|
- sentence length and rhythm
|
||||||
|
- whether the writing is compressed, explanatory, sharp, or formal
|
||||||
|
- how parentheses are used
|
||||||
|
- how often the writer asks questions
|
||||||
|
- whether the writer uses fragments, lists, or hard pivots
|
||||||
|
- formatting habits such as headers, bullets, code blocks, pull quotes
|
||||||
|
- what the writer clearly avoids
|
||||||
|
|
||||||
|
If no voice references are given, default to a sharp operator voice: concrete, unsentimental, useful.
|
||||||
|
|
||||||
|
## Affaan / ECC Voice Reference
|
||||||
|
|
||||||
|
When matching Affaan / ECC voice, bias toward:
|
||||||
|
- direct claims over scene-setting
|
||||||
|
- high specificity
|
||||||
|
- parentheticals used for qualification or over-clarification, not comedy
|
||||||
|
- capitalization chosen situationally, not as a gimmick
|
||||||
|
- very low tolerance for fake thought-leadership cadence
|
||||||
|
- almost no bait questions
|
||||||
|
|
||||||
|
## Banned Patterns
|
||||||
|
|
||||||
|
Delete and rewrite any of these:
|
||||||
|
- "In today's rapidly evolving landscape"
|
||||||
|
- "game-changer", "cutting-edge", "revolutionary"
|
||||||
|
- "no fluff"
|
||||||
|
- "not X, just Y"
|
||||||
|
- "here's why this matters" as a standalone bridge
|
||||||
|
- fake vulnerability arcs
|
||||||
|
- a closing question added only to juice engagement
|
||||||
|
- forced lowercase
|
||||||
|
- corny parenthetical asides
|
||||||
|
- biography padding that does not move the argument
|
||||||
|
|
||||||
|
## Writing Process
|
||||||
|
|
||||||
|
1. Clarify the audience and purpose.
|
||||||
|
2. Build a hard outline with one job per section.
|
||||||
|
3. Start sections with proof, artifact, conflict, or example.
|
||||||
|
4. Expand only where the next sentence earns space.
|
||||||
|
5. Cut anything that sounds templated, overexplained, or self-congratulatory.
|
||||||
|
|
||||||
|
## Structure Guidance
|
||||||
|
|
||||||
|
### Technical Guides
|
||||||
|
|
||||||
|
- open with what the reader gets
|
||||||
|
- use code, commands, screenshots, or concrete output in major sections
|
||||||
|
- end with actionable takeaways, not a soft recap
|
||||||
|
|
||||||
|
### Essays / Opinion
|
||||||
|
|
||||||
|
- start with tension, contradiction, or a specific observation
|
||||||
|
- keep one argument thread per section
|
||||||
|
- make opinions answer to evidence
|
||||||
|
|
||||||
|
### Newsletters
|
||||||
|
|
||||||
|
- keep the first screen doing real work
|
||||||
|
- do not front-load diary filler
|
||||||
|
- use section labels only when they improve scanability
|
||||||
|
|
||||||
|
## Quality Gate
|
||||||
|
|
||||||
|
Before delivering:
|
||||||
|
- factual claims are backed by provided sources
|
||||||
|
- generic AI transitions are gone
|
||||||
|
- the voice matches the supplied examples
|
||||||
|
- every section adds something new
|
||||||
|
- formatting matches the intended medium
|
||||||
7
.agents/skills/article-writing/agents/openai.yaml
Normal file
7
.agents/skills/article-writing/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Article Writing"
|
||||||
|
short_description: "Write long-form content in a supplied voice without sounding templated"
|
||||||
|
brand_color: "#B45309"
|
||||||
|
default_prompt: "Draft a sharp long-form article from these notes and examples"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
@@ -23,7 +23,7 @@ Backend architecture patterns and best practices for scalable server-side applic
|
|||||||
### RESTful API Structure
|
### RESTful API Structure
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ Resource-based URLs
|
// PASS: Resource-based URLs
|
||||||
GET /api/markets # List resources
|
GET /api/markets # List resources
|
||||||
GET /api/markets/:id # Get single resource
|
GET /api/markets/:id # Get single resource
|
||||||
POST /api/markets # Create resource
|
POST /api/markets # Create resource
|
||||||
@@ -31,7 +31,7 @@ PUT /api/markets/:id # Replace resource
|
|||||||
PATCH /api/markets/:id # Update resource
|
PATCH /api/markets/:id # Update resource
|
||||||
DELETE /api/markets/:id # Delete resource
|
DELETE /api/markets/:id # Delete resource
|
||||||
|
|
||||||
// ✅ Query parameters for filtering, sorting, pagination
|
// PASS: Query parameters for filtering, sorting, pagination
|
||||||
GET /api/markets?status=active&sort=volume&limit=20&offset=0
|
GET /api/markets?status=active&sort=volume&limit=20&offset=0
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ export default withAuth(async (req, res) => {
|
|||||||
### Query Optimization
|
### Query Optimization
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Select only needed columns
|
// PASS: GOOD: Select only needed columns
|
||||||
const { data } = await supabase
|
const { data } = await supabase
|
||||||
.from('markets')
|
.from('markets')
|
||||||
.select('id, name, status, volume')
|
.select('id, name, status, volume')
|
||||||
@@ -139,7 +139,7 @@ const { data } = await supabase
|
|||||||
.order('volume', { ascending: false })
|
.order('volume', { ascending: false })
|
||||||
.limit(10)
|
.limit(10)
|
||||||
|
|
||||||
// ❌ BAD: Select everything
|
// FAIL: BAD: Select everything
|
||||||
const { data } = await supabase
|
const { data } = await supabase
|
||||||
.from('markets')
|
.from('markets')
|
||||||
.select('*')
|
.select('*')
|
||||||
@@ -148,13 +148,13 @@ const { data } = await supabase
|
|||||||
### N+1 Query Prevention
|
### N+1 Query Prevention
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ❌ BAD: N+1 query problem
|
// FAIL: BAD: N+1 query problem
|
||||||
const markets = await getMarkets()
|
const markets = await getMarkets()
|
||||||
for (const market of markets) {
|
for (const market of markets) {
|
||||||
market.creator = await getUser(market.creator_id) // N queries
|
market.creator = await getUser(market.creator_id) // N queries
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ GOOD: Batch fetch
|
// PASS: GOOD: Batch fetch
|
||||||
const markets = await getMarkets()
|
const markets = await getMarkets()
|
||||||
const creatorIds = markets.map(m => m.creator_id)
|
const creatorIds = markets.map(m => m.creator_id)
|
||||||
const creators = await getUsers(creatorIds) // 1 query
|
const creators = await getUsers(creatorIds) // 1 query
|
||||||
|
|||||||
84
.agents/skills/bun-runtime/SKILL.md
Normal file
84
.agents/skills/bun-runtime/SKILL.md
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
---
|
||||||
|
name: bun-runtime
|
||||||
|
description: Bun as runtime, package manager, bundler, and test runner. When to choose Bun vs Node, migration notes, and Vercel support.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Bun Runtime
|
||||||
|
|
||||||
|
Bun is a fast all-in-one JavaScript runtime and toolkit: runtime, package manager, bundler, and test runner.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- **Prefer Bun** for: new JS/TS projects, scripts where install/run speed matters, Vercel deployments with Bun runtime, and when you want a single toolchain (run + install + test + build).
|
||||||
|
- **Prefer Node** for: maximum ecosystem compatibility, legacy tooling that assumes Node, or when a dependency has known Bun issues.
|
||||||
|
|
||||||
|
Use when: adopting Bun, migrating from Node, writing or debugging Bun scripts/tests, or configuring Bun on Vercel or other platforms.
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
- **Runtime**: Drop-in Node-compatible runtime (built on JavaScriptCore, implemented in Zig).
|
||||||
|
- **Package manager**: `bun install` is significantly faster than npm/yarn. Lockfile is `bun.lock` (text) by default in current Bun; older versions used `bun.lockb` (binary).
|
||||||
|
- **Bundler**: Built-in bundler and transpiler for apps and libraries.
|
||||||
|
- **Test runner**: Built-in `bun test` with Jest-like API.
|
||||||
|
|
||||||
|
**Migration from Node**: Replace `node script.js` with `bun run script.js` or `bun script.js`. Run `bun install` in place of `npm install`; most packages work. Use `bun run` for npm scripts; `bun x` for npx-style one-off runs. Node built-ins are supported; prefer Bun APIs where they exist for better performance.
|
||||||
|
|
||||||
|
**Vercel**: Set runtime to Bun in project settings. Build: `bun run build` or `bun build ./src/index.ts --outdir=dist`. Install: `bun install --frozen-lockfile` for reproducible deploys.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Run and install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies (creates/updates bun.lock or bun.lockb)
|
||||||
|
bun install
|
||||||
|
|
||||||
|
# Run a script or file
|
||||||
|
bun run dev
|
||||||
|
bun run src/index.ts
|
||||||
|
bun src/index.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
### Scripts and env
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun run --env-file=.env dev
|
||||||
|
FOO=bar bun run script.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun test
|
||||||
|
bun test --watch
|
||||||
|
```
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// test/example.test.ts
|
||||||
|
import { expect, test } from "bun:test";
|
||||||
|
|
||||||
|
test("add", () => {
|
||||||
|
expect(1 + 2).toBe(3);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Runtime API
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const file = Bun.file("package.json");
|
||||||
|
const json = await file.json();
|
||||||
|
|
||||||
|
Bun.serve({
|
||||||
|
port: 3000,
|
||||||
|
fetch(req) {
|
||||||
|
return new Response("Hello");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- Commit the lockfile (`bun.lock` or `bun.lockb`) for reproducible installs.
|
||||||
|
- Prefer `bun run` for scripts. For TypeScript, Bun runs `.ts` natively.
|
||||||
|
- Keep dependencies up to date; Bun and the ecosystem evolve quickly.
|
||||||
7
.agents/skills/bun-runtime/agents/openai.yaml
Normal file
7
.agents/skills/bun-runtime/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Bun Runtime"
|
||||||
|
short_description: "Bun as runtime, package manager, bundler, and test runner"
|
||||||
|
brand_color: "#FBF0DF"
|
||||||
|
default_prompt: "Use Bun for scripts, install, or run"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
337
.agents/skills/claude-api/SKILL.md
Normal file
337
.agents/skills/claude-api/SKILL.md
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
---
|
||||||
|
name: claude-api
|
||||||
|
description: Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Claude API
|
||||||
|
|
||||||
|
Build applications with the Anthropic Claude API and SDKs.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- Building applications that call the Claude API
|
||||||
|
- Code imports `anthropic` (Python) or `@anthropic-ai/sdk` (TypeScript)
|
||||||
|
- User asks about Claude API patterns, tool use, streaming, or vision
|
||||||
|
- Implementing agent workflows with Claude Agent SDK
|
||||||
|
- Optimizing API costs, token usage, or latency
|
||||||
|
|
||||||
|
## Model Selection
|
||||||
|
|
||||||
|
| Model | ID | Best For |
|
||||||
|
|-------|-----|----------|
|
||||||
|
| Opus 4.6 | `claude-opus-4-6` | Complex reasoning, architecture, research |
|
||||||
|
| Sonnet 4.6 | `claude-sonnet-4-6` | Balanced coding, most development tasks |
|
||||||
|
| Haiku 4.5 | `claude-haiku-4-5-20251001` | Fast responses, high-volume, cost-sensitive |
|
||||||
|
|
||||||
|
Default to Sonnet 4.6 unless the task requires deep reasoning (Opus) or speed/cost optimization (Haiku).
|
||||||
|
|
||||||
|
## Python SDK
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install anthropic
|
||||||
|
```
|
||||||
|
|
||||||
|
### Basic Message
|
||||||
|
|
||||||
|
```python
|
||||||
|
import anthropic
|
||||||
|
|
||||||
|
client = anthropic.Anthropic() # reads ANTHROPIC_API_KEY from env
|
||||||
|
|
||||||
|
message = client.messages.create(
|
||||||
|
model="claude-sonnet-4-6",
|
||||||
|
max_tokens=1024,
|
||||||
|
messages=[
|
||||||
|
{"role": "user", "content": "Explain async/await in Python"}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
print(message.content[0].text)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Streaming
|
||||||
|
|
||||||
|
```python
|
||||||
|
with client.messages.stream(
|
||||||
|
model="claude-sonnet-4-6",
|
||||||
|
max_tokens=1024,
|
||||||
|
messages=[{"role": "user", "content": "Write a haiku about coding"}]
|
||||||
|
) as stream:
|
||||||
|
for text in stream.text_stream:
|
||||||
|
print(text, end="", flush=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
### System Prompt
|
||||||
|
|
||||||
|
```python
|
||||||
|
message = client.messages.create(
|
||||||
|
model="claude-sonnet-4-6",
|
||||||
|
max_tokens=1024,
|
||||||
|
system="You are a senior Python developer. Be concise.",
|
||||||
|
messages=[{"role": "user", "content": "Review this function"}]
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## TypeScript SDK
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install @anthropic-ai/sdk
|
||||||
|
```
|
||||||
|
|
||||||
|
### Basic Message
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import Anthropic from "@anthropic-ai/sdk";
|
||||||
|
|
||||||
|
const client = new Anthropic(); // reads ANTHROPIC_API_KEY from env
|
||||||
|
|
||||||
|
const message = await client.messages.create({
|
||||||
|
model: "claude-sonnet-4-6",
|
||||||
|
max_tokens: 1024,
|
||||||
|
messages: [
|
||||||
|
{ role: "user", content: "Explain async/await in TypeScript" }
|
||||||
|
],
|
||||||
|
});
|
||||||
|
console.log(message.content[0].text);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Streaming
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const stream = client.messages.stream({
|
||||||
|
model: "claude-sonnet-4-6",
|
||||||
|
max_tokens: 1024,
|
||||||
|
messages: [{ role: "user", content: "Write a haiku" }],
|
||||||
|
});
|
||||||
|
|
||||||
|
for await (const event of stream) {
|
||||||
|
if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
|
||||||
|
process.stdout.write(event.delta.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tool Use
|
||||||
|
|
||||||
|
Define tools and let Claude call them:
|
||||||
|
|
||||||
|
```python
|
||||||
|
tools = [
|
||||||
|
{
|
||||||
|
"name": "get_weather",
|
||||||
|
"description": "Get current weather for a location",
|
||||||
|
"input_schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"location": {"type": "string", "description": "City name"},
|
||||||
|
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
|
||||||
|
},
|
||||||
|
"required": ["location"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
message = client.messages.create(
|
||||||
|
model="claude-sonnet-4-6",
|
||||||
|
max_tokens=1024,
|
||||||
|
tools=tools,
|
||||||
|
messages=[{"role": "user", "content": "What's the weather in SF?"}]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Handle tool use response
|
||||||
|
for block in message.content:
|
||||||
|
if block.type == "tool_use":
|
||||||
|
# Execute the tool with block.input
|
||||||
|
result = get_weather(**block.input)
|
||||||
|
# Send result back
|
||||||
|
follow_up = client.messages.create(
|
||||||
|
model="claude-sonnet-4-6",
|
||||||
|
max_tokens=1024,
|
||||||
|
tools=tools,
|
||||||
|
messages=[
|
||||||
|
{"role": "user", "content": "What's the weather in SF?"},
|
||||||
|
{"role": "assistant", "content": message.content},
|
||||||
|
{"role": "user", "content": [
|
||||||
|
{"type": "tool_result", "tool_use_id": block.id, "content": str(result)}
|
||||||
|
]}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Vision
|
||||||
|
|
||||||
|
Send images for analysis:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import base64
|
||||||
|
|
||||||
|
with open("diagram.png", "rb") as f:
|
||||||
|
image_data = base64.standard_b64encode(f.read()).decode("utf-8")
|
||||||
|
|
||||||
|
message = client.messages.create(
|
||||||
|
model="claude-sonnet-4-6",
|
||||||
|
max_tokens=1024,
|
||||||
|
messages=[{
|
||||||
|
"role": "user",
|
||||||
|
"content": [
|
||||||
|
{"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": image_data}},
|
||||||
|
{"type": "text", "text": "Describe this diagram"}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Extended Thinking
|
||||||
|
|
||||||
|
For complex reasoning tasks:
|
||||||
|
|
||||||
|
```python
|
||||||
|
message = client.messages.create(
|
||||||
|
model="claude-sonnet-4-6",
|
||||||
|
max_tokens=16000,
|
||||||
|
thinking={
|
||||||
|
"type": "enabled",
|
||||||
|
"budget_tokens": 10000
|
||||||
|
},
|
||||||
|
messages=[{"role": "user", "content": "Solve this math problem step by step..."}]
|
||||||
|
)
|
||||||
|
|
||||||
|
for block in message.content:
|
||||||
|
if block.type == "thinking":
|
||||||
|
print(f"Thinking: {block.thinking}")
|
||||||
|
elif block.type == "text":
|
||||||
|
print(f"Answer: {block.text}")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prompt Caching
|
||||||
|
|
||||||
|
Cache large system prompts or context to reduce costs:
|
||||||
|
|
||||||
|
```python
|
||||||
|
message = client.messages.create(
|
||||||
|
model="claude-sonnet-4-6",
|
||||||
|
max_tokens=1024,
|
||||||
|
system=[
|
||||||
|
{"type": "text", "text": large_system_prompt, "cache_control": {"type": "ephemeral"}}
|
||||||
|
],
|
||||||
|
messages=[{"role": "user", "content": "Question about the cached context"}]
|
||||||
|
)
|
||||||
|
# Check cache usage
|
||||||
|
print(f"Cache read: {message.usage.cache_read_input_tokens}")
|
||||||
|
print(f"Cache creation: {message.usage.cache_creation_input_tokens}")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Batches API
|
||||||
|
|
||||||
|
Process large volumes asynchronously at 50% cost reduction:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import time
|
||||||
|
|
||||||
|
batch = client.messages.batches.create(
|
||||||
|
requests=[
|
||||||
|
{
|
||||||
|
"custom_id": f"request-{i}",
|
||||||
|
"params": {
|
||||||
|
"model": "claude-sonnet-4-6",
|
||||||
|
"max_tokens": 1024,
|
||||||
|
"messages": [{"role": "user", "content": prompt}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i, prompt in enumerate(prompts)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Poll for completion
|
||||||
|
while True:
|
||||||
|
status = client.messages.batches.retrieve(batch.id)
|
||||||
|
if status.processing_status == "ended":
|
||||||
|
break
|
||||||
|
time.sleep(30)
|
||||||
|
|
||||||
|
# Get results
|
||||||
|
for result in client.messages.batches.results(batch.id):
|
||||||
|
print(result.result.message.content[0].text)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Claude Agent SDK
|
||||||
|
|
||||||
|
Build multi-step agents:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Note: Agent SDK API surface may change — check official docs
|
||||||
|
import anthropic
|
||||||
|
|
||||||
|
# Define tools as functions
|
||||||
|
tools = [{
|
||||||
|
"name": "search_codebase",
|
||||||
|
"description": "Search the codebase for relevant code",
|
||||||
|
"input_schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {"query": {"type": "string"}},
|
||||||
|
"required": ["query"]
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
|
||||||
|
# Run an agentic loop with tool use
|
||||||
|
client = anthropic.Anthropic()
|
||||||
|
messages = [{"role": "user", "content": "Review the auth module for security issues"}]
|
||||||
|
|
||||||
|
while True:
|
||||||
|
response = client.messages.create(
|
||||||
|
model="claude-sonnet-4-6",
|
||||||
|
max_tokens=4096,
|
||||||
|
tools=tools,
|
||||||
|
messages=messages,
|
||||||
|
)
|
||||||
|
if response.stop_reason == "end_turn":
|
||||||
|
break
|
||||||
|
# Handle tool calls and continue the loop
|
||||||
|
messages.append({"role": "assistant", "content": response.content})
|
||||||
|
# ... execute tools and append tool_result messages
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cost Optimization
|
||||||
|
|
||||||
|
| Strategy | Savings | When to Use |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| Prompt caching | Up to 90% on cached tokens | Repeated system prompts or context |
|
||||||
|
| Batches API | 50% | Non-time-sensitive bulk processing |
|
||||||
|
| Haiku instead of Sonnet | ~75% | Simple tasks, classification, extraction |
|
||||||
|
| Shorter max_tokens | Variable | When you know output will be short |
|
||||||
|
| Streaming | None (same cost) | Better UX, same price |
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
```python
|
||||||
|
import time
|
||||||
|
|
||||||
|
from anthropic import APIError, RateLimitError, APIConnectionError
|
||||||
|
|
||||||
|
try:
|
||||||
|
message = client.messages.create(...)
|
||||||
|
except RateLimitError:
|
||||||
|
# Back off and retry
|
||||||
|
time.sleep(60)
|
||||||
|
except APIConnectionError:
|
||||||
|
# Network issue, retry with backoff
|
||||||
|
pass
|
||||||
|
except APIError as e:
|
||||||
|
print(f"API error {e.status_code}: {e.message}")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environment Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Required
|
||||||
|
export ANTHROPIC_API_KEY="your-api-key-here"
|
||||||
|
|
||||||
|
# Optional: set default model
|
||||||
|
export ANTHROPIC_MODEL="claude-sonnet-4-6"
|
||||||
|
```
|
||||||
|
|
||||||
|
Never hardcode API keys. Always use environment variables.
|
||||||
7
.agents/skills/claude-api/agents/openai.yaml
Normal file
7
.agents/skills/claude-api/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Claude API"
|
||||||
|
short_description: "Anthropic Claude API patterns and SDKs"
|
||||||
|
brand_color: "#D97706"
|
||||||
|
default_prompt: "Build applications with the Claude API using Messages, tool use, streaming, and Agent SDK"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
@@ -48,12 +48,12 @@ Universal coding standards applicable across all projects.
|
|||||||
### Variable Naming
|
### Variable Naming
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Descriptive names
|
// PASS: GOOD: Descriptive names
|
||||||
const marketSearchQuery = 'election'
|
const marketSearchQuery = 'election'
|
||||||
const isUserAuthenticated = true
|
const isUserAuthenticated = true
|
||||||
const totalRevenue = 1000
|
const totalRevenue = 1000
|
||||||
|
|
||||||
// ❌ BAD: Unclear names
|
// FAIL: BAD: Unclear names
|
||||||
const q = 'election'
|
const q = 'election'
|
||||||
const flag = true
|
const flag = true
|
||||||
const x = 1000
|
const x = 1000
|
||||||
@@ -62,12 +62,12 @@ const x = 1000
|
|||||||
### Function Naming
|
### Function Naming
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Verb-noun pattern
|
// PASS: GOOD: Verb-noun pattern
|
||||||
async function fetchMarketData(marketId: string) { }
|
async function fetchMarketData(marketId: string) { }
|
||||||
function calculateSimilarity(a: number[], b: number[]) { }
|
function calculateSimilarity(a: number[], b: number[]) { }
|
||||||
function isValidEmail(email: string): boolean { }
|
function isValidEmail(email: string): boolean { }
|
||||||
|
|
||||||
// ❌ BAD: Unclear or noun-only
|
// FAIL: BAD: Unclear or noun-only
|
||||||
async function market(id: string) { }
|
async function market(id: string) { }
|
||||||
function similarity(a, b) { }
|
function similarity(a, b) { }
|
||||||
function email(e) { }
|
function email(e) { }
|
||||||
@@ -76,7 +76,7 @@ function email(e) { }
|
|||||||
### Immutability Pattern (CRITICAL)
|
### Immutability Pattern (CRITICAL)
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ ALWAYS use spread operator
|
// PASS: ALWAYS use spread operator
|
||||||
const updatedUser = {
|
const updatedUser = {
|
||||||
...user,
|
...user,
|
||||||
name: 'New Name'
|
name: 'New Name'
|
||||||
@@ -84,7 +84,7 @@ const updatedUser = {
|
|||||||
|
|
||||||
const updatedArray = [...items, newItem]
|
const updatedArray = [...items, newItem]
|
||||||
|
|
||||||
// ❌ NEVER mutate directly
|
// FAIL: NEVER mutate directly
|
||||||
user.name = 'New Name' // BAD
|
user.name = 'New Name' // BAD
|
||||||
items.push(newItem) // BAD
|
items.push(newItem) // BAD
|
||||||
```
|
```
|
||||||
@@ -92,7 +92,7 @@ items.push(newItem) // BAD
|
|||||||
### Error Handling
|
### Error Handling
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Comprehensive error handling
|
// PASS: GOOD: Comprehensive error handling
|
||||||
async function fetchData(url: string) {
|
async function fetchData(url: string) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(url)
|
const response = await fetch(url)
|
||||||
@@ -108,7 +108,7 @@ async function fetchData(url: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ❌ BAD: No error handling
|
// FAIL: BAD: No error handling
|
||||||
async function fetchData(url) {
|
async function fetchData(url) {
|
||||||
const response = await fetch(url)
|
const response = await fetch(url)
|
||||||
return response.json()
|
return response.json()
|
||||||
@@ -118,14 +118,14 @@ async function fetchData(url) {
|
|||||||
### Async/Await Best Practices
|
### Async/Await Best Practices
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Parallel execution when possible
|
// PASS: GOOD: Parallel execution when possible
|
||||||
const [users, markets, stats] = await Promise.all([
|
const [users, markets, stats] = await Promise.all([
|
||||||
fetchUsers(),
|
fetchUsers(),
|
||||||
fetchMarkets(),
|
fetchMarkets(),
|
||||||
fetchStats()
|
fetchStats()
|
||||||
])
|
])
|
||||||
|
|
||||||
// ❌ BAD: Sequential when unnecessary
|
// FAIL: BAD: Sequential when unnecessary
|
||||||
const users = await fetchUsers()
|
const users = await fetchUsers()
|
||||||
const markets = await fetchMarkets()
|
const markets = await fetchMarkets()
|
||||||
const stats = await fetchStats()
|
const stats = await fetchStats()
|
||||||
@@ -134,7 +134,7 @@ const stats = await fetchStats()
|
|||||||
### Type Safety
|
### Type Safety
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Proper types
|
// PASS: GOOD: Proper types
|
||||||
interface Market {
|
interface Market {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
@@ -146,7 +146,7 @@ function getMarket(id: string): Promise<Market> {
|
|||||||
// Implementation
|
// Implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
// ❌ BAD: Using 'any'
|
// FAIL: BAD: Using 'any'
|
||||||
function getMarket(id: any): Promise<any> {
|
function getMarket(id: any): Promise<any> {
|
||||||
// Implementation
|
// Implementation
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ function getMarket(id: any): Promise<any> {
|
|||||||
### Component Structure
|
### Component Structure
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Functional component with types
|
// PASS: GOOD: Functional component with types
|
||||||
interface ButtonProps {
|
interface ButtonProps {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
onClick: () => void
|
onClick: () => void
|
||||||
@@ -182,7 +182,7 @@ export function Button({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ❌ BAD: No types, unclear structure
|
// FAIL: BAD: No types, unclear structure
|
||||||
export function Button(props) {
|
export function Button(props) {
|
||||||
return <button onClick={props.onClick}>{props.children}</button>
|
return <button onClick={props.onClick}>{props.children}</button>
|
||||||
}
|
}
|
||||||
@@ -191,7 +191,7 @@ export function Button(props) {
|
|||||||
### Custom Hooks
|
### Custom Hooks
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Reusable custom hook
|
// PASS: GOOD: Reusable custom hook
|
||||||
export function useDebounce<T>(value: T, delay: number): T {
|
export function useDebounce<T>(value: T, delay: number): T {
|
||||||
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
||||||
|
|
||||||
@@ -213,25 +213,25 @@ const debouncedQuery = useDebounce(searchQuery, 500)
|
|||||||
### State Management
|
### State Management
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Proper state updates
|
// PASS: GOOD: Proper state updates
|
||||||
const [count, setCount] = useState(0)
|
const [count, setCount] = useState(0)
|
||||||
|
|
||||||
// Functional update for state based on previous state
|
// Functional update for state based on previous state
|
||||||
setCount(prev => prev + 1)
|
setCount(prev => prev + 1)
|
||||||
|
|
||||||
// ❌ BAD: Direct state reference
|
// FAIL: BAD: Direct state reference
|
||||||
setCount(count + 1) // Can be stale in async scenarios
|
setCount(count + 1) // Can be stale in async scenarios
|
||||||
```
|
```
|
||||||
|
|
||||||
### Conditional Rendering
|
### Conditional Rendering
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Clear conditional rendering
|
// PASS: GOOD: Clear conditional rendering
|
||||||
{isLoading && <Spinner />}
|
{isLoading && <Spinner />}
|
||||||
{error && <ErrorMessage error={error} />}
|
{error && <ErrorMessage error={error} />}
|
||||||
{data && <DataDisplay data={data} />}
|
{data && <DataDisplay data={data} />}
|
||||||
|
|
||||||
// ❌ BAD: Ternary hell
|
// FAIL: BAD: Ternary hell
|
||||||
{isLoading ? <Spinner /> : error ? <ErrorMessage error={error} /> : data ? <DataDisplay data={data} /> : null}
|
{isLoading ? <Spinner /> : error ? <ErrorMessage error={error} /> : data ? <DataDisplay data={data} /> : null}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ GET /api/markets?status=active&limit=10&offset=0
|
|||||||
### Response Format
|
### Response Format
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Consistent response structure
|
// PASS: GOOD: Consistent response structure
|
||||||
interface ApiResponse<T> {
|
interface ApiResponse<T> {
|
||||||
success: boolean
|
success: boolean
|
||||||
data?: T
|
data?: T
|
||||||
@@ -285,7 +285,7 @@ return NextResponse.json({
|
|||||||
```typescript
|
```typescript
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
|
||||||
// ✅ GOOD: Schema validation
|
// PASS: GOOD: Schema validation
|
||||||
const CreateMarketSchema = z.object({
|
const CreateMarketSchema = z.object({
|
||||||
name: z.string().min(1).max(200),
|
name: z.string().min(1).max(200),
|
||||||
description: z.string().min(1).max(2000),
|
description: z.string().min(1).max(2000),
|
||||||
@@ -348,14 +348,14 @@ types/market.types.ts # camelCase with .types suffix
|
|||||||
### When to Comment
|
### When to Comment
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Explain WHY, not WHAT
|
// PASS: GOOD: Explain WHY, not WHAT
|
||||||
// Use exponential backoff to avoid overwhelming the API during outages
|
// Use exponential backoff to avoid overwhelming the API during outages
|
||||||
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)
|
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)
|
||||||
|
|
||||||
// Deliberately using mutation here for performance with large arrays
|
// Deliberately using mutation here for performance with large arrays
|
||||||
items.push(newItem)
|
items.push(newItem)
|
||||||
|
|
||||||
// ❌ BAD: Stating the obvious
|
// FAIL: BAD: Stating the obvious
|
||||||
// Increment counter by 1
|
// Increment counter by 1
|
||||||
count++
|
count++
|
||||||
|
|
||||||
@@ -395,12 +395,12 @@ export async function searchMarkets(
|
|||||||
```typescript
|
```typescript
|
||||||
import { useMemo, useCallback } from 'react'
|
import { useMemo, useCallback } from 'react'
|
||||||
|
|
||||||
// ✅ GOOD: Memoize expensive computations
|
// PASS: GOOD: Memoize expensive computations
|
||||||
const sortedMarkets = useMemo(() => {
|
const sortedMarkets = useMemo(() => {
|
||||||
return markets.sort((a, b) => b.volume - a.volume)
|
return markets.sort((a, b) => b.volume - a.volume)
|
||||||
}, [markets])
|
}, [markets])
|
||||||
|
|
||||||
// ✅ GOOD: Memoize callbacks
|
// PASS: GOOD: Memoize callbacks
|
||||||
const handleSearch = useCallback((query: string) => {
|
const handleSearch = useCallback((query: string) => {
|
||||||
setSearchQuery(query)
|
setSearchQuery(query)
|
||||||
}, [])
|
}, [])
|
||||||
@@ -411,7 +411,7 @@ const handleSearch = useCallback((query: string) => {
|
|||||||
```typescript
|
```typescript
|
||||||
import { lazy, Suspense } from 'react'
|
import { lazy, Suspense } from 'react'
|
||||||
|
|
||||||
// ✅ GOOD: Lazy load heavy components
|
// PASS: GOOD: Lazy load heavy components
|
||||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||||
|
|
||||||
export function Dashboard() {
|
export function Dashboard() {
|
||||||
@@ -426,13 +426,13 @@ export function Dashboard() {
|
|||||||
### Database Queries
|
### Database Queries
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Select only needed columns
|
// PASS: GOOD: Select only needed columns
|
||||||
const { data } = await supabase
|
const { data } = await supabase
|
||||||
.from('markets')
|
.from('markets')
|
||||||
.select('id, name, status')
|
.select('id, name, status')
|
||||||
.limit(10)
|
.limit(10)
|
||||||
|
|
||||||
// ❌ BAD: Select everything
|
// FAIL: BAD: Select everything
|
||||||
const { data } = await supabase
|
const { data } = await supabase
|
||||||
.from('markets')
|
.from('markets')
|
||||||
.select('*')
|
.select('*')
|
||||||
@@ -459,12 +459,12 @@ test('calculates similarity correctly', () => {
|
|||||||
### Test Naming
|
### Test Naming
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Descriptive test names
|
// PASS: GOOD: Descriptive test names
|
||||||
test('returns empty array when no markets match query', () => { })
|
test('returns empty array when no markets match query', () => { })
|
||||||
test('throws error when OpenAI API key is missing', () => { })
|
test('throws error when OpenAI API key is missing', () => { })
|
||||||
test('falls back to substring search when Redis unavailable', () => { })
|
test('falls back to substring search when Redis unavailable', () => { })
|
||||||
|
|
||||||
// ❌ BAD: Vague test names
|
// FAIL: BAD: Vague test names
|
||||||
test('works', () => { })
|
test('works', () => { })
|
||||||
test('test search', () => { })
|
test('test search', () => { })
|
||||||
```
|
```
|
||||||
@@ -475,12 +475,12 @@ Watch for these anti-patterns:
|
|||||||
|
|
||||||
### 1. Long Functions
|
### 1. Long Functions
|
||||||
```typescript
|
```typescript
|
||||||
// ❌ BAD: Function > 50 lines
|
// FAIL: BAD: Function > 50 lines
|
||||||
function processMarketData() {
|
function processMarketData() {
|
||||||
// 100 lines of code
|
// 100 lines of code
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ GOOD: Split into smaller functions
|
// PASS: GOOD: Split into smaller functions
|
||||||
function processMarketData() {
|
function processMarketData() {
|
||||||
const validated = validateData()
|
const validated = validateData()
|
||||||
const transformed = transformData(validated)
|
const transformed = transformData(validated)
|
||||||
@@ -490,7 +490,7 @@ function processMarketData() {
|
|||||||
|
|
||||||
### 2. Deep Nesting
|
### 2. Deep Nesting
|
||||||
```typescript
|
```typescript
|
||||||
// ❌ BAD: 5+ levels of nesting
|
// FAIL: BAD: 5+ levels of nesting
|
||||||
if (user) {
|
if (user) {
|
||||||
if (user.isAdmin) {
|
if (user.isAdmin) {
|
||||||
if (market) {
|
if (market) {
|
||||||
@@ -503,7 +503,7 @@ if (user) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ GOOD: Early returns
|
// PASS: GOOD: Early returns
|
||||||
if (!user) return
|
if (!user) return
|
||||||
if (!user.isAdmin) return
|
if (!user.isAdmin) return
|
||||||
if (!market) return
|
if (!market) return
|
||||||
@@ -515,11 +515,11 @@ if (!hasPermission) return
|
|||||||
|
|
||||||
### 3. Magic Numbers
|
### 3. Magic Numbers
|
||||||
```typescript
|
```typescript
|
||||||
// ❌ BAD: Unexplained numbers
|
// FAIL: BAD: Unexplained numbers
|
||||||
if (retryCount > 3) { }
|
if (retryCount > 3) { }
|
||||||
setTimeout(callback, 500)
|
setTimeout(callback, 500)
|
||||||
|
|
||||||
// ✅ GOOD: Named constants
|
// PASS: GOOD: Named constants
|
||||||
const MAX_RETRIES = 3
|
const MAX_RETRIES = 3
|
||||||
const DEBOUNCE_DELAY_MS = 500
|
const DEBOUNCE_DELAY_MS = 500
|
||||||
|
|
||||||
|
|||||||
150
.agents/skills/content-engine/SKILL.md
Normal file
150
.agents/skills/content-engine/SKILL.md
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
---
|
||||||
|
name: content-engine
|
||||||
|
description: Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Content Engine
|
||||||
|
|
||||||
|
Build platform-native content without flattening the author's real voice into platform slop.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- writing X posts or threads
|
||||||
|
- drafting LinkedIn posts or launch updates
|
||||||
|
- scripting short-form video or YouTube explainers
|
||||||
|
- repurposing articles, podcasts, demos, docs, or internal notes into public content
|
||||||
|
- building a launch sequence or ongoing content system around a product, insight, or narrative
|
||||||
|
|
||||||
|
## Non-Negotiables
|
||||||
|
|
||||||
|
1. Start from source material, not generic post formulas.
|
||||||
|
2. Adapt the format for the platform, not the persona.
|
||||||
|
3. One post should carry one actual claim.
|
||||||
|
4. Specificity beats adjectives.
|
||||||
|
5. No engagement bait unless the user explicitly asks for it.
|
||||||
|
|
||||||
|
## Source-First Workflow
|
||||||
|
|
||||||
|
Before drafting, identify the source set:
|
||||||
|
- published articles
|
||||||
|
- notes or internal memos
|
||||||
|
- product demos
|
||||||
|
- docs or changelogs
|
||||||
|
- transcripts
|
||||||
|
- screenshots
|
||||||
|
- prior posts from the same author
|
||||||
|
|
||||||
|
If the user wants a specific voice, build a voice profile from real examples before writing.
|
||||||
|
|
||||||
|
## Voice Capture Workflow
|
||||||
|
|
||||||
|
Collect 5 to 20 examples when available. Good sources:
|
||||||
|
- articles or essays
|
||||||
|
- X posts or threads
|
||||||
|
- docs or release notes
|
||||||
|
- newsletters
|
||||||
|
- previous launch posts
|
||||||
|
|
||||||
|
If live X access is available, use `x-api` to pull recent original posts before drafting. If not, use the examples already provided or present in the repo.
|
||||||
|
|
||||||
|
Extract and write down:
|
||||||
|
- sentence length and rhythm
|
||||||
|
- how compressed or explanatory the writing is
|
||||||
|
- whether capitalization is conventional, mixed, or situational
|
||||||
|
- how parentheses are used
|
||||||
|
- whether the writer uses fragments, lists, or abrupt pivots
|
||||||
|
- how often the writer asks questions
|
||||||
|
- how sharp, formal, opinionated, or dry the voice is
|
||||||
|
- what the writer never does
|
||||||
|
|
||||||
|
Do not start drafting until the voice profile is clear enough to enforce.
|
||||||
|
|
||||||
|
## Affaan / ECC Voice Reference
|
||||||
|
|
||||||
|
When the user wants Affaan / ECC voice specifically, default to this unless newer examples clearly override it:
|
||||||
|
- direct, compressed, concrete
|
||||||
|
- strong preference for specific claims, numbers, mechanisms, and receipts
|
||||||
|
- parentheticals used to qualify, narrow, or over-clarify, not to do corny bits
|
||||||
|
- lowercase is optional, not mandatory
|
||||||
|
- questions are rare and should not be added as bait
|
||||||
|
- transitions should feel earned, not polished
|
||||||
|
- tone can be sharp or blunt, but should not sound like a content marketer
|
||||||
|
|
||||||
|
## Hard Bans
|
||||||
|
|
||||||
|
Delete and rewrite any of these:
|
||||||
|
- "In today's rapidly evolving landscape"
|
||||||
|
- "game-changer", "revolutionary", "cutting-edge"
|
||||||
|
- "no fluff"
|
||||||
|
- "not X, just Y"
|
||||||
|
- "here's why this matters" unless it is followed immediately by something concrete
|
||||||
|
- "Excited to share"
|
||||||
|
- fake curiosity gaps
|
||||||
|
- ending with a LinkedIn-style question just to farm replies
|
||||||
|
- forced lowercase when the source voice does not call for it
|
||||||
|
- forced casualness on LinkedIn
|
||||||
|
- parenthetical jokes that were not present in the source voice
|
||||||
|
|
||||||
|
## Platform Adaptation Rules
|
||||||
|
|
||||||
|
### X
|
||||||
|
|
||||||
|
- open with the strongest claim, artifact, or tension
|
||||||
|
- keep the compression if the source voice is compressed
|
||||||
|
- if writing a thread, each post must advance the argument
|
||||||
|
- do not pad with context the audience does not need
|
||||||
|
|
||||||
|
### LinkedIn
|
||||||
|
|
||||||
|
- expand only enough for people outside the immediate niche to follow
|
||||||
|
- do not turn it into a fake lesson post unless the source material actually is reflective
|
||||||
|
- no corporate inspiration cadence
|
||||||
|
- no praise-stacking, no "journey" filler
|
||||||
|
|
||||||
|
### Short Video
|
||||||
|
|
||||||
|
- script around the visual sequence and proof points
|
||||||
|
- first seconds should show the result, problem, or punch
|
||||||
|
- do not write narration that sounds better on paper than on screen
|
||||||
|
|
||||||
|
### YouTube
|
||||||
|
|
||||||
|
- show the result or tension early
|
||||||
|
- organize by argument or progression, not filler sections
|
||||||
|
- use chaptering only when it helps clarity
|
||||||
|
|
||||||
|
### Newsletter
|
||||||
|
|
||||||
|
- open with the point, conflict, or artifact
|
||||||
|
- do not spend the first paragraph warming up
|
||||||
|
- every section needs to add something new
|
||||||
|
|
||||||
|
## Repurposing Flow
|
||||||
|
|
||||||
|
1. Pick the anchor asset.
|
||||||
|
2. Extract 3 to 7 atomic claims or scenes.
|
||||||
|
3. Rank them by sharpness, novelty, and proof.
|
||||||
|
4. Assign one strong idea per output.
|
||||||
|
5. Adapt structure for each platform.
|
||||||
|
6. Strip platform-shaped filler.
|
||||||
|
7. Run the quality gate.
|
||||||
|
|
||||||
|
## Deliverables
|
||||||
|
|
||||||
|
When asked for a campaign, return:
|
||||||
|
- a short voice profile if voice matching matters
|
||||||
|
- the core angle
|
||||||
|
- platform-native drafts
|
||||||
|
- posting order only if it helps execution
|
||||||
|
- gaps that must be filled before publishing
|
||||||
|
|
||||||
|
## Quality Gate
|
||||||
|
|
||||||
|
Before delivering:
|
||||||
|
- every draft sounds like the intended author, not the platform stereotype
|
||||||
|
- every draft contains a real claim, proof point, or concrete observation
|
||||||
|
- no generic hype language remains
|
||||||
|
- no fake engagement bait remains
|
||||||
|
- no duplicated copy across platforms unless requested
|
||||||
|
- any CTA is earned and user-approved
|
||||||
7
.agents/skills/content-engine/agents/openai.yaml
Normal file
7
.agents/skills/content-engine/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Content Engine"
|
||||||
|
short_description: "Turn one idea into platform-native social and content outputs"
|
||||||
|
brand_color: "#DC2626"
|
||||||
|
default_prompt: "Turn this source asset into strong multi-platform content"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
114
.agents/skills/crosspost/SKILL.md
Normal file
114
.agents/skills/crosspost/SKILL.md
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
---
|
||||||
|
name: crosspost
|
||||||
|
description: Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Crosspost
|
||||||
|
|
||||||
|
Distribute content across platforms without turning it into the same fake post in four costumes.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- the user wants to publish the same underlying idea across multiple platforms
|
||||||
|
- a launch, update, release, or essay needs platform-specific versions
|
||||||
|
- the user says "crosspost", "post this everywhere", or "adapt this for X and LinkedIn"
|
||||||
|
|
||||||
|
## Core Rules
|
||||||
|
|
||||||
|
1. Do not publish identical copy across platforms.
|
||||||
|
2. Preserve the author's voice across platforms.
|
||||||
|
3. Adapt for constraints, not stereotypes.
|
||||||
|
4. One post should still be about one thing.
|
||||||
|
5. Do not invent a CTA, question, or moral if the source did not earn one.
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
### Step 1: Start with the Primary Version
|
||||||
|
|
||||||
|
Pick the strongest source version first:
|
||||||
|
- the original X post
|
||||||
|
- the original article
|
||||||
|
- the launch note
|
||||||
|
- the thread
|
||||||
|
- the memo or changelog
|
||||||
|
|
||||||
|
Use `content-engine` first if the source still needs voice shaping.
|
||||||
|
|
||||||
|
### Step 2: Capture the Voice Fingerprint
|
||||||
|
|
||||||
|
Before adapting, note:
|
||||||
|
- how blunt or explanatory the source is
|
||||||
|
- whether the source uses fragments, lists, or longer transitions
|
||||||
|
- whether the source uses parentheses
|
||||||
|
- whether the source avoids questions, hashtags, or CTA language
|
||||||
|
|
||||||
|
The adaptation should preserve that fingerprint.
|
||||||
|
|
||||||
|
### Step 3: Adapt by Platform Constraint
|
||||||
|
|
||||||
|
### X
|
||||||
|
|
||||||
|
- keep it compressed
|
||||||
|
- lead with the sharpest claim or artifact
|
||||||
|
- use a thread only when a single post would collapse the argument
|
||||||
|
- avoid hashtags and generic filler
|
||||||
|
|
||||||
|
### LinkedIn
|
||||||
|
|
||||||
|
- add only the context needed for people outside the niche
|
||||||
|
- do not turn it into a fake founder-reflection post
|
||||||
|
- do not add a closing question just because it is LinkedIn
|
||||||
|
- do not force a polished "professional tone" if the author is naturally sharper
|
||||||
|
|
||||||
|
### Threads
|
||||||
|
|
||||||
|
- keep it readable and direct
|
||||||
|
- do not write fake hyper-casual creator copy
|
||||||
|
- do not paste the LinkedIn version and shorten it
|
||||||
|
|
||||||
|
### Bluesky
|
||||||
|
|
||||||
|
- keep it concise
|
||||||
|
- preserve the author's cadence
|
||||||
|
- do not rely on hashtags or feed-gaming language
|
||||||
|
|
||||||
|
## Posting Order
|
||||||
|
|
||||||
|
Default:
|
||||||
|
1. post the strongest native version first
|
||||||
|
2. adapt for the secondary platforms
|
||||||
|
3. stagger timing only if the user wants sequencing help
|
||||||
|
|
||||||
|
Do not add cross-platform references unless useful. Most of the time, the post should stand on its own.
|
||||||
|
|
||||||
|
## Banned Patterns
|
||||||
|
|
||||||
|
Delete and rewrite any of these:
|
||||||
|
- "Excited to share"
|
||||||
|
- "Here's what I learned"
|
||||||
|
- "What do you think?"
|
||||||
|
- "link in bio" unless that is literally true
|
||||||
|
- "not X, just Y"
|
||||||
|
- generic "professional takeaway" paragraphs that were not in the source
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
Return:
|
||||||
|
- the primary platform version
|
||||||
|
- adapted variants for each requested platform
|
||||||
|
- a short note on what changed and why
|
||||||
|
- any publishing constraint the user still needs to resolve
|
||||||
|
|
||||||
|
## Quality Gate
|
||||||
|
|
||||||
|
Before delivering:
|
||||||
|
- each version reads like the same author under different constraints
|
||||||
|
- no platform version feels padded or sanitized
|
||||||
|
- no copy is duplicated verbatim across platforms
|
||||||
|
- any extra context added for LinkedIn or newsletter use is actually necessary
|
||||||
|
|
||||||
|
## Related Skills
|
||||||
|
|
||||||
|
- `content-engine` for voice capture and source shaping
|
||||||
|
- `x-api` for X publishing workflows
|
||||||
7
.agents/skills/crosspost/agents/openai.yaml
Normal file
7
.agents/skills/crosspost/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Crosspost"
|
||||||
|
short_description: "Multi-platform content distribution with native adaptation"
|
||||||
|
brand_color: "#EC4899"
|
||||||
|
default_prompt: "Distribute content across X, LinkedIn, Threads, and Bluesky with platform-native adaptation"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
155
.agents/skills/deep-research/SKILL.md
Normal file
155
.agents/skills/deep-research/SKILL.md
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
---
|
||||||
|
name: deep-research
|
||||||
|
description: Multi-source deep research using firecrawl and exa MCPs. Searches the web, synthesizes findings, and delivers cited reports with source attribution. Use when the user wants thorough research on any topic with evidence and citations.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Deep Research
|
||||||
|
|
||||||
|
Produce thorough, cited research reports from multiple web sources using firecrawl and exa MCP tools.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- User asks to research any topic in depth
|
||||||
|
- Competitive analysis, technology evaluation, or market sizing
|
||||||
|
- Due diligence on companies, investors, or technologies
|
||||||
|
- Any question requiring synthesis from multiple sources
|
||||||
|
- User says "research", "deep dive", "investigate", or "what's the current state of"
|
||||||
|
|
||||||
|
## MCP Requirements
|
||||||
|
|
||||||
|
At least one of:
|
||||||
|
- **firecrawl** — `firecrawl_search`, `firecrawl_scrape`, `firecrawl_crawl`
|
||||||
|
- **exa** — `web_search_exa`, `web_search_advanced_exa`, `crawling_exa`
|
||||||
|
|
||||||
|
Both together give the best coverage. Configure in `~/.claude.json` or `~/.codex/config.toml`.
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
### Step 1: Understand the Goal
|
||||||
|
|
||||||
|
Ask 1-2 quick clarifying questions:
|
||||||
|
- "What's your goal — learning, making a decision, or writing something?"
|
||||||
|
- "Any specific angle or depth you want?"
|
||||||
|
|
||||||
|
If the user says "just research it" — skip ahead with reasonable defaults.
|
||||||
|
|
||||||
|
### Step 2: Plan the Research
|
||||||
|
|
||||||
|
Break the topic into 3-5 research sub-questions. Example:
|
||||||
|
- Topic: "Impact of AI on healthcare"
|
||||||
|
- What are the main AI applications in healthcare today?
|
||||||
|
- What clinical outcomes have been measured?
|
||||||
|
- What are the regulatory challenges?
|
||||||
|
- What companies are leading this space?
|
||||||
|
- What's the market size and growth trajectory?
|
||||||
|
|
||||||
|
### Step 3: Execute Multi-Source Search
|
||||||
|
|
||||||
|
For EACH sub-question, search using available MCP tools:
|
||||||
|
|
||||||
|
**With firecrawl:**
|
||||||
|
```
|
||||||
|
firecrawl_search(query: "<sub-question keywords>", limit: 8)
|
||||||
|
```
|
||||||
|
|
||||||
|
**With exa:**
|
||||||
|
```
|
||||||
|
web_search_exa(query: "<sub-question keywords>", numResults: 8)
|
||||||
|
web_search_advanced_exa(query: "<keywords>", numResults: 5, startPublishedDate: "2025-01-01")
|
||||||
|
```
|
||||||
|
|
||||||
|
**Search strategy:**
|
||||||
|
- Use 2-3 different keyword variations per sub-question
|
||||||
|
- Mix general and news-focused queries
|
||||||
|
- Aim for 15-30 unique sources total
|
||||||
|
- Prioritize: academic, official, reputable news > blogs > forums
|
||||||
|
|
||||||
|
### Step 4: Deep-Read Key Sources
|
||||||
|
|
||||||
|
For the most promising URLs, fetch full content:
|
||||||
|
|
||||||
|
**With firecrawl:**
|
||||||
|
```
|
||||||
|
firecrawl_scrape(url: "<url>")
|
||||||
|
```
|
||||||
|
|
||||||
|
**With exa:**
|
||||||
|
```
|
||||||
|
crawling_exa(url: "<url>", tokensNum: 5000)
|
||||||
|
```
|
||||||
|
|
||||||
|
Read 3-5 key sources in full for depth. Do not rely only on search snippets.
|
||||||
|
|
||||||
|
### Step 5: Synthesize and Write Report
|
||||||
|
|
||||||
|
Structure the report:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# [Topic]: Research Report
|
||||||
|
*Generated: [date] | Sources: [N] | Confidence: [High/Medium/Low]*
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
[3-5 sentence overview of key findings]
|
||||||
|
|
||||||
|
## 1. [First Major Theme]
|
||||||
|
[Findings with inline citations]
|
||||||
|
- Key point ([Source Name](url))
|
||||||
|
- Supporting data ([Source Name](url))
|
||||||
|
|
||||||
|
## 2. [Second Major Theme]
|
||||||
|
...
|
||||||
|
|
||||||
|
## 3. [Third Major Theme]
|
||||||
|
...
|
||||||
|
|
||||||
|
## Key Takeaways
|
||||||
|
- [Actionable insight 1]
|
||||||
|
- [Actionable insight 2]
|
||||||
|
- [Actionable insight 3]
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
1. [Title](url) — [one-line summary]
|
||||||
|
2. ...
|
||||||
|
|
||||||
|
## Methodology
|
||||||
|
Searched [N] queries across web and news. Analyzed [M] sources.
|
||||||
|
Sub-questions investigated: [list]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 6: Deliver
|
||||||
|
|
||||||
|
- **Short topics**: Post the full report in chat
|
||||||
|
- **Long reports**: Post the executive summary + key takeaways, save full report to a file
|
||||||
|
|
||||||
|
## Parallel Research with Subagents
|
||||||
|
|
||||||
|
For broad topics, use Claude Code's Task tool to parallelize:
|
||||||
|
|
||||||
|
```
|
||||||
|
Launch 3 research agents in parallel:
|
||||||
|
1. Agent 1: Research sub-questions 1-2
|
||||||
|
2. Agent 2: Research sub-questions 3-4
|
||||||
|
3. Agent 3: Research sub-question 5 + cross-cutting themes
|
||||||
|
```
|
||||||
|
|
||||||
|
Each agent searches, reads sources, and returns findings. The main session synthesizes into the final report.
|
||||||
|
|
||||||
|
## Quality Rules
|
||||||
|
|
||||||
|
1. **Every claim needs a source.** No unsourced assertions.
|
||||||
|
2. **Cross-reference.** If only one source says it, flag it as unverified.
|
||||||
|
3. **Recency matters.** Prefer sources from the last 12 months.
|
||||||
|
4. **Acknowledge gaps.** If you couldn't find good info on a sub-question, say so.
|
||||||
|
5. **No hallucination.** If you don't know, say "insufficient data found."
|
||||||
|
6. **Separate fact from inference.** Label estimates, projections, and opinions clearly.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
"Research the current state of nuclear fusion energy"
|
||||||
|
"Deep dive into Rust vs Go for backend services in 2026"
|
||||||
|
"Research the best strategies for bootstrapping a SaaS business"
|
||||||
|
"What's happening with the US housing market right now?"
|
||||||
|
"Investigate the competitive landscape for AI code editors"
|
||||||
|
```
|
||||||
7
.agents/skills/deep-research/agents/openai.yaml
Normal file
7
.agents/skills/deep-research/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Deep Research"
|
||||||
|
short_description: "Multi-source deep research with firecrawl and exa MCPs"
|
||||||
|
brand_color: "#6366F1"
|
||||||
|
default_prompt: "Research the given topic using firecrawl and exa, produce a cited report"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
144
.agents/skills/dmux-workflows/SKILL.md
Normal file
144
.agents/skills/dmux-workflows/SKILL.md
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
---
|
||||||
|
name: dmux-workflows
|
||||||
|
description: Multi-agent orchestration using dmux (tmux pane manager for AI agents). Patterns for parallel agent workflows across Claude Code, Codex, OpenCode, and other harnesses. Use when running multiple agent sessions in parallel or coordinating multi-agent development workflows.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# dmux Workflows
|
||||||
|
|
||||||
|
Orchestrate parallel AI agent sessions using dmux, a tmux pane manager for agent harnesses.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- Running multiple agent sessions in parallel
|
||||||
|
- Coordinating work across Claude Code, Codex, and other harnesses
|
||||||
|
- Complex tasks that benefit from divide-and-conquer parallelism
|
||||||
|
- User says "run in parallel", "split this work", "use dmux", or "multi-agent"
|
||||||
|
|
||||||
|
## What is dmux
|
||||||
|
|
||||||
|
dmux is a tmux-based orchestration tool that manages AI agent panes:
|
||||||
|
- Press `n` to create a new pane with a prompt
|
||||||
|
- Press `m` to merge pane output back to the main session
|
||||||
|
- Supports: Claude Code, Codex, OpenCode, Cline, Gemini, Qwen
|
||||||
|
|
||||||
|
**Install:** `npm install -g dmux` or see [github.com/standardagents/dmux](https://github.com/standardagents/dmux)
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start dmux session
|
||||||
|
dmux
|
||||||
|
|
||||||
|
# Create agent panes (press 'n' in dmux, then type prompt)
|
||||||
|
# Pane 1: "Implement the auth middleware in src/auth/"
|
||||||
|
# Pane 2: "Write tests for the user service"
|
||||||
|
# Pane 3: "Update API documentation"
|
||||||
|
|
||||||
|
# Each pane runs its own agent session
|
||||||
|
# Press 'm' to merge results back
|
||||||
|
```
|
||||||
|
|
||||||
|
## Workflow Patterns
|
||||||
|
|
||||||
|
### Pattern 1: Research + Implement
|
||||||
|
|
||||||
|
Split research and implementation into parallel tracks:
|
||||||
|
|
||||||
|
```
|
||||||
|
Pane 1 (Research): "Research best practices for rate limiting in Node.js.
|
||||||
|
Check current libraries, compare approaches, and write findings to
|
||||||
|
/tmp/rate-limit-research.md"
|
||||||
|
|
||||||
|
Pane 2 (Implement): "Implement rate limiting middleware for our Express API.
|
||||||
|
Start with a basic token bucket, we'll refine after research completes."
|
||||||
|
|
||||||
|
# After Pane 1 completes, merge findings into Pane 2's context
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 2: Multi-File Feature
|
||||||
|
|
||||||
|
Parallelize work across independent files:
|
||||||
|
|
||||||
|
```
|
||||||
|
Pane 1: "Create the database schema and migrations for the billing feature"
|
||||||
|
Pane 2: "Build the billing API endpoints in src/api/billing/"
|
||||||
|
Pane 3: "Create the billing dashboard UI components"
|
||||||
|
|
||||||
|
# Merge all, then do integration in main pane
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 3: Test + Fix Loop
|
||||||
|
|
||||||
|
Run tests in one pane, fix in another:
|
||||||
|
|
||||||
|
```
|
||||||
|
Pane 1 (Watcher): "Run the test suite in watch mode. When tests fail,
|
||||||
|
summarize the failures."
|
||||||
|
|
||||||
|
Pane 2 (Fixer): "Fix failing tests based on the error output from pane 1"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 4: Cross-Harness
|
||||||
|
|
||||||
|
Use different AI tools for different tasks:
|
||||||
|
|
||||||
|
```
|
||||||
|
Pane 1 (Claude Code): "Review the security of the auth module"
|
||||||
|
Pane 2 (Codex): "Refactor the utility functions for performance"
|
||||||
|
Pane 3 (Claude Code): "Write E2E tests for the checkout flow"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 5: Code Review Pipeline
|
||||||
|
|
||||||
|
Parallel review perspectives:
|
||||||
|
|
||||||
|
```
|
||||||
|
Pane 1: "Review src/api/ for security vulnerabilities"
|
||||||
|
Pane 2: "Review src/api/ for performance issues"
|
||||||
|
Pane 3: "Review src/api/ for test coverage gaps"
|
||||||
|
|
||||||
|
# Merge all reviews into a single report
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Independent tasks only.** Don't parallelize tasks that depend on each other's output.
|
||||||
|
2. **Clear boundaries.** Each pane should work on distinct files or concerns.
|
||||||
|
3. **Merge strategically.** Review pane output before merging to avoid conflicts.
|
||||||
|
4. **Use git worktrees.** For file-conflict-prone work, use separate worktrees per pane.
|
||||||
|
5. **Resource awareness.** Each pane uses API tokens — keep total panes under 5-6.
|
||||||
|
|
||||||
|
## Git Worktree Integration
|
||||||
|
|
||||||
|
For tasks that touch overlapping files:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create worktrees for isolation
|
||||||
|
git worktree add ../feature-auth feat/auth
|
||||||
|
git worktree add ../feature-billing feat/billing
|
||||||
|
|
||||||
|
# Run agents in separate worktrees
|
||||||
|
# Pane 1: cd ../feature-auth && claude
|
||||||
|
# Pane 2: cd ../feature-billing && claude
|
||||||
|
|
||||||
|
# Merge branches when done
|
||||||
|
git merge feat/auth
|
||||||
|
git merge feat/billing
|
||||||
|
```
|
||||||
|
|
||||||
|
## Complementary Tools
|
||||||
|
|
||||||
|
| Tool | What It Does | When to Use |
|
||||||
|
|------|-------------|-------------|
|
||||||
|
| **dmux** | tmux pane management for agents | Parallel agent sessions |
|
||||||
|
| **Superset** | Terminal IDE for 10+ parallel agents | Large-scale orchestration |
|
||||||
|
| **Claude Code Task tool** | In-process subagent spawning | Programmatic parallelism within a session |
|
||||||
|
| **Codex multi-agent** | Built-in agent roles | Codex-specific parallel work |
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
- **Pane not responding:** Check if the agent session is waiting for input. Use `m` to read output.
|
||||||
|
- **Merge conflicts:** Use git worktrees to isolate file changes per pane.
|
||||||
|
- **High token usage:** Reduce number of parallel panes. Each pane is a full agent session.
|
||||||
|
- **tmux not found:** Install with `brew install tmux` (macOS) or `apt install tmux` (Linux).
|
||||||
7
.agents/skills/dmux-workflows/agents/openai.yaml
Normal file
7
.agents/skills/dmux-workflows/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "dmux Workflows"
|
||||||
|
short_description: "Multi-agent orchestration with dmux"
|
||||||
|
brand_color: "#14B8A6"
|
||||||
|
default_prompt: "Orchestrate parallel agent sessions using dmux pane manager"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
90
.agents/skills/documentation-lookup/SKILL.md
Normal file
90
.agents/skills/documentation-lookup/SKILL.md
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
---
|
||||||
|
name: documentation-lookup
|
||||||
|
description: Use up-to-date library and framework docs via Context7 MCP instead of training data. Activates for setup questions, API references, code examples, or when the user names a framework (e.g. React, Next.js, Prisma).
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Documentation Lookup (Context7)
|
||||||
|
|
||||||
|
When the user asks about libraries, frameworks, or APIs, fetch current documentation via the Context7 MCP (tools `resolve-library-id` and `query-docs`) instead of relying on training data.
|
||||||
|
|
||||||
|
## Core Concepts
|
||||||
|
|
||||||
|
- **Context7**: MCP server that exposes live documentation; use it instead of training data for libraries and APIs.
|
||||||
|
- **resolve-library-id**: Returns Context7-compatible library IDs (e.g. `/vercel/next.js`) from a library name and query.
|
||||||
|
- **query-docs**: Fetches documentation and code snippets for a given library ID and question. Always call resolve-library-id first to get a valid library ID.
|
||||||
|
|
||||||
|
## When to use
|
||||||
|
|
||||||
|
Activate when the user:
|
||||||
|
|
||||||
|
- Asks setup or configuration questions (e.g. "How do I configure Next.js middleware?")
|
||||||
|
- Requests code that depends on a library ("Write a Prisma query for...")
|
||||||
|
- Needs API or reference information ("What are the Supabase auth methods?")
|
||||||
|
- Mentions specific frameworks or libraries (React, Vue, Svelte, Express, Tailwind, Prisma, Supabase, etc.)
|
||||||
|
|
||||||
|
Use this skill whenever the request depends on accurate, up-to-date behavior of a library, framework, or API. Applies across harnesses that have the Context7 MCP configured (e.g. Claude Code, Cursor, Codex).
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
### Step 1: Resolve the Library ID
|
||||||
|
|
||||||
|
Call the **resolve-library-id** MCP tool with:
|
||||||
|
|
||||||
|
- **libraryName**: The library or product name taken from the user's question (e.g. `Next.js`, `Prisma`, `Supabase`).
|
||||||
|
- **query**: The user's full question. This improves relevance ranking of results.
|
||||||
|
|
||||||
|
You must obtain a Context7-compatible library ID (format `/org/project` or `/org/project/version`) before querying docs. Do not call query-docs without a valid library ID from this step.
|
||||||
|
|
||||||
|
### Step 2: Select the Best Match
|
||||||
|
|
||||||
|
From the resolution results, choose one result using:
|
||||||
|
|
||||||
|
- **Name match**: Prefer exact or closest match to what the user asked for.
|
||||||
|
- **Benchmark score**: Higher scores indicate better documentation quality (100 is highest).
|
||||||
|
- **Source reputation**: Prefer High or Medium reputation when available.
|
||||||
|
- **Version**: If the user specified a version (e.g. "React 19", "Next.js 15"), prefer a version-specific library ID if listed (e.g. `/org/project/v1.2.0`).
|
||||||
|
|
||||||
|
### Step 3: Fetch the Documentation
|
||||||
|
|
||||||
|
Call the **query-docs** MCP tool with:
|
||||||
|
|
||||||
|
- **libraryId**: The selected Context7 library ID from Step 2 (e.g. `/vercel/next.js`).
|
||||||
|
- **query**: The user's specific question or task. Be specific to get relevant snippets.
|
||||||
|
|
||||||
|
Limit: do not call query-docs (or resolve-library-id) more than 3 times per question. If the answer is unclear after 3 calls, state the uncertainty and use the best information you have rather than guessing.
|
||||||
|
|
||||||
|
### Step 4: Use the Documentation
|
||||||
|
|
||||||
|
- Answer the user's question using the fetched, current information.
|
||||||
|
- Include relevant code examples from the docs when helpful.
|
||||||
|
- Cite the library or version when it matters (e.g. "In Next.js 15...").
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Example: Next.js middleware
|
||||||
|
|
||||||
|
1. Call **resolve-library-id** with `libraryName: "Next.js"`, `query: "How do I set up Next.js middleware?"`.
|
||||||
|
2. From results, pick the best match (e.g. `/vercel/next.js`) by name and benchmark score.
|
||||||
|
3. Call **query-docs** with `libraryId: "/vercel/next.js"`, `query: "How do I set up Next.js middleware?"`.
|
||||||
|
4. Use the returned snippets and text to answer; include a minimal `middleware.ts` example from the docs if relevant.
|
||||||
|
|
||||||
|
### Example: Prisma query
|
||||||
|
|
||||||
|
1. Call **resolve-library-id** with `libraryName: "Prisma"`, `query: "How do I query with relations?"`.
|
||||||
|
2. Select the official Prisma library ID (e.g. `/prisma/prisma`).
|
||||||
|
3. Call **query-docs** with that `libraryId` and the query.
|
||||||
|
4. Return the Prisma Client pattern (e.g. `include` or `select`) with a short code snippet from the docs.
|
||||||
|
|
||||||
|
### Example: Supabase auth methods
|
||||||
|
|
||||||
|
1. Call **resolve-library-id** with `libraryName: "Supabase"`, `query: "What are the auth methods?"`.
|
||||||
|
2. Pick the Supabase docs library ID.
|
||||||
|
3. Call **query-docs**; summarize the auth methods and show minimal examples from the fetched docs.
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- **Be specific**: Use the user's full question as the query where possible for better relevance.
|
||||||
|
- **Version awareness**: When users mention versions, use version-specific library IDs from the resolve step when available.
|
||||||
|
- **Prefer official sources**: When multiple matches exist, prefer official or primary packages over community forks.
|
||||||
|
- **No sensitive data**: Redact API keys, passwords, tokens, and other secrets from any query sent to Context7. Treat the user's question as potentially containing secrets before passing it to resolve-library-id or query-docs.
|
||||||
7
.agents/skills/documentation-lookup/agents/openai.yaml
Normal file
7
.agents/skills/documentation-lookup/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Documentation Lookup"
|
||||||
|
short_description: "Fetch up-to-date library docs via Context7 MCP"
|
||||||
|
brand_color: "#6366F1"
|
||||||
|
default_prompt: "Look up docs for a library or API"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
442
.agents/skills/everything-claude-code/SKILL.md
Normal file
442
.agents/skills/everything-claude-code/SKILL.md
Normal file
@@ -0,0 +1,442 @@
|
|||||||
|
---
|
||||||
|
name: everything-claude-code-conventions
|
||||||
|
description: Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Everything Claude Code Conventions
|
||||||
|
|
||||||
|
> Generated from [affaan-m/everything-claude-code](https://github.com/affaan-m/everything-claude-code) on 2026-03-20
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This skill teaches Claude the development patterns and conventions used in everything-claude-code.
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
|
||||||
|
- **Primary Language**: JavaScript
|
||||||
|
- **Architecture**: hybrid module organization
|
||||||
|
- **Test Location**: separate
|
||||||
|
|
||||||
|
## When to Use This Skill
|
||||||
|
|
||||||
|
Activate this skill when:
|
||||||
|
- Making changes to this repository
|
||||||
|
- Adding new features following established patterns
|
||||||
|
- Writing tests that match project conventions
|
||||||
|
- Creating commits with proper message format
|
||||||
|
|
||||||
|
## Commit Conventions
|
||||||
|
|
||||||
|
Follow these commit message conventions based on 500 analyzed commits.
|
||||||
|
|
||||||
|
### Commit Style: Conventional Commits
|
||||||
|
|
||||||
|
### Prefixes Used
|
||||||
|
|
||||||
|
- `fix`
|
||||||
|
- `test`
|
||||||
|
- `feat`
|
||||||
|
- `docs`
|
||||||
|
|
||||||
|
### Message Guidelines
|
||||||
|
|
||||||
|
- Average message length: ~65 characters
|
||||||
|
- Keep first line concise and descriptive
|
||||||
|
- Use imperative mood ("Add feature" not "Added feature")
|
||||||
|
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
feat(rules): add C# language support
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
chore(deps-dev): bump flatted (#675)
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
fix: auto-detect ECC root from plugin cache when CLAUDE_PLUGIN_ROOT is unset (#547) (#691)
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs: add Antigravity setup and usage guide (#552)
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
merge: PR #529 — feat(skills): add documentation-lookup, bun-runtime, nextjs-turbopack; feat(agents): add rust-reviewer
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
Revert "Add Kiro IDE support (.kiro/) (#548)"
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
Add Kiro IDE support (.kiro/) (#548)
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
feat: add block-no-verify hook for Claude Code and Cursor (#649)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Project Structure: Single Package
|
||||||
|
|
||||||
|
This project uses **hybrid** module organization.
|
||||||
|
|
||||||
|
### Configuration Files
|
||||||
|
|
||||||
|
- `.github/workflows/ci.yml`
|
||||||
|
- `.github/workflows/maintenance.yml`
|
||||||
|
- `.github/workflows/monthly-metrics.yml`
|
||||||
|
- `.github/workflows/release.yml`
|
||||||
|
- `.github/workflows/reusable-release.yml`
|
||||||
|
- `.github/workflows/reusable-test.yml`
|
||||||
|
- `.github/workflows/reusable-validate.yml`
|
||||||
|
- `.opencode/package.json`
|
||||||
|
- `.opencode/tsconfig.json`
|
||||||
|
- `.prettierrc`
|
||||||
|
- `eslint.config.js`
|
||||||
|
- `package.json`
|
||||||
|
|
||||||
|
### Guidelines
|
||||||
|
|
||||||
|
- This project uses a hybrid organization
|
||||||
|
- Follow existing patterns when adding new code
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
### Language: JavaScript
|
||||||
|
|
||||||
|
### Naming Conventions
|
||||||
|
|
||||||
|
| Element | Convention |
|
||||||
|
|---------|------------|
|
||||||
|
| Files | camelCase |
|
||||||
|
| Functions | camelCase |
|
||||||
|
| Classes | PascalCase |
|
||||||
|
| Constants | SCREAMING_SNAKE_CASE |
|
||||||
|
|
||||||
|
### Import Style: Relative Imports
|
||||||
|
|
||||||
|
### Export Style: Mixed Style
|
||||||
|
|
||||||
|
|
||||||
|
*Preferred import style*
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Use relative imports
|
||||||
|
import { Button } from '../components/Button'
|
||||||
|
import { useAuth } from './hooks/useAuth'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### Test Framework
|
||||||
|
|
||||||
|
No specific test framework detected — use the repository's existing test patterns.
|
||||||
|
|
||||||
|
### File Pattern: `*.test.js`
|
||||||
|
|
||||||
|
### Test Types
|
||||||
|
|
||||||
|
- **Unit tests**: Test individual functions and components in isolation
|
||||||
|
- **Integration tests**: Test interactions between multiple components/services
|
||||||
|
|
||||||
|
### Coverage
|
||||||
|
|
||||||
|
This project has coverage reporting configured. Aim for 80%+ coverage.
|
||||||
|
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
### Error Handling Style: Try-Catch Blocks
|
||||||
|
|
||||||
|
|
||||||
|
*Standard error handling pattern*
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
try {
|
||||||
|
const result = await riskyOperation()
|
||||||
|
return result
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Operation failed:', error)
|
||||||
|
throw new Error('User-friendly message')
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Workflows
|
||||||
|
|
||||||
|
These workflows were detected from analyzing commit patterns.
|
||||||
|
|
||||||
|
### Database Migration
|
||||||
|
|
||||||
|
Database schema changes with migration files
|
||||||
|
|
||||||
|
**Frequency**: ~2 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Create migration file
|
||||||
|
2. Update schema definitions
|
||||||
|
3. Generate/update types
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `**/schema.*`
|
||||||
|
- `migrations/*`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
feat: implement --with/--without selective install flags (#679)
|
||||||
|
fix: sync catalog counts with filesystem (27 agents, 113 skills, 58 commands) (#693)
|
||||||
|
feat(rules): add Rust language rules (rebased #660) (#686)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Feature Development
|
||||||
|
|
||||||
|
Standard feature implementation workflow
|
||||||
|
|
||||||
|
**Frequency**: ~22 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Add feature implementation
|
||||||
|
2. Add tests for feature
|
||||||
|
3. Update documentation
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `manifests/*`
|
||||||
|
- `schemas/*`
|
||||||
|
- `**/*.test.*`
|
||||||
|
- `**/api/**`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
feat(skills): add documentation-lookup, bun-runtime, nextjs-turbopack; feat(agents): add rust-reviewer
|
||||||
|
docs(skills): align documentation-lookup with CONTRIBUTING template; add cross-harness (Codex/Cursor) skill copies
|
||||||
|
fix: address PR review — skill template (When to use, How it works, Examples), bun.lock, next build note, rust-reviewer CI note, doc-lookup privacy/uncertainty
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Language Rules
|
||||||
|
|
||||||
|
Adds a new programming language to the rules system, including coding style, hooks, patterns, security, and testing guidelines.
|
||||||
|
|
||||||
|
**Frequency**: ~2 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Create a new directory under rules/{language}/
|
||||||
|
2. Add coding-style.md, hooks.md, patterns.md, security.md, and testing.md files with language-specific content
|
||||||
|
3. Optionally reference or link to related skills
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `rules/*/coding-style.md`
|
||||||
|
- `rules/*/hooks.md`
|
||||||
|
- `rules/*/patterns.md`
|
||||||
|
- `rules/*/security.md`
|
||||||
|
- `rules/*/testing.md`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Create a new directory under rules/{language}/
|
||||||
|
Add coding-style.md, hooks.md, patterns.md, security.md, and testing.md files with language-specific content
|
||||||
|
Optionally reference or link to related skills
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add New Skill
|
||||||
|
|
||||||
|
Adds a new skill to the system, documenting its workflow, triggers, and usage, often with supporting scripts.
|
||||||
|
|
||||||
|
**Frequency**: ~4 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Create a new directory under skills/{skill-name}/
|
||||||
|
2. Add SKILL.md with documentation (When to Use, How It Works, Examples, etc.)
|
||||||
|
3. Optionally add scripts or supporting files under skills/{skill-name}/scripts/
|
||||||
|
4. Address review feedback and iterate on documentation
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `skills/*/SKILL.md`
|
||||||
|
- `skills/*/scripts/*.sh`
|
||||||
|
- `skills/*/scripts/*.js`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Create a new directory under skills/{skill-name}/
|
||||||
|
Add SKILL.md with documentation (When to Use, How It Works, Examples, etc.)
|
||||||
|
Optionally add scripts or supporting files under skills/{skill-name}/scripts/
|
||||||
|
Address review feedback and iterate on documentation
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add New Agent
|
||||||
|
|
||||||
|
Adds a new agent to the system for code review, build resolution, or other automated tasks.
|
||||||
|
|
||||||
|
**Frequency**: ~2 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Create a new agent markdown file under agents/{agent-name}.md
|
||||||
|
2. Register the agent in AGENTS.md
|
||||||
|
3. Optionally update README.md and docs/COMMAND-AGENT-MAP.md
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `agents/*.md`
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `README.md`
|
||||||
|
- `docs/COMMAND-AGENT-MAP.md`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Create a new agent markdown file under agents/{agent-name}.md
|
||||||
|
Register the agent in AGENTS.md
|
||||||
|
Optionally update README.md and docs/COMMAND-AGENT-MAP.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add New Workflow Surface
|
||||||
|
|
||||||
|
Adds or updates a workflow entrypoint. Default to skills-first; only add a command shim when legacy slash compatibility is still required.
|
||||||
|
|
||||||
|
**Frequency**: ~1 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Create or update the canonical workflow under skills/{skill-name}/SKILL.md
|
||||||
|
2. Only if needed, add or update commands/{command-name}.md as a compatibility shim
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `skills/*/SKILL.md`
|
||||||
|
- `commands/*.md` (only when a legacy shim is intentionally retained)
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Create or update the canonical skill under skills/{skill-name}/SKILL.md
|
||||||
|
Only if needed, add or update commands/{command-name}.md as a compatibility shim
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sync Catalog Counts
|
||||||
|
|
||||||
|
Synchronizes the documented counts of agents, skills, and commands in AGENTS.md and README.md with the actual repository state.
|
||||||
|
|
||||||
|
**Frequency**: ~3 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Update agent, skill, and command counts in AGENTS.md
|
||||||
|
2. Update the same counts in README.md (quick-start, comparison table, etc.)
|
||||||
|
3. Optionally update other documentation files
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `README.md`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Update agent, skill, and command counts in AGENTS.md
|
||||||
|
Update the same counts in README.md (quick-start, comparison table, etc.)
|
||||||
|
Optionally update other documentation files
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Cross Harness Skill Copies
|
||||||
|
|
||||||
|
Adds skill copies for different agent harnesses (e.g., Codex, Cursor, Antigravity) to ensure compatibility across platforms.
|
||||||
|
|
||||||
|
**Frequency**: ~2 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Copy or adapt SKILL.md to .agents/skills/{skill}/SKILL.md and/or .cursor/skills/{skill}/SKILL.md
|
||||||
|
2. Optionally add harness-specific openai.yaml or config files
|
||||||
|
3. Address review feedback to align with CONTRIBUTING template
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `.agents/skills/*/SKILL.md`
|
||||||
|
- `.cursor/skills/*/SKILL.md`
|
||||||
|
- `.agents/skills/*/agents/openai.yaml`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Copy or adapt SKILL.md to .agents/skills/{skill}/SKILL.md and/or .cursor/skills/{skill}/SKILL.md
|
||||||
|
Optionally add harness-specific openai.yaml or config files
|
||||||
|
Address review feedback to align with CONTRIBUTING template
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Or Update Hook
|
||||||
|
|
||||||
|
Adds or updates git or bash hooks to enforce workflow, quality, or security policies.
|
||||||
|
|
||||||
|
**Frequency**: ~1 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Add or update hook scripts in hooks/ or scripts/hooks/
|
||||||
|
2. Register the hook in hooks/hooks.json or similar config
|
||||||
|
3. Optionally add or update tests in tests/hooks/
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `hooks/*.hook`
|
||||||
|
- `hooks/hooks.json`
|
||||||
|
- `scripts/hooks/*.js`
|
||||||
|
- `tests/hooks/*.test.js`
|
||||||
|
- `.cursor/hooks.json`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Add or update hook scripts in hooks/ or scripts/hooks/
|
||||||
|
Register the hook in hooks/hooks.json or similar config
|
||||||
|
Optionally add or update tests in tests/hooks/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Address Review Feedback
|
||||||
|
|
||||||
|
Addresses code review feedback by updating documentation, scripts, or configuration for clarity, correctness, or convention alignment.
|
||||||
|
|
||||||
|
**Frequency**: ~4 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Edit SKILL.md, agent, or command files to address reviewer comments
|
||||||
|
2. Update examples, headings, or configuration as requested
|
||||||
|
3. Iterate until all review feedback is resolved
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `skills/*/SKILL.md`
|
||||||
|
- `agents/*.md`
|
||||||
|
- `commands/*.md`
|
||||||
|
- `.agents/skills/*/SKILL.md`
|
||||||
|
- `.cursor/skills/*/SKILL.md`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Edit SKILL.md, agent, or command files to address reviewer comments
|
||||||
|
Update examples, headings, or configuration as requested
|
||||||
|
Iterate until all review feedback is resolved
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
Based on analysis of the codebase, follow these practices:
|
||||||
|
|
||||||
|
### Do
|
||||||
|
|
||||||
|
- Use conventional commit format (feat:, fix:, etc.)
|
||||||
|
- Follow *.test.js naming pattern
|
||||||
|
- Use camelCase for file names
|
||||||
|
- Prefer mixed exports
|
||||||
|
|
||||||
|
### Don't
|
||||||
|
|
||||||
|
- Don't write vague commit messages
|
||||||
|
- Don't skip tests for new features
|
||||||
|
- Don't deviate from established patterns without discussion
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*This skill was auto-generated by [ECC Tools](https://ecc.tools). Review and customize as needed for your team.*
|
||||||
6
.agents/skills/everything-claude-code/agents/openai.yaml
Normal file
6
.agents/skills/everything-claude-code/agents/openai.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Everything Claude Code"
|
||||||
|
short_description: "Repo-specific patterns and workflows for everything-claude-code"
|
||||||
|
default_prompt: "Use the everything-claude-code repo skill to follow existing architecture, testing, and workflow conventions."
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
170
.agents/skills/exa-search/SKILL.md
Normal file
170
.agents/skills/exa-search/SKILL.md
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
---
|
||||||
|
name: exa-search
|
||||||
|
description: Neural search via Exa MCP for web, code, and company research. Use when the user needs web search, code examples, company intel, people lookup, or AI-powered deep research with Exa's neural search engine.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Exa Search
|
||||||
|
|
||||||
|
Neural search for web content, code, companies, and people via the Exa MCP server.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- User needs current web information or news
|
||||||
|
- Searching for code examples, API docs, or technical references
|
||||||
|
- Researching companies, competitors, or market players
|
||||||
|
- Finding professional profiles or people in a domain
|
||||||
|
- Running background research for any development task
|
||||||
|
- User says "search for", "look up", "find", or "what's the latest on"
|
||||||
|
|
||||||
|
## MCP Requirement
|
||||||
|
|
||||||
|
Exa MCP server must be configured. Add to `~/.claude.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"exa-web-search": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["-y", "exa-mcp-server"],
|
||||||
|
"env": { "EXA_API_KEY": "YOUR_EXA_API_KEY_HERE" }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Get an API key at [exa.ai](https://exa.ai).
|
||||||
|
|
||||||
|
## Core Tools
|
||||||
|
|
||||||
|
### web_search_exa
|
||||||
|
General web search for current information, news, or facts.
|
||||||
|
|
||||||
|
```
|
||||||
|
web_search_exa(query: "latest AI developments 2026", numResults: 5)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
| Param | Type | Default | Notes |
|
||||||
|
|-------|------|---------|-------|
|
||||||
|
| `query` | string | required | Search query |
|
||||||
|
| `numResults` | number | 8 | Number of results |
|
||||||
|
|
||||||
|
### web_search_advanced_exa
|
||||||
|
Filtered search with domain and date constraints.
|
||||||
|
|
||||||
|
```
|
||||||
|
web_search_advanced_exa(
|
||||||
|
query: "React Server Components best practices",
|
||||||
|
numResults: 5,
|
||||||
|
includeDomains: ["github.com", "react.dev"],
|
||||||
|
startPublishedDate: "2025-01-01"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
| Param | Type | Default | Notes |
|
||||||
|
|-------|------|---------|-------|
|
||||||
|
| `query` | string | required | Search query |
|
||||||
|
| `numResults` | number | 8 | Number of results |
|
||||||
|
| `includeDomains` | string[] | none | Limit to specific domains |
|
||||||
|
| `excludeDomains` | string[] | none | Exclude specific domains |
|
||||||
|
| `startPublishedDate` | string | none | ISO date filter (start) |
|
||||||
|
| `endPublishedDate` | string | none | ISO date filter (end) |
|
||||||
|
|
||||||
|
### get_code_context_exa
|
||||||
|
Find code examples and documentation from GitHub, Stack Overflow, and docs sites.
|
||||||
|
|
||||||
|
```
|
||||||
|
get_code_context_exa(query: "Python asyncio patterns", tokensNum: 3000)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
| Param | Type | Default | Notes |
|
||||||
|
|-------|------|---------|-------|
|
||||||
|
| `query` | string | required | Code or API search query |
|
||||||
|
| `tokensNum` | number | 5000 | Content tokens (1000-50000) |
|
||||||
|
|
||||||
|
### company_research_exa
|
||||||
|
Research companies for business intelligence and news.
|
||||||
|
|
||||||
|
```
|
||||||
|
company_research_exa(companyName: "Anthropic", numResults: 5)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
| Param | Type | Default | Notes |
|
||||||
|
|-------|------|---------|-------|
|
||||||
|
| `companyName` | string | required | Company name |
|
||||||
|
| `numResults` | number | 5 | Number of results |
|
||||||
|
|
||||||
|
### people_search_exa
|
||||||
|
Find professional profiles and bios.
|
||||||
|
|
||||||
|
```
|
||||||
|
people_search_exa(query: "AI safety researchers at Anthropic", numResults: 5)
|
||||||
|
```
|
||||||
|
|
||||||
|
### crawling_exa
|
||||||
|
Extract full page content from a URL.
|
||||||
|
|
||||||
|
```
|
||||||
|
crawling_exa(url: "https://example.com/article", tokensNum: 5000)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
| Param | Type | Default | Notes |
|
||||||
|
|-------|------|---------|-------|
|
||||||
|
| `url` | string | required | URL to extract |
|
||||||
|
| `tokensNum` | number | 5000 | Content tokens |
|
||||||
|
|
||||||
|
### deep_researcher_start / deep_researcher_check
|
||||||
|
Start an AI research agent that runs asynchronously.
|
||||||
|
|
||||||
|
```
|
||||||
|
# Start research
|
||||||
|
deep_researcher_start(query: "comprehensive analysis of AI code editors in 2026")
|
||||||
|
|
||||||
|
# Check status (returns results when complete)
|
||||||
|
deep_researcher_check(researchId: "<id from start>")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage Patterns
|
||||||
|
|
||||||
|
### Quick Lookup
|
||||||
|
```
|
||||||
|
web_search_exa(query: "Node.js 22 new features", numResults: 3)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Code Research
|
||||||
|
```
|
||||||
|
get_code_context_exa(query: "Rust error handling patterns Result type", tokensNum: 3000)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Company Due Diligence
|
||||||
|
```
|
||||||
|
company_research_exa(companyName: "Vercel", numResults: 5)
|
||||||
|
web_search_advanced_exa(query: "Vercel funding valuation 2026", numResults: 3)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Technical Deep Dive
|
||||||
|
```
|
||||||
|
# Start async research
|
||||||
|
deep_researcher_start(query: "WebAssembly component model status and adoption")
|
||||||
|
# ... do other work ...
|
||||||
|
deep_researcher_check(researchId: "<id>")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
- Use `web_search_exa` for broad queries, `web_search_advanced_exa` for filtered results
|
||||||
|
- Lower `tokensNum` (1000-2000) for focused code snippets, higher (5000+) for comprehensive context
|
||||||
|
- Combine `company_research_exa` with `web_search_advanced_exa` for thorough company analysis
|
||||||
|
- Use `crawling_exa` to get full content from specific URLs found in search results
|
||||||
|
- `deep_researcher_start` is best for comprehensive topics that benefit from AI synthesis
|
||||||
|
|
||||||
|
## Related Skills
|
||||||
|
|
||||||
|
- `deep-research` — Full research workflow using firecrawl + exa together
|
||||||
|
- `market-research` — Business-oriented research with decision frameworks
|
||||||
7
.agents/skills/exa-search/agents/openai.yaml
Normal file
7
.agents/skills/exa-search/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Exa Search"
|
||||||
|
short_description: "Neural search via Exa MCP for web, code, and companies"
|
||||||
|
brand_color: "#8B5CF6"
|
||||||
|
default_prompt: "Search using Exa MCP tools for web content, code, or company research"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
277
.agents/skills/fal-ai-media/SKILL.md
Normal file
277
.agents/skills/fal-ai-media/SKILL.md
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
---
|
||||||
|
name: fal-ai-media
|
||||||
|
description: Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# fal.ai Media Generation
|
||||||
|
|
||||||
|
Generate images, videos, and audio using fal.ai models via MCP.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- User wants to generate images from text prompts
|
||||||
|
- Creating videos from text or images
|
||||||
|
- Generating speech, music, or sound effects
|
||||||
|
- Any media generation task
|
||||||
|
- User says "generate image", "create video", "text to speech", "make a thumbnail", or similar
|
||||||
|
|
||||||
|
## MCP Requirement
|
||||||
|
|
||||||
|
fal.ai MCP server must be configured. Add to `~/.claude.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"fal-ai": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["-y", "fal-ai-mcp-server"],
|
||||||
|
"env": { "FAL_KEY": "YOUR_FAL_KEY_HERE" }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Get an API key at [fal.ai](https://fal.ai).
|
||||||
|
|
||||||
|
## MCP Tools
|
||||||
|
|
||||||
|
The fal.ai MCP provides these tools:
|
||||||
|
- `search` — Find available models by keyword
|
||||||
|
- `find` — Get model details and parameters
|
||||||
|
- `generate` — Run a model with parameters
|
||||||
|
- `result` — Check async generation status
|
||||||
|
- `status` — Check job status
|
||||||
|
- `cancel` — Cancel a running job
|
||||||
|
- `estimate_cost` — Estimate generation cost
|
||||||
|
- `models` — List popular models
|
||||||
|
- `upload` — Upload files for use as inputs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Image Generation
|
||||||
|
|
||||||
|
### Nano Banana 2 (Fast)
|
||||||
|
Best for: quick iterations, drafts, text-to-image, image editing.
|
||||||
|
|
||||||
|
```
|
||||||
|
generate(
|
||||||
|
model_name: "fal-ai/nano-banana-2",
|
||||||
|
input: {
|
||||||
|
"prompt": "a futuristic cityscape at sunset, cyberpunk style",
|
||||||
|
"image_size": "landscape_16_9",
|
||||||
|
"num_images": 1,
|
||||||
|
"seed": 42
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nano Banana Pro (High Fidelity)
|
||||||
|
Best for: production images, realism, typography, detailed prompts.
|
||||||
|
|
||||||
|
```
|
||||||
|
generate(
|
||||||
|
model_name: "fal-ai/nano-banana-pro",
|
||||||
|
input: {
|
||||||
|
"prompt": "professional product photo of wireless headphones on marble surface, studio lighting",
|
||||||
|
"image_size": "square",
|
||||||
|
"num_images": 1,
|
||||||
|
"guidance_scale": 7.5
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Image Parameters
|
||||||
|
|
||||||
|
| Param | Type | Options | Notes |
|
||||||
|
|-------|------|---------|-------|
|
||||||
|
| `prompt` | string | required | Describe what you want |
|
||||||
|
| `image_size` | string | `square`, `portrait_4_3`, `landscape_16_9`, `portrait_16_9`, `landscape_4_3` | Aspect ratio |
|
||||||
|
| `num_images` | number | 1-4 | How many to generate |
|
||||||
|
| `seed` | number | any integer | Reproducibility |
|
||||||
|
| `guidance_scale` | number | 1-20 | How closely to follow the prompt (higher = more literal) |
|
||||||
|
|
||||||
|
### Image Editing
|
||||||
|
Use Nano Banana 2 with an input image for inpainting, outpainting, or style transfer:
|
||||||
|
|
||||||
|
```
|
||||||
|
# First upload the source image
|
||||||
|
upload(file_path: "/path/to/image.png")
|
||||||
|
|
||||||
|
# Then generate with image input
|
||||||
|
generate(
|
||||||
|
model_name: "fal-ai/nano-banana-2",
|
||||||
|
input: {
|
||||||
|
"prompt": "same scene but in watercolor style",
|
||||||
|
"image_url": "<uploaded_url>",
|
||||||
|
"image_size": "landscape_16_9"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Video Generation
|
||||||
|
|
||||||
|
### Seedance 1.0 Pro (ByteDance)
|
||||||
|
Best for: text-to-video, image-to-video with high motion quality.
|
||||||
|
|
||||||
|
```
|
||||||
|
generate(
|
||||||
|
model_name: "fal-ai/seedance-1-0-pro",
|
||||||
|
input: {
|
||||||
|
"prompt": "a drone flyover of a mountain lake at golden hour, cinematic",
|
||||||
|
"duration": "5s",
|
||||||
|
"aspect_ratio": "16:9",
|
||||||
|
"seed": 42
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kling Video v3 Pro
|
||||||
|
Best for: text/image-to-video with native audio generation.
|
||||||
|
|
||||||
|
```
|
||||||
|
generate(
|
||||||
|
model_name: "fal-ai/kling-video/v3/pro",
|
||||||
|
input: {
|
||||||
|
"prompt": "ocean waves crashing on a rocky coast, dramatic clouds",
|
||||||
|
"duration": "5s",
|
||||||
|
"aspect_ratio": "16:9"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Veo 3 (Google DeepMind)
|
||||||
|
Best for: video with generated sound, high visual quality.
|
||||||
|
|
||||||
|
```
|
||||||
|
generate(
|
||||||
|
model_name: "fal-ai/veo-3",
|
||||||
|
input: {
|
||||||
|
"prompt": "a bustling Tokyo street market at night, neon signs, crowd noise",
|
||||||
|
"aspect_ratio": "16:9"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Image-to-Video
|
||||||
|
Start from an existing image:
|
||||||
|
|
||||||
|
```
|
||||||
|
generate(
|
||||||
|
model_name: "fal-ai/seedance-1-0-pro",
|
||||||
|
input: {
|
||||||
|
"prompt": "camera slowly zooms out, gentle wind moves the trees",
|
||||||
|
"image_url": "<uploaded_image_url>",
|
||||||
|
"duration": "5s"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Video Parameters
|
||||||
|
|
||||||
|
| Param | Type | Options | Notes |
|
||||||
|
|-------|------|---------|-------|
|
||||||
|
| `prompt` | string | required | Describe the video |
|
||||||
|
| `duration` | string | `"5s"`, `"10s"` | Video length |
|
||||||
|
| `aspect_ratio` | string | `"16:9"`, `"9:16"`, `"1:1"` | Frame ratio |
|
||||||
|
| `seed` | number | any integer | Reproducibility |
|
||||||
|
| `image_url` | string | URL | Source image for image-to-video |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Audio Generation
|
||||||
|
|
||||||
|
### CSM-1B (Conversational Speech)
|
||||||
|
Text-to-speech with natural, conversational quality.
|
||||||
|
|
||||||
|
```
|
||||||
|
generate(
|
||||||
|
model_name: "fal-ai/csm-1b",
|
||||||
|
input: {
|
||||||
|
"text": "Hello, welcome to the demo. Let me show you how this works.",
|
||||||
|
"speaker_id": 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### ThinkSound (Video-to-Audio)
|
||||||
|
Generate matching audio from video content.
|
||||||
|
|
||||||
|
```
|
||||||
|
generate(
|
||||||
|
model_name: "fal-ai/thinksound",
|
||||||
|
input: {
|
||||||
|
"video_url": "<video_url>",
|
||||||
|
"prompt": "ambient forest sounds with birds chirping"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### ElevenLabs (via API, no MCP)
|
||||||
|
For professional voice synthesis, use ElevenLabs directly:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
|
||||||
|
resp = requests.post(
|
||||||
|
"https://api.elevenlabs.io/v1/text-to-speech/<voice_id>",
|
||||||
|
headers={
|
||||||
|
"xi-api-key": os.environ["ELEVENLABS_API_KEY"],
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
json={
|
||||||
|
"text": "Your text here",
|
||||||
|
"model_id": "eleven_turbo_v2_5",
|
||||||
|
"voice_settings": {"stability": 0.5, "similarity_boost": 0.75}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
with open("output.mp3", "wb") as f:
|
||||||
|
f.write(resp.content)
|
||||||
|
```
|
||||||
|
|
||||||
|
### VideoDB Generative Audio
|
||||||
|
If VideoDB is configured, use its generative audio:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Voice generation
|
||||||
|
audio = coll.generate_voice(text="Your narration here", voice="alloy")
|
||||||
|
|
||||||
|
# Music generation
|
||||||
|
music = coll.generate_music(prompt="upbeat electronic background music", duration=30)
|
||||||
|
|
||||||
|
# Sound effects
|
||||||
|
sfx = coll.generate_sound_effect(prompt="thunder crack followed by rain")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Cost Estimation
|
||||||
|
|
||||||
|
Before generating, check estimated cost:
|
||||||
|
|
||||||
|
```
|
||||||
|
estimate_cost(model_name: "fal-ai/nano-banana-pro", input: {...})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Model Discovery
|
||||||
|
|
||||||
|
Find models for specific tasks:
|
||||||
|
|
||||||
|
```
|
||||||
|
search(query: "text to video")
|
||||||
|
find(model_name: "fal-ai/seedance-1-0-pro")
|
||||||
|
models()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
- Use `seed` for reproducible results when iterating on prompts
|
||||||
|
- Start with lower-cost models (Nano Banana 2) for prompt iteration, then switch to Pro for finals
|
||||||
|
- For video, keep prompts descriptive but concise — focus on motion and scene
|
||||||
|
- Image-to-video produces more controlled results than pure text-to-video
|
||||||
|
- Check `estimate_cost` before running expensive video generations
|
||||||
|
|
||||||
|
## Related Skills
|
||||||
|
|
||||||
|
- `videodb` — Video processing, editing, and streaming
|
||||||
|
- `video-editing` — AI-powered video editing workflows
|
||||||
|
- `content-engine` — Content creation for social platforms
|
||||||
7
.agents/skills/fal-ai-media/agents/openai.yaml
Normal file
7
.agents/skills/fal-ai-media/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "fal.ai Media"
|
||||||
|
short_description: "AI image, video, and audio generation via fal.ai"
|
||||||
|
brand_color: "#F43F5E"
|
||||||
|
default_prompt: "Generate images, videos, or audio using fal.ai models"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
@@ -23,7 +23,7 @@ Modern frontend patterns for React, Next.js, and performant user interfaces.
|
|||||||
### Composition Over Inheritance
|
### Composition Over Inheritance
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ GOOD: Component composition
|
// PASS: GOOD: Component composition
|
||||||
interface CardProps {
|
interface CardProps {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
variant?: 'default' | 'outlined'
|
variant?: 'default' | 'outlined'
|
||||||
@@ -294,17 +294,17 @@ export function useMarkets() {
|
|||||||
### Memoization
|
### Memoization
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ✅ useMemo for expensive computations
|
// PASS: useMemo for expensive computations
|
||||||
const sortedMarkets = useMemo(() => {
|
const sortedMarkets = useMemo(() => {
|
||||||
return markets.sort((a, b) => b.volume - a.volume)
|
return markets.sort((a, b) => b.volume - a.volume)
|
||||||
}, [markets])
|
}, [markets])
|
||||||
|
|
||||||
// ✅ useCallback for functions passed to children
|
// PASS: useCallback for functions passed to children
|
||||||
const handleSearch = useCallback((query: string) => {
|
const handleSearch = useCallback((query: string) => {
|
||||||
setSearchQuery(query)
|
setSearchQuery(query)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// ✅ React.memo for pure components
|
// PASS: React.memo for pure components
|
||||||
export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
|
export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
|
||||||
return (
|
return (
|
||||||
<div className="market-card">
|
<div className="market-card">
|
||||||
@@ -320,7 +320,7 @@ export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
|
|||||||
```typescript
|
```typescript
|
||||||
import { lazy, Suspense } from 'react'
|
import { lazy, Suspense } from 'react'
|
||||||
|
|
||||||
// ✅ Lazy load heavy components
|
// PASS: Lazy load heavy components
|
||||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||||
const ThreeJsBackground = lazy(() => import('./ThreeJsBackground'))
|
const ThreeJsBackground = lazy(() => import('./ThreeJsBackground'))
|
||||||
|
|
||||||
@@ -515,7 +515,7 @@ export class ErrorBoundary extends React.Component<
|
|||||||
```typescript
|
```typescript
|
||||||
import { motion, AnimatePresence } from 'framer-motion'
|
import { motion, AnimatePresence } from 'framer-motion'
|
||||||
|
|
||||||
// ✅ List animations
|
// PASS: List animations
|
||||||
export function AnimatedMarketList({ markets }: { markets: Market[] }) {
|
export function AnimatedMarketList({ markets }: { markets: Market[] }) {
|
||||||
return (
|
return (
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
@@ -534,7 +534,7 @@ export function AnimatedMarketList({ markets }: { markets: Market[] }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ Modal animations
|
// PASS: Modal animations
|
||||||
export function Modal({ isOpen, onClose, children }: ModalProps) {
|
export function Modal({ isOpen, onClose, children }: ModalProps) {
|
||||||
return (
|
return (
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
|
|||||||
184
.agents/skills/frontend-slides/SKILL.md
Normal file
184
.agents/skills/frontend-slides/SKILL.md
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
---
|
||||||
|
name: frontend-slides
|
||||||
|
description: Create stunning, animation-rich HTML presentations from scratch or by converting PowerPoint files. Use when the user wants to build a presentation, convert a PPT/PPTX to web, or create slides for a talk/pitch. Helps non-designers discover their aesthetic through visual exploration rather than abstract choices.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Frontend Slides
|
||||||
|
|
||||||
|
Create zero-dependency, animation-rich HTML presentations that run entirely in the browser.
|
||||||
|
|
||||||
|
Inspired by the visual exploration approach showcased in work by [zarazhangrui](https://github.com/zarazhangrui).
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- Creating a talk deck, pitch deck, workshop deck, or internal presentation
|
||||||
|
- Converting `.ppt` or `.pptx` slides into an HTML presentation
|
||||||
|
- Improving an existing HTML presentation's layout, motion, or typography
|
||||||
|
- Exploring presentation styles with a user who does not know their design preference yet
|
||||||
|
|
||||||
|
## Non-Negotiables
|
||||||
|
|
||||||
|
1. **Zero dependencies**: default to one self-contained HTML file with inline CSS and JS.
|
||||||
|
2. **Viewport fit is mandatory**: every slide must fit inside one viewport with no internal scrolling.
|
||||||
|
3. **Show, don't tell**: use visual previews instead of abstract style questionnaires.
|
||||||
|
4. **Distinctive design**: avoid generic purple-gradient, Inter-on-white, template-looking decks.
|
||||||
|
5. **Production quality**: keep code commented, accessible, responsive, and performant.
|
||||||
|
|
||||||
|
Before generating, read `STYLE_PRESETS.md` for the viewport-safe CSS base, density limits, preset catalog, and CSS gotchas.
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
### 1. Detect Mode
|
||||||
|
|
||||||
|
Choose one path:
|
||||||
|
- **New presentation**: user has a topic, notes, or full draft
|
||||||
|
- **PPT conversion**: user has `.ppt` or `.pptx`
|
||||||
|
- **Enhancement**: user already has HTML slides and wants improvements
|
||||||
|
|
||||||
|
### 2. Discover Content
|
||||||
|
|
||||||
|
Ask only the minimum needed:
|
||||||
|
- purpose: pitch, teaching, conference talk, internal update
|
||||||
|
- length: short (5-10), medium (10-20), long (20+)
|
||||||
|
- content state: finished copy, rough notes, topic only
|
||||||
|
|
||||||
|
If the user has content, ask them to paste it before styling.
|
||||||
|
|
||||||
|
### 3. Discover Style
|
||||||
|
|
||||||
|
Default to visual exploration.
|
||||||
|
|
||||||
|
If the user already knows the desired preset, skip previews and use it directly.
|
||||||
|
|
||||||
|
Otherwise:
|
||||||
|
1. Ask what feeling the deck should create: impressed, energized, focused, inspired.
|
||||||
|
2. Generate **3 single-slide preview files** in `.ecc-design/slide-previews/`.
|
||||||
|
3. Each preview must be self-contained, show typography/color/motion clearly, and stay under roughly 100 lines of slide content.
|
||||||
|
4. Ask the user which preview to keep or what elements to mix.
|
||||||
|
|
||||||
|
Use the preset guide in `STYLE_PRESETS.md` when mapping mood to style.
|
||||||
|
|
||||||
|
### 4. Build the Presentation
|
||||||
|
|
||||||
|
Output either:
|
||||||
|
- `presentation.html`
|
||||||
|
- `[presentation-name].html`
|
||||||
|
|
||||||
|
Use an `assets/` folder only when the deck contains extracted or user-supplied images.
|
||||||
|
|
||||||
|
Required structure:
|
||||||
|
- semantic slide sections
|
||||||
|
- a viewport-safe CSS base from `STYLE_PRESETS.md`
|
||||||
|
- CSS custom properties for theme values
|
||||||
|
- a presentation controller class for keyboard, wheel, and touch navigation
|
||||||
|
- Intersection Observer for reveal animations
|
||||||
|
- reduced-motion support
|
||||||
|
|
||||||
|
### 5. Enforce Viewport Fit
|
||||||
|
|
||||||
|
Treat this as a hard gate.
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
- every `.slide` must use `height: 100vh; height: 100dvh; overflow: hidden;`
|
||||||
|
- all type and spacing must scale with `clamp()`
|
||||||
|
- when content does not fit, split into multiple slides
|
||||||
|
- never solve overflow by shrinking text below readable sizes
|
||||||
|
- never allow scrollbars inside a slide
|
||||||
|
|
||||||
|
Use the density limits and mandatory CSS block in `STYLE_PRESETS.md`.
|
||||||
|
|
||||||
|
### 6. Validate
|
||||||
|
|
||||||
|
Check the finished deck at these sizes:
|
||||||
|
- 1920x1080
|
||||||
|
- 1280x720
|
||||||
|
- 768x1024
|
||||||
|
- 375x667
|
||||||
|
- 667x375
|
||||||
|
|
||||||
|
If browser automation is available, use it to verify no slide overflows and that keyboard navigation works.
|
||||||
|
|
||||||
|
### 7. Deliver
|
||||||
|
|
||||||
|
At handoff:
|
||||||
|
- delete temporary preview files unless the user wants to keep them
|
||||||
|
- open the deck with the platform-appropriate opener when useful
|
||||||
|
- summarize file path, preset used, slide count, and easy theme customization points
|
||||||
|
|
||||||
|
Use the correct opener for the current OS:
|
||||||
|
- macOS: `open file.html`
|
||||||
|
- Linux: `xdg-open file.html`
|
||||||
|
- Windows: `start "" file.html`
|
||||||
|
|
||||||
|
## PPT / PPTX Conversion
|
||||||
|
|
||||||
|
For PowerPoint conversion:
|
||||||
|
1. Prefer `python3` with `python-pptx` to extract text, images, and notes.
|
||||||
|
2. If `python-pptx` is unavailable, ask whether to install it or fall back to a manual/export-based workflow.
|
||||||
|
3. Preserve slide order, speaker notes, and extracted assets.
|
||||||
|
4. After extraction, run the same style-selection workflow as a new presentation.
|
||||||
|
|
||||||
|
Keep conversion cross-platform. Do not rely on macOS-only tools when Python can do the job.
|
||||||
|
|
||||||
|
## Implementation Requirements
|
||||||
|
|
||||||
|
### HTML / CSS
|
||||||
|
|
||||||
|
- Use inline CSS and JS unless the user explicitly wants a multi-file project.
|
||||||
|
- Fonts may come from Google Fonts or Fontshare.
|
||||||
|
- Prefer atmospheric backgrounds, strong type hierarchy, and a clear visual direction.
|
||||||
|
- Use abstract shapes, gradients, grids, noise, and geometry rather than illustrations.
|
||||||
|
|
||||||
|
### JavaScript
|
||||||
|
|
||||||
|
Include:
|
||||||
|
- keyboard navigation
|
||||||
|
- touch / swipe navigation
|
||||||
|
- mouse wheel navigation
|
||||||
|
- progress indicator or slide index
|
||||||
|
- reveal-on-enter animation triggers
|
||||||
|
|
||||||
|
### Accessibility
|
||||||
|
|
||||||
|
- use semantic structure (`main`, `section`, `nav`)
|
||||||
|
- keep contrast readable
|
||||||
|
- support keyboard-only navigation
|
||||||
|
- respect `prefers-reduced-motion`
|
||||||
|
|
||||||
|
## Content Density Limits
|
||||||
|
|
||||||
|
Use these maxima unless the user explicitly asks for denser slides and readability still holds:
|
||||||
|
|
||||||
|
| Slide type | Limit |
|
||||||
|
|------------|-------|
|
||||||
|
| Title | 1 heading + 1 subtitle + optional tagline |
|
||||||
|
| Content | 1 heading + 4-6 bullets or 2 short paragraphs |
|
||||||
|
| Feature grid | 6 cards max |
|
||||||
|
| Code | 8-10 lines max |
|
||||||
|
| Quote | 1 quote + attribution |
|
||||||
|
| Image | 1 image constrained by viewport |
|
||||||
|
|
||||||
|
## Anti-Patterns
|
||||||
|
|
||||||
|
- generic startup gradients with no visual identity
|
||||||
|
- system-font decks unless intentionally editorial
|
||||||
|
- long bullet walls
|
||||||
|
- code blocks that need scrolling
|
||||||
|
- fixed-height content boxes that break on short screens
|
||||||
|
- invalid negated CSS functions like `-clamp(...)`
|
||||||
|
|
||||||
|
## Related ECC Skills
|
||||||
|
|
||||||
|
- `frontend-patterns` for component and interaction patterns around the deck
|
||||||
|
- `liquid-glass-design` when a presentation intentionally borrows Apple glass aesthetics
|
||||||
|
- `e2e-testing` if you need automated browser verification for the final deck
|
||||||
|
|
||||||
|
## Deliverable Checklist
|
||||||
|
|
||||||
|
- presentation runs from a local file in a browser
|
||||||
|
- every slide fits the viewport without scrolling
|
||||||
|
- style is distinctive and intentional
|
||||||
|
- animation is meaningful, not noisy
|
||||||
|
- reduced motion is respected
|
||||||
|
- file paths and customization points are explained at handoff
|
||||||
330
.agents/skills/frontend-slides/STYLE_PRESETS.md
Normal file
330
.agents/skills/frontend-slides/STYLE_PRESETS.md
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
# Style Presets Reference
|
||||||
|
|
||||||
|
Curated visual styles for `frontend-slides`.
|
||||||
|
|
||||||
|
Use this file for:
|
||||||
|
- the mandatory viewport-fitting CSS base
|
||||||
|
- preset selection and mood mapping
|
||||||
|
- CSS gotchas and validation rules
|
||||||
|
|
||||||
|
Abstract shapes only. Avoid illustrations unless the user explicitly asks for them.
|
||||||
|
|
||||||
|
## Viewport Fit Is Non-Negotiable
|
||||||
|
|
||||||
|
Every slide must fully fit in one viewport.
|
||||||
|
|
||||||
|
### Golden Rule
|
||||||
|
|
||||||
|
```text
|
||||||
|
Each slide = exactly one viewport height.
|
||||||
|
Too much content = split into more slides.
|
||||||
|
Never scroll inside a slide.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Density Limits
|
||||||
|
|
||||||
|
| Slide Type | Maximum Content |
|
||||||
|
|------------|-----------------|
|
||||||
|
| Title slide | 1 heading + 1 subtitle + optional tagline |
|
||||||
|
| Content slide | 1 heading + 4-6 bullets or 2 paragraphs |
|
||||||
|
| Feature grid | 6 cards maximum |
|
||||||
|
| Code slide | 8-10 lines maximum |
|
||||||
|
| Quote slide | 1 quote + attribution |
|
||||||
|
| Image slide | 1 image, ideally under 60vh |
|
||||||
|
|
||||||
|
## Mandatory Base CSS
|
||||||
|
|
||||||
|
Copy this block into every generated presentation and then theme on top of it.
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* ===========================================
|
||||||
|
VIEWPORT FITTING: MANDATORY BASE STYLES
|
||||||
|
=========================================== */
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-snap-type: y mandatory;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
height: 100dvh;
|
||||||
|
overflow: hidden;
|
||||||
|
scroll-snap-align: start;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-content {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
max-height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: var(--slide-padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--title-size: clamp(1.5rem, 5vw, 4rem);
|
||||||
|
--h2-size: clamp(1.25rem, 3.5vw, 2.5rem);
|
||||||
|
--h3-size: clamp(1rem, 2.5vw, 1.75rem);
|
||||||
|
--body-size: clamp(0.75rem, 1.5vw, 1.125rem);
|
||||||
|
--small-size: clamp(0.65rem, 1vw, 0.875rem);
|
||||||
|
|
||||||
|
--slide-padding: clamp(1rem, 4vw, 4rem);
|
||||||
|
--content-gap: clamp(0.5rem, 2vw, 2rem);
|
||||||
|
--element-gap: clamp(0.25rem, 1vw, 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card, .container, .content-box {
|
||||||
|
max-width: min(90vw, 1000px);
|
||||||
|
max-height: min(80vh, 700px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-list, .bullet-list {
|
||||||
|
gap: clamp(0.4rem, 1vh, 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-list li, .bullet-list li {
|
||||||
|
font-size: var(--body-size);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
|
||||||
|
gap: clamp(0.5rem, 1.5vw, 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
img, .image-container {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: min(50vh, 400px);
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-height: 700px) {
|
||||||
|
:root {
|
||||||
|
--slide-padding: clamp(0.75rem, 3vw, 2rem);
|
||||||
|
--content-gap: clamp(0.4rem, 1.5vw, 1rem);
|
||||||
|
--title-size: clamp(1.25rem, 4.5vw, 2.5rem);
|
||||||
|
--h2-size: clamp(1rem, 3vw, 1.75rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-height: 600px) {
|
||||||
|
:root {
|
||||||
|
--slide-padding: clamp(0.5rem, 2.5vw, 1.5rem);
|
||||||
|
--content-gap: clamp(0.3rem, 1vw, 0.75rem);
|
||||||
|
--title-size: clamp(1.1rem, 4vw, 2rem);
|
||||||
|
--body-size: clamp(0.7rem, 1.2vw, 0.95rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dots, .keyboard-hint, .decorative {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-height: 500px) {
|
||||||
|
:root {
|
||||||
|
--slide-padding: clamp(0.4rem, 2vw, 1rem);
|
||||||
|
--title-size: clamp(1rem, 3.5vw, 1.5rem);
|
||||||
|
--h2-size: clamp(0.9rem, 2.5vw, 1.25rem);
|
||||||
|
--body-size: clamp(0.65rem, 1vw, 0.85rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
:root {
|
||||||
|
--title-size: clamp(1.25rem, 7vw, 2.5rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
*, *::before, *::after {
|
||||||
|
animation-duration: 0.01ms !important;
|
||||||
|
transition-duration: 0.2s !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Viewport Checklist
|
||||||
|
|
||||||
|
- every `.slide` has `height: 100vh`, `height: 100dvh`, and `overflow: hidden`
|
||||||
|
- all typography uses `clamp()`
|
||||||
|
- all spacing uses `clamp()` or viewport units
|
||||||
|
- images have `max-height` constraints
|
||||||
|
- grids adapt with `auto-fit` + `minmax()`
|
||||||
|
- short-height breakpoints exist at `700px`, `600px`, and `500px`
|
||||||
|
- if anything feels cramped, split the slide
|
||||||
|
|
||||||
|
## Mood to Preset Mapping
|
||||||
|
|
||||||
|
| Mood | Good Presets |
|
||||||
|
|------|--------------|
|
||||||
|
| Impressed / Confident | Bold Signal, Electric Studio, Dark Botanical |
|
||||||
|
| Excited / Energized | Creative Voltage, Neon Cyber, Split Pastel |
|
||||||
|
| Calm / Focused | Notebook Tabs, Paper & Ink, Swiss Modern |
|
||||||
|
| Inspired / Moved | Dark Botanical, Vintage Editorial, Pastel Geometry |
|
||||||
|
|
||||||
|
## Preset Catalog
|
||||||
|
|
||||||
|
### 1. Bold Signal
|
||||||
|
|
||||||
|
- Vibe: confident, high-impact, keynote-ready
|
||||||
|
- Best for: pitch decks, launches, statements
|
||||||
|
- Fonts: Archivo Black + Space Grotesk
|
||||||
|
- Palette: charcoal base, hot orange focal card, crisp white text
|
||||||
|
- Signature: oversized section numbers, high-contrast card on dark field
|
||||||
|
|
||||||
|
### 2. Electric Studio
|
||||||
|
|
||||||
|
- Vibe: clean, bold, agency-polished
|
||||||
|
- Best for: client presentations, strategic reviews
|
||||||
|
- Fonts: Manrope only
|
||||||
|
- Palette: black, white, saturated cobalt accent
|
||||||
|
- Signature: two-panel split and sharp editorial alignment
|
||||||
|
|
||||||
|
### 3. Creative Voltage
|
||||||
|
|
||||||
|
- Vibe: energetic, retro-modern, playful confidence
|
||||||
|
- Best for: creative studios, brand work, product storytelling
|
||||||
|
- Fonts: Syne + Space Mono
|
||||||
|
- Palette: electric blue, neon yellow, deep navy
|
||||||
|
- Signature: halftone textures, badges, punchy contrast
|
||||||
|
|
||||||
|
### 4. Dark Botanical
|
||||||
|
|
||||||
|
- Vibe: elegant, premium, atmospheric
|
||||||
|
- Best for: luxury brands, thoughtful narratives, premium product decks
|
||||||
|
- Fonts: Cormorant + IBM Plex Sans
|
||||||
|
- Palette: near-black, warm ivory, blush, gold, terracotta
|
||||||
|
- Signature: blurred abstract circles, fine rules, restrained motion
|
||||||
|
|
||||||
|
### 5. Notebook Tabs
|
||||||
|
|
||||||
|
- Vibe: editorial, organized, tactile
|
||||||
|
- Best for: reports, reviews, structured storytelling
|
||||||
|
- Fonts: Bodoni Moda + DM Sans
|
||||||
|
- Palette: cream paper on charcoal with pastel tabs
|
||||||
|
- Signature: paper sheet, colored side tabs, binder details
|
||||||
|
|
||||||
|
### 6. Pastel Geometry
|
||||||
|
|
||||||
|
- Vibe: approachable, modern, friendly
|
||||||
|
- Best for: product overviews, onboarding, lighter brand decks
|
||||||
|
- Fonts: Plus Jakarta Sans only
|
||||||
|
- Palette: pale blue field, cream card, soft pink/mint/lavender accents
|
||||||
|
- Signature: vertical pills, rounded cards, soft shadows
|
||||||
|
|
||||||
|
### 7. Split Pastel
|
||||||
|
|
||||||
|
- Vibe: playful, modern, creative
|
||||||
|
- Best for: agency intros, workshops, portfolios
|
||||||
|
- Fonts: Outfit only
|
||||||
|
- Palette: peach + lavender split with mint badges
|
||||||
|
- Signature: split backdrop, rounded tags, light grid overlays
|
||||||
|
|
||||||
|
### 8. Vintage Editorial
|
||||||
|
|
||||||
|
- Vibe: witty, personality-driven, magazine-inspired
|
||||||
|
- Best for: personal brands, opinionated talks, storytelling
|
||||||
|
- Fonts: Fraunces + Work Sans
|
||||||
|
- Palette: cream, charcoal, dusty warm accents
|
||||||
|
- Signature: geometric accents, bordered callouts, punchy serif headlines
|
||||||
|
|
||||||
|
### 9. Neon Cyber
|
||||||
|
|
||||||
|
- Vibe: futuristic, techy, kinetic
|
||||||
|
- Best for: AI, infra, dev tools, future-of-X talks
|
||||||
|
- Fonts: Clash Display + Satoshi
|
||||||
|
- Palette: midnight navy, cyan, magenta
|
||||||
|
- Signature: glow, particles, grids, data-radar energy
|
||||||
|
|
||||||
|
### 10. Terminal Green
|
||||||
|
|
||||||
|
- Vibe: developer-focused, hacker-clean
|
||||||
|
- Best for: APIs, CLI tools, engineering demos
|
||||||
|
- Fonts: JetBrains Mono only
|
||||||
|
- Palette: GitHub dark + terminal green
|
||||||
|
- Signature: scan lines, command-line framing, precise monospace rhythm
|
||||||
|
|
||||||
|
### 11. Swiss Modern
|
||||||
|
|
||||||
|
- Vibe: minimal, precise, data-forward
|
||||||
|
- Best for: corporate, product strategy, analytics
|
||||||
|
- Fonts: Archivo + Nunito
|
||||||
|
- Palette: white, black, signal red
|
||||||
|
- Signature: visible grids, asymmetry, geometric discipline
|
||||||
|
|
||||||
|
### 12. Paper & Ink
|
||||||
|
|
||||||
|
- Vibe: literary, thoughtful, story-driven
|
||||||
|
- Best for: essays, keynote narratives, manifesto decks
|
||||||
|
- Fonts: Cormorant Garamond + Source Serif 4
|
||||||
|
- Palette: warm cream, charcoal, crimson accent
|
||||||
|
- Signature: pull quotes, drop caps, elegant rules
|
||||||
|
|
||||||
|
## Direct Selection Prompts
|
||||||
|
|
||||||
|
If the user already knows the style they want, let them pick directly from the preset names above instead of forcing preview generation.
|
||||||
|
|
||||||
|
## Animation Feel Mapping
|
||||||
|
|
||||||
|
| Feeling | Motion Direction |
|
||||||
|
|---------|------------------|
|
||||||
|
| Dramatic / Cinematic | slow fades, parallax, large scale-ins |
|
||||||
|
| Techy / Futuristic | glow, particles, grid motion, scramble text |
|
||||||
|
| Playful / Friendly | springy easing, rounded shapes, floating motion |
|
||||||
|
| Professional / Corporate | subtle 200-300ms transitions, clean slides |
|
||||||
|
| Calm / Minimal | very restrained movement, whitespace-first |
|
||||||
|
| Editorial / Magazine | strong hierarchy, staggered text and image interplay |
|
||||||
|
|
||||||
|
## CSS Gotcha: Negating Functions
|
||||||
|
|
||||||
|
Never write these:
|
||||||
|
|
||||||
|
```css
|
||||||
|
right: -clamp(28px, 3.5vw, 44px);
|
||||||
|
margin-left: -min(10vw, 100px);
|
||||||
|
```
|
||||||
|
|
||||||
|
Browsers ignore them silently.
|
||||||
|
|
||||||
|
Always write this instead:
|
||||||
|
|
||||||
|
```css
|
||||||
|
right: calc(-1 * clamp(28px, 3.5vw, 44px));
|
||||||
|
margin-left: calc(-1 * min(10vw, 100px));
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation Sizes
|
||||||
|
|
||||||
|
Test at minimum:
|
||||||
|
- Desktop: `1920x1080`, `1440x900`, `1280x720`
|
||||||
|
- Tablet: `1024x768`, `768x1024`
|
||||||
|
- Mobile: `375x667`, `414x896`
|
||||||
|
- Landscape phone: `667x375`, `896x414`
|
||||||
|
|
||||||
|
## Anti-Patterns
|
||||||
|
|
||||||
|
Do not use:
|
||||||
|
- purple-on-white startup templates
|
||||||
|
- Inter / Roboto / Arial as the visual voice unless the user explicitly wants utilitarian neutrality
|
||||||
|
- bullet walls, tiny type, or code blocks that require scrolling
|
||||||
|
- decorative illustrations when abstract geometry would do the job better
|
||||||
7
.agents/skills/frontend-slides/agents/openai.yaml
Normal file
7
.agents/skills/frontend-slides/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Frontend Slides"
|
||||||
|
short_description: "Create distinctive HTML slide decks and convert PPTX to web"
|
||||||
|
brand_color: "#FF6B3D"
|
||||||
|
default_prompt: "Create a viewport-safe HTML presentation with strong visual direction"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
96
.agents/skills/investor-materials/SKILL.md
Normal file
96
.agents/skills/investor-materials/SKILL.md
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
---
|
||||||
|
name: investor-materials
|
||||||
|
description: Create and update pitch decks, one-pagers, investor memos, accelerator applications, financial models, and fundraising materials. Use when the user needs investor-facing documents, projections, use-of-funds tables, milestone plans, or materials that must stay internally consistent across multiple fundraising assets.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Investor Materials
|
||||||
|
|
||||||
|
Build investor-facing materials that are consistent, credible, and easy to defend.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- creating or revising a pitch deck
|
||||||
|
- writing an investor memo or one-pager
|
||||||
|
- building a financial model, milestone plan, or use-of-funds table
|
||||||
|
- answering accelerator or incubator application questions
|
||||||
|
- aligning multiple fundraising docs around one source of truth
|
||||||
|
|
||||||
|
## Golden Rule
|
||||||
|
|
||||||
|
All investor materials must agree with each other.
|
||||||
|
|
||||||
|
Create or confirm a single source of truth before writing:
|
||||||
|
- traction metrics
|
||||||
|
- pricing and revenue assumptions
|
||||||
|
- raise size and instrument
|
||||||
|
- use of funds
|
||||||
|
- team bios and titles
|
||||||
|
- milestones and timelines
|
||||||
|
|
||||||
|
If conflicting numbers appear, stop and resolve them before drafting.
|
||||||
|
|
||||||
|
## Core Workflow
|
||||||
|
|
||||||
|
1. inventory the canonical facts
|
||||||
|
2. identify missing assumptions
|
||||||
|
3. choose the asset type
|
||||||
|
4. draft the asset with explicit logic
|
||||||
|
5. cross-check every number against the source of truth
|
||||||
|
|
||||||
|
## Asset Guidance
|
||||||
|
|
||||||
|
### Pitch Deck
|
||||||
|
Recommended flow:
|
||||||
|
1. company + wedge
|
||||||
|
2. problem
|
||||||
|
3. solution
|
||||||
|
4. product / demo
|
||||||
|
5. market
|
||||||
|
6. business model
|
||||||
|
7. traction
|
||||||
|
8. team
|
||||||
|
9. competition / differentiation
|
||||||
|
10. ask
|
||||||
|
11. use of funds / milestones
|
||||||
|
12. appendix
|
||||||
|
|
||||||
|
If the user wants a web-native deck, pair this skill with `frontend-slides`.
|
||||||
|
|
||||||
|
### One-Pager / Memo
|
||||||
|
- state what the company does in one clean sentence
|
||||||
|
- show why now
|
||||||
|
- include traction and proof points early
|
||||||
|
- make the ask precise
|
||||||
|
- keep claims easy to verify
|
||||||
|
|
||||||
|
### Financial Model
|
||||||
|
Include:
|
||||||
|
- explicit assumptions
|
||||||
|
- bear / base / bull cases when useful
|
||||||
|
- clean layer-by-layer revenue logic
|
||||||
|
- milestone-linked spending
|
||||||
|
- sensitivity analysis where the decision hinges on assumptions
|
||||||
|
|
||||||
|
### Accelerator Applications
|
||||||
|
- answer the exact question asked
|
||||||
|
- prioritize traction, insight, and team advantage
|
||||||
|
- avoid puffery
|
||||||
|
- keep internal metrics consistent with the deck and model
|
||||||
|
|
||||||
|
## Red Flags to Avoid
|
||||||
|
|
||||||
|
- unverifiable claims
|
||||||
|
- fuzzy market sizing without assumptions
|
||||||
|
- inconsistent team roles or titles
|
||||||
|
- revenue math that does not sum cleanly
|
||||||
|
- inflated certainty where assumptions are fragile
|
||||||
|
|
||||||
|
## Quality Gate
|
||||||
|
|
||||||
|
Before delivering:
|
||||||
|
- every number matches the current source of truth
|
||||||
|
- use of funds and revenue layers sum correctly
|
||||||
|
- assumptions are visible, not buried
|
||||||
|
- the story is clear without hype language
|
||||||
|
- the final asset is defensible in a partner meeting
|
||||||
7
.agents/skills/investor-materials/agents/openai.yaml
Normal file
7
.agents/skills/investor-materials/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Investor Materials"
|
||||||
|
short_description: "Create decks, memos, and financial materials from one source of truth"
|
||||||
|
brand_color: "#7C3AED"
|
||||||
|
default_prompt: "Draft investor materials that stay numerically consistent across assets"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
87
.agents/skills/investor-outreach/SKILL.md
Normal file
87
.agents/skills/investor-outreach/SKILL.md
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
---
|
||||||
|
name: investor-outreach
|
||||||
|
description: Draft cold emails, warm intro blurbs, follow-ups, update emails, and investor communications for fundraising. Use when the user wants outreach to angels, VCs, strategic investors, or accelerators and needs concise, personalized, investor-facing messaging.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Investor Outreach
|
||||||
|
|
||||||
|
Write investor communication that is short, concrete, and easy to act on.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- writing a cold email to an investor
|
||||||
|
- drafting a warm intro request
|
||||||
|
- sending follow-ups after a meeting or no response
|
||||||
|
- writing investor updates during a process
|
||||||
|
- tailoring outreach based on fund thesis or partner fit
|
||||||
|
|
||||||
|
## Core Rules
|
||||||
|
|
||||||
|
1. Personalize every outbound message.
|
||||||
|
2. Keep the ask low-friction.
|
||||||
|
3. Use proof instead of adjectives.
|
||||||
|
4. Stay concise.
|
||||||
|
5. Never send copy that could go to any investor.
|
||||||
|
|
||||||
|
## Hard Bans
|
||||||
|
|
||||||
|
Delete and rewrite any of these:
|
||||||
|
- "I'd love to connect"
|
||||||
|
- "excited to share"
|
||||||
|
- generic thesis praise without a real tie-in
|
||||||
|
- vague founder adjectives
|
||||||
|
- "no fluff"
|
||||||
|
- begging language
|
||||||
|
- soft closing questions when a direct ask is clearer
|
||||||
|
|
||||||
|
## Cold Email Structure
|
||||||
|
|
||||||
|
1. subject line: short and specific
|
||||||
|
2. opener: why this investor specifically
|
||||||
|
3. pitch: what the company does, why now, and what proof matters
|
||||||
|
4. ask: one concrete next step
|
||||||
|
5. sign-off: name, role, and one credibility anchor if needed
|
||||||
|
|
||||||
|
## Personalization Sources
|
||||||
|
|
||||||
|
Reference one or more of:
|
||||||
|
- relevant portfolio companies
|
||||||
|
- a public thesis, talk, post, or article
|
||||||
|
- a mutual connection
|
||||||
|
- a clear market or product fit with the investor's focus
|
||||||
|
|
||||||
|
If that context is missing, state that the draft still needs personalization instead of pretending it is finished.
|
||||||
|
|
||||||
|
## Follow-Up Cadence
|
||||||
|
|
||||||
|
Default:
|
||||||
|
- day 0: initial outbound
|
||||||
|
- day 4 or 5: short follow-up with one new data point
|
||||||
|
- day 10 to 12: final follow-up with a clean close
|
||||||
|
|
||||||
|
Do not keep nudging after that unless the user wants a longer sequence.
|
||||||
|
|
||||||
|
## Warm Intro Requests
|
||||||
|
|
||||||
|
Make life easy for the connector:
|
||||||
|
- explain why the intro is a fit
|
||||||
|
- include a forwardable blurb
|
||||||
|
- keep the forwardable blurb under 100 words
|
||||||
|
|
||||||
|
## Post-Meeting Updates
|
||||||
|
|
||||||
|
Include:
|
||||||
|
- the specific thing discussed
|
||||||
|
- the answer or update promised
|
||||||
|
- one new proof point if available
|
||||||
|
- the next step
|
||||||
|
|
||||||
|
## Quality Gate
|
||||||
|
|
||||||
|
Before delivering:
|
||||||
|
- the message is genuinely personalized
|
||||||
|
- the ask is explicit
|
||||||
|
- the proof point is concrete
|
||||||
|
- filler praise and softener language are gone
|
||||||
|
- word count stays tight
|
||||||
7
.agents/skills/investor-outreach/agents/openai.yaml
Normal file
7
.agents/skills/investor-outreach/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Investor Outreach"
|
||||||
|
short_description: "Write concise, personalized outreach and follow-ups for fundraising"
|
||||||
|
brand_color: "#059669"
|
||||||
|
default_prompt: "Draft a personalized investor outreach email with a clear low-friction ask"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
75
.agents/skills/market-research/SKILL.md
Normal file
75
.agents/skills/market-research/SKILL.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
---
|
||||||
|
name: market-research
|
||||||
|
description: Conduct market research, competitive analysis, investor due diligence, and industry intelligence with source attribution and decision-oriented summaries. Use when the user wants market sizing, competitor comparisons, fund research, technology scans, or research that informs business decisions.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Market Research
|
||||||
|
|
||||||
|
Produce research that supports decisions, not research theater.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- researching a market, category, company, investor, or technology trend
|
||||||
|
- building TAM/SAM/SOM estimates
|
||||||
|
- comparing competitors or adjacent products
|
||||||
|
- preparing investor dossiers before outreach
|
||||||
|
- pressure-testing a thesis before building, funding, or entering a market
|
||||||
|
|
||||||
|
## Research Standards
|
||||||
|
|
||||||
|
1. Every important claim needs a source.
|
||||||
|
2. Prefer recent data and call out stale data.
|
||||||
|
3. Include contrarian evidence and downside cases.
|
||||||
|
4. Translate findings into a decision, not just a summary.
|
||||||
|
5. Separate fact, inference, and recommendation clearly.
|
||||||
|
|
||||||
|
## Common Research Modes
|
||||||
|
|
||||||
|
### Investor / Fund Diligence
|
||||||
|
Collect:
|
||||||
|
- fund size, stage, and typical check size
|
||||||
|
- relevant portfolio companies
|
||||||
|
- public thesis and recent activity
|
||||||
|
- reasons the fund is or is not a fit
|
||||||
|
- any obvious red flags or mismatches
|
||||||
|
|
||||||
|
### Competitive Analysis
|
||||||
|
Collect:
|
||||||
|
- product reality, not marketing copy
|
||||||
|
- funding and investor history if public
|
||||||
|
- traction metrics if public
|
||||||
|
- distribution and pricing clues
|
||||||
|
- strengths, weaknesses, and positioning gaps
|
||||||
|
|
||||||
|
### Market Sizing
|
||||||
|
Use:
|
||||||
|
- top-down estimates from reports or public datasets
|
||||||
|
- bottom-up sanity checks from realistic customer acquisition assumptions
|
||||||
|
- explicit assumptions for every leap in logic
|
||||||
|
|
||||||
|
### Technology / Vendor Research
|
||||||
|
Collect:
|
||||||
|
- how it works
|
||||||
|
- trade-offs and adoption signals
|
||||||
|
- integration complexity
|
||||||
|
- lock-in, security, compliance, and operational risk
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
Default structure:
|
||||||
|
1. executive summary
|
||||||
|
2. key findings
|
||||||
|
3. implications
|
||||||
|
4. risks and caveats
|
||||||
|
5. recommendation
|
||||||
|
6. sources
|
||||||
|
|
||||||
|
## Quality Gate
|
||||||
|
|
||||||
|
Before delivering:
|
||||||
|
- all numbers are sourced or labeled as estimates
|
||||||
|
- old data is flagged
|
||||||
|
- the recommendation follows from the evidence
|
||||||
|
- risks and counterarguments are included
|
||||||
|
- the output makes a decision easier
|
||||||
7
.agents/skills/market-research/agents/openai.yaml
Normal file
7
.agents/skills/market-research/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Market Research"
|
||||||
|
short_description: "Source-attributed market, competitor, and investor research"
|
||||||
|
brand_color: "#2563EB"
|
||||||
|
default_prompt: "Research this market and summarize the decision-relevant findings"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
67
.agents/skills/mcp-server-patterns/SKILL.md
Normal file
67
.agents/skills/mcp-server-patterns/SKILL.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
name: mcp-server-patterns
|
||||||
|
description: Build MCP servers with Node/TypeScript SDK — tools, resources, prompts, Zod validation, stdio vs Streamable HTTP. Use Context7 or official MCP docs for latest API.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# MCP Server Patterns
|
||||||
|
|
||||||
|
The Model Context Protocol (MCP) lets AI assistants call tools, read resources, and use prompts from your server. Use this skill when building or maintaining MCP servers. The SDK API evolves; check Context7 (query-docs for "MCP") or the official MCP documentation for current method names and signatures.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
Use when: implementing a new MCP server, adding tools or resources, choosing stdio vs HTTP, upgrading the SDK, or debugging MCP registration and transport issues.
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
### Core concepts
|
||||||
|
|
||||||
|
- **Tools**: Actions the model can invoke (e.g. search, run a command). Register with `registerTool()` or `tool()` depending on SDK version.
|
||||||
|
- **Resources**: Read-only data the model can fetch (e.g. file contents, API responses). Register with `registerResource()` or `resource()`. Handlers typically receive a `uri` argument.
|
||||||
|
- **Prompts**: Reusable, parameterised prompt templates the client can surface (e.g. in Claude Desktop). Register with `registerPrompt()` or equivalent.
|
||||||
|
- **Transport**: stdio for local clients (e.g. Claude Desktop); Streamable HTTP is preferred for remote (Cursor, cloud). Legacy HTTP/SSE is for backward compatibility.
|
||||||
|
|
||||||
|
The Node/TypeScript SDK may expose `tool()` / `resource()` or `registerTool()` / `registerResource()`; the official SDK has changed over time. Always verify against the current [MCP docs](https://modelcontextprotocol.io) or Context7.
|
||||||
|
|
||||||
|
### Connecting with stdio
|
||||||
|
|
||||||
|
For local clients, create a stdio transport and pass it to your server’s connect method. The exact API varies by SDK version (e.g. constructor vs factory). See the official MCP documentation or query Context7 for "MCP stdio server" for the current pattern.
|
||||||
|
|
||||||
|
Keep server logic (tools + resources) independent of transport so you can plug in stdio or HTTP in the entrypoint.
|
||||||
|
|
||||||
|
### Remote (Streamable HTTP)
|
||||||
|
|
||||||
|
For Cursor, cloud, or other remote clients, use **Streamable HTTP** (single MCP HTTP endpoint per current spec). Support legacy HTTP/SSE only when backward compatibility is required.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Install and server setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install @modelcontextprotocol/sdk zod
|
||||||
|
```
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const server = new McpServer({ name: "my-server", version: "1.0.0" });
|
||||||
|
```
|
||||||
|
|
||||||
|
Register tools and resources using the API your SDK version provides: some versions use `server.tool(name, description, schema, handler)` (positional args), others use `server.tool({ name, description, inputSchema }, handler)` or `registerTool()`. Same for resources — include a `uri` in the handler when the API provides it. Check the official MCP docs or Context7 for the current `@modelcontextprotocol/sdk` signatures to avoid copy-paste errors.
|
||||||
|
|
||||||
|
Use **Zod** (or the SDK’s preferred schema format) for input validation.
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- **Schema first**: Define input schemas for every tool; document parameters and return shape.
|
||||||
|
- **Errors**: Return structured errors or messages the model can interpret; avoid raw stack traces.
|
||||||
|
- **Idempotency**: Prefer idempotent tools where possible so retries are safe.
|
||||||
|
- **Rate and cost**: For tools that call external APIs, consider rate limits and cost; document in the tool description.
|
||||||
|
- **Versioning**: Pin SDK version in package.json; check release notes when upgrading.
|
||||||
|
|
||||||
|
## Official SDKs and Docs
|
||||||
|
|
||||||
|
- **JavaScript/TypeScript**: `@modelcontextprotocol/sdk` (npm). Use Context7 with library name "MCP" for current registration and transport patterns.
|
||||||
|
- **Go**: Official Go SDK on GitHub (`modelcontextprotocol/go-sdk`).
|
||||||
|
- **C#**: Official C# SDK for .NET.
|
||||||
44
.agents/skills/nextjs-turbopack/SKILL.md
Normal file
44
.agents/skills/nextjs-turbopack/SKILL.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
name: nextjs-turbopack
|
||||||
|
description: Next.js 16+ and Turbopack — incremental bundling, FS caching, dev speed, and when to use Turbopack vs webpack.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Next.js and Turbopack
|
||||||
|
|
||||||
|
Next.js 16+ uses Turbopack by default for local development: an incremental bundler written in Rust that significantly speeds up dev startup and hot updates.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- **Turbopack (default dev)**: Use for day-to-day development. Faster cold start and HMR, especially in large apps.
|
||||||
|
- **Webpack (legacy dev)**: Use only if you hit a Turbopack bug or rely on a webpack-only plugin in dev. Disable with `--webpack` (or `--no-turbopack` depending on your Next.js version; check the docs for your release).
|
||||||
|
- **Production**: Production build behavior (`next build`) may use Turbopack or webpack depending on Next.js version; check the official Next.js docs for your version.
|
||||||
|
|
||||||
|
Use when: developing or debugging Next.js 16+ apps, diagnosing slow dev startup or HMR, or optimizing production bundles.
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
- **Turbopack**: Incremental bundler for Next.js dev. Uses file-system caching so restarts are much faster (e.g. 5–14x on large projects).
|
||||||
|
- **Default in dev**: From Next.js 16, `next dev` runs with Turbopack unless disabled.
|
||||||
|
- **File-system caching**: Restarts reuse previous work; cache is typically under `.next`; no extra config needed for basic use.
|
||||||
|
- **Bundle Analyzer (Next.js 16.1+)**: Experimental Bundle Analyzer to inspect output and find heavy dependencies; enable via config or experimental flag (see Next.js docs for your version).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
next dev
|
||||||
|
next build
|
||||||
|
next start
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
Run `next dev` for local development with Turbopack. Use the Bundle Analyzer (see Next.js docs) to optimize code-splitting and trim large dependencies. Prefer App Router and server components where possible.
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- Stay on a recent Next.js 16.x for stable Turbopack and caching behavior.
|
||||||
|
- If dev is slow, ensure you're on Turbopack (default) and that the cache isn't being cleared unnecessarily.
|
||||||
|
- For production bundle size issues, use the official Next.js bundle analysis tooling for your version.
|
||||||
7
.agents/skills/nextjs-turbopack/agents/openai.yaml
Normal file
7
.agents/skills/nextjs-turbopack/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Next.js Turbopack"
|
||||||
|
short_description: "Next.js 16+ and Turbopack dev bundler"
|
||||||
|
brand_color: "#000000"
|
||||||
|
default_prompt: "Next.js dev, Turbopack, or bundle optimization"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
@@ -22,13 +22,13 @@ This skill ensures all code follows security best practices and identifies poten
|
|||||||
|
|
||||||
### 1. Secrets Management
|
### 1. Secrets Management
|
||||||
|
|
||||||
#### ❌ NEVER Do This
|
#### FAIL: NEVER Do This
|
||||||
```typescript
|
```typescript
|
||||||
const apiKey = "sk-proj-xxxxx" // Hardcoded secret
|
const apiKey = "sk-proj-xxxxx" // Hardcoded secret
|
||||||
const dbPassword = "password123" // In source code
|
const dbPassword = "password123" // In source code
|
||||||
```
|
```
|
||||||
|
|
||||||
#### ✅ ALWAYS Do This
|
#### PASS: ALWAYS Do This
|
||||||
```typescript
|
```typescript
|
||||||
const apiKey = process.env.OPENAI_API_KEY
|
const apiKey = process.env.OPENAI_API_KEY
|
||||||
const dbUrl = process.env.DATABASE_URL
|
const dbUrl = process.env.DATABASE_URL
|
||||||
@@ -108,14 +108,14 @@ function validateFileUpload(file: File) {
|
|||||||
|
|
||||||
### 3. SQL Injection Prevention
|
### 3. SQL Injection Prevention
|
||||||
|
|
||||||
#### ❌ NEVER Concatenate SQL
|
#### FAIL: NEVER Concatenate SQL
|
||||||
```typescript
|
```typescript
|
||||||
// DANGEROUS - SQL Injection vulnerability
|
// DANGEROUS - SQL Injection vulnerability
|
||||||
const query = `SELECT * FROM users WHERE email = '${userEmail}'`
|
const query = `SELECT * FROM users WHERE email = '${userEmail}'`
|
||||||
await db.query(query)
|
await db.query(query)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### ✅ ALWAYS Use Parameterized Queries
|
#### PASS: ALWAYS Use Parameterized Queries
|
||||||
```typescript
|
```typescript
|
||||||
// Safe - parameterized query
|
// Safe - parameterized query
|
||||||
const { data } = await supabase
|
const { data } = await supabase
|
||||||
@@ -140,10 +140,10 @@ await db.query(
|
|||||||
|
|
||||||
#### JWT Token Handling
|
#### JWT Token Handling
|
||||||
```typescript
|
```typescript
|
||||||
// ❌ WRONG: localStorage (vulnerable to XSS)
|
// FAIL: WRONG: localStorage (vulnerable to XSS)
|
||||||
localStorage.setItem('token', token)
|
localStorage.setItem('token', token)
|
||||||
|
|
||||||
// ✅ CORRECT: httpOnly cookies
|
// PASS: CORRECT: httpOnly cookies
|
||||||
res.setHeader('Set-Cookie',
|
res.setHeader('Set-Cookie',
|
||||||
`token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`)
|
`token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`)
|
||||||
```
|
```
|
||||||
@@ -300,18 +300,18 @@ app.use('/api/search', searchLimiter)
|
|||||||
|
|
||||||
#### Logging
|
#### Logging
|
||||||
```typescript
|
```typescript
|
||||||
// ❌ WRONG: Logging sensitive data
|
// FAIL: WRONG: Logging sensitive data
|
||||||
console.log('User login:', { email, password })
|
console.log('User login:', { email, password })
|
||||||
console.log('Payment:', { cardNumber, cvv })
|
console.log('Payment:', { cardNumber, cvv })
|
||||||
|
|
||||||
// ✅ CORRECT: Redact sensitive data
|
// PASS: CORRECT: Redact sensitive data
|
||||||
console.log('User login:', { email, userId })
|
console.log('User login:', { email, userId })
|
||||||
console.log('Payment:', { last4: card.last4, userId })
|
console.log('Payment:', { last4: card.last4, userId })
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Error Messages
|
#### Error Messages
|
||||||
```typescript
|
```typescript
|
||||||
// ❌ WRONG: Exposing internal details
|
// FAIL: WRONG: Exposing internal details
|
||||||
catch (error) {
|
catch (error) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: error.message, stack: error.stack },
|
{ error: error.message, stack: error.stack },
|
||||||
@@ -319,7 +319,7 @@ catch (error) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ CORRECT: Generic error messages
|
// PASS: CORRECT: Generic error messages
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.error('Internal error:', error)
|
console.error('Internal error:', error)
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
|
|||||||
@@ -314,39 +314,39 @@ npm run test:coverage
|
|||||||
|
|
||||||
## Common Testing Mistakes to Avoid
|
## Common Testing Mistakes to Avoid
|
||||||
|
|
||||||
### ❌ WRONG: Testing Implementation Details
|
### FAIL: WRONG: Testing Implementation Details
|
||||||
```typescript
|
```typescript
|
||||||
// Don't test internal state
|
// Don't test internal state
|
||||||
expect(component.state.count).toBe(5)
|
expect(component.state.count).toBe(5)
|
||||||
```
|
```
|
||||||
|
|
||||||
### ✅ CORRECT: Test User-Visible Behavior
|
### PASS: CORRECT: Test User-Visible Behavior
|
||||||
```typescript
|
```typescript
|
||||||
// Test what users see
|
// Test what users see
|
||||||
expect(screen.getByText('Count: 5')).toBeInTheDocument()
|
expect(screen.getByText('Count: 5')).toBeInTheDocument()
|
||||||
```
|
```
|
||||||
|
|
||||||
### ❌ WRONG: Brittle Selectors
|
### FAIL: WRONG: Brittle Selectors
|
||||||
```typescript
|
```typescript
|
||||||
// Breaks easily
|
// Breaks easily
|
||||||
await page.click('.css-class-xyz')
|
await page.click('.css-class-xyz')
|
||||||
```
|
```
|
||||||
|
|
||||||
### ✅ CORRECT: Semantic Selectors
|
### PASS: CORRECT: Semantic Selectors
|
||||||
```typescript
|
```typescript
|
||||||
// Resilient to changes
|
// Resilient to changes
|
||||||
await page.click('button:has-text("Submit")')
|
await page.click('button:has-text("Submit")')
|
||||||
await page.click('[data-testid="submit-button"]')
|
await page.click('[data-testid="submit-button"]')
|
||||||
```
|
```
|
||||||
|
|
||||||
### ❌ WRONG: No Test Isolation
|
### FAIL: WRONG: No Test Isolation
|
||||||
```typescript
|
```typescript
|
||||||
// Tests depend on each other
|
// Tests depend on each other
|
||||||
test('creates user', () => { /* ... */ })
|
test('creates user', () => { /* ... */ })
|
||||||
test('updates same user', () => { /* depends on previous test */ })
|
test('updates same user', () => { /* depends on previous test */ })
|
||||||
```
|
```
|
||||||
|
|
||||||
### ✅ CORRECT: Independent Tests
|
### PASS: CORRECT: Independent Tests
|
||||||
```typescript
|
```typescript
|
||||||
// Each test sets up its own data
|
// Each test sets up its own data
|
||||||
test('creates user', () => {
|
test('creates user', () => {
|
||||||
|
|||||||
308
.agents/skills/video-editing/SKILL.md
Normal file
308
.agents/skills/video-editing/SKILL.md
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
---
|
||||||
|
name: video-editing
|
||||||
|
description: AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Video Editing
|
||||||
|
|
||||||
|
AI-assisted editing for real footage. Not generation from prompts. Editing existing video fast.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- User wants to edit, cut, or structure video footage
|
||||||
|
- Turning long recordings into short-form content
|
||||||
|
- Building vlogs, tutorials, or demo videos from raw capture
|
||||||
|
- Adding overlays, subtitles, music, or voiceover to existing video
|
||||||
|
- Reframing video for different platforms (YouTube, TikTok, Instagram)
|
||||||
|
- User says "edit video", "cut this footage", "make a vlog", or "video workflow"
|
||||||
|
|
||||||
|
## Core Thesis
|
||||||
|
|
||||||
|
AI video editing is useful when you stop asking it to create the whole video and start using it to compress, structure, and augment real footage. The value is not generation. The value is compression.
|
||||||
|
|
||||||
|
## The Pipeline
|
||||||
|
|
||||||
|
```
|
||||||
|
Screen Studio / raw footage
|
||||||
|
→ Claude / Codex
|
||||||
|
→ FFmpeg
|
||||||
|
→ Remotion
|
||||||
|
→ ElevenLabs / fal.ai
|
||||||
|
→ Descript or CapCut
|
||||||
|
```
|
||||||
|
|
||||||
|
Each layer has a specific job. Do not skip layers. Do not try to make one tool do everything.
|
||||||
|
|
||||||
|
## Layer 1: Capture (Screen Studio / Raw Footage)
|
||||||
|
|
||||||
|
Collect the source material:
|
||||||
|
- **Screen Studio**: polished screen recordings for app demos, coding sessions, browser workflows
|
||||||
|
- **Raw camera footage**: vlog footage, interviews, event recordings
|
||||||
|
- **Desktop capture via VideoDB**: session recording with real-time context (see `videodb` skill)
|
||||||
|
|
||||||
|
Output: raw files ready for organization.
|
||||||
|
|
||||||
|
## Layer 2: Organization (Claude / Codex)
|
||||||
|
|
||||||
|
Use Claude Code or Codex to:
|
||||||
|
- **Transcribe and label**: generate transcript, identify topics and themes
|
||||||
|
- **Plan structure**: decide what stays, what gets cut, what order works
|
||||||
|
- **Identify dead sections**: find pauses, tangents, repeated takes
|
||||||
|
- **Generate edit decision list**: timestamps for cuts, segments to keep
|
||||||
|
- **Scaffold FFmpeg and Remotion code**: generate the commands and compositions
|
||||||
|
|
||||||
|
```
|
||||||
|
Example prompt:
|
||||||
|
"Here's the transcript of a 4-hour recording. Identify the 8 strongest segments
|
||||||
|
for a 24-minute vlog. Give me FFmpeg cut commands for each segment."
|
||||||
|
```
|
||||||
|
|
||||||
|
This layer is about structure, not final creative taste.
|
||||||
|
|
||||||
|
## Layer 3: Deterministic Cuts (FFmpeg)
|
||||||
|
|
||||||
|
FFmpeg handles the boring but critical work: splitting, trimming, concatenating, and preprocessing.
|
||||||
|
|
||||||
|
### Extract segment by timestamp
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ffmpeg -i raw.mp4 -ss 00:12:30 -to 00:15:45 -c copy segment_01.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
### Batch cut from edit decision list
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# cuts.txt: start,end,label
|
||||||
|
while IFS=, read -r start end label; do
|
||||||
|
ffmpeg -i raw.mp4 -ss "$start" -to "$end" -c copy "segments/${label}.mp4"
|
||||||
|
done < cuts.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### Concatenate segments
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create file list
|
||||||
|
for f in segments/*.mp4; do echo "file '$f'"; done > concat.txt
|
||||||
|
ffmpeg -f concat -safe 0 -i concat.txt -c copy assembled.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create proxy for faster editing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ffmpeg -i raw.mp4 -vf "scale=960:-2" -c:v libx264 -preset ultrafast -crf 28 proxy.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
### Extract audio for transcription
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ffmpeg -i raw.mp4 -vn -acodec pcm_s16le -ar 16000 audio.wav
|
||||||
|
```
|
||||||
|
|
||||||
|
### Normalize audio levels
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ffmpeg -i segment.mp4 -af loudnorm=I=-16:TP=-1.5:LRA=11 -c:v copy normalized.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
## Layer 4: Programmable Composition (Remotion)
|
||||||
|
|
||||||
|
Remotion turns editing problems into composable code. Use it for things that traditional editors make painful:
|
||||||
|
|
||||||
|
### When to use Remotion
|
||||||
|
|
||||||
|
- Overlays: text, images, branding, lower thirds
|
||||||
|
- Data visualizations: charts, stats, animated numbers
|
||||||
|
- Motion graphics: transitions, explainer animations
|
||||||
|
- Composable scenes: reusable templates across videos
|
||||||
|
- Product demos: annotated screenshots, UI highlights
|
||||||
|
|
||||||
|
### Basic Remotion composition
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { AbsoluteFill, Sequence, Video, useCurrentFrame } from "remotion";
|
||||||
|
|
||||||
|
export const VlogComposition: React.FC = () => {
|
||||||
|
const frame = useCurrentFrame();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AbsoluteFill>
|
||||||
|
{/* Main footage */}
|
||||||
|
<Sequence from={0} durationInFrames={300}>
|
||||||
|
<Video src="/segments/intro.mp4" />
|
||||||
|
</Sequence>
|
||||||
|
|
||||||
|
{/* Title overlay */}
|
||||||
|
<Sequence from={30} durationInFrames={90}>
|
||||||
|
<AbsoluteFill style={{
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
}}>
|
||||||
|
<h1 style={{
|
||||||
|
fontSize: 72,
|
||||||
|
color: "white",
|
||||||
|
textShadow: "2px 2px 8px rgba(0,0,0,0.8)",
|
||||||
|
}}>
|
||||||
|
The AI Editing Stack
|
||||||
|
</h1>
|
||||||
|
</AbsoluteFill>
|
||||||
|
</Sequence>
|
||||||
|
|
||||||
|
{/* Next segment */}
|
||||||
|
<Sequence from={300} durationInFrames={450}>
|
||||||
|
<Video src="/segments/demo.mp4" />
|
||||||
|
</Sequence>
|
||||||
|
</AbsoluteFill>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Render output
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx remotion render src/index.ts VlogComposition output.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [Remotion docs](https://www.remotion.dev/docs) for detailed patterns and API reference.
|
||||||
|
|
||||||
|
## Layer 5: Generated Assets (ElevenLabs / fal.ai)
|
||||||
|
|
||||||
|
Generate only what you need. Do not generate the whole video.
|
||||||
|
|
||||||
|
### Voiceover with ElevenLabs
|
||||||
|
|
||||||
|
```python
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
|
||||||
|
resp = requests.post(
|
||||||
|
f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
|
||||||
|
headers={
|
||||||
|
"xi-api-key": os.environ["ELEVENLABS_API_KEY"],
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
json={
|
||||||
|
"text": "Your narration text here",
|
||||||
|
"model_id": "eleven_turbo_v2_5",
|
||||||
|
"voice_settings": {"stability": 0.5, "similarity_boost": 0.75}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
with open("voiceover.mp3", "wb") as f:
|
||||||
|
f.write(resp.content)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Music and SFX with fal.ai
|
||||||
|
|
||||||
|
Use the `fal-ai-media` skill for:
|
||||||
|
- Background music generation
|
||||||
|
- Sound effects (ThinkSound model for video-to-audio)
|
||||||
|
- Transition sounds
|
||||||
|
|
||||||
|
### Generated visuals with fal.ai
|
||||||
|
|
||||||
|
Use for insert shots, thumbnails, or b-roll that doesn't exist:
|
||||||
|
```
|
||||||
|
generate(model_name: "fal-ai/nano-banana-pro", input: {
|
||||||
|
"prompt": "professional thumbnail for tech vlog, dark background, code on screen",
|
||||||
|
"image_size": "landscape_16_9"
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### VideoDB generative audio
|
||||||
|
|
||||||
|
If VideoDB is configured:
|
||||||
|
```python
|
||||||
|
voiceover = coll.generate_voice(text="Narration here", voice="alloy")
|
||||||
|
music = coll.generate_music(prompt="lo-fi background for coding vlog", duration=120)
|
||||||
|
sfx = coll.generate_sound_effect(prompt="subtle whoosh transition")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Layer 6: Final Polish (Descript / CapCut)
|
||||||
|
|
||||||
|
The last layer is human. Use a traditional editor for:
|
||||||
|
- **Pacing**: adjust cuts that feel too fast or slow
|
||||||
|
- **Captions**: auto-generated, then manually cleaned
|
||||||
|
- **Color grading**: basic correction and mood
|
||||||
|
- **Final audio mix**: balance voice, music, and SFX levels
|
||||||
|
- **Export**: platform-specific formats and quality settings
|
||||||
|
|
||||||
|
This is where taste lives. AI clears the repetitive work. You make the final calls.
|
||||||
|
|
||||||
|
## Social Media Reframing
|
||||||
|
|
||||||
|
Different platforms need different aspect ratios:
|
||||||
|
|
||||||
|
| Platform | Aspect Ratio | Resolution |
|
||||||
|
|----------|-------------|------------|
|
||||||
|
| YouTube | 16:9 | 1920x1080 |
|
||||||
|
| TikTok / Reels | 9:16 | 1080x1920 |
|
||||||
|
| Instagram Feed | 1:1 | 1080x1080 |
|
||||||
|
| X / Twitter | 16:9 or 1:1 | 1280x720 or 720x720 |
|
||||||
|
|
||||||
|
### Reframe with FFmpeg
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 16:9 to 9:16 (center crop)
|
||||||
|
ffmpeg -i input.mp4 -vf "crop=ih*9/16:ih,scale=1080:1920" vertical.mp4
|
||||||
|
|
||||||
|
# 16:9 to 1:1 (center crop)
|
||||||
|
ffmpeg -i input.mp4 -vf "crop=ih:ih,scale=1080:1080" square.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reframe with VideoDB
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Smart reframe (AI-guided subject tracking)
|
||||||
|
reframed = video.reframe(start=0, end=60, target="vertical", mode=ReframeMode.smart)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Scene Detection and Auto-Cut
|
||||||
|
|
||||||
|
### FFmpeg scene detection
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Detect scene changes (threshold 0.3 = moderate sensitivity)
|
||||||
|
ffmpeg -i input.mp4 -vf "select='gt(scene,0.3)',showinfo" -vsync vfr -f null - 2>&1 | grep showinfo
|
||||||
|
```
|
||||||
|
|
||||||
|
### Silence detection for auto-cut
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Find silent segments (useful for cutting dead air)
|
||||||
|
ffmpeg -i input.mp4 -af silencedetect=noise=-30dB:d=2 -f null - 2>&1 | grep silence
|
||||||
|
```
|
||||||
|
|
||||||
|
### Highlight extraction
|
||||||
|
|
||||||
|
Use Claude to analyze transcript + scene timestamps:
|
||||||
|
```
|
||||||
|
"Given this transcript with timestamps and these scene change points,
|
||||||
|
identify the 5 most engaging 30-second clips for social media."
|
||||||
|
```
|
||||||
|
|
||||||
|
## What Each Tool Does Best
|
||||||
|
|
||||||
|
| Tool | Strength | Weakness |
|
||||||
|
|------|----------|----------|
|
||||||
|
| Claude / Codex | Organization, planning, code generation | Not the creative taste layer |
|
||||||
|
| FFmpeg | Deterministic cuts, batch processing, format conversion | No visual editing UI |
|
||||||
|
| Remotion | Programmable overlays, composable scenes, reusable templates | Learning curve for non-devs |
|
||||||
|
| Screen Studio | Polished screen recordings immediately | Only screen capture |
|
||||||
|
| ElevenLabs | Voice, narration, music, SFX | Not the center of the workflow |
|
||||||
|
| Descript / CapCut | Final pacing, captions, polish | Manual, not automatable |
|
||||||
|
|
||||||
|
## Key Principles
|
||||||
|
|
||||||
|
1. **Edit, don't generate.** This workflow is for cutting real footage, not creating from prompts.
|
||||||
|
2. **Structure before style.** Get the story right in Layer 2 before touching anything visual.
|
||||||
|
3. **FFmpeg is the backbone.** Boring but critical. Where long footage becomes manageable.
|
||||||
|
4. **Remotion for repeatability.** If you'll do it more than once, make it a Remotion component.
|
||||||
|
5. **Generate selectively.** Only use AI generation for assets that don't exist, not for everything.
|
||||||
|
6. **Taste is the last layer.** AI clears repetitive work. You make the final creative calls.
|
||||||
|
|
||||||
|
## Related Skills
|
||||||
|
|
||||||
|
- `fal-ai-media` — AI image, video, and audio generation
|
||||||
|
- `videodb` — Server-side video processing, indexing, and streaming
|
||||||
|
- `content-engine` — Platform-native content distribution
|
||||||
7
.agents/skills/video-editing/agents/openai.yaml
Normal file
7
.agents/skills/video-editing/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Video Editing"
|
||||||
|
short_description: "AI-assisted video editing for real footage"
|
||||||
|
brand_color: "#EF4444"
|
||||||
|
default_prompt: "Edit video using AI-assisted pipeline: organize, cut, compose, generate assets, polish"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
214
.agents/skills/x-api/SKILL.md
Normal file
214
.agents/skills/x-api/SKILL.md
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
---
|
||||||
|
name: x-api
|
||||||
|
description: X/Twitter API integration for posting tweets, threads, reading timelines, search, and analytics. Covers OAuth auth patterns, rate limits, and platform-native content posting. Use when the user wants to interact with X programmatically.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# X API
|
||||||
|
|
||||||
|
Programmatic interaction with X (Twitter) for posting, reading, searching, and analytics.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- User wants to post tweets or threads programmatically
|
||||||
|
- Reading timeline, mentions, or user data from X
|
||||||
|
- Searching X for content, trends, or conversations
|
||||||
|
- Building X integrations or bots
|
||||||
|
- Analytics and engagement tracking
|
||||||
|
- User says "post to X", "tweet", "X API", or "Twitter API"
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
### OAuth 2.0 (App-Only / User Context)
|
||||||
|
|
||||||
|
Best for: read-heavy operations, search, public data.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Environment setup
|
||||||
|
export X_BEARER_TOKEN="your-bearer-token"
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
|
||||||
|
bearer = os.environ["X_BEARER_TOKEN"]
|
||||||
|
headers = {"Authorization": f"Bearer {bearer}"}
|
||||||
|
|
||||||
|
# Search recent tweets
|
||||||
|
resp = requests.get(
|
||||||
|
"https://api.x.com/2/tweets/search/recent",
|
||||||
|
headers=headers,
|
||||||
|
params={"query": "claude code", "max_results": 10}
|
||||||
|
)
|
||||||
|
tweets = resp.json()
|
||||||
|
```
|
||||||
|
|
||||||
|
### OAuth 1.0a (User Context)
|
||||||
|
|
||||||
|
Required for: posting tweets, managing account, DMs.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Environment setup — source before use
|
||||||
|
export X_API_KEY="your-api-key"
|
||||||
|
export X_API_SECRET="your-api-secret"
|
||||||
|
export X_ACCESS_TOKEN="your-access-token"
|
||||||
|
export X_ACCESS_SECRET="your-access-secret"
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
import os
|
||||||
|
from requests_oauthlib import OAuth1Session
|
||||||
|
|
||||||
|
oauth = OAuth1Session(
|
||||||
|
os.environ["X_API_KEY"],
|
||||||
|
client_secret=os.environ["X_API_SECRET"],
|
||||||
|
resource_owner_key=os.environ["X_ACCESS_TOKEN"],
|
||||||
|
resource_owner_secret=os.environ["X_ACCESS_SECRET"],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Core Operations
|
||||||
|
|
||||||
|
### Post a Tweet
|
||||||
|
|
||||||
|
```python
|
||||||
|
resp = oauth.post(
|
||||||
|
"https://api.x.com/2/tweets",
|
||||||
|
json={"text": "Hello from Claude Code"}
|
||||||
|
)
|
||||||
|
resp.raise_for_status()
|
||||||
|
tweet_id = resp.json()["data"]["id"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Post a Thread
|
||||||
|
|
||||||
|
```python
|
||||||
|
def post_thread(oauth, tweets: list[str]) -> list[str]:
|
||||||
|
ids = []
|
||||||
|
reply_to = None
|
||||||
|
for text in tweets:
|
||||||
|
payload = {"text": text}
|
||||||
|
if reply_to:
|
||||||
|
payload["reply"] = {"in_reply_to_tweet_id": reply_to}
|
||||||
|
resp = oauth.post("https://api.x.com/2/tweets", json=payload)
|
||||||
|
resp.raise_for_status()
|
||||||
|
tweet_id = resp.json()["data"]["id"]
|
||||||
|
ids.append(tweet_id)
|
||||||
|
reply_to = tweet_id
|
||||||
|
return ids
|
||||||
|
```
|
||||||
|
|
||||||
|
### Read User Timeline
|
||||||
|
|
||||||
|
```python
|
||||||
|
resp = requests.get(
|
||||||
|
f"https://api.x.com/2/users/{user_id}/tweets",
|
||||||
|
headers=headers,
|
||||||
|
params={
|
||||||
|
"max_results": 10,
|
||||||
|
"tweet.fields": "created_at,public_metrics",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Search Tweets
|
||||||
|
|
||||||
|
```python
|
||||||
|
resp = requests.get(
|
||||||
|
"https://api.x.com/2/tweets/search/recent",
|
||||||
|
headers=headers,
|
||||||
|
params={
|
||||||
|
"query": "from:affaanmustafa -is:retweet",
|
||||||
|
"max_results": 10,
|
||||||
|
"tweet.fields": "public_metrics,created_at",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Get User by Username
|
||||||
|
|
||||||
|
```python
|
||||||
|
resp = requests.get(
|
||||||
|
"https://api.x.com/2/users/by/username/affaanmustafa",
|
||||||
|
headers=headers,
|
||||||
|
params={"user.fields": "public_metrics,description,created_at"}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Upload Media and Post
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Media upload uses v1.1 endpoint
|
||||||
|
|
||||||
|
# Step 1: Upload media
|
||||||
|
media_resp = oauth.post(
|
||||||
|
"https://upload.twitter.com/1.1/media/upload.json",
|
||||||
|
files={"media": open("image.png", "rb")}
|
||||||
|
)
|
||||||
|
media_id = media_resp.json()["media_id_string"]
|
||||||
|
|
||||||
|
# Step 2: Post with media
|
||||||
|
resp = oauth.post(
|
||||||
|
"https://api.x.com/2/tweets",
|
||||||
|
json={"text": "Check this out", "media": {"media_ids": [media_id]}}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Rate Limits Reference
|
||||||
|
|
||||||
|
| Endpoint | Limit | Window |
|
||||||
|
|----------|-------|--------|
|
||||||
|
| POST /2/tweets | 200 | 15 min |
|
||||||
|
| GET /2/tweets/search/recent | 450 | 15 min |
|
||||||
|
| GET /2/users/:id/tweets | 1500 | 15 min |
|
||||||
|
| GET /2/users/by/username | 300 | 15 min |
|
||||||
|
| POST media/upload | 415 | 15 min |
|
||||||
|
|
||||||
|
Always check `x-rate-limit-remaining` and `x-rate-limit-reset` headers.
|
||||||
|
|
||||||
|
```python
|
||||||
|
import time
|
||||||
|
|
||||||
|
remaining = int(resp.headers.get("x-rate-limit-remaining", 0))
|
||||||
|
if remaining < 5:
|
||||||
|
reset = int(resp.headers.get("x-rate-limit-reset", 0))
|
||||||
|
wait = max(0, reset - int(time.time()))
|
||||||
|
print(f"Rate limit approaching. Resets in {wait}s")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
```python
|
||||||
|
resp = oauth.post("https://api.x.com/2/tweets", json={"text": content})
|
||||||
|
if resp.status_code == 201:
|
||||||
|
return resp.json()["data"]["id"]
|
||||||
|
elif resp.status_code == 429:
|
||||||
|
reset = int(resp.headers["x-rate-limit-reset"])
|
||||||
|
raise Exception(f"Rate limited. Resets at {reset}")
|
||||||
|
elif resp.status_code == 403:
|
||||||
|
raise Exception(f"Forbidden: {resp.json().get('detail', 'check permissions')}")
|
||||||
|
else:
|
||||||
|
raise Exception(f"X API error {resp.status_code}: {resp.text}")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
- **Never hardcode tokens.** Use environment variables or `.env` files.
|
||||||
|
- **Never commit `.env` files.** Add to `.gitignore`.
|
||||||
|
- **Rotate tokens** if exposed. Regenerate at developer.x.com.
|
||||||
|
- **Use read-only tokens** when write access is not needed.
|
||||||
|
- **Store OAuth secrets securely** — not in source code or logs.
|
||||||
|
|
||||||
|
## Integration with Content Engine
|
||||||
|
|
||||||
|
Use `content-engine` skill to generate platform-native content, then post via X API:
|
||||||
|
1. Generate content with content-engine (X platform format)
|
||||||
|
2. Validate length (280 chars for single tweet)
|
||||||
|
3. Post via X API using patterns above
|
||||||
|
4. Track engagement via public_metrics
|
||||||
|
|
||||||
|
## Related Skills
|
||||||
|
|
||||||
|
- `content-engine` — Generate platform-native content for X
|
||||||
|
- `crosspost` — Distribute content across X, LinkedIn, and other platforms
|
||||||
7
.agents/skills/x-api/agents/openai.yaml
Normal file
7
.agents/skills/x-api/agents/openai.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "X API"
|
||||||
|
short_description: "X/Twitter API integration for posting, threads, and analytics"
|
||||||
|
brand_color: "#000000"
|
||||||
|
default_prompt: "Use X API to post tweets, threads, or retrieve timeline and search data"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: true
|
||||||
@@ -120,7 +120,7 @@ Assume the validator is hostile and literal.
|
|||||||
|
|
||||||
## The `hooks` Field: DO NOT ADD
|
## The `hooks` Field: DO NOT ADD
|
||||||
|
|
||||||
> ⚠️ **CRITICAL:** Do NOT add a `"hooks"` field to `plugin.json`. This is enforced by a regression test.
|
> WARNING: **CRITICAL:** Do NOT add a `"hooks"` field to `plugin.json`. This is enforced by a regression test.
|
||||||
|
|
||||||
### Why This Matters
|
### Why This Matters
|
||||||
|
|
||||||
|
|||||||
@@ -3,3 +3,15 @@
|
|||||||
If you plan to edit `.claude-plugin/plugin.json`, be aware that the Claude plugin validator enforces several **undocumented but strict constraints** that can cause installs to fail with vague errors (for example, `agents: Invalid input`). In particular, component fields must be arrays, `agents` must use explicit file paths rather than directories, and a `version` field is required for reliable validation and installation.
|
If you plan to edit `.claude-plugin/plugin.json`, be aware that the Claude plugin validator enforces several **undocumented but strict constraints** that can cause installs to fail with vague errors (for example, `agents: Invalid input`). In particular, component fields must be arrays, `agents` must use explicit file paths rather than directories, and a `version` field is required for reliable validation and installation.
|
||||||
|
|
||||||
These constraints are not obvious from public examples and have caused repeated installation failures in the past. They are documented in detail in `.claude-plugin/PLUGIN_SCHEMA_NOTES.md`, which should be reviewed before making any changes to the plugin manifest.
|
These constraints are not obvious from public examples and have caused repeated installation failures in the past. They are documented in detail in `.claude-plugin/PLUGIN_SCHEMA_NOTES.md`, which should be reviewed before making any changes to the plugin manifest.
|
||||||
|
|
||||||
|
### Custom Endpoints and Gateways
|
||||||
|
|
||||||
|
ECC does not override Claude Code transport settings. If Claude Code is configured to run through an official LLM gateway or a compatible custom endpoint, the plugin continues to work because hooks, skills, and any retained legacy command shims execute locally after the CLI starts successfully.
|
||||||
|
|
||||||
|
Use Claude Code's own environment/configuration for transport selection, for example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export ANTHROPIC_BASE_URL=https://your-gateway.example.com
|
||||||
|
export ANTHROPIC_AUTH_TOKEN=your-token
|
||||||
|
claude
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
{
|
{
|
||||||
|
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
||||||
"name": "everything-claude-code",
|
"name": "everything-claude-code",
|
||||||
|
"description": "Battle-tested Claude Code configurations from an Anthropic hackathon winner — agents, skills, hooks, rules, and legacy command shims evolved over 10+ months of intensive daily use",
|
||||||
"owner": {
|
"owner": {
|
||||||
"name": "Affaan Mustafa",
|
"name": "Affaan Mustafa",
|
||||||
"email": "affaan@example.com"
|
"email": "me@affaanmustafa.com"
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"description": "Battle-tested Claude Code configurations from an Anthropic hackathon winner"
|
"description": "Battle-tested Claude Code configurations from an Anthropic hackathon winner"
|
||||||
@@ -11,9 +13,11 @@
|
|||||||
{
|
{
|
||||||
"name": "everything-claude-code",
|
"name": "everything-claude-code",
|
||||||
"source": "./",
|
"source": "./",
|
||||||
"description": "Complete collection of agents, skills, hooks, commands, and rules evolved over 10+ months of intensive daily use",
|
"description": "The most comprehensive Claude Code plugin — 36 agents, 142 skills, 68 legacy command shims, and production-ready hooks for TDD, security scanning, code review, and continuous learning",
|
||||||
|
"version": "1.9.0",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Affaan Mustafa"
|
"name": "Affaan Mustafa",
|
||||||
|
"email": "me@affaanmustafa.com"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/affaan-m/everything-claude-code",
|
"homepage": "https://github.com/affaan-m/everything-claude-code",
|
||||||
"repository": "https://github.com/affaan-m/everything-claude-code",
|
"repository": "https://github.com/affaan-m/everything-claude-code",
|
||||||
@@ -38,7 +42,8 @@
|
|||||||
"code-review",
|
"code-review",
|
||||||
"security",
|
"security",
|
||||||
"best-practices"
|
"best-practices"
|
||||||
]
|
],
|
||||||
|
"strict": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "everything-claude-code",
|
"name": "everything-claude-code",
|
||||||
"version": "1.4.1",
|
"version": "1.9.0",
|
||||||
"description": "Complete collection of battle-tested Claude Code configs from an Anthropic hackathon winner - agents, skills, hooks, and rules evolved over 10+ months of intensive daily use",
|
"description": "Complete collection of battle-tested Claude Code configs from an Anthropic hackathon winner - agents, skills, hooks, rules, and legacy command shims evolved over 10+ months of intensive daily use",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Affaan Mustafa",
|
"name": "Affaan Mustafa",
|
||||||
"url": "https://x.com/affaanmustafa"
|
"url": "https://x.com/affaanmustafa"
|
||||||
@@ -22,20 +22,36 @@
|
|||||||
"automation",
|
"automation",
|
||||||
"best-practices"
|
"best-practices"
|
||||||
],
|
],
|
||||||
"skills": ["./skills/", "./commands/"],
|
|
||||||
"agents": [
|
"agents": [
|
||||||
"./agents/architect.md",
|
"./agents/architect.md",
|
||||||
"./agents/build-error-resolver.md",
|
"./agents/build-error-resolver.md",
|
||||||
|
"./agents/chief-of-staff.md",
|
||||||
"./agents/code-reviewer.md",
|
"./agents/code-reviewer.md",
|
||||||
|
"./agents/cpp-build-resolver.md",
|
||||||
|
"./agents/cpp-reviewer.md",
|
||||||
"./agents/database-reviewer.md",
|
"./agents/database-reviewer.md",
|
||||||
"./agents/doc-updater.md",
|
"./agents/doc-updater.md",
|
||||||
|
"./agents/docs-lookup.md",
|
||||||
"./agents/e2e-runner.md",
|
"./agents/e2e-runner.md",
|
||||||
|
"./agents/flutter-reviewer.md",
|
||||||
"./agents/go-build-resolver.md",
|
"./agents/go-build-resolver.md",
|
||||||
"./agents/go-reviewer.md",
|
"./agents/go-reviewer.md",
|
||||||
|
"./agents/harness-optimizer.md",
|
||||||
|
"./agents/java-build-resolver.md",
|
||||||
|
"./agents/java-reviewer.md",
|
||||||
|
"./agents/kotlin-build-resolver.md",
|
||||||
|
"./agents/kotlin-reviewer.md",
|
||||||
|
"./agents/loop-operator.md",
|
||||||
"./agents/planner.md",
|
"./agents/planner.md",
|
||||||
"./agents/python-reviewer.md",
|
"./agents/python-reviewer.md",
|
||||||
|
"./agents/pytorch-build-resolver.md",
|
||||||
"./agents/refactor-cleaner.md",
|
"./agents/refactor-cleaner.md",
|
||||||
|
"./agents/rust-build-resolver.md",
|
||||||
|
"./agents/rust-reviewer.md",
|
||||||
"./agents/security-reviewer.md",
|
"./agents/security-reviewer.md",
|
||||||
"./agents/tdd-guide.md"
|
"./agents/tdd-guide.md",
|
||||||
]
|
"./agents/typescript-reviewer.md"
|
||||||
|
],
|
||||||
|
"skills": ["./skills/"],
|
||||||
|
"commands": ["./commands/"]
|
||||||
}
|
}
|
||||||
|
|||||||
39
.claude/commands/add-language-rules.md
Normal file
39
.claude/commands/add-language-rules.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
name: add-language-rules
|
||||||
|
description: Workflow command scaffold for add-language-rules in everything-claude-code.
|
||||||
|
allowed_tools: ["Bash", "Read", "Write", "Grep", "Glob"]
|
||||||
|
---
|
||||||
|
|
||||||
|
# /add-language-rules
|
||||||
|
|
||||||
|
Use this workflow when working on **add-language-rules** in `everything-claude-code`.
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Adds a new programming language to the rules system, including coding style, hooks, patterns, security, and testing guidelines.
|
||||||
|
|
||||||
|
## Common Files
|
||||||
|
|
||||||
|
- `rules/*/coding-style.md`
|
||||||
|
- `rules/*/hooks.md`
|
||||||
|
- `rules/*/patterns.md`
|
||||||
|
- `rules/*/security.md`
|
||||||
|
- `rules/*/testing.md`
|
||||||
|
|
||||||
|
## Suggested Sequence
|
||||||
|
|
||||||
|
1. Understand the current state and failure mode before editing.
|
||||||
|
2. Make the smallest coherent change that satisfies the workflow goal.
|
||||||
|
3. Run the most relevant verification for touched files.
|
||||||
|
4. Summarize what changed and what still needs review.
|
||||||
|
|
||||||
|
## Typical Commit Signals
|
||||||
|
|
||||||
|
- Create a new directory under rules/{language}/
|
||||||
|
- Add coding-style.md, hooks.md, patterns.md, security.md, and testing.md files with language-specific content
|
||||||
|
- Optionally reference or link to related skills
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Treat this as a scaffold, not a hard-coded script.
|
||||||
|
- Update the command if the workflow evolves materially.
|
||||||
36
.claude/commands/database-migration.md
Normal file
36
.claude/commands/database-migration.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
name: database-migration
|
||||||
|
description: Workflow command scaffold for database-migration in everything-claude-code.
|
||||||
|
allowed_tools: ["Bash", "Read", "Write", "Grep", "Glob"]
|
||||||
|
---
|
||||||
|
|
||||||
|
# /database-migration
|
||||||
|
|
||||||
|
Use this workflow when working on **database-migration** in `everything-claude-code`.
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Database schema changes with migration files
|
||||||
|
|
||||||
|
## Common Files
|
||||||
|
|
||||||
|
- `**/schema.*`
|
||||||
|
- `migrations/*`
|
||||||
|
|
||||||
|
## Suggested Sequence
|
||||||
|
|
||||||
|
1. Understand the current state and failure mode before editing.
|
||||||
|
2. Make the smallest coherent change that satisfies the workflow goal.
|
||||||
|
3. Run the most relevant verification for touched files.
|
||||||
|
4. Summarize what changed and what still needs review.
|
||||||
|
|
||||||
|
## Typical Commit Signals
|
||||||
|
|
||||||
|
- Create migration file
|
||||||
|
- Update schema definitions
|
||||||
|
- Generate/update types
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Treat this as a scaffold, not a hard-coded script.
|
||||||
|
- Update the command if the workflow evolves materially.
|
||||||
38
.claude/commands/feature-development.md
Normal file
38
.claude/commands/feature-development.md
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: feature-development
|
||||||
|
description: Workflow command scaffold for feature-development in everything-claude-code.
|
||||||
|
allowed_tools: ["Bash", "Read", "Write", "Grep", "Glob"]
|
||||||
|
---
|
||||||
|
|
||||||
|
# /feature-development
|
||||||
|
|
||||||
|
Use this workflow when working on **feature-development** in `everything-claude-code`.
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Standard feature implementation workflow
|
||||||
|
|
||||||
|
## Common Files
|
||||||
|
|
||||||
|
- `manifests/*`
|
||||||
|
- `schemas/*`
|
||||||
|
- `**/*.test.*`
|
||||||
|
- `**/api/**`
|
||||||
|
|
||||||
|
## Suggested Sequence
|
||||||
|
|
||||||
|
1. Understand the current state and failure mode before editing.
|
||||||
|
2. Make the smallest coherent change that satisfies the workflow goal.
|
||||||
|
3. Run the most relevant verification for touched files.
|
||||||
|
4. Summarize what changed and what still needs review.
|
||||||
|
|
||||||
|
## Typical Commit Signals
|
||||||
|
|
||||||
|
- Add feature implementation
|
||||||
|
- Add tests for feature
|
||||||
|
- Update documentation
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Treat this as a scaffold, not a hard-coded script.
|
||||||
|
- Update the command if the workflow evolves materially.
|
||||||
334
.claude/ecc-tools.json
Normal file
334
.claude/ecc-tools.json
Normal file
@@ -0,0 +1,334 @@
|
|||||||
|
{
|
||||||
|
"version": "1.3",
|
||||||
|
"schemaVersion": "1.0",
|
||||||
|
"generatedBy": "ecc-tools",
|
||||||
|
"generatedAt": "2026-03-20T12:07:36.496Z",
|
||||||
|
"repo": "https://github.com/affaan-m/everything-claude-code",
|
||||||
|
"profiles": {
|
||||||
|
"requested": "full",
|
||||||
|
"recommended": "full",
|
||||||
|
"effective": "full",
|
||||||
|
"requestedAlias": "full",
|
||||||
|
"recommendedAlias": "full",
|
||||||
|
"effectiveAlias": "full"
|
||||||
|
},
|
||||||
|
"requestedProfile": "full",
|
||||||
|
"profile": "full",
|
||||||
|
"recommendedProfile": "full",
|
||||||
|
"effectiveProfile": "full",
|
||||||
|
"tier": "enterprise",
|
||||||
|
"requestedComponents": [
|
||||||
|
"repo-baseline",
|
||||||
|
"workflow-automation",
|
||||||
|
"security-audits",
|
||||||
|
"research-tooling",
|
||||||
|
"team-rollout",
|
||||||
|
"governance-controls"
|
||||||
|
],
|
||||||
|
"selectedComponents": [
|
||||||
|
"repo-baseline",
|
||||||
|
"workflow-automation",
|
||||||
|
"security-audits",
|
||||||
|
"research-tooling",
|
||||||
|
"team-rollout",
|
||||||
|
"governance-controls"
|
||||||
|
],
|
||||||
|
"requestedAddComponents": [],
|
||||||
|
"requestedRemoveComponents": [],
|
||||||
|
"blockedRemovalComponents": [],
|
||||||
|
"tierFilteredComponents": [],
|
||||||
|
"requestedRootPackages": [
|
||||||
|
"runtime-core",
|
||||||
|
"workflow-pack",
|
||||||
|
"agentshield-pack",
|
||||||
|
"research-pack",
|
||||||
|
"team-config-sync",
|
||||||
|
"enterprise-controls"
|
||||||
|
],
|
||||||
|
"selectedRootPackages": [
|
||||||
|
"runtime-core",
|
||||||
|
"workflow-pack",
|
||||||
|
"agentshield-pack",
|
||||||
|
"research-pack",
|
||||||
|
"team-config-sync",
|
||||||
|
"enterprise-controls"
|
||||||
|
],
|
||||||
|
"requestedPackages": [
|
||||||
|
"runtime-core",
|
||||||
|
"workflow-pack",
|
||||||
|
"agentshield-pack",
|
||||||
|
"research-pack",
|
||||||
|
"team-config-sync",
|
||||||
|
"enterprise-controls"
|
||||||
|
],
|
||||||
|
"requestedAddPackages": [],
|
||||||
|
"requestedRemovePackages": [],
|
||||||
|
"selectedPackages": [
|
||||||
|
"runtime-core",
|
||||||
|
"workflow-pack",
|
||||||
|
"agentshield-pack",
|
||||||
|
"research-pack",
|
||||||
|
"team-config-sync",
|
||||||
|
"enterprise-controls"
|
||||||
|
],
|
||||||
|
"packages": [
|
||||||
|
"runtime-core",
|
||||||
|
"workflow-pack",
|
||||||
|
"agentshield-pack",
|
||||||
|
"research-pack",
|
||||||
|
"team-config-sync",
|
||||||
|
"enterprise-controls"
|
||||||
|
],
|
||||||
|
"blockedRemovalPackages": [],
|
||||||
|
"tierFilteredRootPackages": [],
|
||||||
|
"tierFilteredPackages": [],
|
||||||
|
"conflictingPackages": [],
|
||||||
|
"dependencyGraph": {
|
||||||
|
"runtime-core": [],
|
||||||
|
"workflow-pack": [
|
||||||
|
"runtime-core"
|
||||||
|
],
|
||||||
|
"agentshield-pack": [
|
||||||
|
"workflow-pack"
|
||||||
|
],
|
||||||
|
"research-pack": [
|
||||||
|
"workflow-pack"
|
||||||
|
],
|
||||||
|
"team-config-sync": [
|
||||||
|
"runtime-core"
|
||||||
|
],
|
||||||
|
"enterprise-controls": [
|
||||||
|
"team-config-sync"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resolutionOrder": [
|
||||||
|
"runtime-core",
|
||||||
|
"workflow-pack",
|
||||||
|
"agentshield-pack",
|
||||||
|
"research-pack",
|
||||||
|
"team-config-sync",
|
||||||
|
"enterprise-controls"
|
||||||
|
],
|
||||||
|
"requestedModules": [
|
||||||
|
"runtime-core",
|
||||||
|
"workflow-pack",
|
||||||
|
"agentshield-pack",
|
||||||
|
"research-pack",
|
||||||
|
"team-config-sync",
|
||||||
|
"enterprise-controls"
|
||||||
|
],
|
||||||
|
"selectedModules": [
|
||||||
|
"runtime-core",
|
||||||
|
"workflow-pack",
|
||||||
|
"agentshield-pack",
|
||||||
|
"research-pack",
|
||||||
|
"team-config-sync",
|
||||||
|
"enterprise-controls"
|
||||||
|
],
|
||||||
|
"modules": [
|
||||||
|
"runtime-core",
|
||||||
|
"workflow-pack",
|
||||||
|
"agentshield-pack",
|
||||||
|
"research-pack",
|
||||||
|
"team-config-sync",
|
||||||
|
"enterprise-controls"
|
||||||
|
],
|
||||||
|
"managedFiles": [
|
||||||
|
".claude/skills/everything-claude-code/SKILL.md",
|
||||||
|
".agents/skills/everything-claude-code/SKILL.md",
|
||||||
|
".agents/skills/everything-claude-code/agents/openai.yaml",
|
||||||
|
".claude/identity.json",
|
||||||
|
".codex/config.toml",
|
||||||
|
".codex/AGENTS.md",
|
||||||
|
".codex/agents/explorer.toml",
|
||||||
|
".codex/agents/reviewer.toml",
|
||||||
|
".codex/agents/docs-researcher.toml",
|
||||||
|
".claude/homunculus/instincts/inherited/everything-claude-code-instincts.yaml",
|
||||||
|
".claude/rules/everything-claude-code-guardrails.md",
|
||||||
|
".claude/research/everything-claude-code-research-playbook.md",
|
||||||
|
".claude/team/everything-claude-code-team-config.json",
|
||||||
|
".claude/enterprise/controls.md",
|
||||||
|
".claude/commands/database-migration.md",
|
||||||
|
".claude/commands/feature-development.md",
|
||||||
|
".claude/commands/add-language-rules.md"
|
||||||
|
],
|
||||||
|
"packageFiles": {
|
||||||
|
"runtime-core": [
|
||||||
|
".claude/skills/everything-claude-code/SKILL.md",
|
||||||
|
".agents/skills/everything-claude-code/SKILL.md",
|
||||||
|
".agents/skills/everything-claude-code/agents/openai.yaml",
|
||||||
|
".claude/identity.json",
|
||||||
|
".codex/config.toml",
|
||||||
|
".codex/AGENTS.md",
|
||||||
|
".codex/agents/explorer.toml",
|
||||||
|
".codex/agents/reviewer.toml",
|
||||||
|
".codex/agents/docs-researcher.toml",
|
||||||
|
".claude/homunculus/instincts/inherited/everything-claude-code-instincts.yaml"
|
||||||
|
],
|
||||||
|
"agentshield-pack": [
|
||||||
|
".claude/rules/everything-claude-code-guardrails.md"
|
||||||
|
],
|
||||||
|
"research-pack": [
|
||||||
|
".claude/research/everything-claude-code-research-playbook.md"
|
||||||
|
],
|
||||||
|
"team-config-sync": [
|
||||||
|
".claude/team/everything-claude-code-team-config.json"
|
||||||
|
],
|
||||||
|
"enterprise-controls": [
|
||||||
|
".claude/enterprise/controls.md"
|
||||||
|
],
|
||||||
|
"workflow-pack": [
|
||||||
|
".claude/commands/database-migration.md",
|
||||||
|
".claude/commands/feature-development.md",
|
||||||
|
".claude/commands/add-language-rules.md"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"moduleFiles": {
|
||||||
|
"runtime-core": [
|
||||||
|
".claude/skills/everything-claude-code/SKILL.md",
|
||||||
|
".agents/skills/everything-claude-code/SKILL.md",
|
||||||
|
".agents/skills/everything-claude-code/agents/openai.yaml",
|
||||||
|
".claude/identity.json",
|
||||||
|
".codex/config.toml",
|
||||||
|
".codex/AGENTS.md",
|
||||||
|
".codex/agents/explorer.toml",
|
||||||
|
".codex/agents/reviewer.toml",
|
||||||
|
".codex/agents/docs-researcher.toml",
|
||||||
|
".claude/homunculus/instincts/inherited/everything-claude-code-instincts.yaml"
|
||||||
|
],
|
||||||
|
"agentshield-pack": [
|
||||||
|
".claude/rules/everything-claude-code-guardrails.md"
|
||||||
|
],
|
||||||
|
"research-pack": [
|
||||||
|
".claude/research/everything-claude-code-research-playbook.md"
|
||||||
|
],
|
||||||
|
"team-config-sync": [
|
||||||
|
".claude/team/everything-claude-code-team-config.json"
|
||||||
|
],
|
||||||
|
"enterprise-controls": [
|
||||||
|
".claude/enterprise/controls.md"
|
||||||
|
],
|
||||||
|
"workflow-pack": [
|
||||||
|
".claude/commands/database-migration.md",
|
||||||
|
".claude/commands/feature-development.md",
|
||||||
|
".claude/commands/add-language-rules.md"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"moduleId": "runtime-core",
|
||||||
|
"path": ".claude/skills/everything-claude-code/SKILL.md",
|
||||||
|
"description": "Repository-specific Claude Code skill generated from git history."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "runtime-core",
|
||||||
|
"path": ".agents/skills/everything-claude-code/SKILL.md",
|
||||||
|
"description": "Codex-facing copy of the generated repository skill."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "runtime-core",
|
||||||
|
"path": ".agents/skills/everything-claude-code/agents/openai.yaml",
|
||||||
|
"description": "Codex skill metadata so the repo skill appears cleanly in the skill interface."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "runtime-core",
|
||||||
|
"path": ".claude/identity.json",
|
||||||
|
"description": "Suggested identity.json baseline derived from repository conventions."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "runtime-core",
|
||||||
|
"path": ".codex/config.toml",
|
||||||
|
"description": "Repo-local Codex MCP and multi-agent baseline aligned with ECC defaults."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "runtime-core",
|
||||||
|
"path": ".codex/AGENTS.md",
|
||||||
|
"description": "Codex usage guide that points at the generated repo skill and workflow bundle."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "runtime-core",
|
||||||
|
"path": ".codex/agents/explorer.toml",
|
||||||
|
"description": "Read-only explorer role config for Codex multi-agent work."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "runtime-core",
|
||||||
|
"path": ".codex/agents/reviewer.toml",
|
||||||
|
"description": "Read-only reviewer role config focused on correctness and security."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "runtime-core",
|
||||||
|
"path": ".codex/agents/docs-researcher.toml",
|
||||||
|
"description": "Read-only docs researcher role config for API verification."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "runtime-core",
|
||||||
|
"path": ".claude/homunculus/instincts/inherited/everything-claude-code-instincts.yaml",
|
||||||
|
"description": "Continuous-learning instincts derived from repository patterns."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "agentshield-pack",
|
||||||
|
"path": ".claude/rules/everything-claude-code-guardrails.md",
|
||||||
|
"description": "Repository guardrails distilled from analysis for security and workflow review."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "research-pack",
|
||||||
|
"path": ".claude/research/everything-claude-code-research-playbook.md",
|
||||||
|
"description": "Research workflow playbook for source attribution and long-context tasks."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "team-config-sync",
|
||||||
|
"path": ".claude/team/everything-claude-code-team-config.json",
|
||||||
|
"description": "Team config scaffold that points collaborators at the shared ECC bundle."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "enterprise-controls",
|
||||||
|
"path": ".claude/enterprise/controls.md",
|
||||||
|
"description": "Enterprise governance scaffold for approvals, audit posture, and escalation."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "workflow-pack",
|
||||||
|
"path": ".claude/commands/database-migration.md",
|
||||||
|
"description": "Workflow command scaffold for database-migration."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "workflow-pack",
|
||||||
|
"path": ".claude/commands/feature-development.md",
|
||||||
|
"description": "Workflow command scaffold for feature-development."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleId": "workflow-pack",
|
||||||
|
"path": ".claude/commands/add-language-rules.md",
|
||||||
|
"description": "Workflow command scaffold for add-language-rules."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"workflows": [
|
||||||
|
{
|
||||||
|
"command": "database-migration",
|
||||||
|
"path": ".claude/commands/database-migration.md"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "feature-development",
|
||||||
|
"path": ".claude/commands/feature-development.md"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "add-language-rules",
|
||||||
|
"path": ".claude/commands/add-language-rules.md"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"adapters": {
|
||||||
|
"claudeCode": {
|
||||||
|
"skillPath": ".claude/skills/everything-claude-code/SKILL.md",
|
||||||
|
"identityPath": ".claude/identity.json",
|
||||||
|
"commandPaths": [
|
||||||
|
".claude/commands/database-migration.md",
|
||||||
|
".claude/commands/feature-development.md",
|
||||||
|
".claude/commands/add-language-rules.md"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"codex": {
|
||||||
|
"configPath": ".codex/config.toml",
|
||||||
|
"agentsGuidePath": ".codex/AGENTS.md",
|
||||||
|
"skillPath": ".agents/skills/everything-claude-code/SKILL.md"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
.claude/enterprise/controls.md
Normal file
15
.claude/enterprise/controls.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Enterprise Controls
|
||||||
|
|
||||||
|
This is a starter governance file for enterprise ECC deployments.
|
||||||
|
|
||||||
|
## Baseline
|
||||||
|
|
||||||
|
- Repository: https://github.com/affaan-m/everything-claude-code
|
||||||
|
- Recommended profile: full
|
||||||
|
- Keep install manifests, audit allowlists, and Codex baselines under review.
|
||||||
|
|
||||||
|
## Approval Expectations
|
||||||
|
|
||||||
|
- Security-sensitive workflow changes require explicit reviewer acknowledgement.
|
||||||
|
- Audit suppressions must include a reason and the narrowest viable matcher.
|
||||||
|
- Generated skills should be reviewed before broad rollout to teams.
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
# Curated instincts for affaan-m/everything-claude-code
|
||||||
|
# Import with: /instinct-import .claude/homunculus/instincts/inherited/everything-claude-code-instincts.yaml
|
||||||
|
|
||||||
|
---
|
||||||
|
id: everything-claude-code-conventional-commits
|
||||||
|
trigger: "when making a commit in everything-claude-code"
|
||||||
|
confidence: 0.9
|
||||||
|
domain: git
|
||||||
|
source: repo-curation
|
||||||
|
source_repo: affaan-m/everything-claude-code
|
||||||
|
---
|
||||||
|
|
||||||
|
# Everything Claude Code Conventional Commits
|
||||||
|
|
||||||
|
## Action
|
||||||
|
|
||||||
|
Use conventional commit prefixes such as `feat:`, `fix:`, `docs:`, `test:`, `chore:`, and `refactor:`.
|
||||||
|
|
||||||
|
## Evidence
|
||||||
|
|
||||||
|
- Mainline history consistently uses conventional commit subjects.
|
||||||
|
- Release and changelog automation expect readable commit categorization.
|
||||||
|
|
||||||
|
---
|
||||||
|
id: everything-claude-code-commit-length
|
||||||
|
trigger: "when writing a commit subject in everything-claude-code"
|
||||||
|
confidence: 0.8
|
||||||
|
domain: git
|
||||||
|
source: repo-curation
|
||||||
|
source_repo: affaan-m/everything-claude-code
|
||||||
|
---
|
||||||
|
|
||||||
|
# Everything Claude Code Commit Length
|
||||||
|
|
||||||
|
## Action
|
||||||
|
|
||||||
|
Keep commit subjects concise and close to the repository norm of about 70 characters.
|
||||||
|
|
||||||
|
## Evidence
|
||||||
|
|
||||||
|
- Recent history clusters around ~70 characters, not ~50.
|
||||||
|
- Short, descriptive subjects read well in release notes and PR summaries.
|
||||||
|
|
||||||
|
---
|
||||||
|
id: everything-claude-code-js-file-naming
|
||||||
|
trigger: "when creating a new JavaScript or TypeScript module in everything-claude-code"
|
||||||
|
confidence: 0.85
|
||||||
|
domain: code-style
|
||||||
|
source: repo-curation
|
||||||
|
source_repo: affaan-m/everything-claude-code
|
||||||
|
---
|
||||||
|
|
||||||
|
# Everything Claude Code JS File Naming
|
||||||
|
|
||||||
|
## Action
|
||||||
|
|
||||||
|
Prefer camelCase for JavaScript and TypeScript module filenames, and keep skill or command directories in kebab-case.
|
||||||
|
|
||||||
|
## Evidence
|
||||||
|
|
||||||
|
- `scripts/` and test helpers mostly use camelCase module names.
|
||||||
|
- `skills/` and `commands/` directories use kebab-case consistently.
|
||||||
|
|
||||||
|
---
|
||||||
|
id: everything-claude-code-test-runner
|
||||||
|
trigger: "when adding or updating tests in everything-claude-code"
|
||||||
|
confidence: 0.9
|
||||||
|
domain: testing
|
||||||
|
source: repo-curation
|
||||||
|
source_repo: affaan-m/everything-claude-code
|
||||||
|
---
|
||||||
|
|
||||||
|
# Everything Claude Code Test Runner
|
||||||
|
|
||||||
|
## Action
|
||||||
|
|
||||||
|
Use the repository's existing Node-based test flow: targeted `*.test.js` files first, then `node tests/run-all.js` or `npm test` for broader verification.
|
||||||
|
|
||||||
|
## Evidence
|
||||||
|
|
||||||
|
- The repo uses `tests/run-all.js` as the central test orchestrator.
|
||||||
|
- Test files follow the `*.test.js` naming pattern across hook, CI, and integration coverage.
|
||||||
|
|
||||||
|
---
|
||||||
|
id: everything-claude-code-hooks-change-set
|
||||||
|
trigger: "when modifying hooks or hook-adjacent behavior in everything-claude-code"
|
||||||
|
confidence: 0.88
|
||||||
|
domain: workflow
|
||||||
|
source: repo-curation
|
||||||
|
source_repo: affaan-m/everything-claude-code
|
||||||
|
---
|
||||||
|
|
||||||
|
# Everything Claude Code Hooks Change Set
|
||||||
|
|
||||||
|
## Action
|
||||||
|
|
||||||
|
Update the hook script, its configuration, its tests, and its user-facing documentation together.
|
||||||
|
|
||||||
|
## Evidence
|
||||||
|
|
||||||
|
- Hook fixes routinely span `hooks/hooks.json`, `scripts/hooks/`, `tests/hooks/`, `tests/integration/`, and `hooks/README.md`.
|
||||||
|
- Partial hook changes are a common source of regressions and stale docs.
|
||||||
|
|
||||||
|
---
|
||||||
|
id: everything-claude-code-cross-platform-sync
|
||||||
|
trigger: "when shipping a user-visible feature across ECC surfaces"
|
||||||
|
confidence: 0.9
|
||||||
|
domain: workflow
|
||||||
|
source: repo-curation
|
||||||
|
source_repo: affaan-m/everything-claude-code
|
||||||
|
---
|
||||||
|
|
||||||
|
# Everything Claude Code Cross Platform Sync
|
||||||
|
|
||||||
|
## Action
|
||||||
|
|
||||||
|
Treat the root repo as the source of truth, then mirror shipped changes to `.cursor/`, `.codex/`, `.opencode/`, and `.agents/` only where the feature actually exists.
|
||||||
|
|
||||||
|
## Evidence
|
||||||
|
|
||||||
|
- ECC maintains multiple harness-specific surfaces with overlapping but not identical files.
|
||||||
|
- The safest workflow is root-first followed by explicit parity updates.
|
||||||
|
|
||||||
|
---
|
||||||
|
id: everything-claude-code-release-sync
|
||||||
|
trigger: "when preparing a release for everything-claude-code"
|
||||||
|
confidence: 0.86
|
||||||
|
domain: workflow
|
||||||
|
source: repo-curation
|
||||||
|
source_repo: affaan-m/everything-claude-code
|
||||||
|
---
|
||||||
|
|
||||||
|
# Everything Claude Code Release Sync
|
||||||
|
|
||||||
|
## Action
|
||||||
|
|
||||||
|
Keep package versions, plugin manifests, and release-facing docs synchronized before publishing.
|
||||||
|
|
||||||
|
## Evidence
|
||||||
|
|
||||||
|
- Release work spans `package.json`, `.claude-plugin/*`, `.opencode/package.json`, and release-note content.
|
||||||
|
- Version drift causes broken update paths and confusing install surfaces.
|
||||||
|
|
||||||
|
---
|
||||||
|
id: everything-claude-code-learning-curation
|
||||||
|
trigger: "when importing or evolving instincts for everything-claude-code"
|
||||||
|
confidence: 0.84
|
||||||
|
domain: workflow
|
||||||
|
source: repo-curation
|
||||||
|
source_repo: affaan-m/everything-claude-code
|
||||||
|
---
|
||||||
|
|
||||||
|
# Everything Claude Code Learning Curation
|
||||||
|
|
||||||
|
## Action
|
||||||
|
|
||||||
|
Prefer a small set of accurate instincts over bulk-generated, duplicated, or contradictory instincts.
|
||||||
|
|
||||||
|
## Evidence
|
||||||
|
|
||||||
|
- Auto-generated instinct dumps can duplicate rules, widen triggers too far, or preserve placeholder detector output.
|
||||||
|
- Curated instincts are easier to import, audit, and trust during continuous-learning workflows.
|
||||||
14
.claude/identity.json
Normal file
14
.claude/identity.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0",
|
||||||
|
"technicalLevel": "technical",
|
||||||
|
"preferredStyle": {
|
||||||
|
"verbosity": "minimal",
|
||||||
|
"codeComments": true,
|
||||||
|
"explanations": true
|
||||||
|
},
|
||||||
|
"domains": [
|
||||||
|
"javascript"
|
||||||
|
],
|
||||||
|
"suggestedBy": "ecc-tools-repo-analysis",
|
||||||
|
"createdAt": "2026-03-20T12:07:57.119Z"
|
||||||
|
}
|
||||||
21
.claude/research/everything-claude-code-research-playbook.md
Normal file
21
.claude/research/everything-claude-code-research-playbook.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Everything Claude Code Research Playbook
|
||||||
|
|
||||||
|
Use this when the task is documentation-heavy, source-sensitive, or requires broad repository context.
|
||||||
|
|
||||||
|
## Defaults
|
||||||
|
|
||||||
|
- Prefer primary documentation and direct source links.
|
||||||
|
- Include concrete dates when facts may change over time.
|
||||||
|
- Keep a short evidence trail for each recommendation or conclusion.
|
||||||
|
|
||||||
|
## Suggested Flow
|
||||||
|
|
||||||
|
1. Inspect local code and docs first.
|
||||||
|
2. Browse only for unstable or external facts.
|
||||||
|
3. Summarize findings with file paths, commands, or links.
|
||||||
|
|
||||||
|
## Repo Signals
|
||||||
|
|
||||||
|
- Primary language: JavaScript
|
||||||
|
- Framework: Not detected
|
||||||
|
- Workflows detected: 10
|
||||||
34
.claude/rules/everything-claude-code-guardrails.md
Normal file
34
.claude/rules/everything-claude-code-guardrails.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Everything Claude Code Guardrails
|
||||||
|
|
||||||
|
Generated by ECC Tools from repository history. Review before treating it as a hard policy file.
|
||||||
|
|
||||||
|
## Commit Workflow
|
||||||
|
|
||||||
|
- Prefer `conventional` commit messaging with prefixes such as fix, test, feat, docs.
|
||||||
|
- Keep new changes aligned with the existing pull-request and review flow already present in the repo.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
- Preserve the current `hybrid` module organization.
|
||||||
|
- Respect the current test layout: `separate`.
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
- Use `camelCase` file naming.
|
||||||
|
- Prefer `relative` imports and `mixed` exports.
|
||||||
|
|
||||||
|
## ECC Defaults
|
||||||
|
|
||||||
|
- Current recommended install profile: `full`.
|
||||||
|
- Validate risky config changes in PRs and keep the install manifest in source control.
|
||||||
|
|
||||||
|
## Detected Workflows
|
||||||
|
|
||||||
|
- database-migration: Database schema changes with migration files
|
||||||
|
- feature-development: Standard feature implementation workflow
|
||||||
|
- add-language-rules: Adds a new programming language to the rules system, including coding style, hooks, patterns, security, and testing guidelines.
|
||||||
|
|
||||||
|
## Review Reminder
|
||||||
|
|
||||||
|
- Regenerate this bundle when repository conventions materially change.
|
||||||
|
- Keep suppressions narrow and auditable.
|
||||||
47
.claude/rules/node.md
Normal file
47
.claude/rules/node.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# Node.js Rules for everything-claude-code
|
||||||
|
|
||||||
|
> Project-specific rules for the ECC codebase. Extends common rules.
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
|
||||||
|
- **Runtime**: Node.js >=18 (no transpilation, plain CommonJS)
|
||||||
|
- **Test runner**: `node tests/run-all.js` — individual files via `node tests/**/*.test.js`
|
||||||
|
- **Linter**: ESLint (`@eslint/js`, flat config)
|
||||||
|
- **Coverage**: c8
|
||||||
|
- **Lint**: markdownlint-cli for `.md` files
|
||||||
|
|
||||||
|
## File Conventions
|
||||||
|
|
||||||
|
- `scripts/` — Node.js utilities, hooks. CommonJS (`require`/`module.exports`)
|
||||||
|
- `agents/`, `commands/`, `skills/`, `rules/` — Markdown with YAML frontmatter
|
||||||
|
- `tests/` — Mirror the `scripts/` structure. Test files named `*.test.js`
|
||||||
|
- File naming: **lowercase with hyphens** (e.g. `session-start.js`, `post-edit-format.js`)
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
- CommonJS only — no ESM (`import`/`export`) unless file ends in `.mjs`
|
||||||
|
- No TypeScript — plain `.js` throughout
|
||||||
|
- Prefer `const` over `let`; never `var`
|
||||||
|
- Keep hook scripts under 200 lines — extract helpers to `scripts/lib/`
|
||||||
|
- All hooks must `exit 0` on non-critical errors (never block tool execution unexpectedly)
|
||||||
|
|
||||||
|
## Hook Development
|
||||||
|
|
||||||
|
- Hook scripts normally receive JSON on stdin, but hooks routed through `scripts/hooks/run-with-flags.js` can export `run(rawInput)` and let the wrapper handle parsing/gating
|
||||||
|
- Async hooks: mark `"async": true` in `settings.json` with a timeout ≤30s
|
||||||
|
- Blocking hooks (PreToolUse, stop): keep fast (<200ms) — no network calls
|
||||||
|
- Use `run-with-flags.js` wrapper for all hooks so `ECC_HOOK_PROFILE` and `ECC_DISABLED_HOOKS` runtime gating works
|
||||||
|
- Always exit 0 on parse errors; log to stderr with `[HookName]` prefix
|
||||||
|
|
||||||
|
## Testing Requirements
|
||||||
|
|
||||||
|
- Run `node tests/run-all.js` before committing
|
||||||
|
- New scripts in `scripts/lib/` require a matching test in `tests/lib/`
|
||||||
|
- New hooks require at least one integration test in `tests/hooks/`
|
||||||
|
|
||||||
|
## Markdown / Agent Files
|
||||||
|
|
||||||
|
- Agents: YAML frontmatter with `name`, `description`, `tools`, `model`
|
||||||
|
- Skills: sections — When to Use, How It Works, Examples
|
||||||
|
- Commands: `description:` frontmatter line required
|
||||||
|
- Run `npx markdownlint-cli '**/*.md' --ignore node_modules` before committing
|
||||||
442
.claude/skills/everything-claude-code/SKILL.md
Normal file
442
.claude/skills/everything-claude-code/SKILL.md
Normal file
@@ -0,0 +1,442 @@
|
|||||||
|
---
|
||||||
|
name: everything-claude-code-conventions
|
||||||
|
description: Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Everything Claude Code Conventions
|
||||||
|
|
||||||
|
> Generated from [affaan-m/everything-claude-code](https://github.com/affaan-m/everything-claude-code) on 2026-03-20
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This skill teaches Claude the development patterns and conventions used in everything-claude-code.
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
|
||||||
|
- **Primary Language**: JavaScript
|
||||||
|
- **Architecture**: hybrid module organization
|
||||||
|
- **Test Location**: separate
|
||||||
|
|
||||||
|
## When to Use This Skill
|
||||||
|
|
||||||
|
Activate this skill when:
|
||||||
|
- Making changes to this repository
|
||||||
|
- Adding new features following established patterns
|
||||||
|
- Writing tests that match project conventions
|
||||||
|
- Creating commits with proper message format
|
||||||
|
|
||||||
|
## Commit Conventions
|
||||||
|
|
||||||
|
Follow these commit message conventions based on 500 analyzed commits.
|
||||||
|
|
||||||
|
### Commit Style: Conventional Commits
|
||||||
|
|
||||||
|
### Prefixes Used
|
||||||
|
|
||||||
|
- `fix`
|
||||||
|
- `test`
|
||||||
|
- `feat`
|
||||||
|
- `docs`
|
||||||
|
|
||||||
|
### Message Guidelines
|
||||||
|
|
||||||
|
- Average message length: ~65 characters
|
||||||
|
- Keep first line concise and descriptive
|
||||||
|
- Use imperative mood ("Add feature" not "Added feature")
|
||||||
|
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
feat(rules): add C# language support
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
chore(deps-dev): bump flatted (#675)
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
fix: auto-detect ECC root from plugin cache when CLAUDE_PLUGIN_ROOT is unset (#547) (#691)
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs: add Antigravity setup and usage guide (#552)
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
merge: PR #529 — feat(skills): add documentation-lookup, bun-runtime, nextjs-turbopack; feat(agents): add rust-reviewer
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
Revert "Add Kiro IDE support (.kiro/) (#548)"
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
Add Kiro IDE support (.kiro/) (#548)
|
||||||
|
```
|
||||||
|
|
||||||
|
*Commit message example*
|
||||||
|
|
||||||
|
```text
|
||||||
|
feat: add block-no-verify hook for Claude Code and Cursor (#649)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Project Structure: Single Package
|
||||||
|
|
||||||
|
This project uses **hybrid** module organization.
|
||||||
|
|
||||||
|
### Configuration Files
|
||||||
|
|
||||||
|
- `.github/workflows/ci.yml`
|
||||||
|
- `.github/workflows/maintenance.yml`
|
||||||
|
- `.github/workflows/monthly-metrics.yml`
|
||||||
|
- `.github/workflows/release.yml`
|
||||||
|
- `.github/workflows/reusable-release.yml`
|
||||||
|
- `.github/workflows/reusable-test.yml`
|
||||||
|
- `.github/workflows/reusable-validate.yml`
|
||||||
|
- `.opencode/package.json`
|
||||||
|
- `.opencode/tsconfig.json`
|
||||||
|
- `.prettierrc`
|
||||||
|
- `eslint.config.js`
|
||||||
|
- `package.json`
|
||||||
|
|
||||||
|
### Guidelines
|
||||||
|
|
||||||
|
- This project uses a hybrid organization
|
||||||
|
- Follow existing patterns when adding new code
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
### Language: JavaScript
|
||||||
|
|
||||||
|
### Naming Conventions
|
||||||
|
|
||||||
|
| Element | Convention |
|
||||||
|
|---------|------------|
|
||||||
|
| Files | camelCase |
|
||||||
|
| Functions | camelCase |
|
||||||
|
| Classes | PascalCase |
|
||||||
|
| Constants | SCREAMING_SNAKE_CASE |
|
||||||
|
|
||||||
|
### Import Style: Relative Imports
|
||||||
|
|
||||||
|
### Export Style: Mixed Style
|
||||||
|
|
||||||
|
|
||||||
|
*Preferred import style*
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Use relative imports
|
||||||
|
import { Button } from '../components/Button'
|
||||||
|
import { useAuth } from './hooks/useAuth'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### Test Framework
|
||||||
|
|
||||||
|
No specific test framework detected — use the repository's existing test patterns.
|
||||||
|
|
||||||
|
### File Pattern: `*.test.js`
|
||||||
|
|
||||||
|
### Test Types
|
||||||
|
|
||||||
|
- **Unit tests**: Test individual functions and components in isolation
|
||||||
|
- **Integration tests**: Test interactions between multiple components/services
|
||||||
|
|
||||||
|
### Coverage
|
||||||
|
|
||||||
|
This project has coverage reporting configured. Aim for 80%+ coverage.
|
||||||
|
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
### Error Handling Style: Try-Catch Blocks
|
||||||
|
|
||||||
|
|
||||||
|
*Standard error handling pattern*
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
try {
|
||||||
|
const result = await riskyOperation()
|
||||||
|
return result
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Operation failed:', error)
|
||||||
|
throw new Error('User-friendly message')
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Workflows
|
||||||
|
|
||||||
|
These workflows were detected from analyzing commit patterns.
|
||||||
|
|
||||||
|
### Database Migration
|
||||||
|
|
||||||
|
Database schema changes with migration files
|
||||||
|
|
||||||
|
**Frequency**: ~2 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Create migration file
|
||||||
|
2. Update schema definitions
|
||||||
|
3. Generate/update types
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `**/schema.*`
|
||||||
|
- `migrations/*`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
feat: implement --with/--without selective install flags (#679)
|
||||||
|
fix: sync catalog counts with filesystem (27 agents, 113 skills, 58 commands) (#693)
|
||||||
|
feat(rules): add Rust language rules (rebased #660) (#686)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Feature Development
|
||||||
|
|
||||||
|
Standard feature implementation workflow
|
||||||
|
|
||||||
|
**Frequency**: ~22 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Add feature implementation
|
||||||
|
2. Add tests for feature
|
||||||
|
3. Update documentation
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `manifests/*`
|
||||||
|
- `schemas/*`
|
||||||
|
- `**/*.test.*`
|
||||||
|
- `**/api/**`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
feat(skills): add documentation-lookup, bun-runtime, nextjs-turbopack; feat(agents): add rust-reviewer
|
||||||
|
docs(skills): align documentation-lookup with CONTRIBUTING template; add cross-harness (Codex/Cursor) skill copies
|
||||||
|
fix: address PR review — skill template (When to use, How it works, Examples), bun.lock, next build note, rust-reviewer CI note, doc-lookup privacy/uncertainty
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Language Rules
|
||||||
|
|
||||||
|
Adds a new programming language to the rules system, including coding style, hooks, patterns, security, and testing guidelines.
|
||||||
|
|
||||||
|
**Frequency**: ~2 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Create a new directory under rules/{language}/
|
||||||
|
2. Add coding-style.md, hooks.md, patterns.md, security.md, and testing.md files with language-specific content
|
||||||
|
3. Optionally reference or link to related skills
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `rules/*/coding-style.md`
|
||||||
|
- `rules/*/hooks.md`
|
||||||
|
- `rules/*/patterns.md`
|
||||||
|
- `rules/*/security.md`
|
||||||
|
- `rules/*/testing.md`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Create a new directory under rules/{language}/
|
||||||
|
Add coding-style.md, hooks.md, patterns.md, security.md, and testing.md files with language-specific content
|
||||||
|
Optionally reference or link to related skills
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add New Skill
|
||||||
|
|
||||||
|
Adds a new skill to the system, documenting its workflow, triggers, and usage, often with supporting scripts.
|
||||||
|
|
||||||
|
**Frequency**: ~4 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Create a new directory under skills/{skill-name}/
|
||||||
|
2. Add SKILL.md with documentation (When to Use, How It Works, Examples, etc.)
|
||||||
|
3. Optionally add scripts or supporting files under skills/{skill-name}/scripts/
|
||||||
|
4. Address review feedback and iterate on documentation
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `skills/*/SKILL.md`
|
||||||
|
- `skills/*/scripts/*.sh`
|
||||||
|
- `skills/*/scripts/*.js`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Create a new directory under skills/{skill-name}/
|
||||||
|
Add SKILL.md with documentation (When to Use, How It Works, Examples, etc.)
|
||||||
|
Optionally add scripts or supporting files under skills/{skill-name}/scripts/
|
||||||
|
Address review feedback and iterate on documentation
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add New Agent
|
||||||
|
|
||||||
|
Adds a new agent to the system for code review, build resolution, or other automated tasks.
|
||||||
|
|
||||||
|
**Frequency**: ~2 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Create a new agent markdown file under agents/{agent-name}.md
|
||||||
|
2. Register the agent in AGENTS.md
|
||||||
|
3. Optionally update README.md and docs/COMMAND-AGENT-MAP.md
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `agents/*.md`
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `README.md`
|
||||||
|
- `docs/COMMAND-AGENT-MAP.md`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Create a new agent markdown file under agents/{agent-name}.md
|
||||||
|
Register the agent in AGENTS.md
|
||||||
|
Optionally update README.md and docs/COMMAND-AGENT-MAP.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add New Command
|
||||||
|
|
||||||
|
Adds a new command to the system, often paired with a backing skill.
|
||||||
|
|
||||||
|
**Frequency**: ~1 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Create a new markdown file under commands/{command-name}.md
|
||||||
|
2. Optionally add or update a backing skill under skills/{skill-name}/SKILL.md
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `commands/*.md`
|
||||||
|
- `skills/*/SKILL.md`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Create a new markdown file under commands/{command-name}.md
|
||||||
|
Optionally add or update a backing skill under skills/{skill-name}/SKILL.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sync Catalog Counts
|
||||||
|
|
||||||
|
Synchronizes the documented counts of agents, skills, and commands in AGENTS.md and README.md with the actual repository state.
|
||||||
|
|
||||||
|
**Frequency**: ~3 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Update agent, skill, and command counts in AGENTS.md
|
||||||
|
2. Update the same counts in README.md (quick-start, comparison table, etc.)
|
||||||
|
3. Optionally update other documentation files
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `README.md`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Update agent, skill, and command counts in AGENTS.md
|
||||||
|
Update the same counts in README.md (quick-start, comparison table, etc.)
|
||||||
|
Optionally update other documentation files
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Cross Harness Skill Copies
|
||||||
|
|
||||||
|
Adds skill copies for different agent harnesses (e.g., Codex, Cursor, Antigravity) to ensure compatibility across platforms.
|
||||||
|
|
||||||
|
**Frequency**: ~2 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Copy or adapt SKILL.md to .agents/skills/{skill}/SKILL.md and/or .cursor/skills/{skill}/SKILL.md
|
||||||
|
2. Optionally add harness-specific openai.yaml or config files
|
||||||
|
3. Address review feedback to align with CONTRIBUTING template
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `.agents/skills/*/SKILL.md`
|
||||||
|
- `.cursor/skills/*/SKILL.md`
|
||||||
|
- `.agents/skills/*/agents/openai.yaml`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Copy or adapt SKILL.md to .agents/skills/{skill}/SKILL.md and/or .cursor/skills/{skill}/SKILL.md
|
||||||
|
Optionally add harness-specific openai.yaml or config files
|
||||||
|
Address review feedback to align with CONTRIBUTING template
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Or Update Hook
|
||||||
|
|
||||||
|
Adds or updates git or bash hooks to enforce workflow, quality, or security policies.
|
||||||
|
|
||||||
|
**Frequency**: ~1 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Add or update hook scripts in hooks/ or scripts/hooks/
|
||||||
|
2. Register the hook in hooks/hooks.json or similar config
|
||||||
|
3. Optionally add or update tests in tests/hooks/
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `hooks/*.hook`
|
||||||
|
- `hooks/hooks.json`
|
||||||
|
- `scripts/hooks/*.js`
|
||||||
|
- `tests/hooks/*.test.js`
|
||||||
|
- `.cursor/hooks.json`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Add or update hook scripts in hooks/ or scripts/hooks/
|
||||||
|
Register the hook in hooks/hooks.json or similar config
|
||||||
|
Optionally add or update tests in tests/hooks/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Address Review Feedback
|
||||||
|
|
||||||
|
Addresses code review feedback by updating documentation, scripts, or configuration for clarity, correctness, or convention alignment.
|
||||||
|
|
||||||
|
**Frequency**: ~4 times per month
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
1. Edit SKILL.md, agent, or command files to address reviewer comments
|
||||||
|
2. Update examples, headings, or configuration as requested
|
||||||
|
3. Iterate until all review feedback is resolved
|
||||||
|
|
||||||
|
**Files typically involved**:
|
||||||
|
- `skills/*/SKILL.md`
|
||||||
|
- `agents/*.md`
|
||||||
|
- `commands/*.md`
|
||||||
|
- `.agents/skills/*/SKILL.md`
|
||||||
|
- `.cursor/skills/*/SKILL.md`
|
||||||
|
|
||||||
|
**Example commit sequence**:
|
||||||
|
```
|
||||||
|
Edit SKILL.md, agent, or command files to address reviewer comments
|
||||||
|
Update examples, headings, or configuration as requested
|
||||||
|
Iterate until all review feedback is resolved
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
Based on analysis of the codebase, follow these practices:
|
||||||
|
|
||||||
|
### Do
|
||||||
|
|
||||||
|
- Use conventional commit format (feat:, fix:, etc.)
|
||||||
|
- Follow *.test.js naming pattern
|
||||||
|
- Use camelCase for file names
|
||||||
|
- Prefer mixed exports
|
||||||
|
|
||||||
|
### Don't
|
||||||
|
|
||||||
|
- Don't write vague commit messages
|
||||||
|
- Don't skip tests for new features
|
||||||
|
- Don't deviate from established patterns without discussion
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*This skill was auto-generated by [ECC Tools](https://ecc.tools). Review and customize as needed for your team.*
|
||||||
15
.claude/team/everything-claude-code-team-config.json
Normal file
15
.claude/team/everything-claude-code-team-config.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"version": "1.0",
|
||||||
|
"generatedBy": "ecc-tools",
|
||||||
|
"profile": "full",
|
||||||
|
"sharedSkills": [
|
||||||
|
".claude/skills/everything-claude-code/SKILL.md",
|
||||||
|
".agents/skills/everything-claude-code/SKILL.md"
|
||||||
|
],
|
||||||
|
"commandFiles": [
|
||||||
|
".claude/commands/database-migration.md",
|
||||||
|
".claude/commands/feature-development.md",
|
||||||
|
".claude/commands/add-language-rules.md"
|
||||||
|
],
|
||||||
|
"updatedAt": "2026-03-20T12:07:36.496Z"
|
||||||
|
}
|
||||||
98
.codebuddy/README.md
Normal file
98
.codebuddy/README.md
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# Everything Claude Code for CodeBuddy
|
||||||
|
|
||||||
|
Bring Everything Claude Code (ECC) workflows to CodeBuddy IDE. This repository provides custom commands, agents, skills, and rules that can be installed into any CodeBuddy project using the unified Target Adapter architecture.
|
||||||
|
|
||||||
|
## Quick Start (Recommended)
|
||||||
|
|
||||||
|
Use the unified install system for full lifecycle management:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install with default profile
|
||||||
|
node scripts/install-apply.js --target codebuddy --profile developer
|
||||||
|
|
||||||
|
# Install with full profile (all modules)
|
||||||
|
node scripts/install-apply.js --target codebuddy --profile full
|
||||||
|
|
||||||
|
# Dry-run to preview changes
|
||||||
|
node scripts/install-apply.js --target codebuddy --profile full --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
## Management Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check installation health
|
||||||
|
node scripts/doctor.js --target codebuddy
|
||||||
|
|
||||||
|
# Repair installation
|
||||||
|
node scripts/repair.js --target codebuddy
|
||||||
|
|
||||||
|
# Uninstall cleanly (tracked via install-state)
|
||||||
|
node scripts/uninstall.js --target codebuddy
|
||||||
|
```
|
||||||
|
|
||||||
|
## Shell Script (Legacy)
|
||||||
|
|
||||||
|
The legacy shell scripts are still available for quick setup:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install to current project
|
||||||
|
cd /path/to/your/project
|
||||||
|
.codebuddy/install.sh
|
||||||
|
|
||||||
|
# Install globally
|
||||||
|
.codebuddy/install.sh ~
|
||||||
|
```
|
||||||
|
|
||||||
|
## What's Included
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
Commands are on-demand workflows invocable via the `/` menu in CodeBuddy chat. All commands are reused directly from the project root's `commands/` folder.
|
||||||
|
|
||||||
|
### Agents
|
||||||
|
|
||||||
|
Agents are specialized AI assistants with specific tool configurations. All agents are reused directly from the project root's `agents/` folder.
|
||||||
|
|
||||||
|
### Skills
|
||||||
|
|
||||||
|
Skills are on-demand workflows invocable via the `/` menu in chat. All skills are reused directly from the project's `skills/` folder.
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
Rules provide always-on rules and context that shape how the agent works with your code. Rules are flattened into namespaced files (e.g., `common-coding-style.md`) for CodeBuddy compatibility.
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
.codebuddy/
|
||||||
|
├── commands/ # Command files (reused from project root)
|
||||||
|
├── agents/ # Agent files (reused from project root)
|
||||||
|
├── skills/ # Skill files (reused from skills/)
|
||||||
|
├── rules/ # Rule files (flattened from rules/)
|
||||||
|
├── ecc-install-state.json # Install state tracking
|
||||||
|
├── install.sh # Legacy install script
|
||||||
|
├── uninstall.sh # Legacy uninstall script
|
||||||
|
└── README.md # This file
|
||||||
|
```
|
||||||
|
|
||||||
|
## Benefits of Target Adapter Install
|
||||||
|
|
||||||
|
- **Install-state tracking**: Safe uninstall that only removes ECC-managed files
|
||||||
|
- **Doctor checks**: Verify installation health and detect drift
|
||||||
|
- **Repair**: Auto-fix broken installations
|
||||||
|
- **Selective install**: Choose specific modules via profiles
|
||||||
|
- **Cross-platform**: Node.js-based, works on Windows/macOS/Linux
|
||||||
|
|
||||||
|
## Recommended Workflow
|
||||||
|
|
||||||
|
1. **Start with planning**: Use `/plan` command to break down complex features
|
||||||
|
2. **Write tests first**: Invoke `/tdd` command before implementing
|
||||||
|
3. **Review your code**: Use `/code-review` after writing code
|
||||||
|
4. **Check security**: Use `/code-review` again for auth, API endpoints, or sensitive data handling
|
||||||
|
5. **Fix build errors**: Use `/build-fix` if there are build errors
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
- Open your project in CodeBuddy
|
||||||
|
- Type `/` to see available commands
|
||||||
|
- Enjoy the ECC workflows!
|
||||||
98
.codebuddy/README.zh-CN.md
Normal file
98
.codebuddy/README.zh-CN.md
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# Everything Claude Code for CodeBuddy
|
||||||
|
|
||||||
|
为 CodeBuddy IDE 带来 Everything Claude Code (ECC) 工作流。此仓库提供自定义命令、智能体、技能和规则,可以通过统一的 Target Adapter 架构安装到任何 CodeBuddy 项目中。
|
||||||
|
|
||||||
|
## 快速开始(推荐)
|
||||||
|
|
||||||
|
使用统一安装系统,获得完整的生命周期管理:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 使用默认配置安装
|
||||||
|
node scripts/install-apply.js --target codebuddy --profile developer
|
||||||
|
|
||||||
|
# 使用完整配置安装(所有模块)
|
||||||
|
node scripts/install-apply.js --target codebuddy --profile full
|
||||||
|
|
||||||
|
# 预览模式查看变更
|
||||||
|
node scripts/install-apply.js --target codebuddy --profile full --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
## 管理命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查安装健康状态
|
||||||
|
node scripts/doctor.js --target codebuddy
|
||||||
|
|
||||||
|
# 修复安装
|
||||||
|
node scripts/repair.js --target codebuddy
|
||||||
|
|
||||||
|
# 清洁卸载(通过 install-state 跟踪)
|
||||||
|
node scripts/uninstall.js --target codebuddy
|
||||||
|
```
|
||||||
|
|
||||||
|
## Shell 脚本(旧版)
|
||||||
|
|
||||||
|
旧版 Shell 脚本仍然可用于快速设置:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 安装到当前项目
|
||||||
|
cd /path/to/your/project
|
||||||
|
.codebuddy/install.sh
|
||||||
|
|
||||||
|
# 全局安装
|
||||||
|
.codebuddy/install.sh ~
|
||||||
|
```
|
||||||
|
|
||||||
|
## 包含的内容
|
||||||
|
|
||||||
|
### 命令
|
||||||
|
|
||||||
|
命令是通过 CodeBuddy 聊天中的 `/` 菜单调用的按需工作流。所有命令都直接复用自项目根目录的 `commands/` 文件夹。
|
||||||
|
|
||||||
|
### 智能体
|
||||||
|
|
||||||
|
智能体是具有特定工具配置的专门 AI 助手。所有智能体都直接复用自项目根目录的 `agents/` 文件夹。
|
||||||
|
|
||||||
|
### 技能
|
||||||
|
|
||||||
|
技能是通过聊天中的 `/` 菜单调用的按需工作流。所有技能都直接复用自项目的 `skills/` 文件夹。
|
||||||
|
|
||||||
|
### 规则
|
||||||
|
|
||||||
|
规则提供始终适用的规则和上下文,塑造智能体处理代码的方式。规则会被扁平化为命名空间文件(如 `common-coding-style.md`)以兼容 CodeBuddy。
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
.codebuddy/
|
||||||
|
├── commands/ # 命令文件(复用自项目根目录)
|
||||||
|
├── agents/ # 智能体文件(复用自项目根目录)
|
||||||
|
├── skills/ # 技能文件(复用自 skills/)
|
||||||
|
├── rules/ # 规则文件(从 rules/ 扁平化)
|
||||||
|
├── ecc-install-state.json # 安装状态跟踪
|
||||||
|
├── install.sh # 旧版安装脚本
|
||||||
|
├── uninstall.sh # 旧版卸载脚本
|
||||||
|
└── README.zh-CN.md # 此文件
|
||||||
|
```
|
||||||
|
|
||||||
|
## Target Adapter 安装的优势
|
||||||
|
|
||||||
|
- **安装状态跟踪**:安全卸载,仅删除 ECC 管理的文件
|
||||||
|
- **Doctor 检查**:验证安装健康状态并检测偏移
|
||||||
|
- **修复**:自动修复损坏的安装
|
||||||
|
- **选择性安装**:通过配置文件选择特定模块
|
||||||
|
- **跨平台**:基于 Node.js,支持 Windows/macOS/Linux
|
||||||
|
|
||||||
|
## 推荐的工作流
|
||||||
|
|
||||||
|
1. **从计划开始**:使用 `/plan` 命令分解复杂功能
|
||||||
|
2. **先写测试**:在实现之前调用 `/tdd` 命令
|
||||||
|
3. **审查您的代码**:编写代码后使用 `/code-review`
|
||||||
|
4. **检查安全性**:对于身份验证、API 端点或敏感数据处理,再次使用 `/code-review`
|
||||||
|
5. **修复构建错误**:如果有构建错误,使用 `/build-fix`
|
||||||
|
|
||||||
|
## 下一步
|
||||||
|
|
||||||
|
- 在 CodeBuddy 中打开您的项目
|
||||||
|
- 输入 `/` 以查看可用命令
|
||||||
|
- 享受 ECC 工作流!
|
||||||
312
.codebuddy/install.js
Executable file
312
.codebuddy/install.js
Executable file
@@ -0,0 +1,312 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* ECC CodeBuddy Installer (Cross-platform Node.js version)
|
||||||
|
* Installs Everything Claude Code workflows into a CodeBuddy project.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* node install.js # Install to current directory
|
||||||
|
* node install.js ~ # Install globally to ~/.codebuddy/
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const os = require('os');
|
||||||
|
|
||||||
|
// Platform detection
|
||||||
|
const isWindows = process.platform === 'win32';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get home directory cross-platform
|
||||||
|
*/
|
||||||
|
function getHomeDir() {
|
||||||
|
return process.env.USERPROFILE || process.env.HOME || os.homedir();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure directory exists
|
||||||
|
*/
|
||||||
|
function ensureDir(dirPath) {
|
||||||
|
try {
|
||||||
|
if (!fs.existsSync(dirPath)) {
|
||||||
|
fs.mkdirSync(dirPath, { recursive: true });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (err.code !== 'EEXIST') {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read lines from a file
|
||||||
|
*/
|
||||||
|
function readLines(filePath) {
|
||||||
|
try {
|
||||||
|
if (!fs.existsSync(filePath)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const content = fs.readFileSync(filePath, 'utf8');
|
||||||
|
return content.split('\n').filter(line => line.length > 0);
|
||||||
|
} catch {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if manifest contains an entry
|
||||||
|
*/
|
||||||
|
function manifestHasEntry(manifestPath, entry) {
|
||||||
|
const lines = readLines(manifestPath);
|
||||||
|
return lines.includes(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add entry to manifest
|
||||||
|
*/
|
||||||
|
function ensureManifestEntry(manifestPath, entry) {
|
||||||
|
try {
|
||||||
|
const lines = readLines(manifestPath);
|
||||||
|
if (!lines.includes(entry)) {
|
||||||
|
const content = lines.join('\n') + (lines.length > 0 ? '\n' : '') + entry + '\n';
|
||||||
|
fs.writeFileSync(manifestPath, content, 'utf8');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Error updating manifest: ${err.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy a file and manage in manifest
|
||||||
|
*/
|
||||||
|
function copyManagedFile(sourcePath, targetPath, manifestPath, manifestEntry, makeExecutable = false) {
|
||||||
|
const alreadyManaged = manifestHasEntry(manifestPath, manifestEntry);
|
||||||
|
|
||||||
|
// If target file already exists
|
||||||
|
if (fs.existsSync(targetPath)) {
|
||||||
|
if (alreadyManaged) {
|
||||||
|
ensureManifestEntry(manifestPath, manifestEntry);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the file
|
||||||
|
try {
|
||||||
|
ensureDir(path.dirname(targetPath));
|
||||||
|
fs.copyFileSync(sourcePath, targetPath);
|
||||||
|
|
||||||
|
// Make executable on Unix systems
|
||||||
|
if (makeExecutable && !isWindows) {
|
||||||
|
fs.chmodSync(targetPath, 0o755);
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureManifestEntry(manifestPath, manifestEntry);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Error copying ${sourcePath}: ${err.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively find files in a directory
|
||||||
|
*/
|
||||||
|
function findFiles(dir, extension = '') {
|
||||||
|
const results = [];
|
||||||
|
try {
|
||||||
|
if (!fs.existsSync(dir)) {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
function walk(currentPath) {
|
||||||
|
try {
|
||||||
|
const entries = fs.readdirSync(currentPath, { withFileTypes: true });
|
||||||
|
for (const entry of entries) {
|
||||||
|
const fullPath = path.join(currentPath, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
walk(fullPath);
|
||||||
|
} else if (!extension || entry.name.endsWith(extension)) {
|
||||||
|
results.push(fullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Ignore permission errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
walk(dir);
|
||||||
|
} catch {
|
||||||
|
// Ignore errors
|
||||||
|
}
|
||||||
|
return results.sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main install function
|
||||||
|
*/
|
||||||
|
function doInstall() {
|
||||||
|
// Resolve script directory (where this file lives)
|
||||||
|
const scriptDir = path.dirname(path.resolve(__filename));
|
||||||
|
const repoRoot = path.dirname(scriptDir);
|
||||||
|
const codebuddyDirName = '.codebuddy';
|
||||||
|
|
||||||
|
// Parse arguments
|
||||||
|
let targetDir = process.cwd();
|
||||||
|
if (process.argv.length > 2) {
|
||||||
|
const arg = process.argv[2];
|
||||||
|
if (arg === '~' || arg === getHomeDir()) {
|
||||||
|
targetDir = getHomeDir();
|
||||||
|
} else {
|
||||||
|
targetDir = path.resolve(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine codebuddy full path
|
||||||
|
let codebuddyFullPath;
|
||||||
|
const baseName = path.basename(targetDir);
|
||||||
|
|
||||||
|
if (baseName === codebuddyDirName) {
|
||||||
|
codebuddyFullPath = targetDir;
|
||||||
|
} else {
|
||||||
|
codebuddyFullPath = path.join(targetDir, codebuddyDirName);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('ECC CodeBuddy Installer');
|
||||||
|
console.log('=======================');
|
||||||
|
console.log('');
|
||||||
|
console.log(`Source: ${repoRoot}`);
|
||||||
|
console.log(`Target: ${codebuddyFullPath}/`);
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
// Create subdirectories
|
||||||
|
const subdirs = ['commands', 'agents', 'skills', 'rules'];
|
||||||
|
for (const dir of subdirs) {
|
||||||
|
ensureDir(path.join(codebuddyFullPath, dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manifest file
|
||||||
|
const manifest = path.join(codebuddyFullPath, '.ecc-manifest');
|
||||||
|
ensureDir(path.dirname(manifest));
|
||||||
|
|
||||||
|
// Counters
|
||||||
|
let commands = 0;
|
||||||
|
let agents = 0;
|
||||||
|
let skills = 0;
|
||||||
|
let rules = 0;
|
||||||
|
|
||||||
|
// Copy commands
|
||||||
|
const commandsDir = path.join(repoRoot, 'commands');
|
||||||
|
if (fs.existsSync(commandsDir)) {
|
||||||
|
const files = findFiles(commandsDir, '.md');
|
||||||
|
for (const file of files) {
|
||||||
|
if (path.basename(path.dirname(file)) === 'commands') {
|
||||||
|
const localName = path.basename(file);
|
||||||
|
const targetPath = path.join(codebuddyFullPath, 'commands', localName);
|
||||||
|
if (copyManagedFile(file, targetPath, manifest, `commands/${localName}`)) {
|
||||||
|
commands += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy agents
|
||||||
|
const agentsDir = path.join(repoRoot, 'agents');
|
||||||
|
if (fs.existsSync(agentsDir)) {
|
||||||
|
const files = findFiles(agentsDir, '.md');
|
||||||
|
for (const file of files) {
|
||||||
|
if (path.basename(path.dirname(file)) === 'agents') {
|
||||||
|
const localName = path.basename(file);
|
||||||
|
const targetPath = path.join(codebuddyFullPath, 'agents', localName);
|
||||||
|
if (copyManagedFile(file, targetPath, manifest, `agents/${localName}`)) {
|
||||||
|
agents += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy skills (with subdirectories)
|
||||||
|
const skillsDir = path.join(repoRoot, 'skills');
|
||||||
|
if (fs.existsSync(skillsDir)) {
|
||||||
|
const skillDirs = fs.readdirSync(skillsDir, { withFileTypes: true })
|
||||||
|
.filter(entry => entry.isDirectory())
|
||||||
|
.map(entry => entry.name);
|
||||||
|
|
||||||
|
for (const skillName of skillDirs) {
|
||||||
|
const sourceSkillDir = path.join(skillsDir, skillName);
|
||||||
|
const targetSkillDir = path.join(codebuddyFullPath, 'skills', skillName);
|
||||||
|
let skillCopied = false;
|
||||||
|
|
||||||
|
const skillFiles = findFiles(sourceSkillDir);
|
||||||
|
for (const sourceFile of skillFiles) {
|
||||||
|
const relativePath = path.relative(sourceSkillDir, sourceFile);
|
||||||
|
const targetPath = path.join(targetSkillDir, relativePath);
|
||||||
|
const manifestEntry = `skills/${skillName}/${relativePath.replace(/\\/g, '/')}`;
|
||||||
|
|
||||||
|
if (copyManagedFile(sourceFile, targetPath, manifest, manifestEntry)) {
|
||||||
|
skillCopied = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skillCopied) {
|
||||||
|
skills += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy rules (with subdirectories)
|
||||||
|
const rulesDir = path.join(repoRoot, 'rules');
|
||||||
|
if (fs.existsSync(rulesDir)) {
|
||||||
|
const ruleFiles = findFiles(rulesDir);
|
||||||
|
for (const ruleFile of ruleFiles) {
|
||||||
|
const relativePath = path.relative(rulesDir, ruleFile);
|
||||||
|
const targetPath = path.join(codebuddyFullPath, 'rules', relativePath);
|
||||||
|
const manifestEntry = `rules/${relativePath.replace(/\\/g, '/')}`;
|
||||||
|
|
||||||
|
if (copyManagedFile(ruleFile, targetPath, manifest, manifestEntry)) {
|
||||||
|
rules += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy README files (skip install/uninstall scripts to avoid broken
|
||||||
|
// path references when the copied script runs from the target directory)
|
||||||
|
const readmeFiles = ['README.md', 'README.zh-CN.md'];
|
||||||
|
for (const readmeFile of readmeFiles) {
|
||||||
|
const sourcePath = path.join(scriptDir, readmeFile);
|
||||||
|
if (fs.existsSync(sourcePath)) {
|
||||||
|
const targetPath = path.join(codebuddyFullPath, readmeFile);
|
||||||
|
copyManagedFile(sourcePath, targetPath, manifest, readmeFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add manifest itself
|
||||||
|
ensureManifestEntry(manifest, '.ecc-manifest');
|
||||||
|
|
||||||
|
// Print summary
|
||||||
|
console.log('Installation complete!');
|
||||||
|
console.log('');
|
||||||
|
console.log('Components installed:');
|
||||||
|
console.log(` Commands: ${commands}`);
|
||||||
|
console.log(` Agents: ${agents}`);
|
||||||
|
console.log(` Skills: ${skills}`);
|
||||||
|
console.log(` Rules: ${rules}`);
|
||||||
|
console.log('');
|
||||||
|
console.log(`Directory: ${path.basename(codebuddyFullPath)}`);
|
||||||
|
console.log('');
|
||||||
|
console.log('Next steps:');
|
||||||
|
console.log(' 1. Open your project in CodeBuddy');
|
||||||
|
console.log(' 2. Type / to see available commands');
|
||||||
|
console.log(' 3. Enjoy the ECC workflows!');
|
||||||
|
console.log('');
|
||||||
|
console.log('To uninstall later:');
|
||||||
|
console.log(` cd ${codebuddyFullPath}`);
|
||||||
|
console.log(' node uninstall.js');
|
||||||
|
console.log('');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run installer
|
||||||
|
try {
|
||||||
|
doInstall();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error: ${error.message}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
231
.codebuddy/install.sh
Executable file
231
.codebuddy/install.sh
Executable file
@@ -0,0 +1,231 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# ECC CodeBuddy Installer
|
||||||
|
# Installs Everything Claude Code workflows into a CodeBuddy project.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./install.sh # Install to current directory
|
||||||
|
# ./install.sh ~ # Install globally to ~/.codebuddy/
|
||||||
|
#
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# When globs match nothing, expand to empty list instead of the literal pattern
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
# Resolve the directory where this script lives
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# Locate the ECC repo root by walking up from SCRIPT_DIR to find the marker
|
||||||
|
# file (VERSION). This keeps the script working even when it has been copied
|
||||||
|
# into a target project's .codebuddy/ directory.
|
||||||
|
find_repo_root() {
|
||||||
|
local dir="$(dirname "$SCRIPT_DIR")"
|
||||||
|
# First try the parent of SCRIPT_DIR (original layout: .codebuddy/ lives in repo root)
|
||||||
|
if [ -f "$dir/VERSION" ] && [ -d "$dir/commands" ] && [ -d "$dir/agents" ]; then
|
||||||
|
echo "$dir"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
REPO_ROOT="$(find_repo_root)"
|
||||||
|
if [ -z "$REPO_ROOT" ]; then
|
||||||
|
echo "Error: Cannot locate the ECC repository root."
|
||||||
|
echo "This script must be run from within the ECC repository's .codebuddy/ directory."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# CodeBuddy directory name
|
||||||
|
CODEBUDDY_DIR=".codebuddy"
|
||||||
|
|
||||||
|
ensure_manifest_entry() {
|
||||||
|
local manifest="$1"
|
||||||
|
local entry="$2"
|
||||||
|
|
||||||
|
touch "$manifest"
|
||||||
|
if ! grep -Fqx "$entry" "$manifest"; then
|
||||||
|
echo "$entry" >> "$manifest"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
manifest_has_entry() {
|
||||||
|
local manifest="$1"
|
||||||
|
local entry="$2"
|
||||||
|
|
||||||
|
[ -f "$manifest" ] && grep -Fqx "$entry" "$manifest"
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_managed_file() {
|
||||||
|
local source_path="$1"
|
||||||
|
local target_path="$2"
|
||||||
|
local manifest="$3"
|
||||||
|
local manifest_entry="$4"
|
||||||
|
local make_executable="${5:-0}"
|
||||||
|
|
||||||
|
local already_managed=0
|
||||||
|
if manifest_has_entry "$manifest" "$manifest_entry"; then
|
||||||
|
already_managed=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$target_path" ]; then
|
||||||
|
if [ "$already_managed" -eq 1 ]; then
|
||||||
|
ensure_manifest_entry "$manifest" "$manifest_entry"
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp "$source_path" "$target_path"
|
||||||
|
if [ "$make_executable" -eq 1 ]; then
|
||||||
|
chmod +x "$target_path"
|
||||||
|
fi
|
||||||
|
ensure_manifest_entry "$manifest" "$manifest_entry"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install function
|
||||||
|
do_install() {
|
||||||
|
local target_dir="$PWD"
|
||||||
|
|
||||||
|
# Check if ~ was specified (or expanded to $HOME)
|
||||||
|
if [ "$#" -ge 1 ]; then
|
||||||
|
if [ "$1" = "~" ] || [ "$1" = "$HOME" ]; then
|
||||||
|
target_dir="$HOME"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if we're already inside a .codebuddy directory
|
||||||
|
local current_dir_name="$(basename "$target_dir")"
|
||||||
|
local codebuddy_full_path
|
||||||
|
|
||||||
|
if [ "$current_dir_name" = ".codebuddy" ]; then
|
||||||
|
# Already inside the codebuddy directory, use it directly
|
||||||
|
codebuddy_full_path="$target_dir"
|
||||||
|
else
|
||||||
|
# Normal case: append CODEBUDDY_DIR to target_dir
|
||||||
|
codebuddy_full_path="$target_dir/$CODEBUDDY_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "ECC CodeBuddy Installer"
|
||||||
|
echo "======================="
|
||||||
|
echo ""
|
||||||
|
echo "Source: $REPO_ROOT"
|
||||||
|
echo "Target: $codebuddy_full_path/"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Subdirectories to create
|
||||||
|
SUBDIRS="commands agents skills rules"
|
||||||
|
|
||||||
|
# Create all required codebuddy subdirectories
|
||||||
|
for dir in $SUBDIRS; do
|
||||||
|
mkdir -p "$codebuddy_full_path/$dir"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Manifest file to track installed files
|
||||||
|
MANIFEST="$codebuddy_full_path/.ecc-manifest"
|
||||||
|
touch "$MANIFEST"
|
||||||
|
|
||||||
|
# Counters for summary
|
||||||
|
commands=0
|
||||||
|
agents=0
|
||||||
|
skills=0
|
||||||
|
rules=0
|
||||||
|
|
||||||
|
# Copy commands from repo root
|
||||||
|
if [ -d "$REPO_ROOT/commands" ]; then
|
||||||
|
for f in "$REPO_ROOT/commands"/*.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
local_name=$(basename "$f")
|
||||||
|
target_path="$codebuddy_full_path/commands/$local_name"
|
||||||
|
if copy_managed_file "$f" "$target_path" "$MANIFEST" "commands/$local_name"; then
|
||||||
|
commands=$((commands + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy agents from repo root
|
||||||
|
if [ -d "$REPO_ROOT/agents" ]; then
|
||||||
|
for f in "$REPO_ROOT/agents"/*.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
local_name=$(basename "$f")
|
||||||
|
target_path="$codebuddy_full_path/agents/$local_name"
|
||||||
|
if copy_managed_file "$f" "$target_path" "$MANIFEST" "agents/$local_name"; then
|
||||||
|
agents=$((agents + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy skills from repo root (if available)
|
||||||
|
if [ -d "$REPO_ROOT/skills" ]; then
|
||||||
|
for d in "$REPO_ROOT/skills"/*/; do
|
||||||
|
[ -d "$d" ] || continue
|
||||||
|
skill_name="$(basename "$d")"
|
||||||
|
target_skill_dir="$codebuddy_full_path/skills/$skill_name"
|
||||||
|
skill_copied=0
|
||||||
|
|
||||||
|
while IFS= read -r source_file; do
|
||||||
|
relative_path="${source_file#$d}"
|
||||||
|
target_path="$target_skill_dir/$relative_path"
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$target_path")"
|
||||||
|
if copy_managed_file "$source_file" "$target_path" "$MANIFEST" "skills/$skill_name/$relative_path"; then
|
||||||
|
skill_copied=1
|
||||||
|
fi
|
||||||
|
done < <(find "$d" -type f | sort)
|
||||||
|
|
||||||
|
if [ "$skill_copied" -eq 1 ]; then
|
||||||
|
skills=$((skills + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy rules from repo root
|
||||||
|
if [ -d "$REPO_ROOT/rules" ]; then
|
||||||
|
while IFS= read -r rule_file; do
|
||||||
|
relative_path="${rule_file#$REPO_ROOT/rules/}"
|
||||||
|
target_path="$codebuddy_full_path/rules/$relative_path"
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$target_path")"
|
||||||
|
if copy_managed_file "$rule_file" "$target_path" "$MANIFEST" "rules/$relative_path"; then
|
||||||
|
rules=$((rules + 1))
|
||||||
|
fi
|
||||||
|
done < <(find "$REPO_ROOT/rules" -type f | sort)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy README files (skip install/uninstall scripts to avoid broken
|
||||||
|
# path references when the copied script runs from the target directory)
|
||||||
|
for readme_file in "$SCRIPT_DIR/README.md" "$SCRIPT_DIR/README.zh-CN.md"; do
|
||||||
|
if [ -f "$readme_file" ]; then
|
||||||
|
local_name=$(basename "$readme_file")
|
||||||
|
target_path="$codebuddy_full_path/$local_name"
|
||||||
|
copy_managed_file "$readme_file" "$target_path" "$MANIFEST" "$local_name" || true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Add manifest file itself to manifest
|
||||||
|
ensure_manifest_entry "$MANIFEST" ".ecc-manifest"
|
||||||
|
|
||||||
|
# Installation summary
|
||||||
|
echo "Installation complete!"
|
||||||
|
echo ""
|
||||||
|
echo "Components installed:"
|
||||||
|
echo " Commands: $commands"
|
||||||
|
echo " Agents: $agents"
|
||||||
|
echo " Skills: $skills"
|
||||||
|
echo " Rules: $rules"
|
||||||
|
echo ""
|
||||||
|
echo "Directory: $(basename "$codebuddy_full_path")"
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo " 1. Open your project in CodeBuddy"
|
||||||
|
echo " 2. Type / to see available commands"
|
||||||
|
echo " 3. Enjoy the ECC workflows!"
|
||||||
|
echo ""
|
||||||
|
echo "To uninstall later:"
|
||||||
|
echo " cd $codebuddy_full_path"
|
||||||
|
echo " ./uninstall.sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main logic
|
||||||
|
do_install "$@"
|
||||||
291
.codebuddy/uninstall.js
Executable file
291
.codebuddy/uninstall.js
Executable file
@@ -0,0 +1,291 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* ECC CodeBuddy Uninstaller (Cross-platform Node.js version)
|
||||||
|
* Uninstalls Everything Claude Code workflows from a CodeBuddy project.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* node uninstall.js # Uninstall from current directory
|
||||||
|
* node uninstall.js ~ # Uninstall globally from ~/.codebuddy/
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const os = require('os');
|
||||||
|
const readline = require('readline');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get home directory cross-platform
|
||||||
|
*/
|
||||||
|
function getHomeDir() {
|
||||||
|
return process.env.USERPROFILE || process.env.HOME || os.homedir();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve a path to its canonical form
|
||||||
|
*/
|
||||||
|
function resolvePath(filePath) {
|
||||||
|
try {
|
||||||
|
return fs.realpathSync(filePath);
|
||||||
|
} catch {
|
||||||
|
// If realpath fails, return the path as-is
|
||||||
|
return path.resolve(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a manifest entry is valid (security check)
|
||||||
|
*/
|
||||||
|
function isValidManifestEntry(entry) {
|
||||||
|
// Reject empty, absolute paths, parent directory references
|
||||||
|
if (!entry || entry.length === 0) return false;
|
||||||
|
if (entry.startsWith('/')) return false;
|
||||||
|
if (entry.startsWith('~')) return false;
|
||||||
|
if (entry.includes('/../') || entry.includes('/..')) return false;
|
||||||
|
if (entry.startsWith('../') || entry.startsWith('..\\')) return false;
|
||||||
|
if (entry === '..' || entry === '...' || entry.includes('\\..\\')||entry.includes('/..')) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read lines from manifest file
|
||||||
|
*/
|
||||||
|
function readManifest(manifestPath) {
|
||||||
|
try {
|
||||||
|
if (!fs.existsSync(manifestPath)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||||
|
return content.split('\n').filter(line => line.length > 0);
|
||||||
|
} catch {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively find empty directories
|
||||||
|
*/
|
||||||
|
function findEmptyDirs(dirPath) {
|
||||||
|
const emptyDirs = [];
|
||||||
|
|
||||||
|
function walkDirs(currentPath) {
|
||||||
|
try {
|
||||||
|
const entries = fs.readdirSync(currentPath, { withFileTypes: true });
|
||||||
|
const subdirs = entries.filter(e => e.isDirectory());
|
||||||
|
|
||||||
|
for (const subdir of subdirs) {
|
||||||
|
const subdirPath = path.join(currentPath, subdir.name);
|
||||||
|
walkDirs(subdirPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if directory is now empty
|
||||||
|
try {
|
||||||
|
const remaining = fs.readdirSync(currentPath);
|
||||||
|
if (remaining.length === 0 && currentPath !== dirPath) {
|
||||||
|
emptyDirs.push(currentPath);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Directory might have been deleted
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Ignore errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
walkDirs(dirPath);
|
||||||
|
return emptyDirs.sort().reverse(); // Sort in reverse for removal
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompt user for confirmation
|
||||||
|
*/
|
||||||
|
async function promptConfirm(question) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const rl = readline.createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout,
|
||||||
|
});
|
||||||
|
|
||||||
|
rl.question(question, (answer) => {
|
||||||
|
rl.close();
|
||||||
|
resolve(/^[yY]$/.test(answer));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main uninstall function
|
||||||
|
*/
|
||||||
|
async function doUninstall() {
|
||||||
|
const codebuddyDirName = '.codebuddy';
|
||||||
|
|
||||||
|
// Parse arguments
|
||||||
|
let targetDir = process.cwd();
|
||||||
|
if (process.argv.length > 2) {
|
||||||
|
const arg = process.argv[2];
|
||||||
|
if (arg === '~' || arg === getHomeDir()) {
|
||||||
|
targetDir = getHomeDir();
|
||||||
|
} else {
|
||||||
|
targetDir = path.resolve(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine codebuddy full path
|
||||||
|
let codebuddyFullPath;
|
||||||
|
const baseName = path.basename(targetDir);
|
||||||
|
|
||||||
|
if (baseName === codebuddyDirName) {
|
||||||
|
codebuddyFullPath = targetDir;
|
||||||
|
} else {
|
||||||
|
codebuddyFullPath = path.join(targetDir, codebuddyDirName);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('ECC CodeBuddy Uninstaller');
|
||||||
|
console.log('==========================');
|
||||||
|
console.log('');
|
||||||
|
console.log(`Target: ${codebuddyFullPath}/`);
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
// Check if codebuddy directory exists
|
||||||
|
if (!fs.existsSync(codebuddyFullPath)) {
|
||||||
|
console.error(`Error: ${codebuddyDirName} directory not found at ${targetDir}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const codebuddyRootResolved = resolvePath(codebuddyFullPath);
|
||||||
|
const manifest = path.join(codebuddyFullPath, '.ecc-manifest');
|
||||||
|
|
||||||
|
// Handle missing manifest
|
||||||
|
if (!fs.existsSync(manifest)) {
|
||||||
|
console.log('Warning: No manifest file found (.ecc-manifest)');
|
||||||
|
console.log('');
|
||||||
|
console.log('This could mean:');
|
||||||
|
console.log(' 1. ECC was installed with an older version without manifest support');
|
||||||
|
console.log(' 2. The manifest file was manually deleted');
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
const confirmed = await promptConfirm(`Do you want to remove the entire ${codebuddyDirName} directory? (y/N) `);
|
||||||
|
if (!confirmed) {
|
||||||
|
console.log('Uninstall cancelled.');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.rmSync(codebuddyFullPath, { recursive: true, force: true });
|
||||||
|
console.log('Uninstall complete!');
|
||||||
|
console.log('');
|
||||||
|
console.log(`Removed: ${codebuddyFullPath}/`);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Error removing directory: ${err.message}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Found manifest file - will only remove files installed by ECC');
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
const confirmed = await promptConfirm(`Are you sure you want to uninstall ECC from ${codebuddyDirName}? (y/N) `);
|
||||||
|
if (!confirmed) {
|
||||||
|
console.log('Uninstall cancelled.');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read manifest and remove files
|
||||||
|
const manifestLines = readManifest(manifest);
|
||||||
|
let removed = 0;
|
||||||
|
let skipped = 0;
|
||||||
|
|
||||||
|
for (const filePath of manifestLines) {
|
||||||
|
if (!filePath || filePath.length === 0) continue;
|
||||||
|
|
||||||
|
if (!isValidManifestEntry(filePath)) {
|
||||||
|
console.log(`Skipped: ${filePath} (invalid manifest entry)`);
|
||||||
|
skipped += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fullPath = path.join(codebuddyFullPath, filePath);
|
||||||
|
|
||||||
|
// Security check: use path.relative() to ensure the manifest entry
|
||||||
|
// resolves inside the codebuddy directory. This is stricter than
|
||||||
|
// startsWith and correctly handles edge-cases with symlinks.
|
||||||
|
const relative = path.relative(codebuddyRootResolved, path.resolve(fullPath));
|
||||||
|
if (relative.startsWith('..') || path.isAbsolute(relative)) {
|
||||||
|
console.log(`Skipped: ${filePath} (outside target directory)`);
|
||||||
|
skipped += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const stats = fs.lstatSync(fullPath);
|
||||||
|
|
||||||
|
if (stats.isFile() || stats.isSymbolicLink()) {
|
||||||
|
fs.unlinkSync(fullPath);
|
||||||
|
console.log(`Removed: ${filePath}`);
|
||||||
|
removed += 1;
|
||||||
|
} else if (stats.isDirectory()) {
|
||||||
|
try {
|
||||||
|
const files = fs.readdirSync(fullPath);
|
||||||
|
if (files.length === 0) {
|
||||||
|
fs.rmdirSync(fullPath);
|
||||||
|
console.log(`Removed: ${filePath}/`);
|
||||||
|
removed += 1;
|
||||||
|
} else {
|
||||||
|
console.log(`Skipped: ${filePath}/ (not empty - contains user files)`);
|
||||||
|
skipped += 1;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
console.log(`Skipped: ${filePath}/ (not empty - contains user files)`);
|
||||||
|
skipped += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
skipped += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove empty directories
|
||||||
|
const emptyDirs = findEmptyDirs(codebuddyFullPath);
|
||||||
|
for (const emptyDir of emptyDirs) {
|
||||||
|
try {
|
||||||
|
fs.rmdirSync(emptyDir);
|
||||||
|
const relativePath = path.relative(codebuddyFullPath, emptyDir);
|
||||||
|
console.log(`Removed: ${relativePath}/`);
|
||||||
|
removed += 1;
|
||||||
|
} catch {
|
||||||
|
// Directory might not be empty anymore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to remove main codebuddy directory if empty
|
||||||
|
try {
|
||||||
|
const files = fs.readdirSync(codebuddyFullPath);
|
||||||
|
if (files.length === 0) {
|
||||||
|
fs.rmdirSync(codebuddyFullPath);
|
||||||
|
console.log(`Removed: ${codebuddyDirName}/`);
|
||||||
|
removed += 1;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Directory not empty
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print summary
|
||||||
|
console.log('');
|
||||||
|
console.log('Uninstall complete!');
|
||||||
|
console.log('');
|
||||||
|
console.log('Summary:');
|
||||||
|
console.log(` Removed: ${removed} items`);
|
||||||
|
console.log(` Skipped: ${skipped} items (not found or user-modified)`);
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
if (fs.existsSync(codebuddyFullPath)) {
|
||||||
|
console.log(`Note: ${codebuddyDirName} directory still exists (contains user-added files)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run uninstaller
|
||||||
|
doUninstall().catch((error) => {
|
||||||
|
console.error(`Error: ${error.message}`);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
184
.codebuddy/uninstall.sh
Executable file
184
.codebuddy/uninstall.sh
Executable file
@@ -0,0 +1,184 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# ECC CodeBuddy Uninstaller
|
||||||
|
# Uninstalls Everything Claude Code workflows from a CodeBuddy project.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./uninstall.sh # Uninstall from current directory
|
||||||
|
# ./uninstall.sh ~ # Uninstall globally from ~/.codebuddy/
|
||||||
|
#
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Resolve the directory where this script lives
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# CodeBuddy directory name
|
||||||
|
CODEBUDDY_DIR=".codebuddy"
|
||||||
|
|
||||||
|
resolve_path() {
|
||||||
|
python3 -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_valid_manifest_entry() {
|
||||||
|
local file_path="$1"
|
||||||
|
|
||||||
|
case "$file_path" in
|
||||||
|
""|/*|~*|*/../*|../*|*/..|..)
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main uninstall function
|
||||||
|
do_uninstall() {
|
||||||
|
local target_dir="$PWD"
|
||||||
|
|
||||||
|
# Check if ~ was specified (or expanded to $HOME)
|
||||||
|
if [ "$#" -ge 1 ]; then
|
||||||
|
if [ "$1" = "~" ] || [ "$1" = "$HOME" ]; then
|
||||||
|
target_dir="$HOME"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if we're already inside a .codebuddy directory
|
||||||
|
local current_dir_name="$(basename "$target_dir")"
|
||||||
|
local codebuddy_full_path
|
||||||
|
|
||||||
|
if [ "$current_dir_name" = ".codebuddy" ]; then
|
||||||
|
# Already inside the codebuddy directory, use it directly
|
||||||
|
codebuddy_full_path="$target_dir"
|
||||||
|
else
|
||||||
|
# Normal case: append CODEBUDDY_DIR to target_dir
|
||||||
|
codebuddy_full_path="$target_dir/$CODEBUDDY_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "ECC CodeBuddy Uninstaller"
|
||||||
|
echo "=========================="
|
||||||
|
echo ""
|
||||||
|
echo "Target: $codebuddy_full_path/"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ ! -d "$codebuddy_full_path" ]; then
|
||||||
|
echo "Error: $CODEBUDDY_DIR directory not found at $target_dir"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
codebuddy_root_resolved="$(resolve_path "$codebuddy_full_path")"
|
||||||
|
|
||||||
|
# Manifest file path
|
||||||
|
MANIFEST="$codebuddy_full_path/.ecc-manifest"
|
||||||
|
|
||||||
|
if [ ! -f "$MANIFEST" ]; then
|
||||||
|
echo "Warning: No manifest file found (.ecc-manifest)"
|
||||||
|
echo ""
|
||||||
|
echo "This could mean:"
|
||||||
|
echo " 1. ECC was installed with an older version without manifest support"
|
||||||
|
echo " 2. The manifest file was manually deleted"
|
||||||
|
echo ""
|
||||||
|
read -p "Do you want to remove the entire $CODEBUDDY_DIR directory? (y/N) " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "Uninstall cancelled."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
rm -rf "$codebuddy_full_path"
|
||||||
|
echo "Uninstall complete!"
|
||||||
|
echo ""
|
||||||
|
echo "Removed: $codebuddy_full_path/"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Found manifest file - will only remove files installed by ECC"
|
||||||
|
echo ""
|
||||||
|
read -p "Are you sure you want to uninstall ECC from $CODEBUDDY_DIR? (y/N) " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "Uninstall cancelled."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Counters
|
||||||
|
removed=0
|
||||||
|
skipped=0
|
||||||
|
|
||||||
|
# Read manifest and remove files
|
||||||
|
while IFS= read -r file_path; do
|
||||||
|
[ -z "$file_path" ] && continue
|
||||||
|
|
||||||
|
if ! is_valid_manifest_entry "$file_path"; then
|
||||||
|
echo "Skipped: $file_path (invalid manifest entry)"
|
||||||
|
skipped=$((skipped + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
full_path="$codebuddy_full_path/$file_path"
|
||||||
|
|
||||||
|
# Security check: ensure the path resolves inside the target directory.
|
||||||
|
# Use Python to compute a reliable relative path so symlinks cannot
|
||||||
|
# escape the boundary.
|
||||||
|
relative="$(python3 -c 'import os,sys; print(os.path.relpath(os.path.abspath(sys.argv[1]), sys.argv[2]))' "$full_path" "$codebuddy_root_resolved")"
|
||||||
|
case "$relative" in
|
||||||
|
../*|..)
|
||||||
|
echo "Skipped: $file_path (outside target directory)"
|
||||||
|
skipped=$((skipped + 1))
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -L "$full_path" ] || [ -f "$full_path" ]; then
|
||||||
|
rm -f "$full_path"
|
||||||
|
echo "Removed: $file_path"
|
||||||
|
removed=$((removed + 1))
|
||||||
|
elif [ -d "$full_path" ]; then
|
||||||
|
# Only remove directory if it's empty
|
||||||
|
if [ -z "$(ls -A "$full_path" 2>/dev/null)" ]; then
|
||||||
|
rmdir "$full_path" 2>/dev/null || true
|
||||||
|
if [ ! -d "$full_path" ]; then
|
||||||
|
echo "Removed: $file_path/"
|
||||||
|
removed=$((removed + 1))
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Skipped: $file_path/ (not empty - contains user files)"
|
||||||
|
skipped=$((skipped + 1))
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
skipped=$((skipped + 1))
|
||||||
|
fi
|
||||||
|
done < "$MANIFEST"
|
||||||
|
|
||||||
|
while IFS= read -r empty_dir; do
|
||||||
|
[ "$empty_dir" = "$codebuddy_full_path" ] && continue
|
||||||
|
relative_dir="${empty_dir#$codebuddy_full_path/}"
|
||||||
|
rmdir "$empty_dir" 2>/dev/null || true
|
||||||
|
if [ ! -d "$empty_dir" ]; then
|
||||||
|
echo "Removed: $relative_dir/"
|
||||||
|
removed=$((removed + 1))
|
||||||
|
fi
|
||||||
|
done < <(find "$codebuddy_full_path" -depth -type d -empty 2>/dev/null | sort -r)
|
||||||
|
|
||||||
|
# Try to remove the main codebuddy directory if it's empty
|
||||||
|
if [ -d "$codebuddy_full_path" ] && [ -z "$(ls -A "$codebuddy_full_path" 2>/dev/null)" ]; then
|
||||||
|
rmdir "$codebuddy_full_path" 2>/dev/null || true
|
||||||
|
if [ ! -d "$codebuddy_full_path" ]; then
|
||||||
|
echo "Removed: $CODEBUDDY_DIR/"
|
||||||
|
removed=$((removed + 1))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Uninstall complete!"
|
||||||
|
echo ""
|
||||||
|
echo "Summary:"
|
||||||
|
echo " Removed: $removed items"
|
||||||
|
echo " Skipped: $skipped items (not found or user-modified)"
|
||||||
|
echo ""
|
||||||
|
if [ -d "$codebuddy_full_path" ]; then
|
||||||
|
echo "Note: $CODEBUDDY_DIR directory still exists (contains user-added files)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute uninstall
|
||||||
|
do_uninstall "$@"
|
||||||
51
.codex-plugin/README.md
Normal file
51
.codex-plugin/README.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# .codex-plugin — Codex Native Plugin for ECC
|
||||||
|
|
||||||
|
This directory contains the **Codex plugin manifest** for Everything Claude Code.
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
.codex-plugin/
|
||||||
|
└── plugin.json — Codex plugin manifest (name, version, skills ref, MCP ref)
|
||||||
|
.mcp.json — MCP server configurations at plugin root (NOT inside .codex-plugin/)
|
||||||
|
```
|
||||||
|
|
||||||
|
## What This Provides
|
||||||
|
|
||||||
|
- **142 skills** from `./skills/` — reusable Codex workflows for TDD, security,
|
||||||
|
code review, architecture, and more
|
||||||
|
- **6 MCP servers** — GitHub, Context7, Exa, Memory, Playwright, Sequential Thinking
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Codex plugin support is currently in preview. Once generally available:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install from Codex CLI
|
||||||
|
codex plugin install affaan-m/everything-claude-code
|
||||||
|
|
||||||
|
# Or reference locally during development
|
||||||
|
codex plugin install ./
|
||||||
|
|
||||||
|
Run this from the repository root so `./` points to the repo root and `.mcp.json` resolves correctly.
|
||||||
|
```
|
||||||
|
|
||||||
|
## MCP Servers Included
|
||||||
|
|
||||||
|
| Server | Purpose |
|
||||||
|
|---|---|
|
||||||
|
| `github` | GitHub API access |
|
||||||
|
| `context7` | Live documentation lookup |
|
||||||
|
| `exa` | Neural web search |
|
||||||
|
| `memory` | Persistent memory across sessions |
|
||||||
|
| `playwright` | Browser automation & E2E testing |
|
||||||
|
| `sequential-thinking` | Step-by-step reasoning |
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The `skills/` directory at the repo root is shared between Claude Code (`.claude-plugin/`)
|
||||||
|
and Codex (`.codex-plugin/`) — same source of truth, no duplication
|
||||||
|
- ECC is moving to a skills-first workflow surface. Legacy `commands/` remain for
|
||||||
|
compatibility on harnesses that still expect slash-entry shims.
|
||||||
|
- MCP server credentials are inherited from the launching environment (env vars)
|
||||||
|
- This manifest does **not** override `~/.codex/config.toml` settings
|
||||||
30
.codex-plugin/plugin.json
Normal file
30
.codex-plugin/plugin.json
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "everything-claude-code",
|
||||||
|
"version": "1.9.0",
|
||||||
|
"description": "Battle-tested Codex workflows — 125 skills, production-ready MCP configs, and agent definitions for TDD, security scanning, code review, and autonomous development.",
|
||||||
|
"author": {
|
||||||
|
"name": "Affaan Mustafa",
|
||||||
|
"email": "me@affaanmustafa.com",
|
||||||
|
"url": "https://x.com/affaanmustafa"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/affaan-m/everything-claude-code",
|
||||||
|
"repository": "https://github.com/affaan-m/everything-claude-code",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": ["codex", "agents", "skills", "tdd", "code-review", "security", "workflow", "automation"],
|
||||||
|
"skills": "./skills/",
|
||||||
|
"mcpServers": "./.mcp.json",
|
||||||
|
"interface": {
|
||||||
|
"displayName": "Everything Claude Code",
|
||||||
|
"shortDescription": "125 battle-tested skills for TDD, security, code review, and autonomous development.",
|
||||||
|
"longDescription": "Everything Claude Code (ECC) is a community-maintained collection of Codex skills and MCP configs evolved over 10+ months of intensive daily use. It covers TDD workflows, security scanning, code review, architecture decisions, and more — all in one installable plugin.",
|
||||||
|
"developerName": "Affaan Mustafa",
|
||||||
|
"category": "Productivity",
|
||||||
|
"capabilities": ["Read", "Write"],
|
||||||
|
"websiteURL": "https://github.com/affaan-m/everything-claude-code",
|
||||||
|
"defaultPrompt": [
|
||||||
|
"Use the tdd-workflow skill to write tests before implementation.",
|
||||||
|
"Use the security-review skill to scan for OWASP Top 10 vulnerabilities.",
|
||||||
|
"Use the code-review skill to review this PR for correctness and security."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,10 +6,10 @@ This supplements the root `AGENTS.md` with Codex-specific guidance.
|
|||||||
|
|
||||||
| Task Type | Recommended Model |
|
| Task Type | Recommended Model |
|
||||||
|-----------|------------------|
|
|-----------|------------------|
|
||||||
| Routine coding, tests, formatting | o4-mini |
|
| Routine coding, tests, formatting | GPT 5.4 |
|
||||||
| Complex features, architecture | o3 |
|
| Complex features, architecture | GPT 5.4 |
|
||||||
| Debugging, refactoring | o4-mini |
|
| Debugging, refactoring | GPT 5.4 |
|
||||||
| Security review | o3 |
|
| Security review | GPT 5.4 |
|
||||||
|
|
||||||
## Skills Discovery
|
## Skills Discovery
|
||||||
|
|
||||||
@@ -22,16 +22,57 @@ Available skills:
|
|||||||
- security-review — Comprehensive security checklist
|
- security-review — Comprehensive security checklist
|
||||||
- coding-standards — Universal coding standards
|
- coding-standards — Universal coding standards
|
||||||
- frontend-patterns — React/Next.js patterns
|
- frontend-patterns — React/Next.js patterns
|
||||||
|
- frontend-slides — Viewport-safe HTML presentations and PPTX-to-web conversion
|
||||||
|
- article-writing — Long-form writing from notes and voice references
|
||||||
|
- content-engine — Platform-native social content and repurposing
|
||||||
|
- market-research — Source-attributed market and competitor research
|
||||||
|
- investor-materials — Decks, memos, models, and one-pagers
|
||||||
|
- investor-outreach — Personalized investor outreach and follow-ups
|
||||||
- backend-patterns — API design, database, caching
|
- backend-patterns — API design, database, caching
|
||||||
- e2e-testing — Playwright E2E tests
|
- e2e-testing — Playwright E2E tests
|
||||||
- eval-harness — Eval-driven development
|
- eval-harness — Eval-driven development
|
||||||
- strategic-compact — Context management
|
- strategic-compact — Context management
|
||||||
- api-design — REST API design patterns
|
- api-design — REST API design patterns
|
||||||
- verification-loop — Build, test, lint, typecheck, security
|
- verification-loop — Build, test, lint, typecheck, security
|
||||||
|
- deep-research — Multi-source research with firecrawl and exa MCPs
|
||||||
|
- exa-search — Neural search via Exa MCP for web, code, and companies
|
||||||
|
- claude-api — Anthropic Claude API patterns and SDKs
|
||||||
|
- x-api — X/Twitter API integration for posting, threads, and analytics
|
||||||
|
- crosspost — Multi-platform content distribution
|
||||||
|
- fal-ai-media — AI image/video/audio generation via fal.ai
|
||||||
|
- dmux-workflows — Multi-agent orchestration with dmux
|
||||||
|
|
||||||
## MCP Servers
|
## MCP Servers
|
||||||
|
|
||||||
Configure in `~/.codex/config.toml` under `[mcp_servers]`. See `.codex/config.toml` for reference configuration with GitHub, Context7, Memory, and Sequential Thinking servers.
|
Treat the project-local `.codex/config.toml` as the default Codex baseline for ECC. The current ECC baseline enables GitHub, Context7, Exa, Memory, Playwright, and Sequential Thinking; add heavier extras in `~/.codex/config.toml` only when a task actually needs them.
|
||||||
|
|
||||||
|
ECC's canonical Codex section name is `[mcp_servers.context7]`. The launcher package remains `@upstash/context7-mcp`; only the TOML section name is normalized for consistency with `codex mcp list` and the reference config.
|
||||||
|
|
||||||
|
### Automatic config.toml merging
|
||||||
|
|
||||||
|
The sync script (`scripts/sync-ecc-to-codex.sh`) uses a Node-based TOML parser to safely merge ECC MCP servers into `~/.codex/config.toml`:
|
||||||
|
|
||||||
|
- **Add-only by default** — missing ECC servers are appended; existing servers are never modified or removed.
|
||||||
|
- **7 managed servers** — Supabase, Playwright, Context7, Exa, GitHub, Memory, Sequential Thinking.
|
||||||
|
- **Canonical naming** — ECC manages Context7 as `[mcp_servers.context7]`; legacy `[mcp_servers.context7-mcp]` entries are treated as aliases during updates.
|
||||||
|
- **Package-manager aware** — uses the project's configured package manager (npm/pnpm/yarn/bun) instead of hardcoding `pnpm`.
|
||||||
|
- **Drift warnings** — if an existing server's config differs from the ECC recommendation, the script logs a warning.
|
||||||
|
- **`--update-mcp`** — explicitly replaces all ECC-managed servers with the latest recommended config (safely removes subtables like `[mcp_servers.supabase.env]`).
|
||||||
|
- **User config is always preserved** — custom servers, args, env vars, and credentials outside ECC-managed sections are never touched.
|
||||||
|
|
||||||
|
## Multi-Agent Support
|
||||||
|
|
||||||
|
Codex now supports multi-agent workflows behind the experimental `features.multi_agent` flag.
|
||||||
|
|
||||||
|
- Enable it in `.codex/config.toml` with `[features] multi_agent = true`
|
||||||
|
- Define project-local roles under `[agents.<name>]`
|
||||||
|
- Point each role at a TOML layer under `.codex/agents/`
|
||||||
|
- Use `/agent` inside Codex CLI to inspect and steer child agents
|
||||||
|
|
||||||
|
Sample role configs in this repo:
|
||||||
|
- `.codex/agents/explorer.toml` — read-only evidence gathering
|
||||||
|
- `.codex/agents/reviewer.toml` — correctness/security review
|
||||||
|
- `.codex/agents/docs-researcher.toml` — API and release-note verification
|
||||||
|
|
||||||
## Key Differences from Claude Code
|
## Key Differences from Claude Code
|
||||||
|
|
||||||
@@ -41,9 +82,9 @@ Configure in `~/.codex/config.toml` under `[mcp_servers]`. See `.codex/config.to
|
|||||||
| Context file | CLAUDE.md + AGENTS.md | AGENTS.md only |
|
| Context file | CLAUDE.md + AGENTS.md | AGENTS.md only |
|
||||||
| Skills | Skills loaded via plugin | `.agents/skills/` directory |
|
| Skills | Skills loaded via plugin | `.agents/skills/` directory |
|
||||||
| Commands | `/slash` commands | Instruction-based |
|
| Commands | `/slash` commands | Instruction-based |
|
||||||
| Agents | Subagent Task tool | Single agent model |
|
| Agents | Subagent Task tool | Multi-agent via `/agent` and `[agents.<name>]` roles |
|
||||||
| Security | Hook-based enforcement | Instruction + sandbox |
|
| Security | Hook-based enforcement | Instruction + sandbox |
|
||||||
| MCP | Full support | Command-based only |
|
| MCP | Full support | Supported via `config.toml` and `codex mcp add` |
|
||||||
|
|
||||||
## Security Without Hooks
|
## Security Without Hooks
|
||||||
|
|
||||||
|
|||||||
9
.codex/agents/docs-researcher.toml
Normal file
9
.codex/agents/docs-researcher.toml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
model = "gpt-5.4"
|
||||||
|
model_reasoning_effort = "medium"
|
||||||
|
sandbox_mode = "read-only"
|
||||||
|
|
||||||
|
developer_instructions = """
|
||||||
|
Verify APIs, framework behavior, and release-note claims against primary documentation before changes land.
|
||||||
|
Cite the exact docs or file paths that support each claim.
|
||||||
|
Do not invent undocumented behavior.
|
||||||
|
"""
|
||||||
9
.codex/agents/explorer.toml
Normal file
9
.codex/agents/explorer.toml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
model = "gpt-5.4"
|
||||||
|
model_reasoning_effort = "medium"
|
||||||
|
sandbox_mode = "read-only"
|
||||||
|
|
||||||
|
developer_instructions = """
|
||||||
|
Stay in exploration mode.
|
||||||
|
Trace the real execution path, cite files and symbols, and avoid proposing fixes unless the parent agent asks for them.
|
||||||
|
Prefer targeted search and file reads over broad scans.
|
||||||
|
"""
|
||||||
9
.codex/agents/reviewer.toml
Normal file
9
.codex/agents/reviewer.toml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
model = "gpt-5.4"
|
||||||
|
model_reasoning_effort = "high"
|
||||||
|
sandbox_mode = "read-only"
|
||||||
|
|
||||||
|
developer_instructions = """
|
||||||
|
Review like an owner.
|
||||||
|
Prioritize correctness, security, behavioral regressions, and missing tests.
|
||||||
|
Lead with concrete findings and avoid style-only feedback unless it hides a real bug.
|
||||||
|
"""
|
||||||
@@ -1,57 +1,72 @@
|
|||||||
# Everything Claude Code (ECC) — Codex CLI Reference Configuration
|
#:schema https://developers.openai.com/codex/config-schema.json
|
||||||
|
|
||||||
|
# Everything Claude Code (ECC) — Codex Reference Configuration
|
||||||
#
|
#
|
||||||
# Copy this file to ~/.codex/config.toml to apply globally.
|
# Copy this file to ~/.codex/config.toml for global defaults, or keep it in
|
||||||
# Or keep it in your project root for project-level config.
|
# the project root as .codex/config.toml for project-local settings.
|
||||||
#
|
#
|
||||||
# Docs: https://github.com/openai/codex
|
# Official docs:
|
||||||
|
# - https://developers.openai.com/codex/config-reference
|
||||||
|
# - https://developers.openai.com/codex/multi-agent
|
||||||
|
|
||||||
# Model selection
|
# Model selection
|
||||||
model = "o4-mini"
|
# Leave `model` and `model_provider` unset so Codex CLI uses its current
|
||||||
model_provider = "openai"
|
# built-in defaults. Uncomment and pin them only if you intentionally want
|
||||||
|
# repo-local or global model overrides.
|
||||||
|
|
||||||
# Permissions
|
# Top-level runtime settings (current Codex schema)
|
||||||
[permissions]
|
|
||||||
# "untrusted" = no writes, "on-request" = ask per action, "never" = full auto
|
|
||||||
approval_policy = "on-request"
|
approval_policy = "on-request"
|
||||||
# "off", "workspace-read", "workspace-write", "danger-full-access"
|
|
||||||
sandbox_mode = "workspace-write"
|
sandbox_mode = "workspace-write"
|
||||||
|
web_search = "live"
|
||||||
|
|
||||||
# Notifications (macOS)
|
# External notifications receive a JSON payload on stdin.
|
||||||
[notify]
|
notify = [
|
||||||
command = "terminal-notifier -title 'Codex ECC' -message 'Task completed!' -sound default"
|
"terminal-notifier",
|
||||||
on_complete = true
|
"-title", "Codex ECC",
|
||||||
|
"-message", "Task completed!",
|
||||||
|
"-sound", "default",
|
||||||
|
]
|
||||||
|
|
||||||
# History - persistent instructions applied to every session
|
# Persistent instructions are appended to every prompt (additive, unlike
|
||||||
[history]
|
# model_instructions_file which replaces AGENTS.md).
|
||||||
# These are prepended to every conversation
|
persistent_instructions = "Follow project AGENTS.md guidelines. Use available MCP servers when they can help."
|
||||||
persistent_instructions = """
|
|
||||||
Follow ECC principles:
|
|
||||||
1. Test-Driven Development (TDD) - write tests first, 80%+ coverage required
|
|
||||||
2. Immutability - always create new objects, never mutate
|
|
||||||
3. Security-First - validate all inputs, no hardcoded secrets
|
|
||||||
4. Conventional commits: feat|fix|refactor|docs|test|chore|perf|ci: description
|
|
||||||
5. File organization: many small files (200-400 lines, 800 max)
|
|
||||||
6. Error handling: handle at every level, never swallow errors
|
|
||||||
7. Input validation: schema-based validation at system boundaries
|
|
||||||
"""
|
|
||||||
|
|
||||||
# MCP Servers
|
# model_instructions_file replaces built-in instructions instead of AGENTS.md,
|
||||||
# Codex supports command-based MCP servers
|
# so leave it unset unless you intentionally want a single override file.
|
||||||
|
# model_instructions_file = "/absolute/path/to/instructions.md"
|
||||||
|
|
||||||
|
# MCP servers
|
||||||
|
# Keep the default project set lean. API-backed servers inherit credentials from
|
||||||
|
# the launching environment or can be supplied by a user-level ~/.codex/config.toml.
|
||||||
[mcp_servers.github]
|
[mcp_servers.github]
|
||||||
command = "npx"
|
command = "npx"
|
||||||
args = ["-y", "@modelcontextprotocol/server-github"]
|
args = ["-y", "@modelcontextprotocol/server-github"]
|
||||||
|
startup_timeout_sec = 30
|
||||||
|
|
||||||
[mcp_servers.context7]
|
[mcp_servers.context7]
|
||||||
command = "npx"
|
command = "npx"
|
||||||
|
# Canonical Codex section name is `context7`; the package itself remains
|
||||||
|
# `@upstash/context7-mcp`.
|
||||||
args = ["-y", "@upstash/context7-mcp@latest"]
|
args = ["-y", "@upstash/context7-mcp@latest"]
|
||||||
|
startup_timeout_sec = 30
|
||||||
|
|
||||||
|
[mcp_servers.exa]
|
||||||
|
url = "https://mcp.exa.ai/mcp"
|
||||||
|
|
||||||
[mcp_servers.memory]
|
[mcp_servers.memory]
|
||||||
command = "npx"
|
command = "npx"
|
||||||
args = ["-y", "@modelcontextprotocol/server-memory"]
|
args = ["-y", "@modelcontextprotocol/server-memory"]
|
||||||
|
startup_timeout_sec = 30
|
||||||
|
|
||||||
|
[mcp_servers.playwright]
|
||||||
|
command = "npx"
|
||||||
|
args = ["-y", "@playwright/mcp@latest", "--extension"]
|
||||||
|
startup_timeout_sec = 30
|
||||||
|
|
||||||
[mcp_servers.sequential-thinking]
|
[mcp_servers.sequential-thinking]
|
||||||
command = "npx"
|
command = "npx"
|
||||||
args = ["-y", "@modelcontextprotocol/server-sequential-thinking"]
|
args = ["-y", "@modelcontextprotocol/server-sequential-thinking"]
|
||||||
|
startup_timeout_sec = 30
|
||||||
|
|
||||||
# Additional MCP servers (uncomment as needed):
|
# Additional MCP servers (uncomment as needed):
|
||||||
# [mcp_servers.supabase]
|
# [mcp_servers.supabase]
|
||||||
@@ -62,19 +77,44 @@ args = ["-y", "@modelcontextprotocol/server-sequential-thinking"]
|
|||||||
# command = "npx"
|
# command = "npx"
|
||||||
# args = ["-y", "firecrawl-mcp"]
|
# args = ["-y", "firecrawl-mcp"]
|
||||||
#
|
#
|
||||||
# [mcp_servers.railway]
|
# [mcp_servers.fal-ai]
|
||||||
# command = "npx"
|
# command = "npx"
|
||||||
# args = ["-y", "@anthropic/railway-mcp"]
|
# args = ["-y", "fal-ai-mcp-server"]
|
||||||
|
#
|
||||||
|
# [mcp_servers.cloudflare]
|
||||||
|
# command = "npx"
|
||||||
|
# args = ["-y", "@cloudflare/mcp-server-cloudflare"]
|
||||||
|
|
||||||
# Features
|
|
||||||
[features]
|
[features]
|
||||||
web_search_request = true
|
# Codex multi-agent collaboration is stable and on by default in current builds.
|
||||||
|
# Keep the explicit toggle here so the repo documents its expectation clearly.
|
||||||
|
multi_agent = true
|
||||||
|
|
||||||
# Profiles — switch with CODEX_PROFILE=<name>
|
# Profiles — switch with `codex -p <name>`
|
||||||
[profiles.strict]
|
[profiles.strict]
|
||||||
approval_policy = "on-request"
|
approval_policy = "on-request"
|
||||||
sandbox_mode = "workspace-read"
|
sandbox_mode = "read-only"
|
||||||
|
web_search = "cached"
|
||||||
|
|
||||||
[profiles.yolo]
|
[profiles.yolo]
|
||||||
approval_policy = "never"
|
approval_policy = "never"
|
||||||
sandbox_mode = "workspace-write"
|
sandbox_mode = "workspace-write"
|
||||||
|
web_search = "live"
|
||||||
|
|
||||||
|
[agents]
|
||||||
|
# Multi-agent role limits and local role definitions.
|
||||||
|
# These map to `.codex/agents/*.toml` and mirror the repo's explorer/reviewer/docs workflow.
|
||||||
|
max_threads = 6
|
||||||
|
max_depth = 1
|
||||||
|
|
||||||
|
[agents.explorer]
|
||||||
|
description = "Read-only codebase explorer for gathering evidence before changes are proposed."
|
||||||
|
config_file = "agents/explorer.toml"
|
||||||
|
|
||||||
|
[agents.reviewer]
|
||||||
|
description = "PR reviewer focused on correctness, security, and missing tests."
|
||||||
|
config_file = "agents/reviewer.toml"
|
||||||
|
|
||||||
|
[agents.docs_researcher]
|
||||||
|
description = "Documentation specialist that verifies APIs, framework behavior, and release notes."
|
||||||
|
config_file = "agents/docs-researcher.toml"
|
||||||
|
|||||||
@@ -15,6 +15,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"beforeShellExecution": [
|
"beforeShellExecution": [
|
||||||
|
{
|
||||||
|
"command": "npx block-no-verify@1.1.2",
|
||||||
|
"event": "beforeShellExecution",
|
||||||
|
"description": "Block git hook-bypass flag to protect pre-commit, commit-msg, and pre-push hooks from being skipped"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"command": "node .cursor/hooks/before-shell-execution.js",
|
"command": "node .cursor/hooks/before-shell-execution.js",
|
||||||
"event": "beforeShellExecution",
|
"event": "beforeShellExecution",
|
||||||
|
|||||||
@@ -29,13 +29,14 @@ function transformToClaude(cursorInput, overrides = {}) {
|
|||||||
return {
|
return {
|
||||||
tool_input: {
|
tool_input: {
|
||||||
command: cursorInput.command || cursorInput.args?.command || '',
|
command: cursorInput.command || cursorInput.args?.command || '',
|
||||||
file_path: cursorInput.path || cursorInput.file || '',
|
file_path: cursorInput.path || cursorInput.file || cursorInput.args?.filePath || '',
|
||||||
...overrides.tool_input,
|
...overrides.tool_input,
|
||||||
},
|
},
|
||||||
tool_output: {
|
tool_output: {
|
||||||
output: cursorInput.output || cursorInput.result || '',
|
output: cursorInput.output || cursorInput.result || '',
|
||||||
...overrides.tool_output,
|
...overrides.tool_output,
|
||||||
},
|
},
|
||||||
|
transcript_path: cursorInput.transcript_path || cursorInput.transcriptPath || cursorInput.session?.transcript_path || '',
|
||||||
_cursor: {
|
_cursor: {
|
||||||
conversation_id: cursorInput.conversation_id,
|
conversation_id: cursorInput.conversation_id,
|
||||||
hook_event_name: cursorInput.hook_event_name,
|
hook_event_name: cursorInput.hook_event_name,
|
||||||
@@ -59,4 +60,22 @@ function runExistingHook(scriptName, stdinData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { readStdin, getPluginRoot, transformToClaude, runExistingHook };
|
function hookEnabled(hookId, allowedProfiles = ['standard', 'strict']) {
|
||||||
|
const rawProfile = String(process.env.ECC_HOOK_PROFILE || 'standard').toLowerCase();
|
||||||
|
const profile = ['minimal', 'standard', 'strict'].includes(rawProfile) ? rawProfile : 'standard';
|
||||||
|
|
||||||
|
const disabled = new Set(
|
||||||
|
String(process.env.ECC_DISABLED_HOOKS || '')
|
||||||
|
.split(',')
|
||||||
|
.map(v => v.trim().toLowerCase())
|
||||||
|
.filter(Boolean)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (disabled.has(String(hookId || '').toLowerCase())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return allowedProfiles.includes(profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { readStdin, getPluginRoot, transformToClaude, runExistingHook, hookEnabled };
|
||||||
|
|||||||
@@ -8,9 +8,8 @@ readStdin().then(raw => {
|
|||||||
});
|
});
|
||||||
const claudeStr = JSON.stringify(claudeInput);
|
const claudeStr = JSON.stringify(claudeInput);
|
||||||
|
|
||||||
// Run format, typecheck, and console.log warning sequentially
|
// Accumulate edited paths for batch format+typecheck at stop time
|
||||||
runExistingHook('post-edit-format.js', claudeStr);
|
runExistingHook('post-edit-accumulator.js', claudeStr);
|
||||||
runExistingHook('post-edit-typecheck.js', claudeStr);
|
|
||||||
runExistingHook('post-edit-console-warn.js', claudeStr);
|
runExistingHook('post-edit-console-warn.js', claudeStr);
|
||||||
} catch {}
|
} catch {}
|
||||||
process.stdout.write(raw);
|
process.stdout.write(raw);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
const { readStdin } = require('./adapter');
|
const { readStdin, hookEnabled } = require('./adapter');
|
||||||
|
|
||||||
readStdin().then(raw => {
|
readStdin().then(raw => {
|
||||||
try {
|
try {
|
||||||
const input = JSON.parse(raw);
|
const input = JSON.parse(raw || '{}');
|
||||||
const cmd = input.command || '';
|
const cmd = String(input.command || input.args?.command || '');
|
||||||
const output = input.output || input.result || '';
|
const output = String(input.output || input.result || '');
|
||||||
|
|
||||||
// PR creation logging
|
if (hookEnabled('post:bash:pr-created', ['standard', 'strict']) && /\bgh\s+pr\s+create\b/.test(cmd)) {
|
||||||
if (/gh pr create/.test(cmd)) {
|
|
||||||
const m = output.match(/https:\/\/github\.com\/[^/]+\/[^/]+\/pull\/\d+/);
|
const m = output.match(/https:\/\/github\.com\/[^/]+\/[^/]+\/pull\/\d+/);
|
||||||
if (m) {
|
if (m) {
|
||||||
console.error('[ECC] PR created: ' + m[0]);
|
console.error('[ECC] PR created: ' + m[0]);
|
||||||
@@ -17,10 +17,12 @@ readStdin().then(raw => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build completion notice
|
if (hookEnabled('post:bash:build-complete', ['standard', 'strict']) && /(npm run build|pnpm build|yarn build)/.test(cmd)) {
|
||||||
if (/(npm run build|pnpm build|yarn build)/.test(cmd)) {
|
|
||||||
console.error('[ECC] Build completed');
|
console.error('[ECC] Build completed');
|
||||||
}
|
}
|
||||||
} catch {}
|
} catch {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
process.stdout.write(raw);
|
process.stdout.write(raw);
|
||||||
}).catch(() => process.exit(0));
|
}).catch(() => process.exit(0));
|
||||||
|
|||||||
@@ -1,27 +1,41 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
const { readStdin } = require('./adapter');
|
const { readStdin, hookEnabled } = require('./adapter');
|
||||||
readStdin().then(raw => {
|
const { splitShellSegments } = require('../../scripts/lib/shell-split');
|
||||||
try {
|
|
||||||
const input = JSON.parse(raw);
|
|
||||||
const cmd = input.command || '';
|
|
||||||
|
|
||||||
// 1. Block dev server outside tmux
|
readStdin()
|
||||||
if (process.platform !== 'win32' && /(npm run dev\b|pnpm( run)? dev\b|yarn dev\b|bun run dev\b)/.test(cmd)) {
|
.then(raw => {
|
||||||
console.error('[ECC] BLOCKED: Dev server must run in tmux for log access');
|
try {
|
||||||
console.error('[ECC] Use: tmux new-session -d -s dev "npm run dev"');
|
const input = JSON.parse(raw || '{}');
|
||||||
process.exit(2);
|
const cmd = String(input.command || input.args?.command || '');
|
||||||
|
|
||||||
|
if (hookEnabled('pre:bash:dev-server-block', ['standard', 'strict']) && process.platform !== 'win32') {
|
||||||
|
const segments = splitShellSegments(cmd);
|
||||||
|
const tmuxLauncher = /^\s*tmux\s+(new|new-session|new-window|split-window)\b/;
|
||||||
|
const devPattern = /\b(npm\s+run\s+dev|pnpm(?:\s+run)?\s+dev|yarn\s+dev|bun\s+run\s+dev)\b/;
|
||||||
|
const hasBlockedDev = segments.some(segment => devPattern.test(segment) && !tmuxLauncher.test(segment));
|
||||||
|
if (hasBlockedDev) {
|
||||||
|
console.error('[ECC] BLOCKED: Dev server must run in tmux for log access');
|
||||||
|
console.error('[ECC] Use: tmux new-session -d -s dev "npm run dev"');
|
||||||
|
process.exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
hookEnabled('pre:bash:tmux-reminder', ['strict']) &&
|
||||||
|
process.platform !== 'win32' &&
|
||||||
|
!process.env.TMUX &&
|
||||||
|
/(npm (install|test)|pnpm (install|test)|yarn (install|test)?|bun (install|test)|cargo build|make\b|docker\b|pytest|vitest|playwright)/.test(cmd)
|
||||||
|
) {
|
||||||
|
console.error('[ECC] Consider running in tmux for session persistence');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hookEnabled('pre:bash:git-push-reminder', ['strict']) && /\bgit\s+push\b/.test(cmd)) {
|
||||||
|
console.error('[ECC] Review changes before push: git diff origin/main...HEAD');
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// noop
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Tmux reminder for long-running commands
|
process.stdout.write(raw);
|
||||||
if (process.platform !== 'win32' && !process.env.TMUX &&
|
})
|
||||||
/(npm (install|test)|pnpm (install|test)|yarn (install|test)?|bun (install|test)|cargo build|make\b|docker\b|pytest|vitest|playwright)/.test(cmd)) {
|
.catch(() => process.exit(0));
|
||||||
console.error('[ECC] Consider running in tmux for session persistence');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Git push review reminder
|
|
||||||
if (/git push/.test(cmd)) {
|
|
||||||
console.error('[ECC] Review changes before push: git diff origin/main...HEAD');
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
process.stdout.write(raw);
|
|
||||||
}).catch(() => process.exit(0));
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
const { readStdin, runExistingHook, transformToClaude } = require('./adapter');
|
const { readStdin, runExistingHook, transformToClaude, hookEnabled } = require('./adapter');
|
||||||
readStdin().then(raw => {
|
readStdin().then(raw => {
|
||||||
const input = JSON.parse(raw);
|
const input = JSON.parse(raw || '{}');
|
||||||
const claudeInput = transformToClaude(input);
|
const claudeInput = transformToClaude(input);
|
||||||
runExistingHook('session-end.js', claudeInput);
|
if (hookEnabled('session:end:marker', ['minimal', 'standard', 'strict'])) {
|
||||||
runExistingHook('evaluate-session.js', claudeInput);
|
runExistingHook('session-end-marker.js', claudeInput);
|
||||||
|
}
|
||||||
process.stdout.write(raw);
|
process.stdout.write(raw);
|
||||||
}).catch(() => process.exit(0));
|
}).catch(() => process.exit(0));
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
const { readStdin, runExistingHook, transformToClaude } = require('./adapter');
|
const { readStdin, runExistingHook, transformToClaude, hookEnabled } = require('./adapter');
|
||||||
readStdin().then(raw => {
|
readStdin().then(raw => {
|
||||||
const input = JSON.parse(raw);
|
const input = JSON.parse(raw || '{}');
|
||||||
const claudeInput = transformToClaude(input);
|
const claudeInput = transformToClaude(input);
|
||||||
runExistingHook('session-start.js', claudeInput);
|
if (hookEnabled('session:start', ['minimal', 'standard', 'strict'])) {
|
||||||
|
runExistingHook('session-start.js', claudeInput);
|
||||||
|
}
|
||||||
process.stdout.write(raw);
|
process.stdout.write(raw);
|
||||||
}).catch(() => process.exit(0));
|
}).catch(() => process.exit(0));
|
||||||
|
|||||||
@@ -1,7 +1,21 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
const { readStdin, runExistingHook, transformToClaude } = require('./adapter');
|
const { readStdin, runExistingHook, transformToClaude, hookEnabled } = require('./adapter');
|
||||||
readStdin().then(raw => {
|
readStdin().then(raw => {
|
||||||
const claudeInput = JSON.parse(raw || '{}');
|
const input = JSON.parse(raw || '{}');
|
||||||
runExistingHook('check-console-log.js', transformToClaude(claudeInput));
|
const claudeInput = transformToClaude(input);
|
||||||
|
|
||||||
|
if (hookEnabled('stop:check-console-log', ['standard', 'strict'])) {
|
||||||
|
runExistingHook('check-console-log.js', claudeInput);
|
||||||
|
}
|
||||||
|
if (hookEnabled('stop:session-end', ['minimal', 'standard', 'strict'])) {
|
||||||
|
runExistingHook('session-end.js', claudeInput);
|
||||||
|
}
|
||||||
|
if (hookEnabled('stop:evaluate-session', ['minimal', 'standard', 'strict'])) {
|
||||||
|
runExistingHook('evaluate-session.js', claudeInput);
|
||||||
|
}
|
||||||
|
if (hookEnabled('stop:cost-tracker', ['minimal', 'standard', 'strict'])) {
|
||||||
|
runExistingHook('cost-tracker.js', claudeInput);
|
||||||
|
}
|
||||||
|
|
||||||
process.stdout.write(raw);
|
process.stdout.write(raw);
|
||||||
}).catch(() => process.exit(0));
|
}).catch(() => process.exit(0));
|
||||||
|
|||||||
39
.cursor/rules/kotlin-coding-style.md
Normal file
39
.cursor/rules/kotlin-coding-style.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
description: "Kotlin coding style extending common rules"
|
||||||
|
globs: ["**/*.kt", "**/*.kts", "**/build.gradle.kts"]
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
# Kotlin Coding Style
|
||||||
|
|
||||||
|
> This file extends the common coding style rule with Kotlin-specific content.
|
||||||
|
|
||||||
|
## Formatting
|
||||||
|
|
||||||
|
- Auto-formatting via **ktfmt** or **ktlint** (configured in `kotlin-hooks.md`)
|
||||||
|
- Use trailing commas in multiline declarations
|
||||||
|
|
||||||
|
## Immutability
|
||||||
|
|
||||||
|
The global immutability requirement is enforced in the common coding style rule.
|
||||||
|
For Kotlin specifically:
|
||||||
|
|
||||||
|
- Prefer `val` over `var`
|
||||||
|
- Use immutable collection types (`List`, `Map`, `Set`)
|
||||||
|
- Use `data class` with `copy()` for immutable updates
|
||||||
|
|
||||||
|
## Null Safety
|
||||||
|
|
||||||
|
- Avoid `!!` -- use `?.`, `?:`, `require`, or `checkNotNull`
|
||||||
|
- Handle platform types explicitly at Java interop boundaries
|
||||||
|
|
||||||
|
## Expression Bodies
|
||||||
|
|
||||||
|
Prefer expression bodies for single-expression functions:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
fun isAdult(age: Int): Boolean = age >= 18
|
||||||
|
```
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
See skill: `kotlin-patterns` for comprehensive Kotlin idioms and patterns.
|
||||||
16
.cursor/rules/kotlin-hooks.md
Normal file
16
.cursor/rules/kotlin-hooks.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
description: "Kotlin hooks extending common rules"
|
||||||
|
globs: ["**/*.kt", "**/*.kts", "**/build.gradle.kts"]
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
# Kotlin Hooks
|
||||||
|
|
||||||
|
> This file extends the common hooks rule with Kotlin-specific content.
|
||||||
|
|
||||||
|
## PostToolUse Hooks
|
||||||
|
|
||||||
|
Configure in `~/.claude/settings.json`:
|
||||||
|
|
||||||
|
- **ktfmt/ktlint**: Auto-format `.kt` and `.kts` files after edit
|
||||||
|
- **detekt**: Run static analysis after editing Kotlin files
|
||||||
|
- **./gradlew build**: Verify compilation after changes
|
||||||
50
.cursor/rules/kotlin-patterns.md
Normal file
50
.cursor/rules/kotlin-patterns.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
description: "Kotlin patterns extending common rules"
|
||||||
|
globs: ["**/*.kt", "**/*.kts", "**/build.gradle.kts"]
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
# Kotlin Patterns
|
||||||
|
|
||||||
|
> This file extends the common patterns rule with Kotlin-specific content.
|
||||||
|
|
||||||
|
## Sealed Classes
|
||||||
|
|
||||||
|
Use sealed classes/interfaces for exhaustive type hierarchies:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
sealed class Result<out T> {
|
||||||
|
data class Success<T>(val data: T) : Result<T>()
|
||||||
|
data class Failure(val error: AppError) : Result<Nothing>()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Extension Functions
|
||||||
|
|
||||||
|
Add behavior without inheritance, scoped to where they're used:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
fun String.toSlug(): String =
|
||||||
|
lowercase().replace(Regex("[^a-z0-9\\s-]"), "").replace(Regex("\\s+"), "-")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Scope Functions
|
||||||
|
|
||||||
|
- `let`: Transform nullable or scoped result
|
||||||
|
- `apply`: Configure an object
|
||||||
|
- `also`: Side effects
|
||||||
|
- Avoid nesting scope functions
|
||||||
|
|
||||||
|
## Dependency Injection
|
||||||
|
|
||||||
|
Use Koin for DI in Ktor projects:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val appModule = module {
|
||||||
|
single<UserRepository> { ExposedUserRepository(get()) }
|
||||||
|
single { UserService(get()) }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
See skill: `kotlin-patterns` for comprehensive Kotlin patterns including coroutines, DSL builders, and delegation.
|
||||||
58
.cursor/rules/kotlin-security.md
Normal file
58
.cursor/rules/kotlin-security.md
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
description: "Kotlin security extending common rules"
|
||||||
|
globs: ["**/*.kt", "**/*.kts", "**/build.gradle.kts"]
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
# Kotlin Security
|
||||||
|
|
||||||
|
> This file extends the common security rule with Kotlin-specific content.
|
||||||
|
|
||||||
|
## Secret Management
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val apiKey = System.getenv("API_KEY")
|
||||||
|
?: throw IllegalStateException("API_KEY not configured")
|
||||||
|
```
|
||||||
|
|
||||||
|
## SQL Injection Prevention
|
||||||
|
|
||||||
|
Always use Exposed's parameterized queries:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// Good: Parameterized via Exposed DSL
|
||||||
|
UsersTable.selectAll().where { UsersTable.email eq email }
|
||||||
|
|
||||||
|
// Bad: String interpolation in raw SQL
|
||||||
|
exec("SELECT * FROM users WHERE email = '$email'")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
Use Ktor's Auth plugin with JWT:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
install(Authentication) {
|
||||||
|
jwt("jwt") {
|
||||||
|
verifier(
|
||||||
|
JWT.require(Algorithm.HMAC256(secret))
|
||||||
|
.withAudience(audience)
|
||||||
|
.withIssuer(issuer)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
validate { credential ->
|
||||||
|
val payload = credential.payload
|
||||||
|
if (payload.audience.contains(audience) &&
|
||||||
|
payload.issuer == issuer &&
|
||||||
|
payload.subject != null) {
|
||||||
|
JWTPrincipal(payload)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Null Safety as Security
|
||||||
|
|
||||||
|
Kotlin's type system prevents null-related vulnerabilities -- avoid `!!` to maintain this guarantee.
|
||||||
38
.cursor/rules/kotlin-testing.md
Normal file
38
.cursor/rules/kotlin-testing.md
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
description: "Kotlin testing extending common rules"
|
||||||
|
globs: ["**/*.kt", "**/*.kts", "**/build.gradle.kts"]
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
# Kotlin Testing
|
||||||
|
|
||||||
|
> This file extends the common testing rule with Kotlin-specific content.
|
||||||
|
|
||||||
|
## Framework
|
||||||
|
|
||||||
|
Use **Kotest** with spec styles (StringSpec, FunSpec, BehaviorSpec) and **MockK** for mocking.
|
||||||
|
|
||||||
|
## Coroutine Testing
|
||||||
|
|
||||||
|
Use `runTest` from `kotlinx-coroutines-test`:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
test("async operation completes") {
|
||||||
|
runTest {
|
||||||
|
val result = service.fetchData()
|
||||||
|
result.shouldNotBeEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Coverage
|
||||||
|
|
||||||
|
Use **Kover** for coverage reporting:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew koverHtmlReport
|
||||||
|
./gradlew koverVerify
|
||||||
|
```
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
See skill: `kotlin-testing` for detailed Kotest patterns, MockK usage, and property-based testing.
|
||||||
25
.cursor/rules/php-coding-style.md
Normal file
25
.cursor/rules/php-coding-style.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
description: "PHP coding style extending common rules"
|
||||||
|
globs: ["**/*.php", "**/composer.json"]
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
# PHP Coding Style
|
||||||
|
|
||||||
|
> This file extends the common coding style rule with PHP specific content.
|
||||||
|
|
||||||
|
## Standards
|
||||||
|
|
||||||
|
- Follow **PSR-12** formatting and naming conventions.
|
||||||
|
- Prefer `declare(strict_types=1);` in application code.
|
||||||
|
- Use scalar type hints, return types, and typed properties everywhere new code permits.
|
||||||
|
|
||||||
|
## Immutability
|
||||||
|
|
||||||
|
- Prefer immutable DTOs and value objects for data crossing service boundaries.
|
||||||
|
- Use `readonly` properties or immutable constructors for request/response payloads where possible.
|
||||||
|
- Keep arrays for simple maps; promote business-critical structures into explicit classes.
|
||||||
|
|
||||||
|
## Formatting
|
||||||
|
|
||||||
|
- Use **PHP-CS-Fixer** or **Laravel Pint** for formatting.
|
||||||
|
- Use **PHPStan** or **Psalm** for static analysis.
|
||||||
21
.cursor/rules/php-hooks.md
Normal file
21
.cursor/rules/php-hooks.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
description: "PHP hooks extending common rules"
|
||||||
|
globs: ["**/*.php", "**/composer.json", "**/phpstan.neon", "**/phpstan.neon.dist", "**/psalm.xml"]
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
# PHP Hooks
|
||||||
|
|
||||||
|
> This file extends the common hooks rule with PHP specific content.
|
||||||
|
|
||||||
|
## PostToolUse Hooks
|
||||||
|
|
||||||
|
Configure in `~/.claude/settings.json`:
|
||||||
|
|
||||||
|
- **Pint / PHP-CS-Fixer**: Auto-format edited `.php` files.
|
||||||
|
- **PHPStan / Psalm**: Run static analysis after PHP edits in typed codebases.
|
||||||
|
- **PHPUnit / Pest**: Run targeted tests for touched files or modules when edits affect behavior.
|
||||||
|
|
||||||
|
## Warnings
|
||||||
|
|
||||||
|
- Warn on `var_dump`, `dd`, `dump`, or `die()` left in edited files.
|
||||||
|
- Warn when edited PHP files add raw SQL or disable CSRF/session protections.
|
||||||
23
.cursor/rules/php-patterns.md
Normal file
23
.cursor/rules/php-patterns.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
description: "PHP patterns extending common rules"
|
||||||
|
globs: ["**/*.php", "**/composer.json"]
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
# PHP Patterns
|
||||||
|
|
||||||
|
> This file extends the common patterns rule with PHP specific content.
|
||||||
|
|
||||||
|
## Thin Controllers, Explicit Services
|
||||||
|
|
||||||
|
- Keep controllers focused on transport: auth, validation, serialization, status codes.
|
||||||
|
- Move business rules into application/domain services that are easy to test without HTTP bootstrapping.
|
||||||
|
|
||||||
|
## DTOs and Value Objects
|
||||||
|
|
||||||
|
- Replace shape-heavy associative arrays with DTOs for requests, commands, and external API payloads.
|
||||||
|
- Use value objects for money, identifiers, and constrained concepts.
|
||||||
|
|
||||||
|
## Dependency Injection
|
||||||
|
|
||||||
|
- Depend on interfaces or narrow service contracts, not framework globals.
|
||||||
|
- Pass collaborators through constructors so services are testable without service-locator lookups.
|
||||||
24
.cursor/rules/php-security.md
Normal file
24
.cursor/rules/php-security.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
description: "PHP security extending common rules"
|
||||||
|
globs: ["**/*.php", "**/composer.lock", "**/composer.json"]
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
# PHP Security
|
||||||
|
|
||||||
|
> This file extends the common security rule with PHP specific content.
|
||||||
|
|
||||||
|
## Database Safety
|
||||||
|
|
||||||
|
- Use prepared statements (`PDO`, Doctrine, Eloquent query builder) for all dynamic queries.
|
||||||
|
- Scope ORM mass-assignment carefully and whitelist writable fields.
|
||||||
|
|
||||||
|
## Secrets and Dependencies
|
||||||
|
|
||||||
|
- Load secrets from environment variables or a secret manager, never from committed config files.
|
||||||
|
- Run `composer audit` in CI and review package trust before adding dependencies.
|
||||||
|
|
||||||
|
## Auth and Session Safety
|
||||||
|
|
||||||
|
- Use `password_hash()` / `password_verify()` for password storage.
|
||||||
|
- Regenerate session identifiers after authentication and privilege changes.
|
||||||
|
- Enforce CSRF protection on state-changing web requests.
|
||||||
26
.cursor/rules/php-testing.md
Normal file
26
.cursor/rules/php-testing.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
description: "PHP testing extending common rules"
|
||||||
|
globs: ["**/*.php", "**/phpunit.xml", "**/phpunit.xml.dist", "**/composer.json"]
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
# PHP Testing
|
||||||
|
|
||||||
|
> This file extends the common testing rule with PHP specific content.
|
||||||
|
|
||||||
|
## Framework
|
||||||
|
|
||||||
|
Use **PHPUnit** as the default test framework. **Pest** is also acceptable when the project already uses it.
|
||||||
|
|
||||||
|
## Coverage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
vendor/bin/phpunit --coverage-text
|
||||||
|
# or
|
||||||
|
vendor/bin/pest --coverage
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test Organization
|
||||||
|
|
||||||
|
- Separate fast unit tests from framework/database integration tests.
|
||||||
|
- Use factory/builders for fixtures instead of large hand-written arrays.
|
||||||
|
- Keep HTTP/controller tests focused on transport and validation; move business rules into service-level tests.
|
||||||
85
.cursor/skills/article-writing/SKILL.md
Normal file
85
.cursor/skills/article-writing/SKILL.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
---
|
||||||
|
name: article-writing
|
||||||
|
description: Write articles, guides, blog posts, tutorials, newsletter issues, and other long-form content in a distinctive voice derived from supplied examples or brand guidance. Use when the user wants polished written content longer than a paragraph, especially when voice consistency, structure, and credibility matter.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Article Writing
|
||||||
|
|
||||||
|
Write long-form content that sounds like a real person or brand, not generic AI output.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- drafting blog posts, essays, launch posts, guides, tutorials, or newsletter issues
|
||||||
|
- turning notes, transcripts, or research into polished articles
|
||||||
|
- matching an existing founder, operator, or brand voice from examples
|
||||||
|
- tightening structure, pacing, and evidence in already-written long-form copy
|
||||||
|
|
||||||
|
## Core Rules
|
||||||
|
|
||||||
|
1. Lead with the concrete thing: example, output, anecdote, number, screenshot description, or code block.
|
||||||
|
2. Explain after the example, not before.
|
||||||
|
3. Prefer short, direct sentences over padded ones.
|
||||||
|
4. Use specific numbers when available and sourced.
|
||||||
|
5. Never invent biographical facts, company metrics, or customer evidence.
|
||||||
|
|
||||||
|
## Voice Capture Workflow
|
||||||
|
|
||||||
|
If the user wants a specific voice, collect one or more of:
|
||||||
|
- published articles
|
||||||
|
- newsletters
|
||||||
|
- X / LinkedIn posts
|
||||||
|
- docs or memos
|
||||||
|
- a short style guide
|
||||||
|
|
||||||
|
Then extract:
|
||||||
|
- sentence length and rhythm
|
||||||
|
- whether the voice is formal, conversational, or sharp
|
||||||
|
- favored rhetorical devices such as parentheses, lists, fragments, or questions
|
||||||
|
- tolerance for humor, opinion, and contrarian framing
|
||||||
|
- formatting habits such as headers, bullets, code blocks, and pull quotes
|
||||||
|
|
||||||
|
If no voice references are given, default to a direct, operator-style voice: concrete, practical, and low on hype.
|
||||||
|
|
||||||
|
## Banned Patterns
|
||||||
|
|
||||||
|
Delete and rewrite any of these:
|
||||||
|
- generic openings like "In today's rapidly evolving landscape"
|
||||||
|
- filler transitions such as "Moreover" and "Furthermore"
|
||||||
|
- hype phrases like "game-changer", "cutting-edge", or "revolutionary"
|
||||||
|
- vague claims without evidence
|
||||||
|
- biography or credibility claims not backed by provided context
|
||||||
|
|
||||||
|
## Writing Process
|
||||||
|
|
||||||
|
1. Clarify the audience and purpose.
|
||||||
|
2. Build a skeletal outline with one purpose per section.
|
||||||
|
3. Start each section with evidence, example, or scene.
|
||||||
|
4. Expand only where the next sentence earns its place.
|
||||||
|
5. Remove anything that sounds templated or self-congratulatory.
|
||||||
|
|
||||||
|
## Structure Guidance
|
||||||
|
|
||||||
|
### Technical Guides
|
||||||
|
- open with what the reader gets
|
||||||
|
- use code or terminal examples in every major section
|
||||||
|
- end with concrete takeaways, not a soft summary
|
||||||
|
|
||||||
|
### Essays / Opinion Pieces
|
||||||
|
- start with tension, contradiction, or a sharp observation
|
||||||
|
- keep one argument thread per section
|
||||||
|
- use examples that earn the opinion
|
||||||
|
|
||||||
|
### Newsletters
|
||||||
|
- keep the first screen strong
|
||||||
|
- mix insight with updates, not diary filler
|
||||||
|
- use clear section labels and easy skim structure
|
||||||
|
|
||||||
|
## Quality Gate
|
||||||
|
|
||||||
|
Before delivering:
|
||||||
|
- verify factual claims against provided sources
|
||||||
|
- remove filler and corporate language
|
||||||
|
- confirm the voice matches the supplied examples
|
||||||
|
- ensure every section adds new information
|
||||||
|
- check formatting for the intended platform
|
||||||
84
.cursor/skills/bun-runtime/SKILL.md
Normal file
84
.cursor/skills/bun-runtime/SKILL.md
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
---
|
||||||
|
name: bun-runtime
|
||||||
|
description: Bun as runtime, package manager, bundler, and test runner. When to choose Bun vs Node, migration notes, and Vercel support.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Bun Runtime
|
||||||
|
|
||||||
|
Bun is a fast all-in-one JavaScript runtime and toolkit: runtime, package manager, bundler, and test runner.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- **Prefer Bun** for: new JS/TS projects, scripts where install/run speed matters, Vercel deployments with Bun runtime, and when you want a single toolchain (run + install + test + build).
|
||||||
|
- **Prefer Node** for: maximum ecosystem compatibility, legacy tooling that assumes Node, or when a dependency has known Bun issues.
|
||||||
|
|
||||||
|
Use when: adopting Bun, migrating from Node, writing or debugging Bun scripts/tests, or configuring Bun on Vercel or other platforms.
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
- **Runtime**: Drop-in Node-compatible runtime (built on JavaScriptCore, implemented in Zig).
|
||||||
|
- **Package manager**: `bun install` is significantly faster than npm/yarn. Lockfile is `bun.lock` (text) by default in current Bun; older versions used `bun.lockb` (binary).
|
||||||
|
- **Bundler**: Built-in bundler and transpiler for apps and libraries.
|
||||||
|
- **Test runner**: Built-in `bun test` with Jest-like API.
|
||||||
|
|
||||||
|
**Migration from Node**: Replace `node script.js` with `bun run script.js` or `bun script.js`. Run `bun install` in place of `npm install`; most packages work. Use `bun run` for npm scripts; `bun x` for npx-style one-off runs. Node built-ins are supported; prefer Bun APIs where they exist for better performance.
|
||||||
|
|
||||||
|
**Vercel**: Set runtime to Bun in project settings. Build: `bun run build` or `bun build ./src/index.ts --outdir=dist`. Install: `bun install --frozen-lockfile` for reproducible deploys.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Run and install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies (creates/updates bun.lock or bun.lockb)
|
||||||
|
bun install
|
||||||
|
|
||||||
|
# Run a script or file
|
||||||
|
bun run dev
|
||||||
|
bun run src/index.ts
|
||||||
|
bun src/index.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
### Scripts and env
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun run --env-file=.env dev
|
||||||
|
FOO=bar bun run script.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun test
|
||||||
|
bun test --watch
|
||||||
|
```
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// test/example.test.ts
|
||||||
|
import { expect, test } from "bun:test";
|
||||||
|
|
||||||
|
test("add", () => {
|
||||||
|
expect(1 + 2).toBe(3);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Runtime API
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const file = Bun.file("package.json");
|
||||||
|
const json = await file.json();
|
||||||
|
|
||||||
|
Bun.serve({
|
||||||
|
port: 3000,
|
||||||
|
fetch(req) {
|
||||||
|
return new Response("Hello");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- Commit the lockfile (`bun.lock` or `bun.lockb`) for reproducible installs.
|
||||||
|
- Prefer `bun run` for scripts. For TypeScript, Bun runs `.ts` natively.
|
||||||
|
- Keep dependencies up to date; Bun and the ecosystem evolve quickly.
|
||||||
88
.cursor/skills/content-engine/SKILL.md
Normal file
88
.cursor/skills/content-engine/SKILL.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
---
|
||||||
|
name: content-engine
|
||||||
|
description: Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Content Engine
|
||||||
|
|
||||||
|
Turn one idea into strong, platform-native content instead of posting the same thing everywhere.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- writing X posts or threads
|
||||||
|
- drafting LinkedIn posts or launch updates
|
||||||
|
- scripting short-form video or YouTube explainers
|
||||||
|
- repurposing articles, podcasts, demos, or docs into social content
|
||||||
|
- building a lightweight content plan around a launch, milestone, or theme
|
||||||
|
|
||||||
|
## First Questions
|
||||||
|
|
||||||
|
Clarify:
|
||||||
|
- source asset: what are we adapting from
|
||||||
|
- audience: builders, investors, customers, operators, or general audience
|
||||||
|
- platform: X, LinkedIn, TikTok, YouTube, newsletter, or multi-platform
|
||||||
|
- goal: awareness, conversion, recruiting, authority, launch support, or engagement
|
||||||
|
|
||||||
|
## Core Rules
|
||||||
|
|
||||||
|
1. Adapt for the platform. Do not cross-post the same copy.
|
||||||
|
2. Hooks matter more than summaries.
|
||||||
|
3. Every post should carry one clear idea.
|
||||||
|
4. Use specifics over slogans.
|
||||||
|
5. Keep the ask small and clear.
|
||||||
|
|
||||||
|
## Platform Guidance
|
||||||
|
|
||||||
|
### X
|
||||||
|
- open fast
|
||||||
|
- one idea per post or per tweet in a thread
|
||||||
|
- keep links out of the main body unless necessary
|
||||||
|
- avoid hashtag spam
|
||||||
|
|
||||||
|
### LinkedIn
|
||||||
|
- strong first line
|
||||||
|
- short paragraphs
|
||||||
|
- more explicit framing around lessons, results, and takeaways
|
||||||
|
|
||||||
|
### TikTok / Short Video
|
||||||
|
- first 3 seconds must interrupt attention
|
||||||
|
- script around visuals, not just narration
|
||||||
|
- one demo, one claim, one CTA
|
||||||
|
|
||||||
|
### YouTube
|
||||||
|
- show the result early
|
||||||
|
- structure by chapter
|
||||||
|
- refresh the visual every 20-30 seconds
|
||||||
|
|
||||||
|
### Newsletter
|
||||||
|
- deliver one clear lens, not a bundle of unrelated items
|
||||||
|
- make section titles skimmable
|
||||||
|
- keep the opening paragraph doing real work
|
||||||
|
|
||||||
|
## Repurposing Flow
|
||||||
|
|
||||||
|
Default cascade:
|
||||||
|
1. anchor asset: article, video, demo, memo, or launch doc
|
||||||
|
2. extract 3-7 atomic ideas
|
||||||
|
3. write platform-native variants
|
||||||
|
4. trim repetition across outputs
|
||||||
|
5. align CTAs with platform intent
|
||||||
|
|
||||||
|
## Deliverables
|
||||||
|
|
||||||
|
When asked for a campaign, return:
|
||||||
|
- the core angle
|
||||||
|
- platform-specific drafts
|
||||||
|
- optional posting order
|
||||||
|
- optional CTA variants
|
||||||
|
- any missing inputs needed before publishing
|
||||||
|
|
||||||
|
## Quality Gate
|
||||||
|
|
||||||
|
Before delivering:
|
||||||
|
- each draft reads natively for its platform
|
||||||
|
- hooks are strong and specific
|
||||||
|
- no generic hype language
|
||||||
|
- no duplicated copy across platforms unless requested
|
||||||
|
- the CTA matches the content and audience
|
||||||
90
.cursor/skills/documentation-lookup/SKILL.md
Normal file
90
.cursor/skills/documentation-lookup/SKILL.md
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
---
|
||||||
|
name: documentation-lookup
|
||||||
|
description: Use up-to-date library and framework docs via Context7 MCP instead of training data. Activates for setup questions, API references, code examples, or when the user names a framework (e.g. React, Next.js, Prisma).
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Documentation Lookup (Context7)
|
||||||
|
|
||||||
|
When the user asks about libraries, frameworks, or APIs, fetch current documentation via the Context7 MCP (tools `resolve-library-id` and `query-docs`) instead of relying on training data.
|
||||||
|
|
||||||
|
## Core Concepts
|
||||||
|
|
||||||
|
- **Context7**: MCP server that exposes live documentation; use it instead of training data for libraries and APIs.
|
||||||
|
- **resolve-library-id**: Returns Context7-compatible library IDs (e.g. `/vercel/next.js`) from a library name and query.
|
||||||
|
- **query-docs**: Fetches documentation and code snippets for a given library ID and question. Always call resolve-library-id first to get a valid library ID.
|
||||||
|
|
||||||
|
## When to use
|
||||||
|
|
||||||
|
Activate when the user:
|
||||||
|
|
||||||
|
- Asks setup or configuration questions (e.g. "How do I configure Next.js middleware?")
|
||||||
|
- Requests code that depends on a library ("Write a Prisma query for...")
|
||||||
|
- Needs API or reference information ("What are the Supabase auth methods?")
|
||||||
|
- Mentions specific frameworks or libraries (React, Vue, Svelte, Express, Tailwind, Prisma, Supabase, etc.)
|
||||||
|
|
||||||
|
Use this skill whenever the request depends on accurate, up-to-date behavior of a library, framework, or API. Applies across harnesses that have the Context7 MCP configured (e.g. Claude Code, Cursor, Codex).
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
### Step 1: Resolve the Library ID
|
||||||
|
|
||||||
|
Call the **resolve-library-id** MCP tool with:
|
||||||
|
|
||||||
|
- **libraryName**: The library or product name taken from the user's question (e.g. `Next.js`, `Prisma`, `Supabase`).
|
||||||
|
- **query**: The user's full question. This improves relevance ranking of results.
|
||||||
|
|
||||||
|
You must obtain a Context7-compatible library ID (format `/org/project` or `/org/project/version`) before querying docs. Do not call query-docs without a valid library ID from this step.
|
||||||
|
|
||||||
|
### Step 2: Select the Best Match
|
||||||
|
|
||||||
|
From the resolution results, choose one result using:
|
||||||
|
|
||||||
|
- **Name match**: Prefer exact or closest match to what the user asked for.
|
||||||
|
- **Benchmark score**: Higher scores indicate better documentation quality (100 is highest).
|
||||||
|
- **Source reputation**: Prefer High or Medium reputation when available.
|
||||||
|
- **Version**: If the user specified a version (e.g. "React 19", "Next.js 15"), prefer a version-specific library ID if listed (e.g. `/org/project/v1.2.0`).
|
||||||
|
|
||||||
|
### Step 3: Fetch the Documentation
|
||||||
|
|
||||||
|
Call the **query-docs** MCP tool with:
|
||||||
|
|
||||||
|
- **libraryId**: The selected Context7 library ID from Step 2 (e.g. `/vercel/next.js`).
|
||||||
|
- **query**: The user's specific question or task. Be specific to get relevant snippets.
|
||||||
|
|
||||||
|
Limit: do not call query-docs (or resolve-library-id) more than 3 times per question. If the answer is unclear after 3 calls, state the uncertainty and use the best information you have rather than guessing.
|
||||||
|
|
||||||
|
### Step 4: Use the Documentation
|
||||||
|
|
||||||
|
- Answer the user's question using the fetched, current information.
|
||||||
|
- Include relevant code examples from the docs when helpful.
|
||||||
|
- Cite the library or version when it matters (e.g. "In Next.js 15...").
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Example: Next.js middleware
|
||||||
|
|
||||||
|
1. Call **resolve-library-id** with `libraryName: "Next.js"`, `query: "How do I set up Next.js middleware?"`.
|
||||||
|
2. From results, pick the best match (e.g. `/vercel/next.js`) by name and benchmark score.
|
||||||
|
3. Call **query-docs** with `libraryId: "/vercel/next.js"`, `query: "How do I set up Next.js middleware?"`.
|
||||||
|
4. Use the returned snippets and text to answer; include a minimal `middleware.ts` example from the docs if relevant.
|
||||||
|
|
||||||
|
### Example: Prisma query
|
||||||
|
|
||||||
|
1. Call **resolve-library-id** with `libraryName: "Prisma"`, `query: "How do I query with relations?"`.
|
||||||
|
2. Select the official Prisma library ID (e.g. `/prisma/prisma`).
|
||||||
|
3. Call **query-docs** with that `libraryId` and the query.
|
||||||
|
4. Return the Prisma Client pattern (e.g. `include` or `select`) with a short code snippet from the docs.
|
||||||
|
|
||||||
|
### Example: Supabase auth methods
|
||||||
|
|
||||||
|
1. Call **resolve-library-id** with `libraryName: "Supabase"`, `query: "What are the auth methods?"`.
|
||||||
|
2. Pick the Supabase docs library ID.
|
||||||
|
3. Call **query-docs**; summarize the auth methods and show minimal examples from the fetched docs.
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- **Be specific**: Use the user's full question as the query where possible for better relevance.
|
||||||
|
- **Version awareness**: When users mention versions, use version-specific library IDs from the resolve step when available.
|
||||||
|
- **Prefer official sources**: When multiple matches exist, prefer official or primary packages over community forks.
|
||||||
|
- **No sensitive data**: Redact API keys, passwords, tokens, and other secrets from any query sent to Context7. Treat the user's question as potentially containing secrets before passing it to resolve-library-id or query-docs.
|
||||||
184
.cursor/skills/frontend-slides/SKILL.md
Normal file
184
.cursor/skills/frontend-slides/SKILL.md
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
---
|
||||||
|
name: frontend-slides
|
||||||
|
description: Create stunning, animation-rich HTML presentations from scratch or by converting PowerPoint files. Use when the user wants to build a presentation, convert a PPT/PPTX to web, or create slides for a talk/pitch. Helps non-designers discover their aesthetic through visual exploration rather than abstract choices.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Frontend Slides
|
||||||
|
|
||||||
|
Create zero-dependency, animation-rich HTML presentations that run entirely in the browser.
|
||||||
|
|
||||||
|
Inspired by the visual exploration approach showcased in work by [zarazhangrui](https://github.com/zarazhangrui).
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- Creating a talk deck, pitch deck, workshop deck, or internal presentation
|
||||||
|
- Converting `.ppt` or `.pptx` slides into an HTML presentation
|
||||||
|
- Improving an existing HTML presentation's layout, motion, or typography
|
||||||
|
- Exploring presentation styles with a user who does not know their design preference yet
|
||||||
|
|
||||||
|
## Non-Negotiables
|
||||||
|
|
||||||
|
1. **Zero dependencies**: default to one self-contained HTML file with inline CSS and JS.
|
||||||
|
2. **Viewport fit is mandatory**: every slide must fit inside one viewport with no internal scrolling.
|
||||||
|
3. **Show, don't tell**: use visual previews instead of abstract style questionnaires.
|
||||||
|
4. **Distinctive design**: avoid generic purple-gradient, Inter-on-white, template-looking decks.
|
||||||
|
5. **Production quality**: keep code commented, accessible, responsive, and performant.
|
||||||
|
|
||||||
|
Before generating, read `STYLE_PRESETS.md` for the viewport-safe CSS base, density limits, preset catalog, and CSS gotchas.
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
### 1. Detect Mode
|
||||||
|
|
||||||
|
Choose one path:
|
||||||
|
- **New presentation**: user has a topic, notes, or full draft
|
||||||
|
- **PPT conversion**: user has `.ppt` or `.pptx`
|
||||||
|
- **Enhancement**: user already has HTML slides and wants improvements
|
||||||
|
|
||||||
|
### 2. Discover Content
|
||||||
|
|
||||||
|
Ask only the minimum needed:
|
||||||
|
- purpose: pitch, teaching, conference talk, internal update
|
||||||
|
- length: short (5-10), medium (10-20), long (20+)
|
||||||
|
- content state: finished copy, rough notes, topic only
|
||||||
|
|
||||||
|
If the user has content, ask them to paste it before styling.
|
||||||
|
|
||||||
|
### 3. Discover Style
|
||||||
|
|
||||||
|
Default to visual exploration.
|
||||||
|
|
||||||
|
If the user already knows the desired preset, skip previews and use it directly.
|
||||||
|
|
||||||
|
Otherwise:
|
||||||
|
1. Ask what feeling the deck should create: impressed, energized, focused, inspired.
|
||||||
|
2. Generate **3 single-slide preview files** in `.ecc-design/slide-previews/`.
|
||||||
|
3. Each preview must be self-contained, show typography/color/motion clearly, and stay under roughly 100 lines of slide content.
|
||||||
|
4. Ask the user which preview to keep or what elements to mix.
|
||||||
|
|
||||||
|
Use the preset guide in `STYLE_PRESETS.md` when mapping mood to style.
|
||||||
|
|
||||||
|
### 4. Build the Presentation
|
||||||
|
|
||||||
|
Output either:
|
||||||
|
- `presentation.html`
|
||||||
|
- `[presentation-name].html`
|
||||||
|
|
||||||
|
Use an `assets/` folder only when the deck contains extracted or user-supplied images.
|
||||||
|
|
||||||
|
Required structure:
|
||||||
|
- semantic slide sections
|
||||||
|
- a viewport-safe CSS base from `STYLE_PRESETS.md`
|
||||||
|
- CSS custom properties for theme values
|
||||||
|
- a presentation controller class for keyboard, wheel, and touch navigation
|
||||||
|
- Intersection Observer for reveal animations
|
||||||
|
- reduced-motion support
|
||||||
|
|
||||||
|
### 5. Enforce Viewport Fit
|
||||||
|
|
||||||
|
Treat this as a hard gate.
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
- every `.slide` must use `height: 100vh; height: 100dvh; overflow: hidden;`
|
||||||
|
- all type and spacing must scale with `clamp()`
|
||||||
|
- when content does not fit, split into multiple slides
|
||||||
|
- never solve overflow by shrinking text below readable sizes
|
||||||
|
- never allow scrollbars inside a slide
|
||||||
|
|
||||||
|
Use the density limits and mandatory CSS block in `STYLE_PRESETS.md`.
|
||||||
|
|
||||||
|
### 6. Validate
|
||||||
|
|
||||||
|
Check the finished deck at these sizes:
|
||||||
|
- 1920x1080
|
||||||
|
- 1280x720
|
||||||
|
- 768x1024
|
||||||
|
- 375x667
|
||||||
|
- 667x375
|
||||||
|
|
||||||
|
If browser automation is available, use it to verify no slide overflows and that keyboard navigation works.
|
||||||
|
|
||||||
|
### 7. Deliver
|
||||||
|
|
||||||
|
At handoff:
|
||||||
|
- delete temporary preview files unless the user wants to keep them
|
||||||
|
- open the deck with the platform-appropriate opener when useful
|
||||||
|
- summarize file path, preset used, slide count, and easy theme customization points
|
||||||
|
|
||||||
|
Use the correct opener for the current OS:
|
||||||
|
- macOS: `open file.html`
|
||||||
|
- Linux: `xdg-open file.html`
|
||||||
|
- Windows: `start "" file.html`
|
||||||
|
|
||||||
|
## PPT / PPTX Conversion
|
||||||
|
|
||||||
|
For PowerPoint conversion:
|
||||||
|
1. Prefer `python3` with `python-pptx` to extract text, images, and notes.
|
||||||
|
2. If `python-pptx` is unavailable, ask whether to install it or fall back to a manual/export-based workflow.
|
||||||
|
3. Preserve slide order, speaker notes, and extracted assets.
|
||||||
|
4. After extraction, run the same style-selection workflow as a new presentation.
|
||||||
|
|
||||||
|
Keep conversion cross-platform. Do not rely on macOS-only tools when Python can do the job.
|
||||||
|
|
||||||
|
## Implementation Requirements
|
||||||
|
|
||||||
|
### HTML / CSS
|
||||||
|
|
||||||
|
- Use inline CSS and JS unless the user explicitly wants a multi-file project.
|
||||||
|
- Fonts may come from Google Fonts or Fontshare.
|
||||||
|
- Prefer atmospheric backgrounds, strong type hierarchy, and a clear visual direction.
|
||||||
|
- Use abstract shapes, gradients, grids, noise, and geometry rather than illustrations.
|
||||||
|
|
||||||
|
### JavaScript
|
||||||
|
|
||||||
|
Include:
|
||||||
|
- keyboard navigation
|
||||||
|
- touch / swipe navigation
|
||||||
|
- mouse wheel navigation
|
||||||
|
- progress indicator or slide index
|
||||||
|
- reveal-on-enter animation triggers
|
||||||
|
|
||||||
|
### Accessibility
|
||||||
|
|
||||||
|
- use semantic structure (`main`, `section`, `nav`)
|
||||||
|
- keep contrast readable
|
||||||
|
- support keyboard-only navigation
|
||||||
|
- respect `prefers-reduced-motion`
|
||||||
|
|
||||||
|
## Content Density Limits
|
||||||
|
|
||||||
|
Use these maxima unless the user explicitly asks for denser slides and readability still holds:
|
||||||
|
|
||||||
|
| Slide type | Limit |
|
||||||
|
|------------|-------|
|
||||||
|
| Title | 1 heading + 1 subtitle + optional tagline |
|
||||||
|
| Content | 1 heading + 4-6 bullets or 2 short paragraphs |
|
||||||
|
| Feature grid | 6 cards max |
|
||||||
|
| Code | 8-10 lines max |
|
||||||
|
| Quote | 1 quote + attribution |
|
||||||
|
| Image | 1 image constrained by viewport |
|
||||||
|
|
||||||
|
## Anti-Patterns
|
||||||
|
|
||||||
|
- generic startup gradients with no visual identity
|
||||||
|
- system-font decks unless intentionally editorial
|
||||||
|
- long bullet walls
|
||||||
|
- code blocks that need scrolling
|
||||||
|
- fixed-height content boxes that break on short screens
|
||||||
|
- invalid negated CSS functions like `-clamp(...)`
|
||||||
|
|
||||||
|
## Related ECC Skills
|
||||||
|
|
||||||
|
- `frontend-patterns` for component and interaction patterns around the deck
|
||||||
|
- `liquid-glass-design` when a presentation intentionally borrows Apple glass aesthetics
|
||||||
|
- `e2e-testing` if you need automated browser verification for the final deck
|
||||||
|
|
||||||
|
## Deliverable Checklist
|
||||||
|
|
||||||
|
- presentation runs from a local file in a browser
|
||||||
|
- every slide fits the viewport without scrolling
|
||||||
|
- style is distinctive and intentional
|
||||||
|
- animation is meaningful, not noisy
|
||||||
|
- reduced motion is respected
|
||||||
|
- file paths and customization points are explained at handoff
|
||||||
330
.cursor/skills/frontend-slides/STYLE_PRESETS.md
Normal file
330
.cursor/skills/frontend-slides/STYLE_PRESETS.md
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
# Style Presets Reference
|
||||||
|
|
||||||
|
Curated visual styles for `frontend-slides`.
|
||||||
|
|
||||||
|
Use this file for:
|
||||||
|
- the mandatory viewport-fitting CSS base
|
||||||
|
- preset selection and mood mapping
|
||||||
|
- CSS gotchas and validation rules
|
||||||
|
|
||||||
|
Abstract shapes only. Avoid illustrations unless the user explicitly asks for them.
|
||||||
|
|
||||||
|
## Viewport Fit Is Non-Negotiable
|
||||||
|
|
||||||
|
Every slide must fully fit in one viewport.
|
||||||
|
|
||||||
|
### Golden Rule
|
||||||
|
|
||||||
|
```text
|
||||||
|
Each slide = exactly one viewport height.
|
||||||
|
Too much content = split into more slides.
|
||||||
|
Never scroll inside a slide.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Density Limits
|
||||||
|
|
||||||
|
| Slide Type | Maximum Content |
|
||||||
|
|------------|-----------------|
|
||||||
|
| Title slide | 1 heading + 1 subtitle + optional tagline |
|
||||||
|
| Content slide | 1 heading + 4-6 bullets or 2 paragraphs |
|
||||||
|
| Feature grid | 6 cards maximum |
|
||||||
|
| Code slide | 8-10 lines maximum |
|
||||||
|
| Quote slide | 1 quote + attribution |
|
||||||
|
| Image slide | 1 image, ideally under 60vh |
|
||||||
|
|
||||||
|
## Mandatory Base CSS
|
||||||
|
|
||||||
|
Copy this block into every generated presentation and then theme on top of it.
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* ===========================================
|
||||||
|
VIEWPORT FITTING: MANDATORY BASE STYLES
|
||||||
|
=========================================== */
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-snap-type: y mandatory;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
height: 100dvh;
|
||||||
|
overflow: hidden;
|
||||||
|
scroll-snap-align: start;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-content {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
max-height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: var(--slide-padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--title-size: clamp(1.5rem, 5vw, 4rem);
|
||||||
|
--h2-size: clamp(1.25rem, 3.5vw, 2.5rem);
|
||||||
|
--h3-size: clamp(1rem, 2.5vw, 1.75rem);
|
||||||
|
--body-size: clamp(0.75rem, 1.5vw, 1.125rem);
|
||||||
|
--small-size: clamp(0.65rem, 1vw, 0.875rem);
|
||||||
|
|
||||||
|
--slide-padding: clamp(1rem, 4vw, 4rem);
|
||||||
|
--content-gap: clamp(0.5rem, 2vw, 2rem);
|
||||||
|
--element-gap: clamp(0.25rem, 1vw, 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card, .container, .content-box {
|
||||||
|
max-width: min(90vw, 1000px);
|
||||||
|
max-height: min(80vh, 700px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-list, .bullet-list {
|
||||||
|
gap: clamp(0.4rem, 1vh, 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-list li, .bullet-list li {
|
||||||
|
font-size: var(--body-size);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
|
||||||
|
gap: clamp(0.5rem, 1.5vw, 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
img, .image-container {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: min(50vh, 400px);
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-height: 700px) {
|
||||||
|
:root {
|
||||||
|
--slide-padding: clamp(0.75rem, 3vw, 2rem);
|
||||||
|
--content-gap: clamp(0.4rem, 1.5vw, 1rem);
|
||||||
|
--title-size: clamp(1.25rem, 4.5vw, 2.5rem);
|
||||||
|
--h2-size: clamp(1rem, 3vw, 1.75rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-height: 600px) {
|
||||||
|
:root {
|
||||||
|
--slide-padding: clamp(0.5rem, 2.5vw, 1.5rem);
|
||||||
|
--content-gap: clamp(0.3rem, 1vw, 0.75rem);
|
||||||
|
--title-size: clamp(1.1rem, 4vw, 2rem);
|
||||||
|
--body-size: clamp(0.7rem, 1.2vw, 0.95rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dots, .keyboard-hint, .decorative {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-height: 500px) {
|
||||||
|
:root {
|
||||||
|
--slide-padding: clamp(0.4rem, 2vw, 1rem);
|
||||||
|
--title-size: clamp(1rem, 3.5vw, 1.5rem);
|
||||||
|
--h2-size: clamp(0.9rem, 2.5vw, 1.25rem);
|
||||||
|
--body-size: clamp(0.65rem, 1vw, 0.85rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
:root {
|
||||||
|
--title-size: clamp(1.25rem, 7vw, 2.5rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
*, *::before, *::after {
|
||||||
|
animation-duration: 0.01ms !important;
|
||||||
|
transition-duration: 0.2s !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Viewport Checklist
|
||||||
|
|
||||||
|
- every `.slide` has `height: 100vh`, `height: 100dvh`, and `overflow: hidden`
|
||||||
|
- all typography uses `clamp()`
|
||||||
|
- all spacing uses `clamp()` or viewport units
|
||||||
|
- images have `max-height` constraints
|
||||||
|
- grids adapt with `auto-fit` + `minmax()`
|
||||||
|
- short-height breakpoints exist at `700px`, `600px`, and `500px`
|
||||||
|
- if anything feels cramped, split the slide
|
||||||
|
|
||||||
|
## Mood to Preset Mapping
|
||||||
|
|
||||||
|
| Mood | Good Presets |
|
||||||
|
|------|--------------|
|
||||||
|
| Impressed / Confident | Bold Signal, Electric Studio, Dark Botanical |
|
||||||
|
| Excited / Energized | Creative Voltage, Neon Cyber, Split Pastel |
|
||||||
|
| Calm / Focused | Notebook Tabs, Paper & Ink, Swiss Modern |
|
||||||
|
| Inspired / Moved | Dark Botanical, Vintage Editorial, Pastel Geometry |
|
||||||
|
|
||||||
|
## Preset Catalog
|
||||||
|
|
||||||
|
### 1. Bold Signal
|
||||||
|
|
||||||
|
- Vibe: confident, high-impact, keynote-ready
|
||||||
|
- Best for: pitch decks, launches, statements
|
||||||
|
- Fonts: Archivo Black + Space Grotesk
|
||||||
|
- Palette: charcoal base, hot orange focal card, crisp white text
|
||||||
|
- Signature: oversized section numbers, high-contrast card on dark field
|
||||||
|
|
||||||
|
### 2. Electric Studio
|
||||||
|
|
||||||
|
- Vibe: clean, bold, agency-polished
|
||||||
|
- Best for: client presentations, strategic reviews
|
||||||
|
- Fonts: Manrope only
|
||||||
|
- Palette: black, white, saturated cobalt accent
|
||||||
|
- Signature: two-panel split and sharp editorial alignment
|
||||||
|
|
||||||
|
### 3. Creative Voltage
|
||||||
|
|
||||||
|
- Vibe: energetic, retro-modern, playful confidence
|
||||||
|
- Best for: creative studios, brand work, product storytelling
|
||||||
|
- Fonts: Syne + Space Mono
|
||||||
|
- Palette: electric blue, neon yellow, deep navy
|
||||||
|
- Signature: halftone textures, badges, punchy contrast
|
||||||
|
|
||||||
|
### 4. Dark Botanical
|
||||||
|
|
||||||
|
- Vibe: elegant, premium, atmospheric
|
||||||
|
- Best for: luxury brands, thoughtful narratives, premium product decks
|
||||||
|
- Fonts: Cormorant + IBM Plex Sans
|
||||||
|
- Palette: near-black, warm ivory, blush, gold, terracotta
|
||||||
|
- Signature: blurred abstract circles, fine rules, restrained motion
|
||||||
|
|
||||||
|
### 5. Notebook Tabs
|
||||||
|
|
||||||
|
- Vibe: editorial, organized, tactile
|
||||||
|
- Best for: reports, reviews, structured storytelling
|
||||||
|
- Fonts: Bodoni Moda + DM Sans
|
||||||
|
- Palette: cream paper on charcoal with pastel tabs
|
||||||
|
- Signature: paper sheet, colored side tabs, binder details
|
||||||
|
|
||||||
|
### 6. Pastel Geometry
|
||||||
|
|
||||||
|
- Vibe: approachable, modern, friendly
|
||||||
|
- Best for: product overviews, onboarding, lighter brand decks
|
||||||
|
- Fonts: Plus Jakarta Sans only
|
||||||
|
- Palette: pale blue field, cream card, soft pink/mint/lavender accents
|
||||||
|
- Signature: vertical pills, rounded cards, soft shadows
|
||||||
|
|
||||||
|
### 7. Split Pastel
|
||||||
|
|
||||||
|
- Vibe: playful, modern, creative
|
||||||
|
- Best for: agency intros, workshops, portfolios
|
||||||
|
- Fonts: Outfit only
|
||||||
|
- Palette: peach + lavender split with mint badges
|
||||||
|
- Signature: split backdrop, rounded tags, light grid overlays
|
||||||
|
|
||||||
|
### 8. Vintage Editorial
|
||||||
|
|
||||||
|
- Vibe: witty, personality-driven, magazine-inspired
|
||||||
|
- Best for: personal brands, opinionated talks, storytelling
|
||||||
|
- Fonts: Fraunces + Work Sans
|
||||||
|
- Palette: cream, charcoal, dusty warm accents
|
||||||
|
- Signature: geometric accents, bordered callouts, punchy serif headlines
|
||||||
|
|
||||||
|
### 9. Neon Cyber
|
||||||
|
|
||||||
|
- Vibe: futuristic, techy, kinetic
|
||||||
|
- Best for: AI, infra, dev tools, future-of-X talks
|
||||||
|
- Fonts: Clash Display + Satoshi
|
||||||
|
- Palette: midnight navy, cyan, magenta
|
||||||
|
- Signature: glow, particles, grids, data-radar energy
|
||||||
|
|
||||||
|
### 10. Terminal Green
|
||||||
|
|
||||||
|
- Vibe: developer-focused, hacker-clean
|
||||||
|
- Best for: APIs, CLI tools, engineering demos
|
||||||
|
- Fonts: JetBrains Mono only
|
||||||
|
- Palette: GitHub dark + terminal green
|
||||||
|
- Signature: scan lines, command-line framing, precise monospace rhythm
|
||||||
|
|
||||||
|
### 11. Swiss Modern
|
||||||
|
|
||||||
|
- Vibe: minimal, precise, data-forward
|
||||||
|
- Best for: corporate, product strategy, analytics
|
||||||
|
- Fonts: Archivo + Nunito
|
||||||
|
- Palette: white, black, signal red
|
||||||
|
- Signature: visible grids, asymmetry, geometric discipline
|
||||||
|
|
||||||
|
### 12. Paper & Ink
|
||||||
|
|
||||||
|
- Vibe: literary, thoughtful, story-driven
|
||||||
|
- Best for: essays, keynote narratives, manifesto decks
|
||||||
|
- Fonts: Cormorant Garamond + Source Serif 4
|
||||||
|
- Palette: warm cream, charcoal, crimson accent
|
||||||
|
- Signature: pull quotes, drop caps, elegant rules
|
||||||
|
|
||||||
|
## Direct Selection Prompts
|
||||||
|
|
||||||
|
If the user already knows the style they want, let them pick directly from the preset names above instead of forcing preview generation.
|
||||||
|
|
||||||
|
## Animation Feel Mapping
|
||||||
|
|
||||||
|
| Feeling | Motion Direction |
|
||||||
|
|---------|------------------|
|
||||||
|
| Dramatic / Cinematic | slow fades, parallax, large scale-ins |
|
||||||
|
| Techy / Futuristic | glow, particles, grid motion, scramble text |
|
||||||
|
| Playful / Friendly | springy easing, rounded shapes, floating motion |
|
||||||
|
| Professional / Corporate | subtle 200-300ms transitions, clean slides |
|
||||||
|
| Calm / Minimal | very restrained movement, whitespace-first |
|
||||||
|
| Editorial / Magazine | strong hierarchy, staggered text and image interplay |
|
||||||
|
|
||||||
|
## CSS Gotcha: Negating Functions
|
||||||
|
|
||||||
|
Never write these:
|
||||||
|
|
||||||
|
```css
|
||||||
|
right: -clamp(28px, 3.5vw, 44px);
|
||||||
|
margin-left: -min(10vw, 100px);
|
||||||
|
```
|
||||||
|
|
||||||
|
Browsers ignore them silently.
|
||||||
|
|
||||||
|
Always write this instead:
|
||||||
|
|
||||||
|
```css
|
||||||
|
right: calc(-1 * clamp(28px, 3.5vw, 44px));
|
||||||
|
margin-left: calc(-1 * min(10vw, 100px));
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation Sizes
|
||||||
|
|
||||||
|
Test at minimum:
|
||||||
|
- Desktop: `1920x1080`, `1440x900`, `1280x720`
|
||||||
|
- Tablet: `1024x768`, `768x1024`
|
||||||
|
- Mobile: `375x667`, `414x896`
|
||||||
|
- Landscape phone: `667x375`, `896x414`
|
||||||
|
|
||||||
|
## Anti-Patterns
|
||||||
|
|
||||||
|
Do not use:
|
||||||
|
- purple-on-white startup templates
|
||||||
|
- Inter / Roboto / Arial as the visual voice unless the user explicitly wants utilitarian neutrality
|
||||||
|
- bullet walls, tiny type, or code blocks that require scrolling
|
||||||
|
- decorative illustrations when abstract geometry would do the job better
|
||||||
96
.cursor/skills/investor-materials/SKILL.md
Normal file
96
.cursor/skills/investor-materials/SKILL.md
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
---
|
||||||
|
name: investor-materials
|
||||||
|
description: Create and update pitch decks, one-pagers, investor memos, accelerator applications, financial models, and fundraising materials. Use when the user needs investor-facing documents, projections, use-of-funds tables, milestone plans, or materials that must stay internally consistent across multiple fundraising assets.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Investor Materials
|
||||||
|
|
||||||
|
Build investor-facing materials that are consistent, credible, and easy to defend.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- creating or revising a pitch deck
|
||||||
|
- writing an investor memo or one-pager
|
||||||
|
- building a financial model, milestone plan, or use-of-funds table
|
||||||
|
- answering accelerator or incubator application questions
|
||||||
|
- aligning multiple fundraising docs around one source of truth
|
||||||
|
|
||||||
|
## Golden Rule
|
||||||
|
|
||||||
|
All investor materials must agree with each other.
|
||||||
|
|
||||||
|
Create or confirm a single source of truth before writing:
|
||||||
|
- traction metrics
|
||||||
|
- pricing and revenue assumptions
|
||||||
|
- raise size and instrument
|
||||||
|
- use of funds
|
||||||
|
- team bios and titles
|
||||||
|
- milestones and timelines
|
||||||
|
|
||||||
|
If conflicting numbers appear, stop and resolve them before drafting.
|
||||||
|
|
||||||
|
## Core Workflow
|
||||||
|
|
||||||
|
1. inventory the canonical facts
|
||||||
|
2. identify missing assumptions
|
||||||
|
3. choose the asset type
|
||||||
|
4. draft the asset with explicit logic
|
||||||
|
5. cross-check every number against the source of truth
|
||||||
|
|
||||||
|
## Asset Guidance
|
||||||
|
|
||||||
|
### Pitch Deck
|
||||||
|
Recommended flow:
|
||||||
|
1. company + wedge
|
||||||
|
2. problem
|
||||||
|
3. solution
|
||||||
|
4. product / demo
|
||||||
|
5. market
|
||||||
|
6. business model
|
||||||
|
7. traction
|
||||||
|
8. team
|
||||||
|
9. competition / differentiation
|
||||||
|
10. ask
|
||||||
|
11. use of funds / milestones
|
||||||
|
12. appendix
|
||||||
|
|
||||||
|
If the user wants a web-native deck, pair this skill with `frontend-slides`.
|
||||||
|
|
||||||
|
### One-Pager / Memo
|
||||||
|
- state what the company does in one clean sentence
|
||||||
|
- show why now
|
||||||
|
- include traction and proof points early
|
||||||
|
- make the ask precise
|
||||||
|
- keep claims easy to verify
|
||||||
|
|
||||||
|
### Financial Model
|
||||||
|
Include:
|
||||||
|
- explicit assumptions
|
||||||
|
- bear / base / bull cases when useful
|
||||||
|
- clean layer-by-layer revenue logic
|
||||||
|
- milestone-linked spending
|
||||||
|
- sensitivity analysis where the decision hinges on assumptions
|
||||||
|
|
||||||
|
### Accelerator Applications
|
||||||
|
- answer the exact question asked
|
||||||
|
- prioritize traction, insight, and team advantage
|
||||||
|
- avoid puffery
|
||||||
|
- keep internal metrics consistent with the deck and model
|
||||||
|
|
||||||
|
## Red Flags to Avoid
|
||||||
|
|
||||||
|
- unverifiable claims
|
||||||
|
- fuzzy market sizing without assumptions
|
||||||
|
- inconsistent team roles or titles
|
||||||
|
- revenue math that does not sum cleanly
|
||||||
|
- inflated certainty where assumptions are fragile
|
||||||
|
|
||||||
|
## Quality Gate
|
||||||
|
|
||||||
|
Before delivering:
|
||||||
|
- every number matches the current source of truth
|
||||||
|
- use of funds and revenue layers sum correctly
|
||||||
|
- assumptions are visible, not buried
|
||||||
|
- the story is clear without hype language
|
||||||
|
- the final asset is defensible in a partner meeting
|
||||||
76
.cursor/skills/investor-outreach/SKILL.md
Normal file
76
.cursor/skills/investor-outreach/SKILL.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
---
|
||||||
|
name: investor-outreach
|
||||||
|
description: Draft cold emails, warm intro blurbs, follow-ups, update emails, and investor communications for fundraising. Use when the user wants outreach to angels, VCs, strategic investors, or accelerators and needs concise, personalized, investor-facing messaging.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Investor Outreach
|
||||||
|
|
||||||
|
Write investor communication that is short, personalized, and easy to act on.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- writing a cold email to an investor
|
||||||
|
- drafting a warm intro request
|
||||||
|
- sending follow-ups after a meeting or no response
|
||||||
|
- writing investor updates during a process
|
||||||
|
- tailoring outreach based on fund thesis or partner fit
|
||||||
|
|
||||||
|
## Core Rules
|
||||||
|
|
||||||
|
1. Personalize every outbound message.
|
||||||
|
2. Keep the ask low-friction.
|
||||||
|
3. Use proof, not adjectives.
|
||||||
|
4. Stay concise.
|
||||||
|
5. Never send generic copy that could go to any investor.
|
||||||
|
|
||||||
|
## Cold Email Structure
|
||||||
|
|
||||||
|
1. subject line: short and specific
|
||||||
|
2. opener: why this investor specifically
|
||||||
|
3. pitch: what the company does, why now, what proof matters
|
||||||
|
4. ask: one concrete next step
|
||||||
|
5. sign-off: name, role, one credibility anchor if needed
|
||||||
|
|
||||||
|
## Personalization Sources
|
||||||
|
|
||||||
|
Reference one or more of:
|
||||||
|
- relevant portfolio companies
|
||||||
|
- a public thesis, talk, post, or article
|
||||||
|
- a mutual connection
|
||||||
|
- a clear market or product fit with the investor's focus
|
||||||
|
|
||||||
|
If that context is missing, ask for it or state that the draft is a template awaiting personalization.
|
||||||
|
|
||||||
|
## Follow-Up Cadence
|
||||||
|
|
||||||
|
Default:
|
||||||
|
- day 0: initial outbound
|
||||||
|
- day 4-5: short follow-up with one new data point
|
||||||
|
- day 10-12: final follow-up with a clean close
|
||||||
|
|
||||||
|
Do not keep nudging after that unless the user wants a longer sequence.
|
||||||
|
|
||||||
|
## Warm Intro Requests
|
||||||
|
|
||||||
|
Make life easy for the connector:
|
||||||
|
- explain why the intro is a fit
|
||||||
|
- include a forwardable blurb
|
||||||
|
- keep the forwardable blurb under 100 words
|
||||||
|
|
||||||
|
## Post-Meeting Updates
|
||||||
|
|
||||||
|
Include:
|
||||||
|
- the specific thing discussed
|
||||||
|
- the answer or update promised
|
||||||
|
- one new proof point if available
|
||||||
|
- the next step
|
||||||
|
|
||||||
|
## Quality Gate
|
||||||
|
|
||||||
|
Before delivering:
|
||||||
|
- message is personalized
|
||||||
|
- the ask is explicit
|
||||||
|
- there is no fluff or begging language
|
||||||
|
- the proof point is concrete
|
||||||
|
- word count stays tight
|
||||||
75
.cursor/skills/market-research/SKILL.md
Normal file
75
.cursor/skills/market-research/SKILL.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
---
|
||||||
|
name: market-research
|
||||||
|
description: Conduct market research, competitive analysis, investor due diligence, and industry intelligence with source attribution and decision-oriented summaries. Use when the user wants market sizing, competitor comparisons, fund research, technology scans, or research that informs business decisions.
|
||||||
|
origin: ECC
|
||||||
|
---
|
||||||
|
|
||||||
|
# Market Research
|
||||||
|
|
||||||
|
Produce research that supports decisions, not research theater.
|
||||||
|
|
||||||
|
## When to Activate
|
||||||
|
|
||||||
|
- researching a market, category, company, investor, or technology trend
|
||||||
|
- building TAM/SAM/SOM estimates
|
||||||
|
- comparing competitors or adjacent products
|
||||||
|
- preparing investor dossiers before outreach
|
||||||
|
- pressure-testing a thesis before building, funding, or entering a market
|
||||||
|
|
||||||
|
## Research Standards
|
||||||
|
|
||||||
|
1. Every important claim needs a source.
|
||||||
|
2. Prefer recent data and call out stale data.
|
||||||
|
3. Include contrarian evidence and downside cases.
|
||||||
|
4. Translate findings into a decision, not just a summary.
|
||||||
|
5. Separate fact, inference, and recommendation clearly.
|
||||||
|
|
||||||
|
## Common Research Modes
|
||||||
|
|
||||||
|
### Investor / Fund Diligence
|
||||||
|
Collect:
|
||||||
|
- fund size, stage, and typical check size
|
||||||
|
- relevant portfolio companies
|
||||||
|
- public thesis and recent activity
|
||||||
|
- reasons the fund is or is not a fit
|
||||||
|
- any obvious red flags or mismatches
|
||||||
|
|
||||||
|
### Competitive Analysis
|
||||||
|
Collect:
|
||||||
|
- product reality, not marketing copy
|
||||||
|
- funding and investor history if public
|
||||||
|
- traction metrics if public
|
||||||
|
- distribution and pricing clues
|
||||||
|
- strengths, weaknesses, and positioning gaps
|
||||||
|
|
||||||
|
### Market Sizing
|
||||||
|
Use:
|
||||||
|
- top-down estimates from reports or public datasets
|
||||||
|
- bottom-up sanity checks from realistic customer acquisition assumptions
|
||||||
|
- explicit assumptions for every leap in logic
|
||||||
|
|
||||||
|
### Technology / Vendor Research
|
||||||
|
Collect:
|
||||||
|
- how it works
|
||||||
|
- trade-offs and adoption signals
|
||||||
|
- integration complexity
|
||||||
|
- lock-in, security, compliance, and operational risk
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
Default structure:
|
||||||
|
1. executive summary
|
||||||
|
2. key findings
|
||||||
|
3. implications
|
||||||
|
4. risks and caveats
|
||||||
|
5. recommendation
|
||||||
|
6. sources
|
||||||
|
|
||||||
|
## Quality Gate
|
||||||
|
|
||||||
|
Before delivering:
|
||||||
|
- all numbers are sourced or labeled as estimates
|
||||||
|
- old data is flagged
|
||||||
|
- the recommendation follows from the evidence
|
||||||
|
- risks and counterarguments are included
|
||||||
|
- the output makes a decision easier
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user