Compare commits
578 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6fcafeb1c | ||
|
|
72d742e153 | ||
|
|
7b0386d917 | ||
|
|
895b4be37e | ||
|
|
36d8f13a1e | ||
|
|
390f5146bf | ||
|
|
de66e10cd0 | ||
|
|
48dc1cf173 | ||
|
|
5e50e08885 | ||
|
|
9e8b0cb0b0 | ||
|
|
204eef574c | ||
|
|
4934681cd2 | ||
|
|
28f5603bc2 | ||
|
|
336c4f838a | ||
|
|
43a3e619a1 | ||
|
|
b2a92ba052 | ||
|
|
3c8fc0fd16 | ||
|
|
980e4f0bb2 | ||
|
|
13385c7c4d | ||
|
|
5f3de01dba | ||
|
|
5ad4aae76b | ||
|
|
f2f77ff889 | ||
|
|
d661d27ef4 | ||
|
|
3956e5408b | ||
|
|
aaf763c3a6 | ||
|
|
7eb9c23c32 | ||
|
|
9b1d761c67 | ||
|
|
550b965a69 | ||
|
|
991bd993ac | ||
|
|
5c0d8b3029 | ||
|
|
947764127b | ||
|
|
f8c6f0ef73 | ||
|
|
de981da0ec | ||
|
|
d767725c6e | ||
|
|
ad21a38689 | ||
|
|
3378ecea57 | ||
|
|
d39264b47c | ||
|
|
95d3adda6d | ||
|
|
390c8b8b49 | ||
|
|
4226ca8052 | ||
|
|
bd99c01e3f | ||
|
|
4d5f1d20be | ||
|
|
ab2f84ab10 | ||
|
|
f1b60f8ef4 | ||
|
|
07021b927e | ||
|
|
f9d7053cb1 | ||
|
|
0e451065e3 | ||
|
|
223f5a30f8 | ||
|
|
4fb7e0bc29 | ||
|
|
d33b2671cf | ||
|
|
4c90a52d54 | ||
|
|
061882ba79 | ||
|
|
e7ac425107 | ||
|
|
752753bf72 | ||
|
|
dbe942214d | ||
|
|
07891681fb | ||
|
|
ce01a273b3 | ||
|
|
11c4e1e516 | ||
|
|
effadea79f | ||
|
|
844f4a35cc | ||
|
|
e608baad6e | ||
|
|
5a9c275418 | ||
|
|
81e316bc89 | ||
|
|
051f93f59f | ||
|
|
6d22863f8d | ||
|
|
f8eb840d11 | ||
|
|
58746dc785 | ||
|
|
2598479c83 | ||
|
|
ef1b2d8026 | ||
|
|
3f530cf49e | ||
|
|
ce67928122 | ||
|
|
cca1e05ddf | ||
|
|
87b598a51a | ||
|
|
3036316a8a | ||
|
|
b80fcda721 | ||
|
|
cd879d8052 | ||
|
|
dde19062f3 | ||
|
|
2f2022de18 | ||
|
|
8cb0f52a35 | ||
|
|
b085e116c5 | ||
|
|
cb83780242 | ||
|
|
489de4ce4c | ||
|
|
b01cff4cda | ||
|
|
a1b84fb223 | ||
|
|
f5a0bbcf6c | ||
|
|
665663cac1 | ||
|
|
d77f819637 | ||
|
|
bf383691e2 | ||
|
|
38ce7e260c | ||
|
|
f3dda7d525 | ||
|
|
23f85110a7 | ||
|
|
edefe50783 | ||
|
|
37f2064f89 | ||
|
|
e3ef98a1be | ||
|
|
94151f68f6 | ||
|
|
fdee3698c2 | ||
|
|
757b63b1c0 | ||
|
|
bb87fa13e8 | ||
|
|
9319f43f9c | ||
|
|
96e7a495c1 | ||
|
|
d2d8e87cf9 | ||
|
|
3441b926ed | ||
|
|
caf3a2fd5b | ||
|
|
866c1dfba9 | ||
|
|
d518a317af | ||
|
|
f375cf76b1 | ||
|
|
5d68dbf89c | ||
|
|
b295e73b0b | ||
|
|
818cb877c7 | ||
|
|
8fc3325930 | ||
|
|
ebc0ccea0e | ||
|
|
cc223d5ef1 | ||
|
|
820bcb8ee3 | ||
|
|
f7b918d694 | ||
|
|
10781b230d | ||
|
|
0ece03a0c1 | ||
|
|
5c3389ef4a | ||
|
|
ee24204705 | ||
|
|
cadf380493 | ||
|
|
025a3a627c | ||
|
|
dd952bd124 | ||
|
|
aa04310650 | ||
|
|
f515922468 | ||
|
|
27ea7f4d63 | ||
|
|
8f4fb7ae0f | ||
|
|
34d4cd5d5d | ||
|
|
70a0d595e5 | ||
|
|
ddcd380f51 | ||
|
|
191e153a29 | ||
|
|
65f46984c5 | ||
|
|
5a62c8a075 | ||
|
|
d80ca055ef | ||
|
|
38cd20421c | ||
|
|
fd9917e7ff | ||
|
|
825f800240 | ||
|
|
90e825e534 | ||
|
|
ee5477e6d2 | ||
|
|
71917747a4 | ||
|
|
53c58974f3 | ||
|
|
831d49eb77 | ||
|
|
e8727695e3 | ||
|
|
3b6f0e48b4 | ||
|
|
a177179f77 | ||
|
|
3f825caafe | ||
|
|
fc0b9f6924 | ||
|
|
cd77d3f301 | ||
|
|
04330336f8 | ||
|
|
708d419d71 | ||
|
|
dbd9d0dd4d | ||
|
|
e12d683099 | ||
|
|
aa716d029d | ||
|
|
0f5891abf1 | ||
|
|
1e2f2dcca8 | ||
|
|
4d97e293dc | ||
|
|
26fd7a8451 | ||
|
|
afa84b445e | ||
|
|
1e024ea854 | ||
|
|
0807ddbc5c | ||
|
|
50a46b2d21 | ||
|
|
26d70866dc | ||
|
|
75b944c189 | ||
|
|
e083e63e3f | ||
|
|
1cb3b1a492 | ||
|
|
9c9bd2e92a | ||
|
|
ddd2f7f2a5 | ||
|
|
209390194c | ||
|
|
e6cabc216b | ||
|
|
2b4cce7d87 | ||
|
|
9c12fcc25e | ||
|
|
7dae63e834 | ||
|
|
cb5a7c8d5f | ||
|
|
b8fea8f1a2 | ||
|
|
dab7aa6729 | ||
|
|
fdf52effe2 | ||
|
|
614067ac57 | ||
|
|
c1150bd71f | ||
|
|
fe3f7151cc | ||
|
|
1b8fae3284 | ||
|
|
0f1c54dfe5 | ||
|
|
c8c5f9dc56 | ||
|
|
0481567238 | ||
|
|
d995f2ac25 | ||
|
|
3b73388d4d | ||
|
|
fc4419f809 | ||
|
|
9881fe4690 | ||
|
|
4457f17a29 | ||
|
|
758bad1185 | ||
|
|
b24a631e44 | ||
|
|
b2a969eb56 | ||
|
|
40103c9618 | ||
|
|
93124850ef | ||
|
|
effb57c569 | ||
|
|
450905e71c | ||
|
|
f401d0e1f7 | ||
|
|
01c6a9e8ed | ||
|
|
a3fafab537 | ||
|
|
d9a978ab9c | ||
|
|
53f7abf39b | ||
|
|
1524e3eb31 | ||
|
|
aba68b8165 | ||
|
|
e60e84e635 | ||
|
|
4e12c022c1 | ||
|
|
b903c9609c | ||
|
|
b4d0094b4e | ||
|
|
8c7092e935 | ||
|
|
a3b49565ee | ||
|
|
878519452f | ||
|
|
0936740e52 | ||
|
|
1c1465960d | ||
|
|
b636ef1968 | ||
|
|
761e83ddca | ||
|
|
e9fceed955 | ||
|
|
11d96d65e9 | ||
|
|
f6b08dbde7 | ||
|
|
51150142ac | ||
|
|
89af6fffc4 | ||
|
|
b092ba5d4a | ||
|
|
d9473cf7db | ||
|
|
ab90165e0e | ||
|
|
03608abcfe | ||
|
|
54aa571461 | ||
|
|
a257aa95cf | ||
|
|
659ab860c9 | ||
|
|
d5e4a2d091 | ||
|
|
f060994898 | ||
|
|
5bd00bf61d | ||
|
|
66d1ad45cc | ||
|
|
595e3d30cc | ||
|
|
7d83e4b777 | ||
|
|
45fae4a4d9 | ||
|
|
457dd0003d | ||
|
|
044285c33a | ||
|
|
9b13286d8b | ||
|
|
80528059b4 | ||
|
|
63de55a76c | ||
|
|
a54a70c091 | ||
|
|
29d4730d9a | ||
|
|
8f0ec17697 | ||
|
|
3539f565a3 | ||
|
|
a4ba5878bf | ||
|
|
6fa0dbba7d | ||
|
|
289a807d73 | ||
|
|
2b5c6adddb | ||
|
|
cbcae7bbf7 | ||
|
|
535d326e7b | ||
|
|
7a1d69cc3f | ||
|
|
b82768fd53 | ||
|
|
37a148ba51 | ||
|
|
e143ef2f95 | ||
|
|
5c0468f297 | ||
|
|
79b547bdf8 | ||
|
|
75c41d78a2 | ||
|
|
5172775c78 | ||
|
|
acaea259e2 | ||
|
|
2065d9d897 | ||
|
|
9a9159d3cf | ||
|
|
410bbf4fa2 | ||
|
|
be68d7674c | ||
|
|
a7e3e714fc | ||
|
|
8e6540e971 | ||
|
|
33b69c5d58 | ||
|
|
ac09da43cc | ||
|
|
fe166d76a5 | ||
|
|
da0b522f91 | ||
|
|
d10c002a8c | ||
|
|
25e1c0f569 | ||
|
|
aaf95ee57b | ||
|
|
412d3f22ae | ||
|
|
de480b6c97 | ||
|
|
1420470acb | ||
|
|
e5cb785e4e | ||
|
|
cd54077cae | ||
|
|
01a85c39a6 | ||
|
|
eb20fb0dcb | ||
|
|
4d7364170c | ||
|
|
f46024432e | ||
|
|
ae9c503b0c | ||
|
|
3c09cdef68 | ||
|
|
33c927f3bf | ||
|
|
d1d16162cc | ||
|
|
12841c6d7d | ||
|
|
747e003b9e | ||
|
|
968bf2a2e3 | ||
|
|
2b97bcadaf | ||
|
|
85888da56c | ||
|
|
f42f4b59e3 | ||
|
|
2550d1a89a | ||
|
|
086de416d8 | ||
|
|
d936ab5433 | ||
|
|
968da4bf37 | ||
|
|
97dd95f2b4 | ||
|
|
180558eaeb | ||
|
|
083424ae3f | ||
|
|
b90c89dd70 | ||
|
|
398fc377c6 | ||
|
|
e0b68aa2f3 | ||
|
|
8b4e35c50b | ||
|
|
0303a33f1e | ||
|
|
774faa9069 | ||
|
|
1cf2a91a65 | ||
|
|
6f54236ed3 | ||
|
|
e7460e3c05 | ||
|
|
05207f2591 | ||
|
|
e4c9292e54 | ||
|
|
f479f5d2d4 | ||
|
|
e5006500f4 | ||
|
|
4635e61b80 | ||
|
|
405d15a241 | ||
|
|
002d766225 | ||
|
|
75f688228a | ||
|
|
c86a02a2f5 | ||
|
|
d589652ff9 | ||
|
|
899a51bfbd | ||
|
|
575404d3c2 | ||
|
|
d30c2feead | ||
|
|
a9643a925d | ||
|
|
5144c87c92 | ||
|
|
37a2b709b1 | ||
|
|
b58ad7e874 | ||
|
|
f4b05302fa | ||
|
|
cc82696b1f | ||
|
|
909323b5f7 | ||
|
|
c39f71686d | ||
|
|
ce8d40f083 | ||
|
|
ca6a521890 | ||
|
|
71add64426 | ||
|
|
d9b2503391 | ||
|
|
04a7be2319 | ||
|
|
cb364cc3d8 | ||
|
|
f93d13b08e | ||
|
|
b75f4e8d08 | ||
|
|
71e26ffa6d | ||
|
|
1531326a59 | ||
|
|
903caa6a26 | ||
|
|
d3a22a7092 | ||
|
|
1346c01d9d | ||
|
|
4b90d0ca5b | ||
|
|
436c8608f2 | ||
|
|
8f9003c443 | ||
|
|
575f1e586f | ||
|
|
4f46196223 | ||
|
|
81589710a5 | ||
|
|
a8b937c56b | ||
|
|
c84622c08a | ||
|
|
3ff22d0c3a | ||
|
|
2c7ffbbf6d | ||
|
|
20e1be89f3 | ||
|
|
d965eb83bc | ||
|
|
1299970688 | ||
|
|
204314ea22 | ||
|
|
e46b77d962 | ||
|
|
cfffe4d166 | ||
|
|
2f3d0d724e | ||
|
|
85591617fc | ||
|
|
0c4a7eaf16 | ||
|
|
fc60a11f85 | ||
|
|
3454f76e88 | ||
|
|
29c3240f1a | ||
|
|
f198f38b22 | ||
|
|
4b7c910bb5 | ||
|
|
69fbf862bd | ||
|
|
c61a6a2ee0 | ||
|
|
3ed035e64c | ||
|
|
d452499891 | ||
|
|
24ee2e3c49 | ||
|
|
5dfb909509 | ||
|
|
a4eabbb519 | ||
|
|
5642c61b33 | ||
|
|
7f94783fab | ||
|
|
b271271df4 | ||
|
|
6e29728849 | ||
|
|
e67029685b | ||
|
|
e62b0eb98b | ||
|
|
5e62d71168 | ||
|
|
b0923b2e06 | ||
|
|
0cec94a92a | ||
|
|
2585a40ab5 | ||
|
|
f72b7f4521 | ||
|
|
4787f98d98 | ||
|
|
29c869326e | ||
|
|
a472690126 | ||
|
|
c58a309012 | ||
|
|
6040d02c8c | ||
|
|
8dc5701063 | ||
|
|
d4177ce3a5 | ||
|
|
f54b1bb174 | ||
|
|
29ae12d2c0 | ||
|
|
77883baba2 | ||
|
|
791fd2361c | ||
|
|
730531e0d7 | ||
|
|
55811bdbbe | ||
|
|
c576d2e66a | ||
|
|
ba2afda31c | ||
|
|
e3a7a85122 | ||
|
|
518261c4f2 | ||
|
|
70a34bd652 | ||
|
|
b4b8572244 | ||
|
|
3f76537f75 | ||
|
|
07e8e0e284 | ||
|
|
3feaa90860 | ||
|
|
6fcc786915 | ||
|
|
18ecbc3b30 | ||
|
|
3c98f0cada | ||
|
|
fa3a20ca4d | ||
|
|
9bc98cabe8 | ||
|
|
a33b572e44 | ||
|
|
ea9e0b60e7 | ||
|
|
5490490294 | ||
|
|
86b5d1d30b | ||
|
|
0ffa12a0e2 | ||
|
|
f6f3023d3d | ||
|
|
f8da4bf9a7 | ||
|
|
8bbf1fc840 | ||
|
|
6df504f03c | ||
|
|
df58339850 | ||
|
|
509190118f | ||
|
|
0d98fa353c | ||
|
|
1a65439ebf | ||
|
|
96372cee99 | ||
|
|
7b7110eebb | ||
|
|
1506a60993 | ||
|
|
910bcfdc8b | ||
|
|
dcde063723 | ||
|
|
88300014e2 | ||
|
|
c7c5bc21ff | ||
|
|
98670bcf47 | ||
|
|
a0f81aeaa3 | ||
|
|
79e03ea0f6 | ||
|
|
21bbff2c4e | ||
|
|
313ba28adf | ||
|
|
672a49bb6a | ||
|
|
2198b84be2 | ||
|
|
f8d0f97660 | ||
|
|
54a592d7f1 | ||
|
|
ea5a287cf9 | ||
|
|
97d7901870 | ||
|
|
39bb842a21 | ||
|
|
21f8536cef | ||
|
|
0607ad9cf8 | ||
|
|
259e01f7fd | ||
|
|
f7585b7624 | ||
|
|
1c8470a7c5 | ||
|
|
b955648f14 | ||
|
|
dc250634e4 | ||
|
|
1f59444cec | ||
|
|
99f23be117 | ||
|
|
6f4713387d | ||
|
|
747fd11f93 | ||
|
|
7a3ce8fb18 | ||
|
|
e05e5373d0 | ||
|
|
00f8890b77 | ||
|
|
02e19e3df9 | ||
|
|
b376b40f59 | ||
|
|
3d4baba365 | ||
|
|
22b0ad54ab | ||
|
|
9d0125f93b | ||
|
|
326b043b8f | ||
|
|
5a471d9c36 | ||
|
|
2597540aa1 | ||
|
|
3a5f2e2227 | ||
|
|
d80ddf17c9 | ||
|
|
7f9a689126 | ||
|
|
63801af8e6 | ||
|
|
5c71912049 | ||
|
|
21801d71b2 | ||
|
|
49024095e3 | ||
|
|
d17d74dc5d | ||
|
|
06ac0af626 | ||
|
|
a31cf4dd97 | ||
|
|
79a598e060 | ||
|
|
1d306c59cf | ||
|
|
b71988fcdf | ||
|
|
cd537c1af6 | ||
|
|
c5413a6b5c | ||
|
|
497232fbc1 | ||
|
|
2a42585d11 | ||
|
|
8578c44724 | ||
|
|
b4e35897ae | ||
|
|
25f29ac3db | ||
|
|
bbe8a15cf7 | ||
|
|
955a36ac82 | ||
|
|
e2e00231da | ||
|
|
f086d9f499 | ||
|
|
68f8f709f3 | ||
|
|
a7221bb237 | ||
|
|
b6a6d698db | ||
|
|
38c1560c7b | ||
|
|
7232cf73a9 | ||
|
|
29536568d4 | ||
|
|
912bdc7afa | ||
|
|
7942c59146 | ||
|
|
808578ba03 | ||
|
|
2cb6f2e645 | ||
|
|
87497a3c60 | ||
|
|
ca49c8c105 | ||
|
|
9ab5b29dc5 | ||
|
|
90aea1b0a5 | ||
|
|
5ef0ccddc2 | ||
|
|
9cb0c2f934 | ||
|
|
7fff998fe6 | ||
|
|
15d9e4699a | ||
|
|
e268d8db9b | ||
|
|
1d716b0375 | ||
|
|
c127b737a5 | ||
|
|
5b52a8dd23 | ||
|
|
3439a21f57 | ||
|
|
d243a12564 | ||
|
|
70375367d6 | ||
|
|
4427270a71 | ||
|
|
9827af22ad | ||
|
|
58a32ff246 | ||
|
|
8f337f1574 | ||
|
|
6de317a90c | ||
|
|
805b1e1e0b | ||
|
|
9a89e01aba | ||
|
|
2621ee329d | ||
|
|
57bde764fe | ||
|
|
4fc6ac7727 | ||
|
|
95a3b74b3b | ||
|
|
1e00b1536e | ||
|
|
312f18ae60 | ||
|
|
4fb9c053f7 | ||
|
|
4515ca6268 | ||
|
|
09d9aa3bb2 | ||
|
|
cf1d4aac5d | ||
|
|
d4ca5984ca | ||
|
|
a643493a32 | ||
|
|
c85faf039a | ||
|
|
ae60fcf620 | ||
|
|
78331e1b37 | ||
|
|
ab4aff4670 | ||
|
|
6560f1d779 | ||
|
|
49567890a6 | ||
|
|
ec10daba7e | ||
|
|
280a53f95e | ||
|
|
9347d99355 | ||
|
|
90de96a99b | ||
|
|
8d82c83a1a | ||
|
|
7e8deebf96 | ||
|
|
7763491813 | ||
|
|
16e47a1755 | ||
|
|
a077cee836 | ||
|
|
7caef7df68 | ||
|
|
bf4267161f | ||
|
|
6ac2a15e39 | ||
|
|
41f272c2bd | ||
|
|
02574ba19d | ||
|
|
ea638c5618 | ||
|
|
8e7a791871 | ||
|
|
3bb0ee77be | ||
|
|
e5fc882746 | ||
|
|
65b39d45d6 | ||
|
|
c078c98ad2 | ||
|
|
2e80732340 | ||
|
|
2fc3e6a88e | ||
|
|
d94f21c51f | ||
|
|
19c0b390ee | ||
|
|
54cab8e4b5 | ||
|
|
ad2dfc3446 | ||
|
|
63f257d81e | ||
|
|
8be6c6c307 | ||
|
|
cc99fdb57d | ||
|
|
50fdaf1b04 | ||
|
|
82663ee1de | ||
|
|
2873d0e39d | ||
|
|
0e4939147f | ||
|
|
5b7081cbff | ||
|
|
ffad3d81b0 | ||
|
|
1225ddecf1 | ||
|
|
4ad4f9970f | ||
|
|
63a4293f1a | ||
|
|
f124e28509 | ||
|
|
c56fa43747 | ||
|
|
86d8878eeb | ||
|
|
d57129ca3f | ||
|
|
537edff2a1 | ||
|
|
6ddea4786e | ||
|
|
094d5aa9f1 |
@@ -1,169 +0,0 @@
|
||||
|
||||
{
|
||||
"name": "claude-scientific-skills",
|
||||
"owner": {
|
||||
"name": "Timothy Kassis",
|
||||
"email": "timothy.kassis@k-dense.ai"
|
||||
},
|
||||
"metadata": {
|
||||
"description": "Claude scientific skills from K-Dense Inc",
|
||||
"version": "1.68.0"
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "scientific-packages",
|
||||
"description": "Collection of python scientific packages",
|
||||
"source": "./",
|
||||
"strict": false,
|
||||
"skills": [
|
||||
"./scientific-packages/aeon",
|
||||
"./scientific-packages/anndata",
|
||||
"./scientific-packages/arboreto",
|
||||
"./scientific-packages/astropy",
|
||||
"./scientific-packages/biomni",
|
||||
"./scientific-packages/biopython",
|
||||
"./scientific-packages/bioservices",
|
||||
"./scientific-packages/cellxgene-census",
|
||||
"./scientific-packages/cobrapy",
|
||||
"./scientific-packages/dask",
|
||||
"./scientific-packages/datacommons-client",
|
||||
"./scientific-packages/datamol",
|
||||
"./scientific-packages/deepchem",
|
||||
"./scientific-packages/deeptools",
|
||||
"./scientific-packages/diffdock",
|
||||
"./scientific-packages/esm",
|
||||
"./scientific-packages/etetoolkit",
|
||||
"./scientific-packages/flowio",
|
||||
"./scientific-packages/gget",
|
||||
"./scientific-packages/hypogenic",
|
||||
"./scientific-packages/histolab",
|
||||
"./scientific-packages/lamindb",
|
||||
"./scientific-packages/markitdown",
|
||||
"./scientific-packages/matchms",
|
||||
"./scientific-packages/matplotlib",
|
||||
"./scientific-packages/medchem",
|
||||
"./scientific-packages/molfeat",
|
||||
"./scientific-packages/neurokit2",
|
||||
"./scientific-packages/networkx",
|
||||
"./scientific-packages/paper-2-web",
|
||||
"./scientific-packages/pathml",
|
||||
"./scientific-packages/polars",
|
||||
"./scientific-packages/pydeseq2",
|
||||
"./scientific-packages/pydicom",
|
||||
"./scientific-packages/pyhealth",
|
||||
"./scientific-packages/pymatgen",
|
||||
"./scientific-packages/pymc",
|
||||
"./scientific-packages/pylabrobot",
|
||||
"./scientific-packages/pymoo",
|
||||
"./scientific-packages/pufferlib",
|
||||
"./scientific-packages/pyopenms",
|
||||
"./scientific-packages/pysam",
|
||||
"./scientific-packages/pytdc",
|
||||
"./scientific-packages/pytorch-lightning",
|
||||
"./scientific-packages/rdkit",
|
||||
"./scientific-packages/reportlab",
|
||||
"./scientific-packages/scanpy",
|
||||
"./scientific-packages/scvi-tools",
|
||||
"./scientific-packages/scikit-bio",
|
||||
"./scientific-packages/scikit-learn",
|
||||
"./scientific-packages/scikit-survival",
|
||||
"./scientific-packages/seaborn",
|
||||
"./scientific-packages/shap",
|
||||
"./scientific-packages/simpy",
|
||||
"./scientific-packages/stable-baselines3",
|
||||
"./scientific-packages/statsmodels",
|
||||
"./scientific-packages/sympy",
|
||||
"./scientific-packages/torch_geometric",
|
||||
"./scientific-packages/torchdrug",
|
||||
"./scientific-packages/tooluniverse",
|
||||
"./scientific-packages/transformers",
|
||||
"./scientific-packages/umap-learn",
|
||||
"./scientific-packages/vaex",
|
||||
"./scientific-packages/zarr-python"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "scientific-databases",
|
||||
"description": "Collection of scientific databases",
|
||||
"source": "./",
|
||||
"strict": false,
|
||||
"skills": [
|
||||
"./scientific-databases/alphafold-database",
|
||||
"./scientific-databases/biorxiv-database",
|
||||
"./scientific-databases/chembl-database",
|
||||
"./scientific-databases/clinpgx-database",
|
||||
"./scientific-databases/clinvar-database",
|
||||
"./scientific-databases/clinicaltrials-database",
|
||||
"./scientific-databases/cosmic-database",
|
||||
"./scientific-databases/drugbank-database",
|
||||
"./scientific-databases/ena-database",
|
||||
"./scientific-databases/ensembl-database",
|
||||
"./scientific-databases/fda-database",
|
||||
"./scientific-databases/gene-database",
|
||||
"./scientific-databases/geo-database",
|
||||
"./scientific-databases/gwas-database",
|
||||
"./scientific-databases/hmdb-database",
|
||||
"./scientific-databases/kegg-database",
|
||||
"./scientific-databases/metabolomics-workbench-database",
|
||||
"./scientific-databases/opentargets-database",
|
||||
"./scientific-databases/pdb-database",
|
||||
"./scientific-databases/pubchem-database",
|
||||
"./scientific-databases/pubmed-database",
|
||||
"./scientific-databases/reactome-database",
|
||||
"./scientific-databases/string-database",
|
||||
"./scientific-databases/uniprot-database",
|
||||
"./scientific-databases/uspto-database",
|
||||
"./scientific-databases/zinc-database"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "scientific-thinking",
|
||||
"description": "Collection of scientific thinking methodologies",
|
||||
"source": "./",
|
||||
"strict": false,
|
||||
"skills": [
|
||||
"./scientific-thinking/exploratory-data-analysis",
|
||||
"./scientific-thinking/hypothesis-generation",
|
||||
"./scientific-thinking/literature-review",
|
||||
"./scientific-thinking/peer-review",
|
||||
"./scientific-thinking/scholar-evaluation",
|
||||
"./scientific-thinking/scientific-brainstorming",
|
||||
"./scientific-thinking/scientific-critical-thinking",
|
||||
"./scientific-thinking/scientific-writing",
|
||||
"./scientific-thinking/statistical-analysis",
|
||||
"./scientific-thinking/scientific-visualization",
|
||||
"./scientific-thinking/document-skills/docx",
|
||||
"./scientific-thinking/document-skills/pdf",
|
||||
"./scientific-thinking/document-skills/pptx",
|
||||
"./scientific-thinking/document-skills/xlsx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "scientific-integrations",
|
||||
"description": "Collection of scientific platform integrations",
|
||||
"source": "./",
|
||||
"strict": false,
|
||||
"skills": [
|
||||
"./scientific-integrations/benchling-integration",
|
||||
"./scientific-integrations/dnanexus-integration",
|
||||
"./scientific-integrations/labarchive-integration",
|
||||
"./scientific-integrations/latchbio-integration",
|
||||
"./scientific-integrations/omero-integration",
|
||||
"./scientific-integrations/opentrons-integration",
|
||||
"./scientific-integrations/protocolsio-integration"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "scientific-context-initialization",
|
||||
"description": "Always Auto-invoked skill that creates/updates workspace AGENT.md to instruct the agent to always search for existing skills before attempting any scientific task",
|
||||
"source": "./scientific-helpers/scientific-context-initialization",
|
||||
"strict": false
|
||||
},
|
||||
{
|
||||
"name": "get-available-resources",
|
||||
"description": "Detects and reports available system resources (CPU cores, GPUs, memory, disk space) to inform computational approach decisions",
|
||||
"source": "./scientific-helpers/get-available-resources",
|
||||
"strict": false
|
||||
}
|
||||
]
|
||||
}
|
||||
95
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
name: Bug report
|
||||
description: A skill or repository tool behaves incorrectly — wrong output, broken script, failing install, or instructions an agent cannot follow.
|
||||
title: "[Bug]: "
|
||||
labels: ["bug", "needs-triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for reporting this. Please do **not** use this form for security
|
||||
vulnerabilities — use [private vulnerability reporting](https://github.com/K-Dense-AI/scientific-agent-skills/security/advisories/new)
|
||||
instead, as described in [SECURITY.md](https://github.com/K-Dense-AI/scientific-agent-skills/blob/main/SECURITY.md).
|
||||
|
||||
- type: dropdown
|
||||
id: area
|
||||
attributes:
|
||||
label: Area
|
||||
description: Which part of the repository is affected?
|
||||
options:
|
||||
- A skill under skills/
|
||||
- Repository tooling (scan_skills.py, tests, CI workflows)
|
||||
- Documentation (README, CONTRIBUTING, AGENTS)
|
||||
- Not sure
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: skill
|
||||
attributes:
|
||||
label: Skill name
|
||||
description: The skill directory name, exactly as it appears under `skills/`. Leave blank if this is not skill-specific.
|
||||
placeholder: scanpy
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened
|
||||
description: What did the skill or tool actually do?
|
||||
placeholder: The skill's example call to sc.pp.neighbors() fails with a TypeError.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: What you expected instead
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: reproduce
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: The smallest sequence that triggers it. Include the prompt you gave the agent, if relevant.
|
||||
placeholder: |
|
||||
1. Load the `scanpy` skill in Claude Code
|
||||
2. Ask: "cluster my AnnData object"
|
||||
3. Run the code the agent produces
|
||||
4. See the error below
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Error output
|
||||
description: Paste the traceback or scanner output. This is rendered as a code block, so no backticks are needed.
|
||||
render: shell
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment
|
||||
description: Skill behavior varies by agent host and model, so please tell us where you saw this.
|
||||
value: |
|
||||
- Agent host (Claude Code, Cursor, Codex, other):
|
||||
- Model:
|
||||
- Repository version or commit:
|
||||
- Python version:
|
||||
- Operating system:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Before submitting
|
||||
options:
|
||||
- label: I searched existing issues and this is not a duplicate.
|
||||
required: true
|
||||
- label: This is not a security vulnerability. (Those go through private reporting.)
|
||||
required: true
|
||||
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Report a security vulnerability
|
||||
url: https://github.com/K-Dense-AI/scientific-agent-skills/security/advisories/new
|
||||
about: Do not open a public issue. Use private vulnerability reporting so the report stays confidential until a fix ships. See SECURITY.md.
|
||||
- name: Contributing guide
|
||||
url: https://github.com/K-Dense-AI/scientific-agent-skills/blob/main/CONTRIBUTING.md
|
||||
about: Read this before proposing a skill change — skill format, validation, tests, and the pull request checklist.
|
||||
- name: Agent Skills specification
|
||||
url: https://agentskills.io/specification
|
||||
about: The open specification every skill in this repository follows.
|
||||
- name: K-Dense documentation
|
||||
url: https://k-dense.ai
|
||||
about: Product documentation and general questions about K-Dense.
|
||||
90
.github/ISSUE_TEMPLATE/new_skill_request.yml
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
name: New skill request
|
||||
description: Propose a skill for a scientific package, database, platform, workflow, or research method that the library does not cover yet.
|
||||
title: "[New skill]: "
|
||||
labels: ["enhancement", "skill-request", "needs-triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Check the [skill list in the README](https://github.com/K-Dense-AI/scientific-agent-skills#readme)
|
||||
first — the library already ships a large number of skills. If you plan to
|
||||
write this skill yourself, [CONTRIBUTING.md](https://github.com/K-Dense-AI/scientific-agent-skills/blob/main/CONTRIBUTING.md)
|
||||
has the required format and validation steps.
|
||||
|
||||
- type: input
|
||||
id: name
|
||||
attributes:
|
||||
label: Proposed skill name
|
||||
description: Lowercase letters, numbers, and single hyphens only — this becomes the directory name under `skills/`.
|
||||
placeholder: alphafold-db
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: category
|
||||
attributes:
|
||||
label: Category
|
||||
options:
|
||||
- Scientific package or library
|
||||
- Database or public data resource
|
||||
- Platform, service, or API
|
||||
- Analysis workflow or research method
|
||||
- Laboratory instrument or hardware
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: what
|
||||
attributes:
|
||||
label: What the skill would do
|
||||
description: What should an agent be able to accomplish with it that it cannot do reliably today?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: when
|
||||
attributes:
|
||||
label: When an agent should use it
|
||||
description: The situations that should trigger this skill. This becomes the "when to use" half of the skill description.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: docs
|
||||
attributes:
|
||||
label: Official documentation and sources
|
||||
description: Links to the package docs, API reference, publication, or database homepage a skill author would need.
|
||||
placeholder: |
|
||||
- Docs: https://...
|
||||
- API reference: https://...
|
||||
- Paper: https://doi.org/...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: credentials
|
||||
attributes:
|
||||
label: Credentials or access requirements
|
||||
description: Does it need an API key, licence, registration, or institutional access? Name the environment variables if you know them.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: dropdown
|
||||
id: contribute
|
||||
attributes:
|
||||
label: Would you like to write this skill?
|
||||
options:
|
||||
- "Yes — I plan to open a pull request"
|
||||
- "Maybe, with some guidance"
|
||||
- "No, I am requesting it"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Before submitting
|
||||
options:
|
||||
- label: I checked the README skill list and this skill does not already exist.
|
||||
required: true
|
||||
68
.github/ISSUE_TEMPLATE/skill_improvement.yml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
name: Improve an existing skill
|
||||
description: An existing skill is outdated, unclear, or incomplete — stale API, missing workflow, weak examples, or a description that triggers at the wrong time.
|
||||
title: "[Improve]: "
|
||||
labels: ["enhancement", "needs-triage"]
|
||||
body:
|
||||
- type: input
|
||||
id: skill
|
||||
attributes:
|
||||
label: Skill name
|
||||
description: The skill directory name, exactly as it appears under `skills/`.
|
||||
placeholder: transformers
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: kind
|
||||
attributes:
|
||||
label: What needs improving
|
||||
multiple: true
|
||||
options:
|
||||
- Outdated API or deprecated calls
|
||||
- Missing workflow or capability
|
||||
- Examples are wrong, untested, or too thin
|
||||
- Instructions are ambiguous for an agent
|
||||
- Description triggers too often or not often enough
|
||||
- Missing or broken references
|
||||
- Missing tests
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: current
|
||||
attributes:
|
||||
label: Current behavior
|
||||
description: What does the skill say or do today? Quote the relevant part of `SKILL.md` or a reference file, with the file path.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: proposed
|
||||
attributes:
|
||||
label: Proposed change
|
||||
description: What should it say or do instead?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: evidence
|
||||
attributes:
|
||||
label: Supporting sources
|
||||
description: Upstream release notes, migration guides, or docs that show the current content is out of date.
|
||||
placeholder: |
|
||||
- Changelog: https://...
|
||||
- Migration guide: https://...
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: dropdown
|
||||
id: contribute
|
||||
attributes:
|
||||
label: Would you like to make this change?
|
||||
options:
|
||||
- "Yes — I plan to open a pull request"
|
||||
- "Maybe, with some guidance"
|
||||
- "No, I am reporting it"
|
||||
validations:
|
||||
required: true
|
||||
68
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
# Summary
|
||||
|
||||
<!-- What changed, and why it matters. One or two sentences is fine. -->
|
||||
|
||||
## Type of change
|
||||
|
||||
<!-- Keep the lines that apply, delete the rest. -->
|
||||
|
||||
- [ ] New skill
|
||||
- [ ] Update to an existing skill
|
||||
- [ ] Tests
|
||||
- [ ] Repository tooling or CI
|
||||
- [ ] Documentation
|
||||
- [ ] Other:
|
||||
|
||||
## Skills touched
|
||||
|
||||
<!-- Directory names under skills/, one per line. Write "none" if this PR does not touch skills/. -->
|
||||
|
||||
-
|
||||
|
||||
## How this was tested
|
||||
|
||||
<!-- The commands you ran and what they reported. -->
|
||||
|
||||
```
|
||||
uv run skills-ref validate ./skills/<name>
|
||||
uv run --with pytest python -m pytest tests/<name> -q
|
||||
```
|
||||
|
||||
## Related issues and references
|
||||
|
||||
<!-- Closes #123. Link upstream docs, release notes, or security findings that justify the change. -->
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
Drawn from the [Pull Request Checklist](https://github.com/K-Dense-AI/scientific-agent-skills/blob/main/CONTRIBUTING.md#pull-request-checklist) in CONTRIBUTING.md. Items that do not apply to this PR can be left unchecked with a short note.
|
||||
|
||||
**Skill format**
|
||||
|
||||
- [ ] The skill directory name and the `name` frontmatter match exactly.
|
||||
- [ ] The skill directory contains only `SKILL.md`, `references/`, `scripts/`, and `assets/` — no `tests/` directory and no `test_*.py` files.
|
||||
- [ ] `SKILL.md` has valid YAML frontmatter and a Markdown body.
|
||||
- [ ] Only the six spec-defined top-level fields are present; everything else lives under `metadata`.
|
||||
- [ ] `metadata` is a block mapping, not single-line JSON, and scalar values are quoted where needed.
|
||||
- [ ] Any `metadata.openclaw` or `metadata.hermes` block is a nested mapping, not a JSON string.
|
||||
- [ ] `metadata.version` exists, is quoted, and is bumped if an existing skill changed.
|
||||
- [ ] The `description` says both what the skill does and when an agent should use it.
|
||||
|
||||
**Validation and tests**
|
||||
|
||||
- [ ] `uv run skills-ref validate ./skills/<name>` passes.
|
||||
- [ ] Tests live in `tests/<skill-name>/`, and any new `scripts/` skill has a `[skills.<name>]` entry in `tests/skill-requirements.toml`.
|
||||
- [ ] Relevant test suites pass, or the failures are explained below.
|
||||
- [ ] Security scanner results are clean or explained in this PR.
|
||||
|
||||
**Content and safety**
|
||||
|
||||
- [ ] Examples and scripts were tested, or are clearly marked as illustrative.
|
||||
- [ ] No secrets, credentials, private data, or unsafe instructions are included.
|
||||
- [ ] Credentials the skill needs are named in `compatibility` and declared in `metadata.openclaw.envVars`.
|
||||
- [ ] Relevant official documentation is linked where useful.
|
||||
|
||||
## Notes for reviewers
|
||||
|
||||
<!-- Anything unresolved, deliberately out of scope, or worth a closer look. -->
|
||||
113
.github/workflows/pr-skill-scan.yml
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
name: PR Skill Scan
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "skills/**"
|
||||
- "scan_skills.py"
|
||||
- "scan_pr_skills.py"
|
||||
- "pyproject.toml"
|
||||
- "uv.lock"
|
||||
- ".github/workflows/pr-skill-scan.yml"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: pr-skill-scan-${{ github.event.pull_request.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
scan:
|
||||
name: Scan changed skills
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
|
||||
steps:
|
||||
- name: Checkout PR
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Detect changed skills
|
||||
id: changed
|
||||
run: |
|
||||
set -euo pipefail
|
||||
BASE_SHA="${{ github.event.pull_request.base.sha }}"
|
||||
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
|
||||
echo "Base: $BASE_SHA"
|
||||
echo "Head: $HEAD_SHA"
|
||||
|
||||
# Files added/copied/modified/renamed under skills/<skill>/...
|
||||
CHANGED_FILES=$(git diff --name-only --diff-filter=ACMR "$BASE_SHA" "$HEAD_SHA" -- 'skills/**' || true)
|
||||
echo "Changed files under skills/:"
|
||||
echo "$CHANGED_FILES"
|
||||
|
||||
# Derive unique top-level skill directories and keep only those that still exist with a SKILL.md
|
||||
SKILL_DIRS=$(echo "$CHANGED_FILES" \
|
||||
| awk -F/ 'NF>=2 && $1=="skills" {print $1 "/" $2}' \
|
||||
| sort -u)
|
||||
|
||||
EXISTING=""
|
||||
for d in $SKILL_DIRS; do
|
||||
if [ -f "$d/SKILL.md" ]; then
|
||||
EXISTING="$EXISTING $d"
|
||||
fi
|
||||
done
|
||||
EXISTING=$(echo "$EXISTING" | xargs || true)
|
||||
|
||||
echo "Skill dirs to scan: '$EXISTING'"
|
||||
echo "skill_dirs=$EXISTING" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up uv
|
||||
if: steps.changed.outputs.skill_dirs != ''
|
||||
uses: astral-sh/setup-uv@v8.0.0
|
||||
with:
|
||||
enable-cache: true
|
||||
cache-dependency-glob: uv.lock
|
||||
python-version: "3.13"
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.changed.outputs.skill_dirs != ''
|
||||
run: uv sync --python 3.13
|
||||
|
||||
# Fork PRs do not receive SKILL_SCANNER_LLM_API_KEY. scan_pr_skills.py
|
||||
# detects the missing key, writes an explanatory sticky comment, and exits 0.
|
||||
- name: Run scanner on changed skills
|
||||
if: steps.changed.outputs.skill_dirs != ''
|
||||
id: scan
|
||||
env:
|
||||
SKILL_SCANNER_LLM_API_KEY: ${{ secrets.SKILL_SCANNER_LLM_API_KEY }}
|
||||
SKILL_SCANNER_LLM_MODEL: ${{ vars.SKILL_SCANNER_LLM_MODEL || 'claude-opus-5' }}
|
||||
run: |
|
||||
uv run python scan_pr_skills.py \
|
||||
--output pr_scan_comment.md \
|
||||
--fail-on HIGH \
|
||||
${{ steps.changed.outputs.skill_dirs }}
|
||||
|
||||
- name: Prepare no-op comment
|
||||
if: steps.changed.outputs.skill_dirs == ''
|
||||
run: |
|
||||
cat > pr_scan_comment.md <<'EOF'
|
||||
<!-- skill-security-scan -->
|
||||
## 🛡️ Skill Security Scan
|
||||
|
||||
No skill directories (with a `SKILL.md`) were changed in this PR — nothing to scan.
|
||||
EOF
|
||||
|
||||
- name: Upload scan comment as artifact
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pr-skill-scan-comment
|
||||
path: pr_scan_comment.md
|
||||
if-no-files-found: ignore
|
||||
|
||||
- name: Post or update PR comment
|
||||
if: always() && hashFiles('pr_scan_comment.md') != ''
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
with:
|
||||
header: skill-security-scan
|
||||
path: pr_scan_comment.md
|
||||
10
.github/workflows/release.yml
vendored
@@ -5,7 +5,7 @@ on:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- '.claude-plugin/marketplace.json'
|
||||
- 'pyproject.toml'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
@@ -17,14 +17,14 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0 # Fetch all history for release notes
|
||||
|
||||
- name: Extract version from marketplace.json
|
||||
- name: Extract version from pyproject.toml
|
||||
id: get_version
|
||||
run: |
|
||||
VERSION=$(jq -r '.metadata.version' .claude-plugin/marketplace.json)
|
||||
VERSION=$(grep '^version' pyproject.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "tag=v$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Extracted version: $VERSION"
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
|
||||
- name: Create Release
|
||||
if: steps.check_tag.outputs.exists == 'false'
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ steps.get_version.outputs.tag }}
|
||||
name: v${{ steps.get_version.outputs.version }}
|
||||
|
||||
71
.github/workflows/security-scan.yml
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
name: Weekly Security Scan
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 9 * * 1" # Every Monday at 09:00 UTC
|
||||
workflow_dispatch: # Allow manual trigger
|
||||
inputs:
|
||||
full_scan:
|
||||
description: "Rescan every skill, ignoring cached findings"
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
# Scans run concurrently and reuse findings for unchanged skills, so a
|
||||
# typical incremental run is minutes. The headroom is for a full rescan
|
||||
# (triggered by a scanner/model change or the 30-day backstop) plus the
|
||||
# scanner's own rate-limit retries.
|
||||
timeout-minutes: 60
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: astral-sh/setup-uv@v8.0.0
|
||||
with:
|
||||
enable-cache: true
|
||||
cache-dependency-glob: uv.lock
|
||||
python-version: "3.13"
|
||||
|
||||
- name: Install dependencies
|
||||
run: uv sync --python 3.13
|
||||
|
||||
- name: Run security scan
|
||||
env:
|
||||
SKILL_SCANNER_LLM_API_KEY: ${{ secrets.SKILL_SCANNER_LLM_API_KEY }}
|
||||
SKILL_SCANNER_LLM_MODEL: ${{ vars.SKILL_SCANNER_LLM_MODEL || 'claude-opus-5' }}
|
||||
# Each skill scan is blocked on LLM network I/O, so concurrency is
|
||||
# bounded by API rate limits rather than by the runner. Lower this if
|
||||
# runs start hitting sustained 429s.
|
||||
SKILL_SCAN_WORKERS: ${{ vars.SKILL_SCAN_WORKERS || '8' }}
|
||||
SKILL_SCAN_FULL: ${{ inputs.full_scan && '1' || '' }}
|
||||
run: uv run python scan_skills.py
|
||||
|
||||
- name: Upload report artifact
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: security-report
|
||||
path: |
|
||||
docs/security-report.md
|
||||
docs/security-report.json
|
||||
if-no-files-found: warn
|
||||
|
||||
- name: Commit updated security report
|
||||
run: |
|
||||
if [ -z "$(git status --porcelain docs/security-report.md docs/security-report.json)" ]; then
|
||||
echo "Report unchanged; nothing to commit."
|
||||
exit 0
|
||||
fi
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git stash --include-untracked
|
||||
git pull --rebase
|
||||
git stash pop || true
|
||||
git add docs/security-report.md docs/security-report.json
|
||||
git commit -m "chore: update security scan report [skip ci]"
|
||||
git push
|
||||
150
.github/workflows/skill-spec-validation.yml
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
name: Skill Spec Validation
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "skills/**"
|
||||
- "pyproject.toml"
|
||||
- "uv.lock"
|
||||
- ".github/workflows/skill-spec-validation.yml"
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "skills/**"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: skill-spec-validation-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
name: Validate skills against the Agent Skills spec
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up uv
|
||||
uses: astral-sh/setup-uv@v8.0.0
|
||||
with:
|
||||
enable-cache: true
|
||||
cache-dependency-glob: uv.lock
|
||||
python-version: "3.13"
|
||||
|
||||
- name: Install dependencies
|
||||
run: uv sync --python 3.13
|
||||
|
||||
# The reference validator from https://agentskills.io/specification. It checks the
|
||||
# closed set of allowed frontmatter fields, name rules (incl. directory match),
|
||||
# description/compatibility length limits, and parses frontmatter with strictyaml
|
||||
# -- which rejects JSON-style flow mappings such as `metadata: {"version": "1.0"}`.
|
||||
- name: skills-ref validate
|
||||
run: |
|
||||
set -uo pipefail
|
||||
fail=0
|
||||
for d in skills/*/; do
|
||||
if ! out=$(uv run skills-ref validate "$d" 2>&1); then
|
||||
fail=1
|
||||
echo "::error file=${d}SKILL.md::$(echo "$out" | tail -n +2 | tr '\n' ' ')"
|
||||
echo "FAIL $d"
|
||||
echo "$out" | sed 's/^/ /'
|
||||
fi
|
||||
done
|
||||
echo "Validated $(ls -d skills/*/ | wc -l) skills."
|
||||
exit $fail
|
||||
|
||||
# Rules the reference validator does not enforce: this repo's metadata.version
|
||||
# requirement (see AGENTS.md), plus spec constraints skills-ref accepts but the
|
||||
# spec text requires -- allowed-tools must be a space-separated string, and
|
||||
# metadata values must be strings apart from the host-manifest blocks that have
|
||||
# to stay nested objects (see NESTED_OK below).
|
||||
- name: Repo and spec rules skills-ref does not check
|
||||
run: |
|
||||
uv run --with pyyaml python - <<'PY'
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
import yaml
|
||||
|
||||
# Host manifest blocks that must stay nested mappings. OpenClaw's
|
||||
# resolveOpenClawManifestBlock() requires `typeof candidate === "object"`, so
|
||||
# encoding these as JSON strings silently disables its gating and credential
|
||||
# injection. Nested mappings still pass `skills-ref validate`.
|
||||
NESTED_OK = {"openclaw", "hermes"}
|
||||
|
||||
# Requires the closing delimiter on its own line. A naive split("---") would
|
||||
# happily re-split at a `---` accidentally glued to the last frontmatter value.
|
||||
FM_RE = re.compile(r"\A---\n(.*?)\n---\n", re.S)
|
||||
|
||||
errors, warnings = [], []
|
||||
for d in sorted(Path("skills").iterdir()):
|
||||
if not d.is_dir():
|
||||
continue
|
||||
md = d / "SKILL.md"
|
||||
if not md.exists():
|
||||
errors.append(f"{d}: missing SKILL.md")
|
||||
continue
|
||||
text = md.read_text()
|
||||
m_fm = FM_RE.match(text)
|
||||
if not m_fm:
|
||||
errors.append(
|
||||
f"{md}: frontmatter must open with `---` and close with `---` "
|
||||
f"on its own line"
|
||||
)
|
||||
continue
|
||||
fm = yaml.safe_load(m_fm.group(1))
|
||||
|
||||
at = fm.get("allowed-tools")
|
||||
if at is not None:
|
||||
if not isinstance(at, str):
|
||||
errors.append(
|
||||
f"{md}: allowed-tools must be a space-separated string, "
|
||||
f"got {type(at).__name__}"
|
||||
)
|
||||
elif "," in at:
|
||||
errors.append(
|
||||
f"{md}: allowed-tools must be space-separated, not "
|
||||
f"comma-separated: {at!r}"
|
||||
)
|
||||
|
||||
m = fm.get("metadata")
|
||||
if not isinstance(m, dict):
|
||||
errors.append(f"{md}: missing a `metadata` mapping (see AGENTS.md)")
|
||||
else:
|
||||
if "version" not in m:
|
||||
errors.append(f"{md}: metadata.version is required (see AGENTS.md)")
|
||||
for k, v in m.items():
|
||||
if k in NESTED_OK:
|
||||
if not isinstance(v, dict):
|
||||
errors.append(
|
||||
f"{md}: metadata.{k} must stay a nested mapping, got "
|
||||
f"{type(v).__name__} -- a JSON string silently disables "
|
||||
f"host gating and credential injection"
|
||||
)
|
||||
continue
|
||||
if isinstance(v, str):
|
||||
continue
|
||||
errors.append(
|
||||
f"{md}: metadata.{k} must be a string, got {type(v).__name__} "
|
||||
f"-- quote it (versions and dates especially)"
|
||||
)
|
||||
|
||||
lines = text.count("\n") + 1
|
||||
if lines > 500:
|
||||
warnings.append(f"{md}: {lines} lines; the spec recommends under 500")
|
||||
|
||||
for w in warnings:
|
||||
print(f"::warning file={w.split(':')[0]}::{w}")
|
||||
for e in errors:
|
||||
print(f"::error file={e.split(':')[0]}::{e}")
|
||||
print(f"FAIL {e}")
|
||||
print(f"\n{len(errors)} error(s), {len(warnings)} warning(s).")
|
||||
sys.exit(1 if errors else 0)
|
||||
PY
|
||||
103
.github/workflows/skill-tests.yml
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
name: Skill Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "skills/**"
|
||||
- "tests/**"
|
||||
- "pyproject.toml"
|
||||
- "uv.lock"
|
||||
- ".github/workflows/skill-tests.yml"
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "skills/**"
|
||||
- "tests/**"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: skill-tests-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
contract:
|
||||
name: Repo-wide contract and coverage guard
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up uv
|
||||
uses: astral-sh/setup-uv@v8.0.0
|
||||
with:
|
||||
enable-cache: true
|
||||
cache-dependency-glob: uv.lock
|
||||
python-version: "3.13"
|
||||
|
||||
- name: Install dependencies
|
||||
run: uv sync --python 3.13
|
||||
|
||||
# tests/_meta checks every skill against the shared structural contract
|
||||
# (frontmatter, SKILL.md length, local links, scripts parse, no shipped
|
||||
# bytecode, no hardcoded local paths, ...) and enforces the repo rule that
|
||||
# a skill shipping scripts/ has a suite under tests/ and an entry in
|
||||
# tests/skill-requirements.toml. It imports no skill code and needs no
|
||||
# scientific packages, so it runs in seconds on every pull request.
|
||||
- name: Structural contract and coverage
|
||||
run: uv run --python 3.13 python -m pytest tests/_meta -q
|
||||
|
||||
suites:
|
||||
name: Standard-library-only skill suites
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
needs: contract
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up uv
|
||||
uses: astral-sh/setup-uv@v8.0.0
|
||||
with:
|
||||
enable-cache: true
|
||||
cache-dependency-glob: uv.lock
|
||||
python-version: "3.13"
|
||||
|
||||
# The skills whose bundled tooling is standard-library only -- read from
|
||||
# `packages = []` in tests/skill-requirements.toml, so the list needs no
|
||||
# separate maintenance. Each still gets a clean throwaway environment.
|
||||
#
|
||||
# The full `--isolated` sweep across every skill is deliberately NOT run
|
||||
# here: it builds ~100 environments including torch, qiskit, and scanpy,
|
||||
# and several skills need CUDA, a JDK, or a MATLAB install that CI does
|
||||
# not have. Run it locally or on a schedule:
|
||||
# python tests/run_all.py --isolated
|
||||
- name: Select standard-library-only skills
|
||||
id: select
|
||||
run: |
|
||||
set -euo pipefail
|
||||
SKILLS=$(python3 - <<'PY'
|
||||
import pathlib, tomllib
|
||||
manifest = tomllib.loads(
|
||||
pathlib.Path("tests/skill-requirements.toml").read_text()
|
||||
)
|
||||
names = sorted(
|
||||
name
|
||||
for name, entry in manifest["skills"].items()
|
||||
if not entry.get("packages") and "python" not in entry
|
||||
and (pathlib.Path("tests") / name).is_dir()
|
||||
)
|
||||
print(" ".join(names))
|
||||
PY
|
||||
)
|
||||
echo "Selected: $SKILLS"
|
||||
echo "skills=$SKILLS" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Run suites, one environment each
|
||||
run: uv run --python 3.13 python tests/run_all.py --isolated ${{ steps.select.outputs.skills }}
|
||||
29
.gitignore
vendored
@@ -1,13 +1,26 @@
|
||||
.claude
|
||||
# OS
|
||||
.DS_Store
|
||||
|
||||
temp/
|
||||
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
|
||||
# Python
|
||||
.venv/
|
||||
.python-version
|
||||
main.py
|
||||
__pycache__/
|
||||
.pytest_cache/
|
||||
|
||||
__pycache__/
|
||||
# Secrets
|
||||
.env
|
||||
|
||||
# Project
|
||||
temp/
|
||||
research/
|
||||
|
||||
# Local agent tooling
|
||||
.claude/
|
||||
.agents/
|
||||
# Anchored: an unanchored "scripts/" also matches skills/<name>/scripts/,
|
||||
# which silently drops every new skill's bundled tooling from git.
|
||||
/scripts/
|
||||
|
||||
skills-lock.json
|
||||
|
||||
uv.lock
|
||||
372
AGENTS.md
Normal file
@@ -0,0 +1,372 @@
|
||||
# Repository Guidance
|
||||
|
||||
This repository is a collection of Agent Skills for science and research. Every skill lives in its
|
||||
own directory under `skills/` and must conform to the open
|
||||
[Agent Skills specification](https://agentskills.io/specification).
|
||||
|
||||
Read this file before creating or changing a skill. `CONTRIBUTING.md` covers the same ground at
|
||||
more length, plus the pull-request process.
|
||||
|
||||
## What belongs here
|
||||
|
||||
**In scope:** a narrow skill for one scientific package, database, platform, or research workflow —
|
||||
`scanpy`, `depmap`, `benchling-integration`, `experimental-design`.
|
||||
|
||||
**Out of scope**, and routinely declined:
|
||||
|
||||
- General software-engineering or coding-judgment skills — they compete for selection on every task.
|
||||
- General infrastructure with a scientific example bolted on (a vector database, a cloud SDK) —
|
||||
accepting one implies carrying every competitor.
|
||||
- Broad "orchestrator" skills that route to other skills — they overlap every specialist by design.
|
||||
- A second provider for a service an existing skill already reaches.
|
||||
|
||||
The general-purpose skills that do exist are narrow output-format helpers (`docx`, `pdf`, `pptx`,
|
||||
`generate-image`, `markdown-mermaid-writing`). They are not precedent for broadening scope.
|
||||
|
||||
## Layout
|
||||
|
||||
The repository root is an [Agent Plugins](https://agent-plugins.org/) 1.0.0 package: `plugin.json`
|
||||
plus the portable `skills/` tree. Keep `plugin.json` valid against the Agent Plugins manifest
|
||||
schema, and keep its `version` identical to `pyproject.toml` `[project].version`. Do not add
|
||||
non-portable top-level fields to `plugin.json` (no inline MCP, hooks, or client-only keys — use
|
||||
`mcp.json` or a reverse-domain `extensions` namespace if those are ever needed).
|
||||
|
||||
```text
|
||||
plugin.json # Agent Plugins manifest (repo root)
|
||||
skills/<skill-name>/
|
||||
├── SKILL.md # required
|
||||
├── references/ # optional: long documentation, loaded only when needed
|
||||
├── scripts/ # optional: executable helpers
|
||||
└── assets/ # optional: templates and static resources
|
||||
```
|
||||
|
||||
Only `SKILL.md` is required inside each skill. Reference other files with relative paths from the
|
||||
skill root, kept one level deep.
|
||||
|
||||
**Tests never live under `skills/`.** A skill directory ships only what an agent loads. Checks for a
|
||||
skill's scripts and structure go in the repository-level suite instead:
|
||||
|
||||
```text
|
||||
tests/<skill-name>/ # same name as the skill directory
|
||||
├── test_scripts.py
|
||||
└── fixtures/ # optional test data
|
||||
```
|
||||
|
||||
**Diagrams never live under `skills/` either.** A skill may have a generated workflow diagram at
|
||||
`docs/images/<skill-name>.png`, produced by `scripts/generate_skill_image.py`. Diagrams are optional
|
||||
— see [Skill diagrams](#skill-diagrams).
|
||||
|
||||
Tests reach their skill through an explicit anchor, never a relative walk:
|
||||
|
||||
```python
|
||||
SKILL_ROOT = Path(__file__).resolve().parents[2] / "skills" / "<skill-name>"
|
||||
```
|
||||
|
||||
## Creating a skill
|
||||
|
||||
1. Create `skills/<name>/` — **the directory name is the skill name** and must equal frontmatter
|
||||
`name`.
|
||||
2. Write `SKILL.md` from the template below. Start at `metadata.version: "1.0"`.
|
||||
3. Add `references/`, `scripts/`, or `assets/` only when they earn their place.
|
||||
4. Run the commands and code you document. Scope claims to the release you actually tested
|
||||
("targets stable GeoPandas 1.1.4"), and mark anything untested as illustrative.
|
||||
5. If the skill ships `scripts/`, put their tests in **`tests/<name>/`** — never in the skill
|
||||
directory. Fixtures go in `tests/<name>/fixtures/`.
|
||||
6. Validate and scan (below).
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: skill-name
|
||||
description: What the skill does and when an agent should use it, including the terms that should trigger it.
|
||||
license: MIT
|
||||
compatibility: Requires Python 3.12+ with <package> installed. Needs network access.
|
||||
metadata:
|
||||
version: "1.0"
|
||||
skill-author: Your Name
|
||||
---
|
||||
|
||||
# Skill Title
|
||||
|
||||
## When to use
|
||||
|
||||
Use this skill when...
|
||||
|
||||
## Workflow
|
||||
|
||||
1. ...
|
||||
|
||||
## Examples
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
## Updating a skill
|
||||
|
||||
1. Read the current `SKILL.md` and its supporting files first.
|
||||
2. Check upstream docs — APIs move, and the skill may be pinned to an older release.
|
||||
3. Make the smallest useful change.
|
||||
4. **Bump `metadata.version` in the same change**: minor for normal improvements (`"1.2"` →
|
||||
`"1.3"`), major only for a breaking change or substantial redesign (`"1.9"` → `"2.0"`).
|
||||
5. Re-run any example, command, or script you touched, plus `tests/<name>/` if that suite exists.
|
||||
Suites check that `metadata.version` is present and quoted, not what it equals, so a version bump
|
||||
never needs a matching test edit.
|
||||
## Frontmatter
|
||||
|
||||
`SKILL.md` starts with YAML frontmatter. **Only these six fields are allowed** — the spec defines a
|
||||
closed set, and any other top-level key is a validation error:
|
||||
|
||||
| Field | Required | Constraints |
|
||||
| --- | --- | --- |
|
||||
| `name` | Yes | 1–64 chars, lowercase letters/digits/hyphens only, no leading, trailing, or consecutive hyphens, and **must equal the directory name**. |
|
||||
| `description` | Yes | 1–1024 chars. Say what the skill does *and* when to use it, with the keywords that should trigger it. Write it in third person. |
|
||||
| `license` | No | License name, or a reference to a bundled license file. |
|
||||
| `compatibility` | No | Max 500 chars. Environment requirements only — omit it if the skill has none. |
|
||||
| `allowed-tools` | No | A **space-separated string**, e.g. `Read Write Edit Bash`. Not a YAML list, not comma-separated. |
|
||||
| `metadata` | No | Mapping of string keys to **string** values, except the host manifest blocks below. Required here: `metadata.version`. |
|
||||
|
||||
Put anything else — authorship, upstream versions, review dates, client-specific config — inside
|
||||
`metadata`, never at the top level. In particular, Hermes' top-level
|
||||
`required_environment_variables` cannot be used here: it fails the validator and, because
|
||||
`strictyaml` rejects the whole document, takes `name` and `description` down with it. Declare
|
||||
credentials in `compatibility` and `metadata.openclaw.envVars` instead.
|
||||
|
||||
### Write block-style YAML, not JSON flow style
|
||||
|
||||
The reference validator parses frontmatter with `strictyaml`, which **rejects JSON-style flow
|
||||
mappings and sequences**. A flow mapping does not merely fail one check: the whole frontmatter
|
||||
fails to parse, so `name` and `description` become unreadable and the skill will not register.
|
||||
|
||||
```yaml
|
||||
# Wrong -- breaks the validator
|
||||
metadata: {"version": "1.1", "skill-author": "K-Dense Inc."}
|
||||
|
||||
# Right
|
||||
metadata:
|
||||
version: "1.1"
|
||||
skill-author: K-Dense Inc.
|
||||
```
|
||||
|
||||
### Quote `metadata` scalars
|
||||
|
||||
Quote values that would otherwise be parsed as a number, boolean, or date — `version: "1.0"`,
|
||||
`last-reviewed: "2026-07-23"` — so they stay strings as the spec requires.
|
||||
|
||||
### Host manifest blocks stay nested mappings
|
||||
|
||||
`metadata.openclaw` and `metadata.hermes` are the documented exception: keep them as **nested
|
||||
mappings**, not JSON strings. OpenClaw's `resolveOpenClawManifestBlock()` requires
|
||||
`typeof candidate === "object"`, so a JSON string silently disables its dependency gating and
|
||||
credential injection. Nested mappings still pass `skills-ref validate`.
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
version: "1.1"
|
||||
skill-author: Exa
|
||||
openclaw:
|
||||
primaryEnv: EXA_API_KEY
|
||||
envVars:
|
||||
- name: EXA_API_KEY
|
||||
required: true
|
||||
description: Exa search API key.
|
||||
hermes:
|
||||
category: research
|
||||
```
|
||||
|
||||
Only skills with external requirements need these blocks; most omit them. A failed `requires` /
|
||||
`requires_toolsets` gate *hides* the skill from the agent, so gate only on something the skill
|
||||
genuinely cannot run without.
|
||||
|
||||
## Body and layout
|
||||
|
||||
- Keep `SKILL.md` under 500 lines. CI warns above that. Move long reference material into
|
||||
`references/` so agents load it only when needed.
|
||||
- A skill directory ships only what an agent loads. Tests, fixtures, scratch data, and generated
|
||||
artifacts stay out of it; tests go in `tests/<name>/`.
|
||||
- Give concrete workflows, commands, and worked examples rather than background explanation.
|
||||
- Name the required packages, system dependencies, credentials, and network access.
|
||||
- Include the scientific caveats and validation checks that matter.
|
||||
- Put fragile or repetitive logic in `scripts/` instead of asking the agent to recreate it.
|
||||
- Never include secrets, API keys, private URLs, or unpublished data.
|
||||
|
||||
## Validate and scan
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
|
||||
# spec conformance for one skill
|
||||
uv run skills-ref validate skills/<name>
|
||||
|
||||
# every skill, the way CI does
|
||||
for d in skills/*/; do uv run skills-ref validate "$d"; done
|
||||
```
|
||||
|
||||
`.github/workflows/skill-spec-validation.yml` runs that on every PR touching `skills/`, plus the
|
||||
repo rules `skills-ref` does not check: `metadata.version` present, `allowed-tools` a
|
||||
space-separated string, `metadata` scalars quoted, and a warning past 500 lines.
|
||||
|
||||
Security-scan new or substantially changed skills. Scanning uses
|
||||
[Cisco AI Defense Skill Scanner](https://github.com/cisco-ai-defense/skill-scanner) — the
|
||||
`cisco-ai-skill-scanner` package pinned in `pyproject.toml`, which detects prompt injection, data
|
||||
exfiltration, and malicious code patterns in Agent Skills. Its README documents the rule IDs and
|
||||
CLI flags; consult it when a finding's rule is unfamiliar.
|
||||
|
||||
`.github/workflows/pr-skill-scan.yml` runs the repo wrapper for changed skills on every PR and
|
||||
posts a sticky comment, failing on HIGH or above:
|
||||
|
||||
```bash
|
||||
# needs SKILL_SCANNER_LLM_API_KEY (see .env)
|
||||
uv run python scan_pr_skills.py skills/<name>
|
||||
|
||||
# or the upstream CLI directly, without the repo wrapper
|
||||
uv run skill-scanner scan skills/<name> --use-behavioral
|
||||
```
|
||||
|
||||
**Verify a finding against the code before "fixing" it.** Known systematic false positives:
|
||||
`BEHAVIOR_*_EXFILTRATION` and `BEHAVIOR_ENV_VAR_HARVESTING` on any skill that reads its own API key
|
||||
and calls its own service; `MDBLOCK_PYTHON_SUBPROCESS` on any `subprocess` snippet, including the
|
||||
safe argument-list form; and `*_EVAL_EXEC` on substrings inside ordinary identifiers (`retrieval`,
|
||||
`executor`) or on `model.eval()`. Findings sometimes cite files a skill does not contain — check
|
||||
against `find skills/<name> -type f` before acting.
|
||||
|
||||
If the skill has tests in `tests/<name>/`, run them:
|
||||
|
||||
```bash
|
||||
uv run --with pytest python -m pytest tests/<name> -q
|
||||
|
||||
# every skill's suite, one process each, after the repo-wide guard
|
||||
uv run --with pytest python tests/run_all.py
|
||||
```
|
||||
|
||||
**One skill per pytest process.** Skills' `scripts/` directories own plain top-level module names —
|
||||
32 of them ship a `scripts/_common.py` — so collecting two skills into one interpreter resolves
|
||||
`_common` to whichever skill imported first and silently tests the wrong files. `tests/conftest.py`
|
||||
refuses such a session; `tests/run_all.py` forks per skill.
|
||||
|
||||
### The repo-wide guard
|
||||
|
||||
```bash
|
||||
uv run --with pytest python -m pytest tests/_meta -q
|
||||
```
|
||||
|
||||
`tests/_meta` is the fastest useful signal in the repo: pure standard library, no scientific
|
||||
packages, a couple of seconds. It runs the shared structural contract against **every** skill and
|
||||
fails if a skill ships `scripts/` without a suite under `tests/<name>/` or an entry in
|
||||
`tests/skill-requirements.toml`. `.github/workflows/skill-tests.yml` runs it on every pull request,
|
||||
so a skill with untested scripts cannot land. A full run of `tests/run_all.py` starts with it.
|
||||
|
||||
It is not one of the per-skill processes because it deliberately spans all of them at once — safe
|
||||
because it never imports skill code, only parses it.
|
||||
|
||||
### The shared contract
|
||||
|
||||
`tests/_contract/` holds the assertions every skill shares, so a per-skill suite contains only what
|
||||
is actually specific to that skill. `tests/conftest.py` registers it as the importable module
|
||||
`skill_contract`:
|
||||
|
||||
```python
|
||||
import skill_contract
|
||||
|
||||
# every argparse script answers --help; skips when its packages are absent,
|
||||
# runs for real under --isolated
|
||||
CliHelpTests = skill_contract.cli.help_test_case(SKILL_ROOT)
|
||||
|
||||
# for library-style scripts with an `if __name__ == "__main__"` worked example
|
||||
DemoBlockTests = skill_contract.cli.demo_test_case(SKILL_ROOT, ("doe_designs.py",))
|
||||
```
|
||||
|
||||
- `structure` — frontmatter conformance, the 500-line limit, no tests or bytecode under `skills/`,
|
||||
local links resolve, scripts parse, no `eval`/`exec`/`os.system`, no standard-library shadowing,
|
||||
no hardcoded local paths, shell scripts valid. Run repo-wide by `tests/_meta`; do not duplicate
|
||||
these in a per-skill suite.
|
||||
- `cli` — the `--help` and demo-block cases above.
|
||||
- `office` / `schematic` — behaviour for files several skills ship byte-identical copies of (the
|
||||
OOXML tree under docx/pptx/xlsx; the AI schematic generator under five skills). `tests/_meta`
|
||||
separately fails if those copies drift apart, so fix them together.
|
||||
|
||||
### One environment per skill
|
||||
|
||||
The project environment deliberately does not carry the skills' scientific packages. Their upstream
|
||||
pins are mutually exclusive — `opentrons` needs `numpy<2`, `esm` caps `transformers` below the
|
||||
version the `transformers` skill targets, `geniml` and `spikeinterface` pin `zarr<3` against the
|
||||
`zarr-python` skill's 3.x, `bioservices` caps `lxml<6` against `matchms`, and `pytdc`, `molfeat`,
|
||||
`deepchem`, `histolab`, `vaex`, and `ete3` each need an interpreter older than 3.13. Installing them
|
||||
together forces every one of those skills to the losing side of a version fight.
|
||||
|
||||
So `--isolated` builds a throwaway `uv` environment per skill instead, from
|
||||
[`tests/skill-requirements.toml`](tests/skill-requirements.toml):
|
||||
|
||||
```bash
|
||||
python tests/run_all.py --isolated # every suite, one env each
|
||||
python tests/run_all.py --isolated scanpy qiskit # just these
|
||||
```
|
||||
|
||||
Each entry lists the packages that skill documents, plus an optional `python` when the skill cannot
|
||||
run on the default interpreter; uv downloads that interpreter on demand. Packages that cannot be
|
||||
installed at all — a GitHub-only SDK, a conda-forge-only library, a CUDA build — are recorded under
|
||||
`[unavailable]` with the reason, and the runner prints them so the gap shows up in test output.
|
||||
|
||||
Adding a skill with `scripts/` means adding its `[skills.<name>]` entry — `tests/_meta` fails
|
||||
without one. Use `packages = []` for skills whose bundled tooling is standard-library only; they
|
||||
still get a clean environment, and CI runs exactly that set on every pull request. uv caches wheels
|
||||
globally, so repeat runs create each environment in milliseconds.
|
||||
|
||||
The full `--isolated` sweep is not run in CI: it builds one environment per skill, several of which
|
||||
need a CUDA toolchain, a JDK, or a local MATLAB install. Run it before a release, or whenever you
|
||||
touch the shared contract.
|
||||
|
||||
## Skill diagrams
|
||||
|
||||
A skill may carry a generated workflow diagram at `docs/images/<skill-name>.png`. Diagrams are
|
||||
optional: neither a new skill nor a change to an existing one is blocked on having or refreshing an
|
||||
image, and no CI check enforces them. If you do ship one, note that it is derived from the
|
||||
documentation, so regenerate it when the skill's workflow changes rather than leaving a picture that
|
||||
misrepresents the skill.
|
||||
|
||||
`scripts/generate_skill_image.py` is local repository tooling, standard library only, and runs in
|
||||
two stages on one `OPENROUTER_API_KEY` (environment variable, repository `.env`, or `--api-key`):
|
||||
a text model reads `SKILL.md` plus everything under `references/` and a manifest of `scripts/` and
|
||||
`assets/`, distils it into a description of one diagram, then an image model draws it. Because it
|
||||
reads the whole skill, run it **after** the documentation is final, not before.
|
||||
|
||||
```bash
|
||||
# one skill -> docs/images/<name>.png, replacing any existing image
|
||||
uv run python scripts/generate_skill_image.py --skill <name>
|
||||
|
||||
# see which files feed the reader, and where the image lands — no API calls, nothing billed
|
||||
uv run python scripts/generate_skill_image.py --skill <name> --dry-run
|
||||
|
||||
# read the skill and print the diagram prompt without drawing it
|
||||
uv run python scripts/generate_skill_image.py --skill <name> --prompt-only
|
||||
|
||||
# several skills in one batch
|
||||
uv run python scripts/generate_skill_image.py --skill <name-a> <name-b>
|
||||
|
||||
# backfill everything missing an image, six at a time
|
||||
uv run python scripts/generate_skill_image.py --all --skip-existing -j 6
|
||||
```
|
||||
|
||||
Look at the result before committing it. Image models misspell labels and occasionally point an
|
||||
arrow at the wrong card; regenerate rather than ship a diagram whose text is wrong. `--quality low`
|
||||
makes iteration cheap while checking composition, but commit a `high` render. Both the art direction
|
||||
and the reader's instructions live at the top of the script — change them there rather than
|
||||
hand-tuning one skill's prompt, so the set stays visually consistent.
|
||||
|
||||
## Before opening a PR
|
||||
|
||||
- Directory name and frontmatter `name` match exactly.
|
||||
- No `tests/` directory and no `test_*.py` anywhere under `skills/<name>/` — tests belong in
|
||||
`tests/<name>/`.
|
||||
- Only the six spec-defined top-level fields; everything else under `metadata`.
|
||||
- `metadata.version` exists, is quoted, and is bumped if you changed an existing skill.
|
||||
- `metadata` is a block mapping; `openclaw` / `hermes` blocks are nested mappings.
|
||||
- `uv run skills-ref validate skills/<name>` passes.
|
||||
- If the collection version changes, `plugin.json` `version` matches `pyproject.toml`.
|
||||
- `uv run --with pytest python -m pytest tests/_meta -q` passes — this is what CI blocks on, and it
|
||||
catches a missing suite, a missing `skill-requirements.toml` entry, a broken local link, a
|
||||
leaked local path, and a drifted Agent Plugins manifest.
|
||||
- If the skill ships `scripts/`: a suite exists at `tests/<name>/`, a `[skills.<name>]` entry exists
|
||||
in `tests/skill-requirements.toml`, and `python tests/run_all.py --isolated <name>` passes.
|
||||
- If the skill ships `docs/images/<name>.png`, its labels are spelled correctly and its arrows point
|
||||
where they should. The image itself is optional.
|
||||
- Examples and scripts are tested, or clearly marked illustrative.
|
||||
- No secrets or private data; scan results clean or explained in the PR.
|
||||
3
CLAUDE.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# CLAUDE.md
|
||||
|
||||
Repository guidance for this project lives in [AGENTS.md](AGENTS.md). Read it and follow it.
|
||||
135
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,135 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||
identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the overall
|
||||
community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or advances of
|
||||
any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email address,
|
||||
without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official email address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
[contact@k-dense.ai](mailto:contact@k-dense.ai).
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
Note that this address is for conduct reports. Security vulnerabilities follow a
|
||||
separate, confidential process — see [SECURITY.md](SECURITY.md).
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of
|
||||
actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or permanent
|
||||
ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||
community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.1, available at
|
||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
||||
|
||||
Community Impact Guidelines were inspired by
|
||||
[Mozilla's code of conduct enforcement ladder][mozilla coc].
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
[https://www.contributor-covenant.org/faq][faq]. Translations are available at
|
||||
[https://www.contributor-covenant.org/translations][translations].
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
||||
[mozilla coc]: https://github.com/mozilla/inclusion
|
||||
[faq]: https://www.contributor-covenant.org/faq
|
||||
[translations]: https://www.contributor-covenant.org/translations
|
||||
369
CONTRIBUTING.md
Normal file
@@ -0,0 +1,369 @@
|
||||
# Contributing Skills
|
||||
|
||||
Thanks for helping improve Scientific Agent Skills. This guide explains how to add or update a skill in this repository while following the open [Agent Skills specification](https://agentskills.io/specification).
|
||||
|
||||
Participation in this project is governed by our [Code of Conduct](CODE_OF_CONDUCT.md).
|
||||
|
||||
## Ways to Contribute
|
||||
|
||||
- Add a new scientific package, database, platform, workflow, or research method skill.
|
||||
- Improve an existing skill with clearer instructions, current APIs, better examples, references, or scripts.
|
||||
- Fix outdated examples, broken install steps, security issues, or documentation gaps.
|
||||
- Add or extend a skill's tests under `tests/<skill-name>/` (see [Tests](#tests)).
|
||||
- Report bugs or request new skills through GitHub Issues.
|
||||
|
||||
## Skill Location
|
||||
|
||||
All repository skills live under `skills/`. The repository root is also an
|
||||
[Agent Plugins](https://agent-plugins.org/) package: keep root `plugin.json` schema-valid, do not
|
||||
add non-portable top-level fields, and keep its `version` in sync with `pyproject.toml` whenever
|
||||
you bump the collection version.
|
||||
|
||||
```text
|
||||
plugin.json
|
||||
skills/
|
||||
└── skill-name/
|
||||
├── SKILL.md
|
||||
├── references/
|
||||
├── scripts/
|
||||
└── assets/
|
||||
```
|
||||
|
||||
Only `SKILL.md` is required. Use optional directories when they make the skill easier to maintain:
|
||||
|
||||
- `references/` for longer documentation that agents should read only when needed.
|
||||
- `scripts/` for executable helpers, validators, or reusable workflow code.
|
||||
- `assets/` for templates, static resources, or example data.
|
||||
|
||||
Those four are the only directories a skill may contain. Anything else — tests, fixtures, scratch data, generated output — belongs outside `skills/`.
|
||||
|
||||
Keep references one level deep from `SKILL.md` where possible, and keep the main `SKILL.md` concise. The Agent Skills specification recommends keeping `SKILL.md` under 500 lines and using progressive disclosure for longer material.
|
||||
|
||||
A skill directory holds only what an agent loads, so tests do not belong there. They live in the repository-level suite under `tests/<skill-name>/`, mirroring the skill directory name, with any fixtures in `tests/<skill-name>/fixtures/`. See [Tests](#tests).
|
||||
|
||||
## Required Skill Format
|
||||
|
||||
Every skill must be a directory containing a `SKILL.md` file with YAML frontmatter followed by Markdown instructions.
|
||||
|
||||
Use this minimum template:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: skill-name
|
||||
description: Clear description of what the skill does and when an agent should use it.
|
||||
metadata:
|
||||
version: "1.0"
|
||||
skill-author: Your Name
|
||||
---
|
||||
|
||||
# Skill Title
|
||||
|
||||
## When to Use
|
||||
|
||||
Use this skill when...
|
||||
|
||||
## Workflow
|
||||
|
||||
1. ...
|
||||
2. ...
|
||||
|
||||
## Examples
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
### Frontmatter Requirements
|
||||
|
||||
Follow the [Agent Skills specification](https://agentskills.io/specification) and this repository's conventions:
|
||||
|
||||
- `name` is required, must match the parent directory name, and must be 1-64 characters.
|
||||
- `name` may contain only lowercase letters, numbers, and hyphens.
|
||||
- `name` must not start or end with a hyphen and must not contain consecutive hyphens.
|
||||
- `description` is required, non-empty, and must be at most 1024 characters.
|
||||
- `description` should explain both what the skill does and when an agent should use it.
|
||||
- `metadata.version` is required in this repository, even though `metadata` is optional in the upstream spec.
|
||||
- Version values must be quoted numeric strings, such as `"1.0"` or `"1.1"`.
|
||||
- **Only the six fields defined by the specification are allowed** at the top level: `name`, `description`, `license`, `compatibility`, `allowed-tools`, and `metadata`. The spec defines a closed set and the reference validator rejects any other top-level key, so everything else belongs under `metadata`.
|
||||
- **Write `metadata` as a block mapping, not single-line JSON.** The reference validator parses frontmatter with `strictyaml`, which rejects JSON-style flow mappings. A flow mapping does not merely fail one check — the entire frontmatter fails to parse, so `name` and `description` become unreadable and the skill does not register.
|
||||
|
||||
```yaml
|
||||
# Wrong -- breaks the reference validator
|
||||
metadata: {"version": "1.0", "skill-author": "K-Dense Inc."}
|
||||
|
||||
# Right
|
||||
metadata:
|
||||
version: "1.0"
|
||||
skill-author: K-Dense Inc.
|
||||
```
|
||||
|
||||
Optional frontmatter fields from the specification may be used when relevant:
|
||||
|
||||
- `license`: the license for the individual skill, if different or worth stating explicitly.
|
||||
- `compatibility`: environment requirements such as Python version, system packages, agent host, or network access. Maximum 500 characters.
|
||||
- `metadata`: additional metadata, as a block mapping of string keys to string values. Quote any value that would otherwise parse as a number, boolean, or date (`version: "1.0"`, `last-reviewed: "2026-07-23"`). Common keys: `version` (required), `skill-author`, and an optional nested `openclaw` or `hermes` block (see below).
|
||||
- `allowed-tools`: a **space-separated string** of tool permissions for hosts that support this experimental field, for example `allowed-tools: Read Write Edit Bash`. Not a YAML list.
|
||||
|
||||
### OpenClaw gating (`metadata.openclaw`)
|
||||
|
||||
OpenClaw reads an optional `openclaw` object nested inside `metadata` for dependency gating, credential injection, and display. Because it lives under `metadata`, the Agent Skills spec permits it and other hosts ignore it. It is only needed for skills with external requirements (credentials, daemons, specific binaries) — most skills omit it entirely.
|
||||
|
||||
**Keep this block a nested mapping — never a JSON string.** OpenClaw's `resolveOpenClawManifestBlock()` requires `typeof candidate === "object"`, so a stringified block silently disables gating and credential injection with no error. This is the one documented exception to the string-values rule for `metadata`, and it still passes `skills-ref validate`.
|
||||
|
||||
Supported keys:
|
||||
|
||||
- `requires`: hard eligibility gates — `{"bins": [...]}` (all must be on `PATH`), `{"anyBins": [...]}` (at least one), `{"env": [...]}` (vars that must be set), `{"config": [...]}`. A failed gate hides the skill from the agent, so only gate on things the skill genuinely cannot run without.
|
||||
- `primaryEnv`: the main credential variable; OpenClaw injects it from its config (`skills.entries.<name>.apiKey`).
|
||||
- `envVars`: descriptive (non-gating) declarations — `[{"name": "X_API_KEY", "required": true, "description": "..."}]`. Declare every env var your scripts reference so ClawHub's security analysis does not flag a metadata mismatch.
|
||||
- `os`: platform filter, e.g. `["darwin", "linux"]`.
|
||||
- `emoji`, `homepage`: display only.
|
||||
|
||||
Example (an API-key skill that stays available even without the key set, so it gates nothing and only declares the credential):
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
version: "1.0"
|
||||
skill-author: K-Dense Inc.
|
||||
openclaw:
|
||||
primaryEnv: EXA_API_KEY
|
||||
envVars:
|
||||
- name: EXA_API_KEY
|
||||
required: true
|
||||
description: Exa search API key.
|
||||
```
|
||||
|
||||
### Hermes compatibility (`required_environment_variables` and `metadata.hermes`)
|
||||
|
||||
[Hermes](https://hermes-agent.nousresearch.com/docs) is Agent Skills-compatible, so every skill in this repository already loads and runs there with no changes. Two optional fields make credentialed skills first-class on Hermes:
|
||||
|
||||
- **`metadata.hermes`** (nested, spec-safe like `openclaw`): optional classification and gating — `tags`, `category`, `requires_toolsets`, `fallback_for_toolsets`. A failed `requires_toolsets` gate *hides* the skill, so only gate on a tool the skill genuinely cannot run without; prefer leaving it unset so the skill stays available. Keep it a nested mapping, not a JSON string.
|
||||
|
||||
Example (an API-key skill, declaring its credential for OpenClaw and classifying itself for Hermes):
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
version: "1.0"
|
||||
skill-author: Exa
|
||||
openclaw:
|
||||
primaryEnv: EXA_API_KEY
|
||||
envVars:
|
||||
- name: EXA_API_KEY
|
||||
required: true
|
||||
description: Exa search API key.
|
||||
hermes:
|
||||
category: research
|
||||
```
|
||||
|
||||
### `required_environment_variables` is not used in this repository
|
||||
|
||||
Hermes also reads a **top-level** `required_environment_variables` array to prompt for credentials. That field cannot coexist with spec conformance: the specification defines a closed set of six top-level fields, so the reference validator rejects it outright — and because `strictyaml` fails the whole frontmatter block on an unknown-shaped document, the failure is not confined to that one key.
|
||||
|
||||
This repository therefore does not use it. Declare credentials in two spec-legal places instead:
|
||||
|
||||
- `compatibility` — a human- and agent-readable sentence naming the variables the skill needs.
|
||||
- `metadata.openclaw.envVars` — the machine-readable declaration, which ClawHub's security analysis also checks against the variables your scripts actually reference.
|
||||
|
||||
Skills still load and run on Hermes; only its automatic credential prompt is unavailable, and the required variables remain discoverable from the two fields above.
|
||||
|
||||
## Versioning
|
||||
|
||||
Every `SKILL.md` must include a quoted `version` inside the `metadata` mapping:
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
version: "1.0"
|
||||
```
|
||||
|
||||
For a new skill, start at `"1.0"`.
|
||||
|
||||
When updating an existing skill, increment `metadata.version` in the same pull request:
|
||||
|
||||
- Use a minor bump for normal improvements, for example `"1.0"` to `"1.1"`.
|
||||
- Use a major bump only for a breaking change or substantial redesign, for example `"1.9"` to `"2.0"`.
|
||||
|
||||
## Writing a Good Skill
|
||||
|
||||
Good skills are specific, practical, and easy for an agent to apply.
|
||||
|
||||
- Write the `description` in third person with useful trigger terms.
|
||||
- Include concrete workflows, commands, and examples instead of broad background explanations.
|
||||
- Prefer current official APIs, docs, and installation instructions.
|
||||
- Document required Python packages, system dependencies, credentials, or network access.
|
||||
- Include scientific best practices, caveats, and validation checks where they matter.
|
||||
- Move long API details, tables, and extended examples into `references/`.
|
||||
- Use scripts for fragile or repetitive logic instead of asking the agent to recreate it every time.
|
||||
- Avoid secrets, credentials, API keys, private URLs, and unpublished data.
|
||||
|
||||
## Adding a New Skill
|
||||
|
||||
1. Fork the repository and create a branch:
|
||||
|
||||
```bash
|
||||
git checkout -b add-skill-name
|
||||
```
|
||||
|
||||
2. Create a new directory under `skills/` whose name matches the skill name:
|
||||
|
||||
```text
|
||||
skills/skill-name/
|
||||
```
|
||||
|
||||
3. Add `SKILL.md` with valid frontmatter, including `metadata.version`.
|
||||
|
||||
4. Add supporting `references/`, `scripts/`, or `assets/` only when they are useful.
|
||||
|
||||
5. Test any commands, code examples, and scripts included in the skill.
|
||||
|
||||
6. If the skill ships `scripts/`, add their tests in the repository-level suite, not in the skill directory:
|
||||
|
||||
```text
|
||||
tests/skill-name/
|
||||
```
|
||||
|
||||
See [Tests](#tests) for the layout, the path anchor to use, and how to run them.
|
||||
|
||||
7. Update related documentation if the new skill changes repository-level lists, examples, or setup guidance.
|
||||
|
||||
8. Run validation and security checks before opening a pull request.
|
||||
|
||||
## Updating an Existing Skill
|
||||
|
||||
1. Read the current `SKILL.md` and any supporting files.
|
||||
2. Check upstream package, API, or platform documentation for current behavior.
|
||||
3. Make the smallest useful change that fixes or improves the skill.
|
||||
4. Increment `metadata.version`.
|
||||
5. Test changed examples, commands, and scripts.
|
||||
6. Run the skill's suite if it has one: `uv run --with pytest python -m pytest tests/skill-name -q`. Suites check that `metadata.version` is present and quoted, not what it equals, so a version bump never needs a matching test edit.
|
||||
7. Note any behavior changes in the pull request description.
|
||||
|
||||
## Validation
|
||||
|
||||
Validate Agent Skills format with the reference validator, which is already a dev dependency:
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
uv run skills-ref validate ./skills/skill-name
|
||||
|
||||
# or check every skill at once, the same way CI does
|
||||
for d in skills/*/; do uv run skills-ref validate "$d"; done
|
||||
```
|
||||
|
||||
CI runs this on every pull request that touches `skills/`, along with the repo-specific checks in `.github/workflows/skill-spec-validation.yml` (a required `metadata.version`, `allowed-tools` as a string, quoted `metadata` scalars, and a warning above 500 lines).
|
||||
|
||||
Security-scan new or substantially changed skills:
|
||||
|
||||
```bash
|
||||
uv pip install cisco-ai-skill-scanner
|
||||
skill-scanner scan ./skills/skill-name --use-behavioral
|
||||
```
|
||||
|
||||
A clean scan reduces review noise but does not replace manual review.
|
||||
|
||||
## Tests
|
||||
|
||||
**Tests never live under `skills/`.** A skill directory ships only what an agent loads, so tests go in the repository-level suite instead — one directory per skill, named exactly after the skill directory:
|
||||
|
||||
```text
|
||||
tests/
|
||||
└── skill-name/ # matches skills/skill-name/
|
||||
├── test_scripts.py
|
||||
└── fixtures/ # optional test data
|
||||
```
|
||||
|
||||
A test reaches the skill it covers through an explicit anchor rather than a relative walk:
|
||||
|
||||
```python
|
||||
SKILL_ROOT = Path(__file__).resolve().parents[2] / "skills" / "skill-name"
|
||||
```
|
||||
|
||||
Anything the CLIs under test resolve relative to the working directory should be repo-root relative, since the suite runs from the repository root — `tests/skill-name/fixtures/manifest.json`, not `fixtures/manifest.json`.
|
||||
|
||||
Run one skill's suite, or the whole tree:
|
||||
|
||||
```bash
|
||||
uv run --with pytest python -m pytest tests/skill-name -q
|
||||
|
||||
# every skill, in a separate process each, after the repo-wide guard
|
||||
uv run --with pytest python tests/run_all.py
|
||||
```
|
||||
|
||||
Each skill's suite must run in its own process. Skills' `scripts/` directories own plain top-level module names — 32 skills ship a `scripts/_common.py`, and names like `cluster.py` and `validate_manifest.py` recur — so collecting two skills into one interpreter would resolve those imports to whichever skill was imported first and silently test the wrong files. `tests/conftest.py` rejects a multi-skill session, and `tests/run_all.py` forks per skill.
|
||||
|
||||
### The repo-wide guard, and what you no longer have to write
|
||||
|
||||
```bash
|
||||
uv run --with pytest python -m pytest tests/_meta -q
|
||||
```
|
||||
|
||||
`tests/_meta` is the check to run first and the one CI blocks on. It needs no scientific packages and finishes in seconds. It spans every skill at once — safe, because it parses scripts with `ast` and never imports them — and it enforces the rule this whole layout exists for: **a skill that ships `scripts/` must have a suite at `tests/<name>/` and a `[skills.<name>]` entry in `skill-requirements.toml`.** It also runs the shared structural contract over every skill: frontmatter conformance, the 500-line `SKILL.md` limit, no tests or compiled bytecode under `skills/`, every local link resolving, every script parsing, no `eval`/`exec`/`os.system`, no script shadowing a standard-library module, no hardcoded local path, and valid shell scripts.
|
||||
|
||||
Because `tests/_meta` already covers all of that repo-wide, a per-skill suite should not repeat it. Write only what is specific to the skill, and pull the shared pieces from `tests/_contract/`, which `tests/conftest.py` registers as the importable module `skill_contract`:
|
||||
|
||||
```python
|
||||
import skill_contract
|
||||
|
||||
# every argparse script answers --help; skips when the skill's packages are
|
||||
# absent, and runs for real under --isolated
|
||||
CliHelpTests = skill_contract.cli.help_test_case(SKILL_ROOT)
|
||||
|
||||
# for scripts that are importable libraries with a worked example under
|
||||
# `if __name__ == "__main__":` rather than argparse CLIs
|
||||
DemoBlockTests = skill_contract.cli.demo_test_case(SKILL_ROOT, ("doe_designs.py",))
|
||||
```
|
||||
|
||||
`skill_contract.office` and `skill_contract.schematic` cover files that several skills ship byte-identical copies of — the OOXML `office/` tree under `docx`/`pptx`/`xlsx`, and the AI schematic generator under five skills. Instantiate them against your skill root rather than writing the tests again; `tests/_meta` separately fails if the copies drift apart, so those files have to be changed together.
|
||||
|
||||
Guard heavy imports at module scope so a suite degrades to skips rather than a collection error when a package is missing:
|
||||
|
||||
```python
|
||||
np = pytest.importorskip("numpy", reason="skill-name needs numpy")
|
||||
```
|
||||
|
||||
### One environment per skill
|
||||
|
||||
Four suites fail on this repository's default environment because their scientific dependencies are not installed (`exa-search`, `qutip`, `scikit-survival`, `simpy`), and installing them all into one environment is not possible: the skills' upstream pins contradict each other. `opentrons` requires `numpy<2`; `esm` caps `transformers` below the release the `transformers` skill targets; `geniml` and `spikeinterface` pin `zarr<3` while the `zarr-python` skill targets 3.x; `bioservices` caps `lxml<6` while `matchms` requires 6.0.2+; and `pytdc`, `molfeat`, `deepchem`, `histolab`, `vaex`, and `ete3` each need an interpreter older than 3.13.
|
||||
|
||||
`--isolated` therefore gives each skill its own throwaway `uv` environment, built from [`tests/skill-requirements.toml`](tests/skill-requirements.toml):
|
||||
|
||||
```bash
|
||||
python tests/run_all.py --isolated # every suite, one env each
|
||||
python tests/run_all.py --isolated qutip exa-search # just these
|
||||
```
|
||||
|
||||
Nothing is installed into the project environment, so `uv sync` is unaffected. Each `[skills.<name>]` entry lists the packages that skill documents and, where needed, a `python` version for that skill alone — uv downloads the interpreter on demand. Packages that cannot be installed at all (a GitHub-only SDK, a conda-forge-only library, a CUDA build) are listed under `[unavailable]` with the reason, and the runner prints them so the gap appears in the test output.
|
||||
|
||||
A new skill that ships `scripts/` needs a `[skills.<name>]` entry — `tests/_meta` fails without one. Use `packages = []` when its bundled tooling is standard-library only — the skill still gets a clean environment with just pytest. uv caches wheels globally, so repeat runs create each environment in milliseconds.
|
||||
|
||||
`.github/workflows/skill-tests.yml` runs `tests/_meta` plus every `packages = []` suite on each pull request, which is fast and needs no wheels beyond pytest. The full `--isolated` sweep is not run in CI: it builds an environment per skill, and several of them need a CUDA toolchain, a JDK, or a local MATLAB install that a runner does not have. Run it locally before a release, and whenever you change anything under `tests/_contract/`.
|
||||
|
||||
## Pull Request Checklist
|
||||
|
||||
Before submitting a pull request, confirm:
|
||||
|
||||
- The skill directory name and `name` frontmatter match exactly.
|
||||
- The skill directory contains only `SKILL.md`, `references/`, `scripts/`, and `assets/` — no `tests/` directory and no `test_*.py` files. Tests live in `tests/<skill-name>/`.
|
||||
- `SKILL.md` has valid YAML frontmatter and Markdown body content.
|
||||
- `uv run skills-ref validate ./skills/<name>` passes.
|
||||
- Only the six spec-defined top-level fields are present; anything else lives under `metadata`.
|
||||
- `metadata` is a block mapping, not single-line JSON, and its scalar values are quoted where needed.
|
||||
- Any `metadata.openclaw` or `metadata.hermes` block is a nested mapping, not a JSON string.
|
||||
- If the skill needs credentials, they are named in `compatibility` and declared in `metadata.openclaw.envVars`.
|
||||
- `metadata.version` exists and is quoted.
|
||||
- Existing skills have a version bump when changed.
|
||||
- If the collection version changes, `plugin.json` `version` matches `pyproject.toml`.
|
||||
- The `description` clearly says what the skill does and when to use it.
|
||||
- `uv run --with pytest python -m pytest tests/_meta -q` passes. This is what CI blocks on, and it catches a missing suite, a missing `skill-requirements.toml` entry, a broken local link, a leaked local path, and a `SKILL.md` over 500 lines.
|
||||
- If the skill ships `scripts/`: a suite exists at `tests/<skill-name>/`, a `[skills.<skill-name>]` entry exists in `tests/skill-requirements.toml`, and `python tests/run_all.py --isolated <skill-name>` passes.
|
||||
- Examples and scripts have been tested or clearly marked as illustrative.
|
||||
- No secrets, credentials, private data, or unsafe instructions are included.
|
||||
- Relevant official documentation is linked where useful.
|
||||
- Security scanner results are clean or explained in the pull request.
|
||||
|
||||
## Pull Request Process
|
||||
|
||||
1. Push your branch to your fork.
|
||||
2. Open a pull request with a clear title, such as `Add scanpy workflow examples` or `Update astropy skill for current API`.
|
||||
3. Describe what changed, why it matters, and how you tested it.
|
||||
4. Link related issues, package documentation, release notes, or security findings.
|
||||
5. Respond to review comments and update the skill as needed.
|
||||
|
||||
Thank you for helping make scientific computing more accessible to AI agents and researchers.
|
||||
87
SECURITY.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Security Policy
|
||||
|
||||
This is the security policy for **Scientific Agent Skills**, maintained by [K-Dense](https://www.k-dense.ai).
|
||||
|
||||
GitHub surfaces this file as the repository's security policy. It is hand-authored. The output of our automated skill scanning is a separate document — see [Automated skill scanning](#automated-skill-scanning) below.
|
||||
|
||||
---
|
||||
|
||||
## Reporting a vulnerability
|
||||
|
||||
**Please do not open a public issue for a security vulnerability.**
|
||||
|
||||
Use GitHub's private vulnerability reporting, which keeps the report confidential until a fix is available:
|
||||
|
||||
> **Security** tab → **Report a vulnerability**
|
||||
|
||||
<!-- TODO(maintainers): add a monitored security contact address here as a second channel,
|
||||
or delete this comment if private vulnerability reporting is the only intended route. -->
|
||||
|
||||
Please include, as far as you are able:
|
||||
|
||||
- The affected skill (or repository tooling) and the version or commit you observed it on
|
||||
- What an attacker could achieve, and what access they would need to achieve it
|
||||
- The steps to reproduce, ideally with the smallest input that triggers it
|
||||
- Any agent host and model you reproduced it on, since skill behavior varies by host
|
||||
|
||||
We will acknowledge your report and tell you whether we consider it in scope. If we accept it, we will keep you informed as we work on a fix and will credit you in the release notes unless you ask us not to.
|
||||
|
||||
---
|
||||
|
||||
## Supported versions
|
||||
|
||||
| Version | Supported |
|
||||
|---|---|
|
||||
| `main` | ✅ |
|
||||
| Latest tagged release | ✅ |
|
||||
| Earlier tagged releases | ❌ — fixes land in a new release rather than being backported |
|
||||
|
||||
If you pin skills to a tag or commit (see the version-pinning section of the [README](README.md#version-pinning)), you are responsible for moving that pin forward to receive fixes.
|
||||
|
||||
---
|
||||
|
||||
## What is in scope
|
||||
|
||||
This repository distributes **Agent Skills**: instructions, reference material, and bundled scripts that an AI agent reads and may execute on your machine. In-scope reports concern content in this repository that could harm someone who installs it:
|
||||
|
||||
- A bundled script that reads credentials, files, or environment variables it has no reason to read, or that transmits data to an unexpected destination
|
||||
- Instructions in a `SKILL.md` that steer an agent toward destructive, exfiltrating, or unauthorized action
|
||||
- Prompt-injection vectors — including content in `references/` or `assets/` that an agent is instructed to treat as authoritative
|
||||
- A skill whose documented behavior materially misrepresents what its bundled code does
|
||||
- Unsafe credential handling, such as instructions to place secrets where they will be committed or logged
|
||||
- Vulnerabilities in this repository's own tooling (`scan_skills.py`, `scan_pr_skills.py`) or its GitHub Actions workflows
|
||||
|
||||
## What is out of scope
|
||||
|
||||
- **Vulnerabilities in the third-party libraries and services a skill documents.** A flaw in RDKit, Scanpy, or a public API belongs to that project — please report it upstream. A skill that *instructs users to use a library unsafely* is in scope here.
|
||||
- **Vulnerabilities in agent hosts.** Issues in Claude Code, Cursor, Codex, and similar belong to those vendors.
|
||||
- **The inherent capability of skills.** Skills are instructions for an agent that can execute code; a skill performing the work it documents is not a vulnerability. See the [Security Disclaimer](README.md#%EF%B8%8F-security-disclaimer) in the README.
|
||||
- **Missing version pins on documented dependencies**, unless you can show a concrete exploitation path.
|
||||
|
||||
---
|
||||
|
||||
## Before you install
|
||||
|
||||
Skills execute code and influence your agent's behavior. Review what you install, and prefer installing the subset of skills you actually need. Bundled scripts that reach the network or read credentials are documented as such in the relevant `SKILL.md`. Treat skill content from any source — including this repository — as code review material, not as trusted input.
|
||||
|
||||
---
|
||||
|
||||
## Automated skill scanning
|
||||
|
||||
Skills in this repository are scanned using [`cisco-ai-skill-scanner`](https://pypi.org/project/cisco-ai-skill-scanner/), which combines static behavioral analysis, trigger analysis, and LLM-assisted review. Changed skills are scanned on every pull request.
|
||||
|
||||
The scheduled scan runs weekly and is incremental: a skill whose package contents are unchanged since the last scan carries its previous findings forward rather than being rescanned. Every skill is rescanned in full whenever the scanner version or the model changes, when a maintainer triggers a full run, and at least every 30 days regardless. Each skill's `last_scanned` date is recorded in the JSON report, so you can always see when a given finding was actually produced.
|
||||
|
||||
- **Report:** [`docs/security-report.md`](docs/security-report.md) (machine-readable companion: [`docs/security-report.json`](docs/security-report.json))
|
||||
- **Triage:** [`docs/security-triage.md`](docs/security-triage.md) — maintainer verdicts on the current report: what was verified and fixed, and which rules are systematic false positives, each with the check that decides it
|
||||
- **Workflow:** [`.github/workflows/security-scan.yml`](.github/workflows/security-scan.yml)
|
||||
|
||||
**How to read the report.** It is generated by automated tooling, including a language model, and is published to be useful rather than authoritative. It is not an audit, a certification, or a guarantee. Each scan is published automatically, with no pre-publication check that its claims are consistent with the contents of `skills/`, so verify a finding against the skill itself before acting on it. A finding in the report is a prompt to review a skill, not a determination that the skill is malicious.
|
||||
|
||||
**If you believe a finding is wrong**, open a regular issue (false positives are not sensitive) with the skill name, the rule ID, and why the finding cannot hold. If a class of false positive originates in the scanner rather than in our configuration, we will also raise it upstream.
|
||||
|
||||
---
|
||||
|
||||
## Reporting a malicious skill elsewhere
|
||||
|
||||
If you find a skill published *outside* this repository that impersonates Scientific Agent Skills or K-Dense, please tell us through the private reporting channel above so we can respond and warn users.
|
||||
6651
docs/examples.md
Normal file
BIN
docs/images/adaptyv.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/aeon.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/analytical-method-validation.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/anndata.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
docs/images/arbor.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/arboreto.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/astropy.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/autoskill.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/benchling-integration.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/bgpt-paper-search.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/bids.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/biopython.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/bioservices.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/bulk-rnaseq.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/cellxgene-census.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/cirq.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/citation-management.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/clinical-decision-support.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/clinical-reports.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/cobrapy.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/consciousness-council.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/dask.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/database-lookup.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/datamol.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/deepchem.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/deepspot-m.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/deeptools.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/depmap.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/dhdna-profiler.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/diffdock.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
docs/images/dnanexus-integration.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/docx.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/esm.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
docs/images/etetoolkit.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/exa-search.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/experimental-design.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/exploratory-data-analysis.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/flowio.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/fluidsim.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/generate-image.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/geniml.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/genomic-coordinates.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/genomic-intelligence.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/geomaster.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
docs/images/geopandas.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/get-available-resources.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/gget.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/ginkgo-cloud-lab.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/glycoengineering.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/gtars.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/histolab.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
docs/images/hugging-science.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
docs/images/hypogenic.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/hypothesis-generation.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/imaging-data-commons.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
docs/images/infographics.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/iso-standards-readiness.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/lab-hardware-cad.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/labarchive-integration.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/lamindb.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/latchbio-integration.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/latex-posters.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/liteparse.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/literature-review.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/markdown-mermaid-writing.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/market-research-reports.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/markitdown.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/matchms.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/matlab.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/matplotlib.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/medchem.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/modal.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/molecular-dynamics.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/molfeat.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/networkx.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/neurokit2.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/neuropixels-analysis.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/images/nextflow.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/omero-integration.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/images/onekgpd.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/images/ontology-term-resolution.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |