Compare commits
822 Commits
v0.42.0
...
fix/linux-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d63fa91a3b | ||
|
|
c0889577ba | ||
|
|
8de2bf984f | ||
|
|
1b8720740c | ||
|
|
91be726381 | ||
|
|
ff5386a24a | ||
|
|
a5f3c4da65 | ||
|
|
e5a852dd3d | ||
|
|
aee30ce8e1 | ||
|
|
0833c8d42d | ||
|
|
036c7f280b | ||
|
|
000429277d | ||
|
|
f8535fd96d | ||
|
|
f0cbf77924 | ||
|
|
17be06eb2f | ||
|
|
0e90785500 | ||
|
|
2bb432b0f2 | ||
|
|
565ce18eba | ||
|
|
81350c0d7f | ||
|
|
9bdb2413ec | ||
|
|
ace9307878 | ||
|
|
83a25ad301 | ||
|
|
4b191a759c | ||
|
|
d02b3f74e6 | ||
|
|
86c62f14a5 | ||
|
|
42c3e8fe01 | ||
|
|
517750e880 | ||
|
|
6c053a5f29 | ||
|
|
1c5ffdf878 | ||
|
|
39a7d49c25 | ||
|
|
ed948f4b59 | ||
|
|
aad5bc16fd | ||
|
|
cee318a40b | ||
|
|
febaf58f91 | ||
|
|
aacb47f7ee | ||
|
|
b3003542d8 | ||
|
|
aba7a10430 | ||
|
|
b7462aa042 | ||
|
|
883bcc9670 | ||
|
|
279b41fdc4 | ||
|
|
220577b41c | ||
|
|
03b45013a6 | ||
|
|
aa85907212 | ||
|
|
085352a6f0 | ||
|
|
c0578d0e53 | ||
|
|
663c18ee97 | ||
|
|
48727750b4 | ||
|
|
30a3a96a57 | ||
|
|
6773ce39da | ||
|
|
342a3e4a07 | ||
|
|
09406ea794 | ||
|
|
1f00cbc9cc | ||
|
|
422a829f5e | ||
|
|
ed109fcedf | ||
|
|
19af96d08e | ||
|
|
e0304b203c | ||
|
|
af65bdbcfb | ||
|
|
d79c2a4123 | ||
|
|
e3d57e5347 | ||
|
|
392312f203 | ||
|
|
0f193055c7 | ||
|
|
f45cb58889 | ||
|
|
37ead6d129 | ||
|
|
5ea9463030 | ||
|
|
dde35ccbd5 | ||
|
|
7f20319272 | ||
|
|
c8204efab6 | ||
|
|
fb5143b563 | ||
|
|
fe257cd8d1 | ||
|
|
890d3406dd | ||
|
|
c316e09c11 | ||
|
|
65547c60c0 | ||
|
|
0babc05077 | ||
|
|
1270b5b55c | ||
|
|
e97d8bc1cb | ||
|
|
5109ca4347 | ||
|
|
f14942c6f9 | ||
|
|
86ec88ed80 | ||
|
|
4928b7e84b | ||
|
|
94a1a701f6 | ||
|
|
ecf2efa857 | ||
|
|
026c6a03a3 | ||
|
|
2b53daf641 | ||
|
|
3cc946ded8 | ||
|
|
70be5c5c21 | ||
|
|
0f9d93058f | ||
|
|
cafed57832 | ||
|
|
f157436e7d | ||
|
|
ba7892322b | ||
|
|
4e90b4561a | ||
|
|
86eed82350 | ||
|
|
be6ed22af4 | ||
|
|
149cde118d | ||
|
|
9bc5e666c4 | ||
|
|
2271277b4d | ||
|
|
f865d301a2 | ||
|
|
6f398f0b36 | ||
|
|
8548bcf50a | ||
|
|
e3601bfdc1 | ||
|
|
2b4fdf1aad | ||
|
|
11d15d079f | ||
|
|
9257832acf | ||
|
|
7bde0d59fa | ||
|
|
1c737b0f02 | ||
|
|
5d0a2b9bfe | ||
|
|
720baaed3e | ||
|
|
cee9c764b1 | ||
|
|
7bdeeb85d5 | ||
|
|
19069cb9c4 | ||
|
|
5bb6143373 | ||
|
|
f4d4b73a24 | ||
|
|
d965698905 | ||
|
|
50b2f45590 | ||
|
|
1b88ade021 | ||
|
|
079a254fa4 | ||
|
|
42aa0ff1ef | ||
|
|
4000f094f6 | ||
|
|
151be81cee | ||
|
|
46a8326140 | ||
|
|
4b18723a21 | ||
|
|
4909927c03 | ||
|
|
22c5e85707 | ||
|
|
59b00a6837 | ||
|
|
44af9aea6d | ||
|
|
1779e1e7bd | ||
|
|
2597cdbc70 | ||
|
|
515ad44826 | ||
|
|
2a6848bc1d | ||
|
|
74f6a2dff1 | ||
|
|
58adac17db | ||
|
|
e67c17a0f8 | ||
|
|
94e3f99adb | ||
|
|
e2069bc999 | ||
|
|
2d51c82722 | ||
|
|
29056226bb | ||
|
|
d1d2074abc | ||
|
|
41c9b1547c | ||
|
|
8b0e6dbfd3 | ||
|
|
07a2d13f16 | ||
|
|
46031ed573 | ||
|
|
ecd31efcb0 | ||
|
|
c79c775fb8 | ||
|
|
4bee76253d | ||
|
|
5b1b4e22cb | ||
|
|
439acc8b12 | ||
|
|
95c855a091 | ||
|
|
5ad6581f6d | ||
|
|
2c04d79830 | ||
|
|
304b3b3289 | ||
|
|
96b0a7cfc8 | ||
|
|
290ee91a8b | ||
|
|
8f148d0918 | ||
|
|
e7680d4972 | ||
|
|
90bd4be300 | ||
|
|
6405639d36 | ||
|
|
2d1e989a1c | ||
|
|
7c89198dcf | ||
|
|
8a38e90e24 | ||
|
|
2c8cbbb77f | ||
|
|
b96d8e6c29 | ||
|
|
32dd42cc6b | ||
|
|
b94e9c411d | ||
|
|
bde80fedd6 | ||
|
|
39ddabf3a7 | ||
|
|
47d32dbc7d | ||
|
|
d9b593afa2 | ||
|
|
29356c3df6 | ||
|
|
cc5bc3fff7 | ||
|
|
f02fecf732 | ||
|
|
a12b3b4ffc | ||
|
|
038ae259f0 | ||
|
|
4041aeb01c | ||
|
|
90400e3fcf | ||
|
|
58a216fde3 | ||
|
|
38cc388894 | ||
|
|
418fa879ee | ||
|
|
bcc1c54ccc | ||
|
|
8173a443ff | ||
|
|
2da099797e | ||
|
|
d04a1f7e2a | ||
|
|
40d0a6982e | ||
|
|
ef9eebfd94 | ||
|
|
355392ca14 | ||
|
|
166f6e1b9e | ||
|
|
9b996c5752 | ||
|
|
c7dde92960 | ||
|
|
32ce02b59f | ||
|
|
7566f0ee82 | ||
|
|
ffe1f8a469 | ||
|
|
a5e7c359e3 | ||
|
|
3f4cccdf12 | ||
|
|
866fe88acd | ||
|
|
385cf03227 | ||
|
|
a824078f6d | ||
|
|
3e23796724 | ||
|
|
ae49da6e09 | ||
|
|
bcd91a8e03 | ||
|
|
2d6d08c9fe | ||
|
|
4472c2b890 | ||
|
|
2477063673 | ||
|
|
146b9af17c | ||
|
|
de70525889 | ||
|
|
f81e73f6a4 | ||
|
|
4fc68b5264 | ||
|
|
5b27933c63 | ||
|
|
d1937b3280 | ||
|
|
15755a84d9 | ||
|
|
7d20768d8e | ||
|
|
cd6ca756c1 | ||
|
|
da137cbb97 | ||
|
|
91995854fa | ||
|
|
e312f29138 | ||
|
|
a2eb965759 | ||
|
|
e1a9174de1 | ||
|
|
1e6b5ac7a8 | ||
|
|
f35ac0ddd3 | ||
|
|
b6b45404ee | ||
|
|
ca777dd2fd | ||
|
|
797c75baee | ||
|
|
44071cb0f4 | ||
|
|
b035278ad9 | ||
|
|
04ca38c93b | ||
|
|
09bd10cb56 | ||
|
|
3e3ffb3f51 | ||
|
|
3808faf94d | ||
|
|
eb208b0515 | ||
|
|
60a4167a0e | ||
|
|
c8a674fe93 | ||
|
|
2e79933cae | ||
|
|
db3d38ae3c | ||
|
|
dafad1dd14 | ||
|
|
577de3bad3 | ||
|
|
fb2ad66c91 | ||
|
|
7dbf645457 | ||
|
|
bc53ff52e5 | ||
|
|
9b0c484d06 | ||
|
|
d778cd6ba9 | ||
|
|
3477772e4e | ||
|
|
696d520199 | ||
|
|
c56186111e | ||
|
|
cc075e7770 | ||
|
|
ddc376a026 | ||
|
|
64b25c1610 | ||
|
|
b7e63a4a1f | ||
|
|
9fdb361d67 | ||
|
|
e37d19da51 | ||
|
|
88cb227444 | ||
|
|
2b605bdaa3 | ||
|
|
ec725b3781 | ||
|
|
52570bd6aa | ||
|
|
fb58a6ee1c | ||
|
|
a91bef1cd1 | ||
|
|
915ab12c40 | ||
|
|
2bc5d6f5e4 | ||
|
|
61776cb0d6 | ||
|
|
a21efd7325 | ||
|
|
609341a445 | ||
|
|
3969660906 | ||
|
|
010fb88b56 | ||
|
|
51505e1de6 | ||
|
|
acb7dfc624 | ||
|
|
92c20eef73 | ||
|
|
ad4c0af4fe | ||
|
|
52f9dfb2e4 | ||
|
|
6d736e9158 | ||
|
|
12f8407fd6 | ||
|
|
d4447adf65 | ||
|
|
ae2c216321 | ||
|
|
20bb4cb21e | ||
|
|
14ab8fe97e | ||
|
|
36b9a78d56 | ||
|
|
f449162699 | ||
|
|
de52afbc55 | ||
|
|
d84feb105c | ||
|
|
053480d753 | ||
|
|
f74c353698 | ||
|
|
899d322a8b | ||
|
|
54f7e90a61 | ||
|
|
793d35c5e5 | ||
|
|
c5afcea1fb | ||
|
|
3717ab4fe8 | ||
|
|
713ad8f64a | ||
|
|
2988bf3640 | ||
|
|
3aca3a6f5c | ||
|
|
61cd98cbd6 | ||
|
|
80fe2493e7 | ||
|
|
8f01c614dd | ||
|
|
d65246e43a | ||
|
|
91cb0300d4 | ||
|
|
6cd68605ab | ||
|
|
a3cbcb16df | ||
|
|
47a70b43de | ||
|
|
3060411b7b | ||
|
|
1cba45e7b7 | ||
|
|
3cf222fb36 | ||
|
|
96797ed101 | ||
|
|
f9fb2f8a02 | ||
|
|
e02ba395f9 | ||
|
|
00096752b5 | ||
|
|
618b35b460 | ||
|
|
e4aee822ff | ||
|
|
1f5dcba976 | ||
|
|
19c4175631 | ||
|
|
45c086c1e8 | ||
|
|
d7bb80e04e | ||
|
|
5d082deca3 | ||
|
|
1322638681 | ||
|
|
8c9c5d0d9a | ||
|
|
796112c3d6 | ||
|
|
46674fb952 | ||
|
|
cb8aa6c60e | ||
|
|
f27858f9a7 | ||
|
|
1615f2ab42 | ||
|
|
8138081ca1 | ||
|
|
52f2ebeffd | ||
|
|
c675c18c65 | ||
|
|
b83f50b8f6 | ||
|
|
d9ac4b24c5 | ||
|
|
9bcf54c5c1 | ||
|
|
ff0e71efbd | ||
|
|
16eaa90932 | ||
|
|
81a6d20fe8 | ||
|
|
0b38310ae0 | ||
|
|
38471f6b6a | ||
|
|
3955d6ee62 | ||
|
|
1f5d9ec55c | ||
|
|
1204697873 | ||
|
|
2e1fc2e8f9 | ||
|
|
d775cadc17 | ||
|
|
a169f74d11 | ||
|
|
5e4187a294 | ||
|
|
f35ed67617 | ||
|
|
3b393f0639 | ||
|
|
c7a72b5164 | ||
|
|
2c8c6f6120 | ||
|
|
509451ac2f | ||
|
|
d6b02703df | ||
|
|
27c9a9748e | ||
|
|
be4ab73d61 | ||
|
|
f4f92053f7 | ||
|
|
9508e2334b | ||
|
|
5fe94f74ac | ||
|
|
2539f13c65 | ||
|
|
a31056f9f1 | ||
|
|
f9933ccedc | ||
|
|
3fa732c23e | ||
|
|
23abfdf6f4 | ||
|
|
e35cb6cd16 | ||
|
|
b5a4c3804b | ||
|
|
9f3562eb85 | ||
|
|
d242adde26 | ||
|
|
d7be7520b8 | ||
|
|
e7ab1b6b6d | ||
|
|
33452715ba | ||
|
|
ccd5ab146e | ||
|
|
862cd944b5 | ||
|
|
f8221e95a4 | ||
|
|
b36d74638c | ||
|
|
7788695230 | ||
|
|
163e27ac12 | ||
|
|
a6e2845778 | ||
|
|
09b71c02ce | ||
|
|
882c227ee0 | ||
|
|
a6171ebbcf | ||
|
|
f28d1dea66 | ||
|
|
acca31cb54 | ||
|
|
24971a144a | ||
|
|
a5ac1ed054 | ||
|
|
303d593bb9 | ||
|
|
561466c51a | ||
|
|
24b46f664b | ||
|
|
b262962c08 | ||
|
|
8639f2b20a | ||
|
|
b4d0a53f8f | ||
|
|
36fe8790b0 | ||
|
|
06dd421776 | ||
|
|
89a53eec5e | ||
|
|
5a74215af1 | ||
|
|
6fd90ec235 | ||
|
|
ecee03cb55 | ||
|
|
ec91d69b1d | ||
|
|
69e159f886 | ||
|
|
9cc2b02fb7 | ||
|
|
8354ad5ab5 | ||
|
|
aeb1fb37e7 | ||
|
|
ee29881669 | ||
|
|
51c6ef8163 | ||
|
|
101a04a097 | ||
|
|
814c82d1b8 | ||
|
|
edfdaaeaf5 | ||
|
|
cfbb99faa0 | ||
|
|
36656f4c1d | ||
|
|
a0df1ae0bb | ||
|
|
1fdc0c1b9e | ||
|
|
49f603a3a6 | ||
|
|
fefee6af82 | ||
|
|
38e2bd7e50 | ||
|
|
7fd8616203 | ||
|
|
892a1304e8 | ||
|
|
37360b0ff9 | ||
|
|
6c68f6c9dd | ||
|
|
8657146fb6 | ||
|
|
e71a3c1a9e | ||
|
|
0d3ed6a841 | ||
|
|
e83af388f2 | ||
|
|
ad4e391b9c | ||
|
|
c09a44418c | ||
|
|
f308e7e542 | ||
|
|
8499346d69 | ||
|
|
45bab813ac | ||
|
|
3588585f20 | ||
|
|
fd3cdace91 | ||
|
|
a4bae1f0c7 | ||
|
|
4a785b6e77 | ||
|
|
1180ba9458 | ||
|
|
78f0834124 | ||
|
|
63c89c1712 | ||
|
|
bf86fc2496 | ||
|
|
fa1c5040e9 | ||
|
|
9194d3360c | ||
|
|
132ca01151 | ||
|
|
b859700440 | ||
|
|
6f30dc748e | ||
|
|
5bd63e89c0 | ||
|
|
f472b2f13a | ||
|
|
826c6f6946 | ||
|
|
a497ac4f0d | ||
|
|
eacdfaf579 | ||
|
|
f63af69883 | ||
|
|
1f55966c8a | ||
|
|
85ab5e9d3d | ||
|
|
aba5745709 | ||
|
|
5cfd0a7511 | ||
|
|
f977257e3e | ||
|
|
be01c1d1a9 | ||
|
|
9f87d817ff | ||
|
|
9bb0686865 | ||
|
|
5bd45f0658 | ||
|
|
8d2c70689a | ||
|
|
d9a6bb173f | ||
|
|
9ea236dbb4 | ||
|
|
e3e3965b42 | ||
|
|
5025e4c207 | ||
|
|
4d77a02e9e | ||
|
|
07745799db | ||
|
|
6e3bc75d5f | ||
|
|
64cd2b9dd9 | ||
|
|
01e91defc3 | ||
|
|
dbfe70a0cf | ||
|
|
b55217dd63 | ||
|
|
230929587b | ||
|
|
e7a302f919 | ||
|
|
58a6114511 | ||
|
|
50f64a715b | ||
|
|
472147db25 | ||
|
|
850560cdfb | ||
|
|
e4830f485a | ||
|
|
552558e2fd | ||
|
|
752f4319b6 | ||
|
|
7cfe55a360 | ||
|
|
c5f29c67f6 | ||
|
|
481161e7d9 | ||
|
|
3546a125cb | ||
|
|
cef3d2e981 | ||
|
|
a7276c5181 | ||
|
|
4b9433774b | ||
|
|
a1155114fa | ||
|
|
9798fb70bc | ||
|
|
4ef0a99b0d | ||
|
|
27f8598e92 | ||
|
|
ce78a4a8d3 | ||
|
|
bca394c83b | ||
|
|
3d7afaa0ae | ||
|
|
149c325a58 | ||
|
|
c803baf50b | ||
|
|
9b1887fe3b | ||
|
|
1b5eb2e83b | ||
|
|
4f0ff4ff49 | ||
|
|
997aeb0374 | ||
|
|
5c71725df0 | ||
|
|
03d703c1c8 | ||
|
|
3525dc9026 | ||
|
|
eb15382825 | ||
|
|
9643c09111 | ||
|
|
95f91c9f19 | ||
|
|
3a870d4d8e | ||
|
|
9854870291 | ||
|
|
940bdebaaf | ||
|
|
f843bf1c23 | ||
|
|
bae940b01c | ||
|
|
18632cb25c | ||
|
|
3bdfa58257 | ||
|
|
26368f965f | ||
|
|
c9670c0417 | ||
|
|
9e1aed99f2 | ||
|
|
3b838d0f94 | ||
|
|
1539384603 | ||
|
|
2c833e4dd2 | ||
|
|
151eeef8de | ||
|
|
4a018e2c27 | ||
|
|
734872e4d0 | ||
|
|
ee6fe09dcb | ||
|
|
8b8c81eb74 | ||
|
|
1f3841d5d6 | ||
|
|
9aa15c2e7f | ||
|
|
2ac655b69e | ||
|
|
9c6bccd46e | ||
|
|
f925f52657 | ||
|
|
366ba97e31 | ||
|
|
afddda015a | ||
|
|
727df53fb5 | ||
|
|
297f212c80 | ||
|
|
c61d1df504 | ||
|
|
dc75515a62 | ||
|
|
7dbf458989 | ||
|
|
25b11b3188 | ||
|
|
980c10a411 | ||
|
|
79944037bb | ||
|
|
e1e0aa264b | ||
|
|
31ad862bd0 | ||
|
|
76ed7cf887 | ||
|
|
c64c4851f4 | ||
|
|
0f24b5d24a | ||
|
|
bd311ba085 | ||
|
|
192bf2b0a1 | ||
|
|
2294381369 | ||
|
|
d97d547d5b | ||
|
|
f46a1ba00c | ||
|
|
20e536166e | ||
|
|
1e672a9dd9 | ||
|
|
1e964531a5 | ||
|
|
c0a2ffe8f4 | ||
|
|
3b2b89b98a | ||
|
|
86ec6eac28 | ||
|
|
a8a4f2ca5e | ||
|
|
0d52a42a4d | ||
|
|
485b36cf89 | ||
|
|
38138e2012 | ||
|
|
8f4e281d44 | ||
|
|
255a2127c0 | ||
|
|
e702977911 | ||
|
|
d1561df83c | ||
|
|
3a370ce27d | ||
|
|
f66fdae2c1 | ||
|
|
ad16a77484 | ||
|
|
2869c3ade1 | ||
|
|
c26a529c8a | ||
|
|
951e1b0cc1 | ||
|
|
384a5e35ef | ||
|
|
8f8d0bc69a | ||
|
|
81d19cde05 | ||
|
|
c4dac9380b | ||
|
|
ee5de61967 | ||
|
|
47b9c1894d | ||
|
|
27124baccb | ||
|
|
90068f915f | ||
|
|
39ce685443 | ||
|
|
473a7b8ebd | ||
|
|
56686940b3 | ||
|
|
f08513c109 | ||
|
|
af392c514e | ||
|
|
ba3540c75f | ||
|
|
82c8faa9cf | ||
|
|
1044888d9a | ||
|
|
b7549c1b2c | ||
|
|
82a5a9319d | ||
|
|
c20d0fc6fd | ||
|
|
4eeb441e06 | ||
|
|
1ac17f5ac4 | ||
|
|
168e6cca01 | ||
|
|
025780faea | ||
|
|
7267082991 | ||
|
|
f5cba0c3eb | ||
|
|
176fb9e8c7 | ||
|
|
4958f13f1d | ||
|
|
22fe4db2eb | ||
|
|
999bde30df | ||
|
|
f0d0903106 | ||
|
|
ee14a0841c | ||
|
|
5cb9986a29 | ||
|
|
803ea51dbf | ||
|
|
742c349f86 | ||
|
|
ab362d828d | ||
|
|
1732006039 | ||
|
|
fe65169879 | ||
|
|
4e9b60e5e4 | ||
|
|
af24a9bcfe | ||
|
|
8fc6f394ec | ||
|
|
e2e73edf93 | ||
|
|
55a3b52384 | ||
|
|
a34def2a34 | ||
|
|
69f856056c | ||
|
|
7562e2d3ea | ||
|
|
4fe2d2637c | ||
|
|
e93194ac02 | ||
|
|
3d5696be3e | ||
|
|
038056161e | ||
|
|
0fc9741a5d | ||
|
|
687d4d058c | ||
|
|
d88582c0fc | ||
|
|
c4314d0119 | ||
|
|
2b9f494cf0 | ||
|
|
b8a552796a | ||
|
|
50053497e8 | ||
|
|
47cd94d26d | ||
|
|
a71cebd92b | ||
|
|
44425b4d19 | ||
|
|
d348cb40c3 | ||
|
|
2581af1202 | ||
|
|
df1229e55f | ||
|
|
8c6de1f6c9 | ||
|
|
c1b8a678e8 | ||
|
|
cdcb0f0561 | ||
|
|
72fd6c326b | ||
|
|
c9d1c683a6 | ||
|
|
f22b16d48e | ||
|
|
9f1c79009d | ||
|
|
91d33031fd | ||
|
|
84b64337d8 | ||
|
|
7cefc12472 | ||
|
|
2071aa6041 | ||
|
|
884303e708 | ||
|
|
21b03f45ae | ||
|
|
7bb3a94742 | ||
|
|
0d1f70f833 | ||
|
|
f888098d20 | ||
|
|
9641729980 | ||
|
|
4fdfcfa442 | ||
|
|
b3be656e3a | ||
|
|
5aa1d15899 | ||
|
|
94540e3705 | ||
|
|
e638b1d315 | ||
|
|
fbfea78318 | ||
|
|
c8ed2f7692 | ||
|
|
b55ca719d6 | ||
|
|
5297dd8768 | ||
|
|
89e89cb87c | ||
|
|
304ba9e7d4 | ||
|
|
c1d792ef6c | ||
|
|
44e4519d4c | ||
|
|
875ff6a900 | ||
|
|
a04c830b34 | ||
|
|
c33ae43f43 | ||
|
|
3f6160df24 | ||
|
|
027ba05941 | ||
|
|
637890eded | ||
|
|
b2d29c77bd | ||
|
|
9a3b9539df | ||
|
|
756e8bc267 | ||
|
|
9a0c7b44d5 | ||
|
|
3f9c42029e | ||
|
|
b3e2f679f8 | ||
|
|
d0eab4c1d9 | ||
|
|
6a1f9fb926 | ||
|
|
b1e8ac0475 | ||
|
|
1cdca0bae3 | ||
|
|
f40644b850 | ||
|
|
960d3bf682 | ||
|
|
51ea8cc193 | ||
|
|
a284773715 | ||
|
|
2dc376ce40 | ||
|
|
72c3aac9c6 | ||
|
|
0d1f4168dc | ||
|
|
d3c5dfa588 | ||
|
|
c385925bab | ||
|
|
da4326e968 | ||
|
|
c72d48cbfe | ||
|
|
5795e1edf8 | ||
|
|
e1ee1ded14 | ||
|
|
474476186a | ||
|
|
f4d3950c86 | ||
|
|
7689dc6e3c | ||
|
|
0d11648bd4 | ||
|
|
883415c9d4 | ||
|
|
c7643e920d | ||
|
|
87c0dea49a | ||
|
|
b79b8ea69b | ||
|
|
e8b5b15b0d | ||
|
|
575b8fb24a | ||
|
|
f31a22d64b | ||
|
|
3d6115851a | ||
|
|
bc9b3ea6da | ||
|
|
255d535f34 | ||
|
|
a2e7614e8b | ||
|
|
5fd4464826 | ||
|
|
4a19abe785 | ||
|
|
6fe4b79bd4 | ||
|
|
31a1ea62d1 | ||
|
|
e710c39ce0 | ||
|
|
a61b37148b | ||
|
|
9cf99b92f1 | ||
|
|
0765f9bcae | ||
|
|
65252b00b4 | ||
|
|
add3f78af1 | ||
|
|
f82a190a6a | ||
|
|
05c4c9267f | ||
|
|
7a9b852c10 | ||
|
|
0274d82ada | ||
|
|
779c958d3b | ||
|
|
56a5cf5fa5 | ||
|
|
878939aa5d | ||
|
|
b76912e8e9 | ||
|
|
4b5e8ec9eb | ||
|
|
fffb0d077f | ||
|
|
ae8b1a82e1 | ||
|
|
54a1eec83c | ||
|
|
6f87bef897 | ||
|
|
dfe53bccdd | ||
|
|
540573d9da | ||
|
|
b98b3440de | ||
|
|
0787d7b2c5 | ||
|
|
a23f8d6156 | ||
|
|
e94279da3f | ||
|
|
40a364f0e5 | ||
|
|
cee71da999 | ||
|
|
94a1b9cc66 | ||
|
|
9af3cf9dd7 | ||
|
|
601450bf45 | ||
|
|
b67ccdf1fa | ||
|
|
00002d9752 | ||
|
|
215241f977 | ||
|
|
13b448a38e | ||
|
|
d1dc974b03 | ||
|
|
a92052b1ca | ||
|
|
de79845d35 | ||
|
|
5b7ad42d1d | ||
|
|
e43d5b9dec | ||
|
|
efa7fa6adc | ||
|
|
51ebccc06b | ||
|
|
c199f37ec9 | ||
|
|
85e99caee2 | ||
|
|
e04417f12a | ||
|
|
036b0646b7 | ||
|
|
51e304cc56 | ||
|
|
5954b980d0 | ||
|
|
c06c3203aa | ||
|
|
efcee368ed | ||
|
|
c4fc5a6800 | ||
|
|
2f829634ea | ||
|
|
a9107d415f | ||
|
|
20501e0531 | ||
|
|
f39760b375 | ||
|
|
639f4474e2 | ||
|
|
81596dbbbe | ||
|
|
0af3d161c0 | ||
|
|
7a77ccd381 | ||
|
|
79f44308d7 | ||
|
|
04a161fbd4 | ||
|
|
33c35b4493 | ||
|
|
94e6b33a1c | ||
|
|
d8c8683af8 | ||
|
|
009c94c2b1 | ||
|
|
4b155d3105 | ||
|
|
396cee001e | ||
|
|
2956e51ddb | ||
|
|
a458b962f7 | ||
|
|
a1e4d2bad0 | ||
|
|
88d760984a | ||
|
|
10eea222cf | ||
|
|
9638cca642 | ||
|
|
031885590e | ||
|
|
6174bf82b6 | ||
|
|
c2d6b60d7c | ||
|
|
c90f891b0b | ||
|
|
24a81ac5ed | ||
|
|
36bb0247fa | ||
|
|
018b48ff04 | ||
|
|
e21a05ac9e | ||
|
|
2b3cb86a93 | ||
|
|
007aa91aa4 | ||
|
|
1916501a96 | ||
|
|
a12366ff99 | ||
|
|
d23f20954d | ||
|
|
0da0cb4583 | ||
|
|
7dca217cf6 | ||
|
|
b879153978 | ||
|
|
d7707985f7 | ||
|
|
7e091188f6 | ||
|
|
384ea76dc7 | ||
|
|
3d0b714f15 | ||
|
|
0f942f619f | ||
|
|
bb8e85116f | ||
|
|
25259dc307 | ||
|
|
09de761eca | ||
|
|
7e8ce4dd96 | ||
|
|
4f0fa2d200 | ||
|
|
beae55c98e | ||
|
|
b3fe55c165 | ||
|
|
c9c2c2bc63 | ||
|
|
57bf7bc808 | ||
|
|
1d93ff9e49 | ||
|
|
787eda13e9 | ||
|
|
d65a06b173 | ||
|
|
61958cf412 | ||
|
|
ab58e17366 | ||
|
|
4032751cc7 | ||
|
|
dea459b9c9 | ||
|
|
b8f137ba32 | ||
|
|
b4a6de2a50 | ||
|
|
85c2e72a4c | ||
|
|
33a73a325b | ||
|
|
f843f62bab | ||
|
|
b3ae2223a5 | ||
|
|
830f372575 | ||
|
|
82058568e2 | ||
|
|
9bda00613d | ||
|
|
3bf5142861 | ||
|
|
de6b2bb66d | ||
|
|
0ae656d8e4 | ||
|
|
3cdbda157b | ||
|
|
a0b0f89ead | ||
|
|
a39484a92c | ||
|
|
f00275a880 | ||
|
|
684c977365 | ||
|
|
8f7ae168ab | ||
|
|
3aba00b4d8 | ||
|
|
4712232d0a | ||
|
|
95bf9a08e7 | ||
|
|
15323e74d6 | ||
|
|
3902192a41 | ||
|
|
0b984ffac6 | ||
|
|
ecee96e3e3 |
34
.config/README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Worktrunk Setup
|
||||
|
||||
This repo uses [Worktrunk](https://github.com/max-sixty/worktrunk) for running multiple Claude Code agents in parallel on different branches.
|
||||
|
||||
## Install Worktrunk
|
||||
|
||||
```bash
|
||||
brew install max-sixty/worktrunk/wt
|
||||
wt config shell install
|
||||
# restart terminal
|
||||
```
|
||||
|
||||
## Quick Commands
|
||||
|
||||
| Task | Command |
|
||||
|------|---------|
|
||||
| Create worktree + start Claude | `wt switch -c -x claude feat-name` |
|
||||
| Switch to existing worktree | `wt switch feat-name` |
|
||||
| List all worktrees | `wt list` |
|
||||
| Create PR | `gh pr create` |
|
||||
| Remove worktree | `wt remove feat-name` |
|
||||
|
||||
## What happens on `wt switch -c`
|
||||
|
||||
1. Creates new worktree at `../browseros-main.feat-name/`
|
||||
2. Runs `bun install` in `packages/browseros-agent/`
|
||||
3. Copies `.env.*` files from main worktree's `packages/browseros-agent/apps/`
|
||||
|
||||
## Hooks
|
||||
|
||||
Hooks are configured in `.config/wt.toml`:
|
||||
|
||||
- **post-create**: Runs `bun install` in the agent package, copies env files and `.llm/` from the main worktree
|
||||
- **pre-remove**: Syncs `.llm/` back to the main worktree before deletion
|
||||
@@ -1,4 +1,6 @@
|
||||
[post-create]
|
||||
install = "cd packages/browseros-agent && bun install"
|
||||
env = "for f in {{ repo_root }}/packages/browseros-agent/apps/*/.env.*; do [ -f \"$f\" ] && cp \"$f\" \"${f#{{ repo_root }}/}\"; done 2>/dev/null || true"
|
||||
llm = "cp -r {{ repo_root }}/.llm . 2>/dev/null || true"
|
||||
|
||||
[pre-remove]
|
||||
|
||||
4
.gitattributes
vendored
@@ -3,12 +3,12 @@ resources/nxtscape-productivity.gif filter=lfs diff=lfs merge=lfs -text
|
||||
resources/media/nxtscape-agent.gif filter=lfs diff=lfs merge=lfs -text
|
||||
resources/media/nxtscape-chat.gif filter=lfs diff=lfs merge=lfs -text
|
||||
docs/videos/browserOS-agent-in-action.gif filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
# Mark Python build/tooling files as generated so they don't count in language stats
|
||||
packages/browseros/build/**/*.py linguist-generated
|
||||
packages/browseros/chromium_patches/**/*.py linguist-generated
|
||||
scripts/*.py linguist-generated
|
||||
# Mark build directories as generated
|
||||
build/* linguist-generated
|
||||
docs/images/** filter=lfs diff=lfs merge=lfs -text
|
||||
# Mark eval/test framework as vendored so it's excluded from language stats
|
||||
packages/browseros-agent/apps/eval/** linguist-vendored
|
||||
docs/videos/** filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
192
.github/workflows/audit.yml
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
name: Daily Security Audit
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Runs at midnight IST (6:30 PM UTC previous day)
|
||||
- cron: "30 18 * * *"
|
||||
workflow_dispatch: # Allows manual triggering
|
||||
|
||||
jobs:
|
||||
security-audit:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: packages/browseros-agent
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun ci
|
||||
|
||||
- name: Run security audit
|
||||
id: audit
|
||||
continue-on-error: true
|
||||
run: |
|
||||
# Run audit and capture output (skip the version line)
|
||||
bun audit --json 2>&1 | tail -n 1 > audit-results.json || true
|
||||
|
||||
# Check if vulnerabilities exist
|
||||
VULN_COUNT=$(cat audit-results.json | bun -e "const data = JSON.parse(require('fs').readFileSync(0, 'utf-8')); console.log(Object.keys(data).reduce((sum, pkg) => sum + data[pkg].length, 0))")
|
||||
echo "vuln_count=$VULN_COUNT" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Parse audit results
|
||||
id: parse
|
||||
if: always()
|
||||
run: |
|
||||
cat > parse-audit.ts << 'EOF'
|
||||
const fs = require('fs');
|
||||
const auditData = JSON.parse(fs.readFileSync('audit-results.json', 'utf-8'));
|
||||
|
||||
// Collect all vulnerabilities from all packages
|
||||
const allVulns: any[] = [];
|
||||
let totalCount = 0;
|
||||
|
||||
for (const [packageName, vulns] of Object.entries(auditData)) {
|
||||
if (Array.isArray(vulns)) {
|
||||
vulns.forEach((vuln: any) => {
|
||||
allVulns.push({ ...vuln, packageName });
|
||||
totalCount++;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (totalCount === 0) {
|
||||
console.log(JSON.stringify({
|
||||
text: "✅ *Daily Security Audit - No Vulnerabilities Found*",
|
||||
blocks: [
|
||||
{
|
||||
type: "section",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: "✅ *Daily Security Audit*\n\nNo vulnerabilities found in dependencies!"
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "context",
|
||||
elements: [
|
||||
{
|
||||
type: "mrkdwn",
|
||||
text: `Repository: ${process.env.GITHUB_REPOSITORY} | Branch: ${process.env.GITHUB_REF_NAME}`
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}));
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Count by severity
|
||||
const severityCounts = {
|
||||
critical: 0,
|
||||
high: 0,
|
||||
moderate: 0,
|
||||
low: 0
|
||||
};
|
||||
|
||||
allVulns.forEach(vuln => {
|
||||
severityCounts[vuln.severity as keyof typeof severityCounts]++;
|
||||
});
|
||||
|
||||
let message = `⚠️ *Daily Security Audit - ${totalCount} Vulnerabilit${totalCount === 1 ? 'y' : 'ies'} Found*\n\n`;
|
||||
message += `*Severity Breakdown:*\n`;
|
||||
message += `• Critical: ${severityCounts.critical}\n`;
|
||||
message += `• High: ${severityCounts.high}\n`;
|
||||
message += `• Moderate: ${severityCounts.moderate}\n`;
|
||||
message += `• Low: ${severityCounts.low}\n\n`;
|
||||
|
||||
message += `*Top Vulnerabilities:*\n`;
|
||||
|
||||
// Sort by severity
|
||||
const severityOrder = { critical: 0, high: 1, moderate: 2, low: 3 };
|
||||
allVulns.sort((a, b) =>
|
||||
severityOrder[a.severity as keyof typeof severityOrder] -
|
||||
severityOrder[b.severity as keyof typeof severityOrder]
|
||||
);
|
||||
|
||||
allVulns.slice(0, 5).forEach(vuln => {
|
||||
const emoji = {
|
||||
critical: '🔴',
|
||||
high: '🟠',
|
||||
moderate: '🟡',
|
||||
low: '🟢'
|
||||
}[vuln.severity] || '⚪';
|
||||
|
||||
message += `\n${emoji} *${vuln.title}*\n`;
|
||||
message += ` Package: \`${vuln.packageName}\`\n`;
|
||||
message += ` Severity: ${vuln.severity.toUpperCase()}\n`;
|
||||
message += ` Vulnerable: ${vuln.vulnerable_versions}\n`;
|
||||
if (vuln.cwe?.length) {
|
||||
message += ` CWE: ${vuln.cwe.join(', ')}\n`;
|
||||
}
|
||||
if (vuln.cvss?.score) {
|
||||
message += ` CVSS: ${vuln.cvss.score}\n`;
|
||||
}
|
||||
if (vuln.url) {
|
||||
message += ` <${vuln.url}|View Details>\n`;
|
||||
}
|
||||
});
|
||||
|
||||
if (allVulns.length > 5) {
|
||||
message += `\n_...and ${allVulns.length - 5} more vulnerabilit${allVulns.length - 5 === 1 ? 'y' : 'ies'}_`;
|
||||
}
|
||||
|
||||
const payload = {
|
||||
text: `⚠️ Security Audit: ${totalCount} vulnerabilit${totalCount === 1 ? 'y' : 'ies'} found`,
|
||||
blocks: [
|
||||
{
|
||||
type: "section",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: message
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "actions",
|
||||
elements: [
|
||||
{
|
||||
type: "button",
|
||||
text: {
|
||||
type: "plain_text",
|
||||
text: "View Full Report"
|
||||
},
|
||||
url: `https://github.com/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: "context",
|
||||
elements: [
|
||||
{
|
||||
type: "mrkdwn",
|
||||
text: `Repository: ${process.env.GITHUB_REPOSITORY} | Branch: ${process.env.GITHUB_REF_NAME}`
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
console.log(JSON.stringify(payload));
|
||||
EOF
|
||||
|
||||
bun run parse-audit.ts > slack-payload.json
|
||||
|
||||
- name: Send to Slack
|
||||
if: always()
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d @slack-payload.json \
|
||||
$SLACK_WEBHOOK_URL
|
||||
|
||||
- name: Fail if vulnerabilities found
|
||||
if: steps.audit.outputs.vuln_count != '0'
|
||||
run: |
|
||||
echo "Security audit found vulnerabilities"
|
||||
exit 1
|
||||
17
.github/workflows/branch-cleaner.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
name: GitHub Branch Cleaner
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * 0'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
cleanup:
|
||||
name: Clean up merged branches
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: mmorenoregalado/action-branches-cleaner@v2.0.3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
base_branches: main
|
||||
days_old_threshold: 30
|
||||
65
.github/workflows/cla.yml
vendored
@@ -1,11 +1,11 @@
|
||||
name: 'CLA Assistant'
|
||||
name: CLA Assistant
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
pull_request_target:
|
||||
types: [opened, closed, synchronize]
|
||||
|
||||
# Explicitly configure permissions
|
||||
permissions:
|
||||
actions: write
|
||||
contents: write
|
||||
@@ -13,47 +13,46 @@ permissions:
|
||||
statuses: write
|
||||
|
||||
jobs:
|
||||
CLAAssistant:
|
||||
cla:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
(github.event_name == 'pull_request_target') ||
|
||||
(github.event_name == 'issue_comment' && github.event.issue.pull_request &&
|
||||
(github.event.comment.body == 'recheck' ||
|
||||
github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA'))
|
||||
steps:
|
||||
- name: 'CLA Assistant'
|
||||
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
|
||||
- name: CLA Assistant
|
||||
uses: contributor-assistant/github-action@v2.6.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PERSONAL_ACCESS_TOKEN: ${{ secrets.CLA_SIGNATURES_TOKEN }}
|
||||
with:
|
||||
# Path where signatures will be stored
|
||||
path-to-signatures: 'signatures/version1/cla.json'
|
||||
|
||||
# Path to your CLA document
|
||||
path-to-document: 'https://github.com/browseros-ai/BrowserOS/blob/main/CLA.md'
|
||||
|
||||
# Branch to store signatures (should not be protected)
|
||||
path-to-signatures: 'cla-signatures.json'
|
||||
path-to-document: 'https://github.com/${{ github.repository }}/blob/main/CLA.md'
|
||||
branch: 'main'
|
||||
|
||||
# Allowlist for users who don't need to sign (bots, core team members)
|
||||
allowlist: shadowfax92,felarof99,dependabot[bot],renovate[bot],github-actions[bot]
|
||||
|
||||
# Optional: Custom messages
|
||||
remote-organization-name: 'browseros-ai'
|
||||
remote-repository-name: 'cla-signatures'
|
||||
allowlist: 'shadowfax92,felarof99,bot*,*[bot],dependabot,renovate,github-actions,snyk-bot,imgbot,greenkeeper,semantic-release-bot,allcontributors'
|
||||
lock-pullrequest-aftermerge: false
|
||||
custom-notsigned-prcomment: |
|
||||
**CLA Assistant Lite bot** Thank you for your submission! We require contributors to sign our [Contributor License Agreement](https://github.com/browseros-ai/BrowserOS/blob/main/CLA.md) before we can accept your contribution.
|
||||
Thank you for your contribution! Before we can merge this PR, we need you to sign our [Contributor License Agreement](https://github.com/${{ github.repository }}/blob/main/CLA.md).
|
||||
|
||||
By signing the CLA, you confirm that:
|
||||
- You have read and agree to the AGPL-3.0 license terms
|
||||
- Your contribution is your original work
|
||||
- You grant us the rights to use your contribution under the AGPL-3.0 license
|
||||
**To sign the CLA**, please add a comment to this PR with the following text:
|
||||
|
||||
**To sign the CLA, please comment on this PR with:**
|
||||
`I have read the CLA Document and I hereby sign the CLA`
|
||||
```
|
||||
I have read the CLA Document and I hereby sign the CLA
|
||||
```
|
||||
|
||||
You only need to sign once. After signing, this check will pass automatically.
|
||||
|
||||
---
|
||||
<details>
|
||||
<summary>Troubleshooting</summary>
|
||||
|
||||
- **Already signed but still failing?** Comment `recheck` to trigger a re-verification.
|
||||
- **Signed with a different email?** Make sure your commit email matches your GitHub account email, or add your commit email to your GitHub account.
|
||||
|
||||
</details>
|
||||
custom-pr-sign-comment: 'I have read the CLA Document and I hereby sign the CLA'
|
||||
|
||||
custom-allsigned-prcomment: |
|
||||
**CLA Assistant Lite bot** ✅ All contributors have signed the CLA. Thank you for helping make BrowserOS better!
|
||||
|
||||
# Lock PR after merge to prevent signature tampering
|
||||
lock-pullrequest-aftermerge: true
|
||||
|
||||
# Custom commit messages
|
||||
create-file-commit-message: 'docs: Create CLA signatures file'
|
||||
signed-commit-message: 'docs: $contributorName signed the CLA in $owner/$repo#$pullRequestNo'
|
||||
All contributors have signed the CLA. Thank you!
|
||||
|
||||
42
.github/workflows/claude.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
name: Claude Code
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, ready_for_review]
|
||||
issue_comment:
|
||||
types: [created]
|
||||
pull_request_review_comment:
|
||||
types: [created]
|
||||
issues:
|
||||
types: [opened, assigned]
|
||||
pull_request_review:
|
||||
types: [submitted]
|
||||
|
||||
jobs:
|
||||
claude:
|
||||
if: |
|
||||
github.event_name == 'pull_request' ||
|
||||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) ||
|
||||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) ||
|
||||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.review.author_association)) ||
|
||||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
issues: read
|
||||
id-token: write
|
||||
actions: read
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Run Claude Code
|
||||
id: claude
|
||||
uses: anthropics/claude-code-action@v1
|
||||
with:
|
||||
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||
additional_permissions: |
|
||||
actions: read
|
||||
60
.github/workflows/code-quality.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
name: Code Quality
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "packages/browseros-agent/**"
|
||||
|
||||
jobs:
|
||||
biome:
|
||||
name: runner / Biome
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: packages/browseros-agent
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Biome
|
||||
uses: biomejs/setup-biome@v2
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Run Biome
|
||||
run: biome ci .
|
||||
|
||||
typecheck:
|
||||
name: runner / Typecheck
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: packages/browseros-agent
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun ci
|
||||
|
||||
- name: Prepare wxt
|
||||
run: VITE_PUBLIC_BROWSEROS_API=http://localhost:3000 bun run --cwd apps/agent wxt prepare
|
||||
|
||||
- name: Run codegen
|
||||
run: bun run --cwd apps/agent codegen
|
||||
|
||||
- name: Run Typecheck
|
||||
run: bun run typecheck
|
||||
98
.github/workflows/eval-weekly.yml
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
name: Weekly Eval
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Every Saturday at 06:00 UTC
|
||||
- cron: '0 6 * * 6'
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'packages/browseros-agent/apps/server/src/agent/**'
|
||||
- 'packages/browseros-agent/apps/server/src/tools/**'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
config:
|
||||
description: 'Eval config file (relative to apps/eval/)'
|
||||
required: false
|
||||
default: 'configs/browseros-agent-weekly.json'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
eval:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 360
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install BrowserOS
|
||||
run: |
|
||||
wget -q https://github.com/browseros-ai/BrowserOS/releases/download/v0.44.0.1/BrowserOS_v0.44.0.1_amd64.deb
|
||||
sudo dpkg -i BrowserOS_v0.44.0.1_amd64.deb
|
||||
browseros --version || echo "BrowserOS installed at $(which browseros)"
|
||||
|
||||
- name: Install Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: packages/browseros-agent
|
||||
run: bun install --ignore-scripts && bun run build:agent-sdk
|
||||
|
||||
- name: Install xvfb
|
||||
run: sudo apt-get update && sudo apt-get install -y xvfb
|
||||
|
||||
- name: Install captcha solver extension
|
||||
working-directory: packages/browseros-agent/apps/eval
|
||||
run: |
|
||||
mkdir -p extensions
|
||||
curl -sL -o /tmp/nopecha.zip https://github.com/NopeCHALLC/nopecha-extension/releases/latest/download/chromium_automation.zip
|
||||
unzip -qo /tmp/nopecha.zip -d extensions/nopecha
|
||||
|
||||
- name: Run eval
|
||||
working-directory: packages/browseros-agent/apps/eval
|
||||
env:
|
||||
FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_API_KEY }}
|
||||
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||
NOPECHA_API_KEY: ${{ secrets.NOPECHA_API_KEY }}
|
||||
BROWSEROS_BINARY: /usr/bin/browseros
|
||||
EVAL_CONFIG: ${{ github.event.inputs.config || 'configs/browseros-agent-weekly.json' }}
|
||||
run: |
|
||||
echo "Running eval with config: $EVAL_CONFIG"
|
||||
xvfb-run --auto-servernum --server-args="-screen 0 1440x900x24" bun run src/index.ts -c "$EVAL_CONFIG"
|
||||
|
||||
- name: Upload runs to R2
|
||||
if: success()
|
||||
working-directory: packages/browseros-agent/apps/eval
|
||||
env:
|
||||
EVAL_R2_ACCOUNT_ID: ${{ secrets.EVAL_R2_ACCOUNT_ID }}
|
||||
EVAL_R2_ACCESS_KEY_ID: ${{ secrets.EVAL_R2_ACCESS_KEY_ID }}
|
||||
EVAL_R2_SECRET_ACCESS_KEY: ${{ secrets.EVAL_R2_SECRET_ACCESS_KEY }}
|
||||
EVAL_R2_BUCKET: ${{ secrets.EVAL_R2_BUCKET }}
|
||||
EVAL_R2_CDN_BASE_URL: ${{ secrets.EVAL_R2_CDN_BASE_URL }}
|
||||
EVAL_CONFIG: ${{ github.event.inputs.config || 'configs/browseros-agent-weekly.json' }}
|
||||
run: |
|
||||
CONFIG_NAME=$(basename "$EVAL_CONFIG" .json)
|
||||
bun scripts/upload-run.ts "results/$CONFIG_NAME"
|
||||
|
||||
- name: Generate trend report
|
||||
if: success()
|
||||
working-directory: packages/browseros-agent
|
||||
env:
|
||||
EVAL_R2_ACCOUNT_ID: ${{ secrets.EVAL_R2_ACCOUNT_ID }}
|
||||
EVAL_R2_ACCESS_KEY_ID: ${{ secrets.EVAL_R2_ACCESS_KEY_ID }}
|
||||
EVAL_R2_SECRET_ACCESS_KEY: ${{ secrets.EVAL_R2_SECRET_ACCESS_KEY }}
|
||||
EVAL_R2_BUCKET: ${{ secrets.EVAL_R2_BUCKET }}
|
||||
EVAL_R2_CDN_BASE_URL: ${{ secrets.EVAL_R2_CDN_BASE_URL }}
|
||||
run: bun apps/eval/scripts/weekly-report.ts /tmp/eval-report.html
|
||||
|
||||
- name: Upload report as artifact
|
||||
if: success()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: eval-report-${{ github.run_id }}
|
||||
path: /tmp/eval-report.html
|
||||
20
.github/workflows/pr-title.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: PR Conventional Commit Validation
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited]
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
issues: write
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
validate-pr-title:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: PR Conventional Commit Validation
|
||||
uses: ytanikin/pr-conventional-commits@1.5.1
|
||||
with:
|
||||
task_types: '["feat","fix","docs","test","ci","refactor","perf","chore","revert","build"]'
|
||||
custom_labels: '{"feat": "feature", "fix": "fix", "docs": "documentation", "test": "test", "ci": "CI/CD", "refactor": "refactor", "perf": "performance", "chore": "chore", "revert": "revert", "wip": "WIP"}'
|
||||
148
.github/workflows/release-agent-extension.yml
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
name: Release BrowserOS Extension
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: release-agent-extension
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
release:
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
defaults:
|
||||
run:
|
||||
working-directory: packages/browseros-agent/apps/agent
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun ci
|
||||
working-directory: packages/browseros-agent
|
||||
|
||||
- name: Build and zip extension
|
||||
run: bun run codegen && bun run zip
|
||||
env:
|
||||
VITE_PUBLIC_BROWSEROS_API: https://api.browseros.com
|
||||
|
||||
- name: Get version and zip path
|
||||
id: version
|
||||
run: |
|
||||
echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
|
||||
echo "release_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||
ZIP_FILE=$(ls "$(pwd)/dist/"*-chrome.zip | head -n 1)
|
||||
echo "zip_path=$ZIP_FILE" >> "$GITHUB_OUTPUT"
|
||||
echo "zip_name=$(basename "$ZIP_FILE")" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Generate release notes
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
AGENT_PATH="packages/browseros-agent/apps/agent"
|
||||
CURRENT_TAG="agent-extension-v${{ steps.version.outputs.version }}"
|
||||
PREV_TAG=$(git tag -l "agent-extension-v*" --sort=-v:refname | grep -v "^${CURRENT_TAG}$" | head -n 1)
|
||||
|
||||
if [ -z "$PREV_TAG" ]; then
|
||||
echo "Initial release" > /tmp/release-notes.md
|
||||
else
|
||||
COMMITS=$(git log "$PREV_TAG"..HEAD --pretty=format:"%H" -- "$AGENT_PATH")
|
||||
|
||||
if [ -z "$COMMITS" ]; then
|
||||
echo "No notable changes." > /tmp/release-notes.md
|
||||
else
|
||||
echo "## What's Changed" > /tmp/release-notes.md
|
||||
echo "" >> /tmp/release-notes.md
|
||||
|
||||
while IFS= read -r SHA; do
|
||||
SUBJECT=$(git log -1 --pretty=format:"%s" "$SHA")
|
||||
PR_NUM=$(gh api "/repos/${{ github.repository }}/commits/${SHA}/pulls" --jq '.[0].number // empty' 2>/dev/null)
|
||||
|
||||
# Skip PR number if already in the commit subject (squash merges include it)
|
||||
if [ -n "$PR_NUM" ] && ! echo "$SUBJECT" | grep -qF "(#${PR_NUM})"; then
|
||||
echo "- ${SUBJECT} (#${PR_NUM})" >> /tmp/release-notes.md
|
||||
else
|
||||
echo "- ${SUBJECT}" >> /tmp/release-notes.md
|
||||
fi
|
||||
done <<< "$COMMITS"
|
||||
fi
|
||||
fi
|
||||
working-directory: ${{ github.workspace }}
|
||||
|
||||
- name: Create GitHub release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
TAG="agent-extension-v${{ steps.version.outputs.version }}"
|
||||
RELEASE_SHA="${{ steps.version.outputs.release_sha }}"
|
||||
TITLE="BrowserOS Extension - v${{ steps.version.outputs.version }}"
|
||||
|
||||
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
||||
echo "Tag $TAG already exists, skipping tag creation"
|
||||
else
|
||||
git tag "$TAG" "$RELEASE_SHA"
|
||||
fi
|
||||
|
||||
if git ls-remote --tags origin "$TAG" | grep -q "$TAG"; then
|
||||
echo "Tag $TAG already on remote, skipping push"
|
||||
else
|
||||
git push origin "$TAG"
|
||||
fi
|
||||
|
||||
if gh release view "$TAG" >/dev/null 2>&1; then
|
||||
echo "Release $TAG already exists, updating"
|
||||
gh release edit "$TAG" --title "$TITLE" --notes-file /tmp/release-notes.md
|
||||
gh release upload "$TAG" "${{ steps.version.outputs.zip_path }}" --clobber
|
||||
else
|
||||
gh release create "$TAG" \
|
||||
--title "$TITLE" \
|
||||
--notes-file /tmp/release-notes.md \
|
||||
"${{ steps.version.outputs.zip_path }}"
|
||||
fi
|
||||
working-directory: ${{ github.workspace }}
|
||||
|
||||
- name: Update CHANGELOG.md via PR
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
VERSION="${{ steps.version.outputs.version }}"
|
||||
DATE=$(date -u +"%Y-%m-%d")
|
||||
BRANCH="docs/agent-extension-changelog-v${VERSION}"
|
||||
CHANGELOG="packages/browseros-agent/apps/agent/CHANGELOG.md"
|
||||
|
||||
git checkout main
|
||||
|
||||
{
|
||||
head -n 1 "$CHANGELOG"
|
||||
echo ""
|
||||
echo "## v${VERSION} (${DATE})"
|
||||
echo ""
|
||||
cat /tmp/release-notes.md
|
||||
echo ""
|
||||
tail -n +2 "$CHANGELOG"
|
||||
} > /tmp/new-changelog.md
|
||||
mv /tmp/new-changelog.md "$CHANGELOG"
|
||||
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git checkout -b "$BRANCH"
|
||||
git add "$CHANGELOG"
|
||||
git commit -m "docs: update agent extension changelog for v${VERSION}"
|
||||
git push origin "$BRANCH"
|
||||
|
||||
gh pr create \
|
||||
--title "docs: update agent extension changelog for v${VERSION}" \
|
||||
--body "Auto-generated changelog update for BrowserOS Extension v${VERSION}." \
|
||||
--base main \
|
||||
--head "$BRANCH"
|
||||
|
||||
gh pr merge "$BRANCH" --squash --auto || true
|
||||
working-directory: ${{ github.workspace }}
|
||||
168
.github/workflows/release-agent-sdk.yml
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
name: Release BrowserOS Agent SDK
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: release-agent-sdk
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
defaults:
|
||||
run:
|
||||
working-directory: packages/browseros-agent/packages/agent-sdk
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "20"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun ci
|
||||
working-directory: packages/browseros-agent
|
||||
|
||||
- name: Build
|
||||
run: bun run build
|
||||
|
||||
- name: Test
|
||||
run: bun test
|
||||
|
||||
- name: Get version
|
||||
id: version
|
||||
run: |
|
||||
echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
|
||||
echo "release_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Generate release notes
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
SDK_PATH="packages/browseros-agent/packages/agent-sdk"
|
||||
CURRENT_TAG="agent-sdk-v${{ steps.version.outputs.version }}"
|
||||
# Find the previous tag, excluding the current version's tag
|
||||
# (which may already exist from a prior failed run)
|
||||
PREV_TAG=$(git tag -l "agent-sdk-v*" --sort=-v:refname | grep -v "^${CURRENT_TAG}$" | head -n 1)
|
||||
|
||||
if [ -z "$PREV_TAG" ]; then
|
||||
echo "Initial release" > /tmp/release-notes.md
|
||||
else
|
||||
# Get commits scoped to the SDK directory
|
||||
COMMITS=$(git log "$PREV_TAG"..HEAD --pretty=format:"%H" -- "$SDK_PATH")
|
||||
|
||||
if [ -z "$COMMITS" ]; then
|
||||
echo "No notable changes." > /tmp/release-notes.md
|
||||
else
|
||||
echo "## What's Changed" > /tmp/release-notes.md
|
||||
echo "" >> /tmp/release-notes.md
|
||||
|
||||
# For each commit, find the associated PR and format with author
|
||||
CONTRIBUTORS=""
|
||||
while IFS= read -r SHA; do
|
||||
# Get commit subject and author
|
||||
SUBJECT=$(git log -1 --pretty=format:"%s" "$SHA")
|
||||
AUTHOR=$(git log -1 --pretty=format:"%an" "$SHA")
|
||||
GITHUB_USER=$(gh api "/repos/${{ github.repository }}/commits/${SHA}" --jq '.author.login // empty' 2>/dev/null)
|
||||
|
||||
# Find associated PR number
|
||||
PR_NUM=$(gh api "/repos/${{ github.repository }}/commits/${SHA}/pulls" --jq '.[0].number // empty' 2>/dev/null)
|
||||
|
||||
# Format line: skip PR number if already in the commit subject
|
||||
# (squash merges include "(#123)" in the subject automatically)
|
||||
if [ -n "$PR_NUM" ] && ! echo "$SUBJECT" | grep -qF "(#${PR_NUM})"; then
|
||||
echo "- ${SUBJECT} (#${PR_NUM})" >> /tmp/release-notes.md
|
||||
else
|
||||
echo "- ${SUBJECT}" >> /tmp/release-notes.md
|
||||
fi
|
||||
done <<< "$COMMITS"
|
||||
fi
|
||||
fi
|
||||
working-directory: ${{ github.workspace }}
|
||||
|
||||
- name: Publish
|
||||
run: npm publish --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Create GitHub release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
TAG="agent-sdk-v${{ steps.version.outputs.version }}"
|
||||
RELEASE_SHA="${{ steps.version.outputs.release_sha }}"
|
||||
TITLE="BrowserOS Agent SDK - v${{ steps.version.outputs.version }}"
|
||||
|
||||
# Create or reuse tag (idempotent for re-runs)
|
||||
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
||||
echo "Tag $TAG already exists, skipping tag creation"
|
||||
else
|
||||
git tag "$TAG" "$RELEASE_SHA"
|
||||
fi
|
||||
|
||||
# Push tag (skip if already on remote)
|
||||
if git ls-remote --tags origin "$TAG" | grep -q "$TAG"; then
|
||||
echo "Tag $TAG already on remote, skipping push"
|
||||
else
|
||||
git push origin "$TAG"
|
||||
fi
|
||||
|
||||
# Create or update release
|
||||
if gh release view "$TAG" >/dev/null 2>&1; then
|
||||
echo "Release $TAG already exists, updating"
|
||||
gh release edit "$TAG" --title "$TITLE" --notes-file /tmp/release-notes.md
|
||||
else
|
||||
gh release create "$TAG" --title "$TITLE" --notes-file /tmp/release-notes.md
|
||||
fi
|
||||
working-directory: ${{ github.workspace }}
|
||||
|
||||
- name: Update CHANGELOG.md via PR
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
VERSION="${{ steps.version.outputs.version }}"
|
||||
DATE=$(date -u +"%Y-%m-%d")
|
||||
BRANCH="docs/agent-sdk-changelog-v${VERSION}"
|
||||
CHANGELOG="packages/browseros-agent/packages/agent-sdk/CHANGELOG.md"
|
||||
|
||||
# Return to main before branching
|
||||
git checkout main
|
||||
|
||||
# Use head/tail to safely insert without sed quoting issues
|
||||
{
|
||||
head -n 1 "$CHANGELOG"
|
||||
echo ""
|
||||
echo "## v${VERSION} (${DATE})"
|
||||
echo ""
|
||||
cat /tmp/release-notes.md
|
||||
echo ""
|
||||
tail -n +2 "$CHANGELOG"
|
||||
} > /tmp/new-changelog.md
|
||||
mv /tmp/new-changelog.md "$CHANGELOG"
|
||||
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git checkout -b "$BRANCH"
|
||||
git add "$CHANGELOG"
|
||||
git commit -m "docs: update agent-sdk changelog for v${VERSION}"
|
||||
git push origin "$BRANCH"
|
||||
|
||||
gh pr create \
|
||||
--title "docs: update agent-sdk changelog for v${VERSION}" \
|
||||
--body "Auto-generated changelog update for BrowserOS Agent SDK v${VERSION}." \
|
||||
--base main \
|
||||
--head "$BRANCH"
|
||||
|
||||
gh pr merge "$BRANCH" --squash --auto || true
|
||||
working-directory: ${{ github.workspace }}
|
||||
161
.github/workflows/release-cli.yml
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
name: Release BrowserOS CLI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "Release version (e.g. 0.1.0)"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
concurrency:
|
||||
group: release-cli
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
release:
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
environment: release-core
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
defaults:
|
||||
run:
|
||||
working-directory: packages/browseros-agent/apps/cli
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: packages/browseros-agent/apps/cli/go.mod
|
||||
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: "1.3.6"
|
||||
|
||||
- name: Run tests
|
||||
run: make test
|
||||
|
||||
- name: Run vet
|
||||
run: make vet
|
||||
|
||||
- name: Build all platforms
|
||||
run: make release VERSION=${{ inputs.version }} POSTHOG_API_KEY=${{ secrets.POSTHOG_API_KEY }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun install
|
||||
working-directory: packages/browseros-agent
|
||||
|
||||
- name: Upload to CDN
|
||||
env:
|
||||
R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }}
|
||||
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
R2_BUCKET: ${{ secrets.R2_BUCKET }}
|
||||
R2_UPLOAD_PREFIX: cli
|
||||
CLI_VERSION: ${{ inputs.version }}
|
||||
run: |
|
||||
bun scripts/build/cli.ts \
|
||||
--release \
|
||||
--version "$CLI_VERSION" \
|
||||
--binaries-dir apps/cli/dist
|
||||
working-directory: packages/browseros-agent
|
||||
|
||||
- name: Generate release notes
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
CLI_PATH="packages/browseros-agent/apps/cli"
|
||||
TAG="browseros-cli-v${{ inputs.version }}"
|
||||
CHANGELOG_FILE="/tmp/release-changelog.md"
|
||||
PREV_TAG=$(git tag -l "browseros-cli-v*" --sort=-v:refname | grep -v "^${TAG}$" | head -n 1)
|
||||
|
||||
if [ -z "$PREV_TAG" ]; then
|
||||
echo "Initial release of browseros-cli." > "$CHANGELOG_FILE"
|
||||
else
|
||||
COMMITS=$(git log "$PREV_TAG"..HEAD --pretty=format:"%H" -- "$CLI_PATH")
|
||||
|
||||
if [ -z "$COMMITS" ]; then
|
||||
echo "No notable changes." > "$CHANGELOG_FILE"
|
||||
else
|
||||
echo "## What's Changed" > "$CHANGELOG_FILE"
|
||||
echo "" >> "$CHANGELOG_FILE"
|
||||
|
||||
while IFS= read -r SHA; do
|
||||
SUBJECT=$(git log -1 --pretty=format:"%s" "$SHA")
|
||||
PR_NUM=$(gh api "/repos/${{ github.repository }}/commits/${SHA}/pulls" --jq '.[0].number // empty' 2>/dev/null)
|
||||
|
||||
if [ -n "$PR_NUM" ] && ! echo "$SUBJECT" | grep -qF "(#${PR_NUM})"; then
|
||||
echo "- ${SUBJECT} (#${PR_NUM})" >> "$CHANGELOG_FILE"
|
||||
else
|
||||
echo "- ${SUBJECT}" >> "$CHANGELOG_FILE"
|
||||
fi
|
||||
done <<< "$COMMITS"
|
||||
fi
|
||||
fi
|
||||
|
||||
cat "$CHANGELOG_FILE" > /tmp/release-notes.md
|
||||
cat >> /tmp/release-notes.md <<'EOF'
|
||||
|
||||
## Install `browseros-cli`
|
||||
|
||||
### npm / npx
|
||||
|
||||
```bash
|
||||
npx browseros-cli --help
|
||||
npm install -g browseros-cli
|
||||
```
|
||||
|
||||
### macOS / Linux
|
||||
|
||||
```bash
|
||||
curl -fsSL https://cdn.browseros.com/cli/install.sh | bash
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
```powershell
|
||||
irm https://cdn.browseros.com/cli/install.ps1 | iex
|
||||
```
|
||||
|
||||
After install, run `browseros-cli init` to point the CLI at your BrowserOS MCP server.
|
||||
EOF
|
||||
working-directory: ${{ github.workspace }}
|
||||
|
||||
- name: Create tag and release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
TAG="browseros-cli-v${{ inputs.version }}"
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
if ! git rev-parse "$TAG" >/dev/null 2>&1; then
|
||||
git tag -a "$TAG" -m "browseros-cli v${{ inputs.version }}"
|
||||
git push origin "$TAG"
|
||||
fi
|
||||
|
||||
CLI_DIST="packages/browseros-agent/apps/cli/dist"
|
||||
gh release create "$TAG" \
|
||||
--title "BrowserOS CLI - v${{ inputs.version }}" \
|
||||
--notes-file /tmp/release-notes.md \
|
||||
${CLI_DIST}/*
|
||||
working-directory: ${{ github.workspace }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- name: Publish to npm
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: |
|
||||
make npm-version VERSION=${{ inputs.version }}
|
||||
cd npm
|
||||
npm publish --access public
|
||||
147
.github/workflows/release-server.yml
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
name: Release BrowserOS Server
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "Release version (e.g. 0.0.80)"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
concurrency:
|
||||
group: release-server
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
release:
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
environment: release-core
|
||||
permissions:
|
||||
contents: write
|
||||
defaults:
|
||||
run:
|
||||
working-directory: packages/browseros-agent
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: "1.3.6"
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun ci
|
||||
|
||||
- name: Prepare production env file
|
||||
run: cp apps/server/.env.production.example apps/server/.env.production
|
||||
|
||||
- name: Validate version
|
||||
id: version
|
||||
env:
|
||||
REQUESTED_VERSION: ${{ inputs.version }}
|
||||
run: |
|
||||
PACKAGE_VERSION=$(node -p "require('./apps/server/package.json').version")
|
||||
echo "package_version=$PACKAGE_VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "release_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
if [ "$PACKAGE_VERSION" != "$REQUESTED_VERSION" ]; then
|
||||
echo "Requested version $REQUESTED_VERSION does not match apps/server/package.json ($PACKAGE_VERSION)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Build release artifacts
|
||||
run: bun run build:server:ci
|
||||
|
||||
- name: Verify release artifacts
|
||||
run: |
|
||||
mapfile -t ZIP_FILES < <(find dist/prod/server -maxdepth 1 -type f -name 'browseros-server-resources-*.zip' | sort)
|
||||
|
||||
if [ "${#ZIP_FILES[@]}" -eq 0 ]; then
|
||||
echo "No server release zip files were produced"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf 'Found release artifacts:\n%s\n' "${ZIP_FILES[@]}"
|
||||
|
||||
- name: Generate release notes
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PACKAGE_VERSION: ${{ steps.version.outputs.package_version }}
|
||||
run: |
|
||||
SERVER_APP_PATH="packages/browseros-agent/apps/server"
|
||||
SERVER_BUILD_DIR="packages/browseros-agent/scripts/build/server"
|
||||
SERVER_BUILD_ENTRY="packages/browseros-agent/scripts/build/server.ts"
|
||||
SERVER_RESOURCE_MANIFEST="packages/browseros-agent/scripts/build/config/server-prod-resources.json"
|
||||
SERVER_WORKSPACE_PKG="packages/browseros-agent/package.json"
|
||||
CURRENT_TAG="browseros-server-v$PACKAGE_VERSION"
|
||||
PREV_TAG=$(git tag -l "browseros-server-v*" --sort=-v:refname | grep -v "^${CURRENT_TAG}$" | head -n 1)
|
||||
|
||||
if [ -z "$PREV_TAG" ]; then
|
||||
echo "Initial release of browseros-server." > /tmp/release-notes.md
|
||||
else
|
||||
COMMITS=$(git log "$PREV_TAG"..HEAD --pretty=format:"%H" -- \
|
||||
"$SERVER_APP_PATH" \
|
||||
"$SERVER_BUILD_DIR" \
|
||||
"$SERVER_BUILD_ENTRY" \
|
||||
"$SERVER_RESOURCE_MANIFEST" \
|
||||
"$SERVER_WORKSPACE_PKG")
|
||||
|
||||
if [ -z "$COMMITS" ]; then
|
||||
echo "No notable changes." > /tmp/release-notes.md
|
||||
else
|
||||
echo "## What's Changed" > /tmp/release-notes.md
|
||||
echo "" >> /tmp/release-notes.md
|
||||
|
||||
while IFS= read -r SHA; do
|
||||
SUBJECT=$(git log -1 --pretty=format:"%s" "$SHA")
|
||||
PR_NUM=$(gh api "/repos/${{ github.repository }}/commits/${SHA}/pulls" --jq '.[0].number // empty' 2>/dev/null)
|
||||
|
||||
if [ -n "$PR_NUM" ] && ! echo "$SUBJECT" | grep -qF "(#${PR_NUM})"; then
|
||||
echo "- ${SUBJECT} (#${PR_NUM})" >> /tmp/release-notes.md
|
||||
else
|
||||
echo "- ${SUBJECT}" >> /tmp/release-notes.md
|
||||
fi
|
||||
done <<< "$COMMITS"
|
||||
fi
|
||||
fi
|
||||
working-directory: ${{ github.workspace }}
|
||||
|
||||
- name: Create GitHub release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PACKAGE_VERSION: ${{ steps.version.outputs.package_version }}
|
||||
RELEASE_SHA: ${{ steps.version.outputs.release_sha }}
|
||||
run: |
|
||||
TAG="browseros-server-v$PACKAGE_VERSION"
|
||||
TITLE="BrowserOS Server - v$PACKAGE_VERSION"
|
||||
mapfile -t ZIP_FILES < <(find packages/browseros-agent/dist/prod/server -maxdepth 1 -type f -name 'browseros-server-resources-*.zip' | sort)
|
||||
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
||||
echo "Tag $TAG already exists, skipping tag creation"
|
||||
else
|
||||
git tag -a "$TAG" -m "browseros-server v$PACKAGE_VERSION" "$RELEASE_SHA"
|
||||
fi
|
||||
|
||||
if git ls-remote --tags origin "$TAG" | grep -q "$TAG"; then
|
||||
echo "Tag $TAG already on remote, skipping push"
|
||||
else
|
||||
git push origin "$TAG"
|
||||
fi
|
||||
|
||||
if gh release view "$TAG" >/dev/null 2>&1; then
|
||||
echo "Release $TAG already exists, updating"
|
||||
gh release edit "$TAG" --title "$TITLE" --notes-file /tmp/release-notes.md
|
||||
gh release upload "$TAG" "${ZIP_FILES[@]}" --clobber
|
||||
else
|
||||
gh release create "$TAG" \
|
||||
--title "$TITLE" \
|
||||
--notes-file /tmp/release-notes.md \
|
||||
"${ZIP_FILES[@]}"
|
||||
fi
|
||||
working-directory: ${{ github.workspace }}
|
||||
141
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- ready_for_review
|
||||
paths:
|
||||
- .github/workflows/test.yml
|
||||
- packages/browseros-agent/**
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
BROWSEROS_APPIMAGE_URL: https://files.browseros.com/download/BrowserOS.AppImage
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Tests / ${{ matrix.suite }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
defaults:
|
||||
run:
|
||||
working-directory: packages/browseros-agent
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- suite: tools
|
||||
test_path: tests/tools
|
||||
junit_path: test-results/tools.xml
|
||||
- suite: integration
|
||||
test_path: tests/server.integration.test.ts
|
||||
junit_path: test-results/integration.xml
|
||||
- suite: sdk
|
||||
test_path: tests/sdk
|
||||
junit_path: test-results/sdk.xml
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun ci
|
||||
|
||||
- name: Resolve BrowserOS cache key
|
||||
id: browseros-cache-key
|
||||
run: |
|
||||
set -euo pipefail
|
||||
headers="$(curl -fsSI "$BROWSEROS_APPIMAGE_URL")"
|
||||
etag="$(printf '%s\n' "$headers" | awk 'BEGIN{IGNORECASE=1} /^etag:/ {sub(/\r$/, "", $2); gsub(/"/, "", $2); print $2; exit}')"
|
||||
last_modified="$(printf '%s\n' "$headers" | awk 'BEGIN{IGNORECASE=1} /^last-modified:/ {$1=""; sub(/^ /, ""); sub(/\r$/, ""); print; exit}')"
|
||||
raw_key="${etag:-$last_modified}"
|
||||
if [ -z "$raw_key" ]; then
|
||||
raw_key="$BROWSEROS_APPIMAGE_URL"
|
||||
fi
|
||||
cache_key="$(printf '%s' "$raw_key" | shasum -a 256 | awk '{print $1}')"
|
||||
echo "key=browseros-appimage-${{ runner.os }}-$cache_key" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Restore BrowserOS cache
|
||||
id: browseros-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: packages/browseros-agent/.ci/bin/BrowserOS.AppImage
|
||||
key: ${{ steps.browseros-cache-key.outputs.key }}
|
||||
|
||||
- name: Download BrowserOS
|
||||
if: steps.browseros-cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
mkdir -p .ci/bin
|
||||
curl -fsSL "$BROWSEROS_APPIMAGE_URL" -o .ci/bin/BrowserOS.AppImage
|
||||
chmod +x .ci/bin/BrowserOS.AppImage
|
||||
|
||||
- name: Prepare BrowserOS wrapper
|
||||
run: |
|
||||
mkdir -p .ci/bin
|
||||
cat > .ci/bin/browseros <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
export APPIMAGE_EXTRACT_AND_RUN=1
|
||||
exec "$(dirname "$0")/BrowserOS.AppImage" "$@"
|
||||
EOF
|
||||
chmod +x .ci/bin/browseros
|
||||
|
||||
- name: Create server env file
|
||||
working-directory: packages/browseros-agent/apps/server
|
||||
run: cp .env.example .env.development
|
||||
|
||||
- name: Run ${{ matrix.suite }} tests
|
||||
id: test
|
||||
env:
|
||||
BROWSEROS_BINARY: ${{ github.workspace }}/packages/browseros-agent/.ci/bin/browseros
|
||||
BROWSEROS_TEST_HEADLESS: "true"
|
||||
BROWSEROS_TEST_EXTRA_ARGS: --no-sandbox --disable-dev-shm-usage
|
||||
run: |
|
||||
set +e
|
||||
mkdir -p test-results
|
||||
cd apps/server
|
||||
bun run test:cleanup
|
||||
bun --env-file=.env.development test "${{ matrix.test_path }}" --reporter=junit --reporter-outfile="../../${{ matrix.junit_path }}"
|
||||
exit_code=$?
|
||||
cd ../..
|
||||
if [ ! -f "${{ matrix.junit_path }}" ]; then
|
||||
cat > "${{ matrix.junit_path }}" <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites tests="1" failures="1">
|
||||
<testsuite name="${{ matrix.suite }}" tests="1" failures="1">
|
||||
<testcase classname="workflow" name="${{ matrix.suite }} setup">
|
||||
<failure message="Test run failed before JUnit output was written">See workflow logs for details.</failure>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
EOF
|
||||
fi
|
||||
echo "exit_code=$exit_code" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload JUnit XML
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: junit-${{ matrix.suite }}
|
||||
path: packages/browseros-agent/${{ matrix.junit_path }}
|
||||
|
||||
- name: Summarize suite result
|
||||
if: always()
|
||||
run: |
|
||||
if [ "${{ steps.test.outputs.exit_code }}" = "0" ]; then
|
||||
echo "### :white_check_mark: ${{ matrix.suite }} suite passed" >> "$GITHUB_STEP_SUMMARY"
|
||||
else
|
||||
echo "### :x: ${{ matrix.suite }} suite failed (exit code ${{ steps.test.outputs.exit_code }})" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "See the uploaded \`junit-${{ matrix.suite }}\` artifact for details." >> "$GITHUB_STEP_SUMMARY"
|
||||
exit 1
|
||||
fi
|
||||
41
.github/workflows/update-agent-submodule.yml
vendored
@@ -1,41 +0,0 @@
|
||||
name: Update Agent Submodule
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run every hour
|
||||
- cron: "0 * * * *"
|
||||
# Allow manual triggering for testing
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: submodule-update
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
update-submodule:
|
||||
runs-on: ubuntu-latest
|
||||
# Only run on the main repository, not on forks
|
||||
if: github.repository == 'browseros-ai/BrowserOS'
|
||||
|
||||
steps:
|
||||
- name: Checkout repository with submodules
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Configure git
|
||||
run: |
|
||||
git config user.name "Felarof"
|
||||
git config user.email "nithin.sonti@gmail.com"
|
||||
|
||||
- name: Update agent submodule
|
||||
run: |
|
||||
bash scripts/update-submodule.sh main
|
||||
|
||||
- name: Push changes
|
||||
run: |
|
||||
git push origin main
|
||||
5
.gitignore
vendored
@@ -24,3 +24,8 @@ gclient.json
|
||||
.env
|
||||
.grove/
|
||||
**/resources/binaries/
|
||||
|
||||
packages/browseros/build/tools/
|
||||
|
||||
# AI SDK DevTools traces
|
||||
.devtools/
|
||||
|
||||
4
.gitmodules
vendored
@@ -1,4 +0,0 @@
|
||||
[submodule "packages/browseros-agent"]
|
||||
path = packages/browseros-agent
|
||||
url = https://github.com/browseros-ai/BrowserOS-agent.git
|
||||
branch = main
|
||||
|
||||
3840
.vscode/PythonImportHelper-v2-Completion.json
vendored
4
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"terminal.integrated.tabs.title": "${sequence} ${process}",
|
||||
"terminal.integrated.tabs.description": "${cwd}"
|
||||
}
|
||||
216
README.md
@@ -6,6 +6,7 @@
|
||||
[](https://dub.sh/browserOS-slack)
|
||||
[](https://twitter.com/browseros_ai)
|
||||
[](LICENSE)
|
||||
[](https://docs.browseros.com)
|
||||
<br></br>
|
||||
<a href="https://files.browseros.com/download/BrowserOS.dmg">
|
||||
<img src="https://img.shields.io/badge/Download-macOS-black?style=flat&logo=apple&logoColor=white" alt="Download for macOS (beta)" />
|
||||
@@ -22,146 +23,183 @@
|
||||
<br />
|
||||
</div>
|
||||
|
||||
##
|
||||
🌐 BrowserOS is an open-source Chromium fork that runs AI agents natively. **The privacy-first alternative to ChatGPT Atlas, Perplexity Comet, and Dia.**
|
||||
BrowserOS is an open-source Chromium fork that runs AI agents natively. **The privacy-first alternative to ChatGPT Atlas, Perplexity Comet, and Dia.**
|
||||
|
||||
🔒 Use your own API keys or run local models with Ollama. Your data never leaves your machine.
|
||||
Use your own API keys or run local models with Ollama. Your data never leaves your machine.
|
||||
|
||||
💡 Join our [Discord](https://discord.gg/YKwjt5vuKr) or [Slack](https://dub.sh/browserOS-slack) and help us build! Have feature requests? [Suggest here](https://github.com/browseros-ai/BrowserOS/issues/99).
|
||||
> **[Documentation](https://docs.browseros.com)** · **[Discord](https://discord.gg/YKwjt5vuKr)** · **[Slack](https://dub.sh/browserOS-slack)** · **[Twitter](https://x.com/browserOS_ai)** · **[Feature Requests](https://github.com/browseros-ai/BrowserOS/issues/99)**
|
||||
|
||||
## Quick start
|
||||
## Quick Start
|
||||
|
||||
1. Download and install BrowserOS:
|
||||
- [macOS](https://files.browseros.com/download/BrowserOS.dmg)
|
||||
- [Windows](https://files.browseros.com/download/BrowserOS_installer.exe)
|
||||
- [Linux (AppImage)](https://files.browseros.com/download/BrowserOS.AppImage)
|
||||
- [Linux (Debian)](https://cdn.browseros.com/download/BrowserOS.deb)
|
||||
1. **Download and install** BrowserOS — [macOS](https://files.browseros.com/download/BrowserOS.dmg) · [Windows](https://files.browseros.com/download/BrowserOS_installer.exe) · [Linux (AppImage)](https://files.browseros.com/download/BrowserOS.AppImage) · [Linux (Debian)](https://cdn.browseros.com/download/BrowserOS.deb)
|
||||
2. **Import your Chrome data** (optional) — bookmarks, passwords, extensions all carry over
|
||||
3. **Connect your AI provider** — Claude, OpenAI, Gemini, ChatGPT Pro via OAuth, or local models via Ollama/LM Studio
|
||||
|
||||
2. Import your Chrome data (optional)
|
||||
## Features
|
||||
|
||||
3. Connect your AI provider — use Claude, OpenAI, Gemini, or local models via Ollama and LMStudio.
|
||||
|
||||
4. Start automating!
|
||||
|
||||
## What makes BrowserOS special
|
||||
- 🏠 Feels like home — same Chrome interface, all your extensions just work
|
||||
- 🤖 AI agents that run on YOUR browser, not in the cloud
|
||||
- 🔒 Privacy first — bring your own keys or run local models with Ollama. Your browsing history stays on your machine
|
||||
- 🤝 [BrowserOS as MCP server](https://docs.browseros.com/features/use-with-claude-code) — control the browser from `claude-code`, `gemini-cli`, or any MCP client (31 tools)
|
||||
- 🔄 [Workflows](https://docs.browseros.com/features/workflows) — build repeatable browser automations with a visual graph builder
|
||||
- 📂 [Cowork](https://docs.browseros.com/features/cowork) — combine browser automation with local file operations. Research the web, save reports to your folder
|
||||
- ⏰ [Scheduled Tasks](https://docs.browseros.com/features/scheduled-tasks) — run the agent on autopilot, daily or every few minutes
|
||||
- 💬 [LLM Hub](https://docs.browseros.com/features/llm-chat-hub) — compare Claude, ChatGPT, and Gemini side-by-side on any page
|
||||
- 🛡️ Built-in ad blocker — [10x more protection than Chrome](https://docs.browseros.com/features/ad-blocking) with uBlock Origin + Manifest V2 support
|
||||
- 🚀 100% open source under AGPL-3.0
|
||||
| Feature | Description | Docs |
|
||||
|---------|-------------|------|
|
||||
| **AI Agent** | 53+ browser automation tools — navigate, click, type, extract data, all with natural language | [Guide](https://docs.browseros.com/getting-started) |
|
||||
| **MCP Server** | Control the browser from Claude Code, Gemini CLI, or any MCP client | [Setup](https://docs.browseros.com/features/use-with-claude-code) |
|
||||
| **Workflows** | Build repeatable browser automations with a visual graph builder | [Docs](https://docs.browseros.com/features/workflows) |
|
||||
| **Cowork** | Combine browser automation with local file operations — research the web, save reports to your folder | [Docs](https://docs.browseros.com/features/cowork) |
|
||||
| **Scheduled Tasks** | Run agents on autopilot — daily, hourly, or every few minutes | [Docs](https://docs.browseros.com/features/scheduled-tasks) |
|
||||
| **Memory** | Persistent memory across conversations — your assistant remembers context over time | [Docs](https://docs.browseros.com/features/memory) |
|
||||
| **SOUL.md** | Define your AI's personality and instructions in a single markdown file | [Docs](https://docs.browseros.com/features/soul-md) |
|
||||
| **LLM Hub** | Compare Claude, ChatGPT, and Gemini responses side-by-side on any page | [Docs](https://docs.browseros.com/features/llm-chat-hub) |
|
||||
| **40+ App Integrations** | Gmail, Slack, GitHub, Linear, Notion, Figma, Salesforce, and more via MCP | [Docs](https://docs.browseros.com/features/connect-apps) |
|
||||
| **Vertical Tabs** | Side-panel tab management — stay organized even with 100+ tabs open | [Docs](https://docs.browseros.com/features/vertical-tabs) |
|
||||
| **Ad Blocking** | uBlock Origin + Manifest V2 support — [10x more protection](https://docs.browseros.com/features/ad-blocking) than Chrome | [Docs](https://docs.browseros.com/features/ad-blocking) |
|
||||
| **Cloud Sync** | Sync browser config and agent history across devices | [Docs](https://docs.browseros.com/features/sync) |
|
||||
| **Skills** | Custom instruction sets that shape how your AI assistant behaves | [Docs](https://docs.browseros.com/features/skills) |
|
||||
| **Smart Nudges** | Contextual suggestions to connect apps and use features at the right moment | [Docs](https://docs.browseros.com/features/smart-nudges) |
|
||||
|
||||
## Demos
|
||||
|
||||
### 🤖 BrowserOS agent in action
|
||||
### BrowserOS agent in action
|
||||
[](https://www.youtube.com/watch?v=SoSFev5R5dI)
|
||||
<br/><br/>
|
||||
|
||||
### 🎇 Install [BrowserOS as MCP](https://docs.browseros.com/features/use-with-claude-code) and control it from `claude-code`
|
||||
### Install [BrowserOS as MCP](https://docs.browseros.com/features/use-with-claude-code) and control it from `claude-code`
|
||||
|
||||
https://github.com/user-attachments/assets/c725d6df-1a0d-40eb-a125-ea009bf664dc
|
||||
|
||||
<br/><br/>
|
||||
|
||||
### 💬 Use BrowserOS to chat
|
||||
### Use BrowserOS to chat
|
||||
|
||||
https://github.com/user-attachments/assets/726803c5-8e36-420e-8694-c63a2607beca
|
||||
|
||||
<br/><br/>
|
||||
|
||||
### ⚡ Use BrowserOS to scrape data
|
||||
### Use BrowserOS to scrape data
|
||||
|
||||
https://github.com/user-attachments/assets/9f038216-bc24-4555-abf1-af2adcb7ebc0
|
||||
|
||||
<br/><br/>
|
||||
|
||||
## Why We're Building BrowserOS
|
||||
## Install `browseros-cli`
|
||||
|
||||
For the first time since Netscape pioneered the web in 1994, AI gives us the chance to completely reimagine the browser. We've seen tools like Cursor deliver 10x productivity gains for developers—yet everyday browsing remains frustratingly archaic.
|
||||
Use `browseros-cli` to launch and control BrowserOS from the terminal or from AI coding agents like Claude Code.
|
||||
|
||||
You're likely juggling 70+ tabs, battling your browser instead of having it assist you. Routine tasks, like ordering something from amazon or filling a form should be handled seamlessly by AI agents.
|
||||
**macOS / Linux:**
|
||||
|
||||
At BrowserOS, we're convinced that AI should empower you by automating tasks locally and securely—keeping your data private. We are building the best browser for this future!
|
||||
```bash
|
||||
curl -fsSL https://cdn.browseros.com/cli/install.sh | bash
|
||||
```
|
||||
|
||||
## How we compare
|
||||
**Windows:**
|
||||
|
||||
<details>
|
||||
<summary><b>vs Chrome</b></summary>
|
||||
<br>
|
||||
While we're grateful for Google open-sourcing Chromium, but Chrome hasn't evolved much in 10 years. No AI features, no automation, no MCP support.
|
||||
</details>
|
||||
```powershell
|
||||
irm https://cdn.browseros.com/cli/install.ps1 | iex
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><b>vs Brave</b></summary>
|
||||
<br>
|
||||
We love what Brave started, but they've spread themselves too thin with crypto, search, VPNs. We're laser-focused on AI-powered browsing.
|
||||
</details>
|
||||
After install, run `browseros-cli init` to connect the CLI to your running BrowserOS instance.
|
||||
|
||||
<details>
|
||||
<summary><b>vs Arc/Dia</b></summary>
|
||||
<br>
|
||||
Many loved Arc, but it was closed source. When they abandoned users, there was no recourse. We're 100% open source - fork it anytime!
|
||||
</details>
|
||||
## LLM Providers
|
||||
|
||||
<details>
|
||||
<summary><b>vs Perplexity Comet</b></summary>
|
||||
<br>
|
||||
They're a search/ad company. Your browser history becomes their product. We keep everything local.
|
||||
</details>
|
||||
BrowserOS works with any LLM. Bring your own keys, use OAuth, or run models locally.
|
||||
|
||||
<details>
|
||||
<summary><b>vs ChatGPT Atlas</b></summary>
|
||||
<br>
|
||||
Your browsing data could be used for ads or to train their models. We keep your history and agent interactions strictly local.
|
||||
</details>
|
||||
| Provider | Type | Auth |
|
||||
|----------|------|------|
|
||||
| Kimi K2.5 | Cloud (default) | Built-in |
|
||||
| ChatGPT Pro/Plus | Cloud | [OAuth](https://docs.browseros.com/features/chatgpt) |
|
||||
| GitHub Copilot | Cloud | [OAuth](https://docs.browseros.com/features/github-copilot) |
|
||||
| Qwen Code | Cloud | [OAuth](https://docs.browseros.com/features/qwen-code) |
|
||||
| Claude (Anthropic) | Cloud | API key |
|
||||
| GPT-4o / o3 (OpenAI) | Cloud | API key |
|
||||
| Gemini (Google) | Cloud | API key |
|
||||
| Azure OpenAI | Cloud | API key |
|
||||
| AWS Bedrock | Cloud | IAM credentials |
|
||||
| OpenRouter | Cloud | API key |
|
||||
| Ollama | Local | [Setup](https://docs.browseros.com/features/ollama) |
|
||||
| LM Studio | Local | [Setup](https://docs.browseros.com/features/lm-studio) |
|
||||
|
||||
## How We Compare
|
||||
|
||||
| | BrowserOS | Chrome | Brave | Dia | Comet | Atlas |
|
||||
|---|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
| Open Source | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
||||
| AI Agent | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ |
|
||||
| MCP Server | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
| Visual Workflows | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
| Cowork (files + browser) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
| Scheduled Tasks | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
| Bring Your Own Keys | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
||||
| Local Models (Ollama) | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
||||
| Local-first Privacy | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
||||
| Ad Blocking (MV2) | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
|
||||
|
||||
**Detailed comparisons:**
|
||||
- [BrowserOS vs Chrome DevTools MCP](https://docs.browseros.com/comparisons/chrome-devtools-mcp) — developer-focused comparison for browser automation
|
||||
- [BrowserOS vs Claude Cowork](https://docs.browseros.com/comparisons/claude-cowork) — getting real work done with AI
|
||||
- [BrowserOS vs OpenClaw](https://docs.browseros.com/comparisons/openclaw) — everyday AI assistance
|
||||
|
||||
## Architecture
|
||||
|
||||
BrowserOS is a monorepo with two main subsystems: the **browser** (Chromium fork) and the **agent platform** (TypeScript/Go).
|
||||
|
||||
```
|
||||
BrowserOS/
|
||||
├── packages/browseros/ # Chromium fork + build system (Python)
|
||||
│ ├── chromium_patches/ # Patches applied to Chromium source
|
||||
│ ├── build/ # Build CLI and modules
|
||||
│ └── resources/ # Icons, entitlements, signing
|
||||
│
|
||||
├── packages/browseros-agent/ # Agent platform (TypeScript/Go)
|
||||
│ ├── apps/
|
||||
│ │ ├── server/ # MCP server + AI agent loop (Bun)
|
||||
│ │ ├── agent/ # Browser extension UI (WXT + React)
|
||||
│ │ ├── cli/ # CLI tool (Go)
|
||||
│ │ ├── eval/ # Benchmark framework
|
||||
│ │ └── controller-ext/ # Chrome API bridge extension
|
||||
│ │
|
||||
│ └── packages/
|
||||
│ ├── agent-sdk/ # Node.js SDK (npm: @browseros-ai/agent-sdk)
|
||||
│ ├── cdp-protocol/ # CDP type bindings
|
||||
│ └── shared/ # Shared constants
|
||||
```
|
||||
|
||||
| Package | What it does |
|
||||
|---------|-------------|
|
||||
| [`packages/browseros`](packages/browseros/) | Chromium fork — patches, build system, signing |
|
||||
| [`apps/server`](packages/browseros-agent/apps/server/) | Bun server exposing 53+ MCP tools and running the AI agent loop |
|
||||
| [`apps/agent`](packages/browseros-agent/apps/agent/) | Browser extension — new tab, side panel chat, onboarding, settings |
|
||||
| [`apps/cli`](packages/browseros-agent/apps/cli/) | Go CLI — control BrowserOS from the terminal or AI coding agents |
|
||||
| [`apps/eval`](packages/browseros-agent/apps/eval/) | Benchmark framework — WebVoyager, Mind2Web evaluation |
|
||||
| [`agent-sdk`](packages/browseros-agent/packages/agent-sdk/) | Node.js SDK for browser automation with natural language |
|
||||
| [`cdp-protocol`](packages/browseros-agent/packages/cdp-protocol/) | Type-safe Chrome DevTools Protocol bindings |
|
||||
|
||||
## Contributing
|
||||
|
||||
We'd love your help making BrowserOS better!
|
||||
We'd love your help making BrowserOS better! See our [Contributing Guide](CONTRIBUTING.md) for details.
|
||||
|
||||
- 🐛 [Report bugs](https://github.com/browseros-ai/BrowserOS/issues)
|
||||
- 💡 [Suggest features](https://github.com/browseros-ai/BrowserOS/issues/99)
|
||||
- 💬 [Join Discord](https://discord.gg/YKwjt5vuKr)
|
||||
- 🐦 [Follow on Twitter](https://x.com/browserOS_ai)
|
||||
- [Report bugs](https://github.com/browseros-ai/BrowserOS/issues)
|
||||
- [Suggest features](https://github.com/browseros-ai/BrowserOS/issues/99)
|
||||
- [Join Discord](https://discord.gg/YKwjt5vuKr) · [Join Slack](https://dub.sh/browserOS-slack)
|
||||
- [Follow on Twitter](https://x.com/browserOS_ai)
|
||||
|
||||
**Agent development** (TypeScript/Go) — see the [agent monorepo README](packages/browseros-agent/README.md) for setup instructions.
|
||||
|
||||
**Browser development** (C++/Python) — requires ~100GB disk space. See [`packages/browseros`](packages/browseros/) for build instructions.
|
||||
|
||||
## Credits
|
||||
|
||||
- [ungoogled-chromium](https://github.com/ungoogled-software/ungoogled-chromium) — BrowserOS uses some patches for enhanced privacy. Thanks to everyone behind this project!
|
||||
- [The Chromium Project](https://www.chromium.org/) — at the core of BrowserOS, making it possible to exist in the first place.
|
||||
|
||||
## License
|
||||
|
||||
BrowserOS is open source under the [AGPL-3.0 license](LICENSE).
|
||||
|
||||
## Credits
|
||||
|
||||
- [ungoogled-chromium](https://github.com/ungoogled-software/ungoogled-chromium) - BrowserOS uses some patches for enhanced privacy. Thanks to everyone behind this project!
|
||||
- [The Chromium Project](https://www.chromium.org/) - At the core of BrowserOS, making it possible to exist in the first place.
|
||||
|
||||
## Citation
|
||||
|
||||
If you use BrowserOS in your research or project, please cite:
|
||||
|
||||
```bibtex
|
||||
@software{browseros2025,
|
||||
author = {Sonti, Nithin Venkat and Sonti, Nikhil Venkat and {BrowserOS-team}},
|
||||
title = {BrowserOS: The open-source Agentic browser},
|
||||
url = {https://github.com/browseros-ai/BrowserOS},
|
||||
year = {2025},
|
||||
publisher = {GitHub},
|
||||
license = {AGPL-3.0},
|
||||
}
|
||||
```
|
||||
|
||||
Copyright © 2025 Felafax, Inc.
|
||||
Copyright © 2026 Felafax, Inc.
|
||||
|
||||
## Stargazers
|
||||
|
||||
Thank you to all our supporters!
|
||||
|
||||
[](https://www.star-history.com/#browseros-ai/BrowserOS&Date)
|
||||
|
||||
##
|
||||
<p align="center">
|
||||
Built with ❤️ from San Francisco
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,24 @@ All notable changes to BrowserOS are documented here. For the full release histo
|
||||
|
||||
---
|
||||
|
||||
## v0.42.0
|
||||
<sub>March 9, 2026</sub>
|
||||
|
||||
- **SOUL.md** — Your assistant now has a soul. Tell it how you like to communicate, set boundaries, shape its personality — and it adapts on its own over time. The more you use it, the more it feels like *your* assistant. [Read more →](/features/soul)
|
||||
- **Vertical tabs** — One of the most requested features is here. BrowserOS now ships with vertical tabs by default. More screen space, better tab management, and a cleaner layout out of the box. Prefer horizontal? You can switch back anytime in settings. [Read more →](/features/vertical-tabs)
|
||||
- **Long-term memory** — Your assistant finally remembers you. Your name, your projects, what you talked about last week — it carries context across every conversation so you never have to repeat yourself. All stored locally on your machine. [Read more →](/features/memory)
|
||||
- **Chromium 146** — Updated to the latest Chromium release with all recent upstream fixes and security patches
|
||||
|
||||
<Frame>
|
||||
<img src="/images/changelog/0.42.0/soul-memory.png" alt="BrowserOS v0.42.0 SOUL.md feature for agent personalization" />
|
||||
</Frame>
|
||||
|
||||
<Frame>
|
||||
<img src="/images/changelog/0.42.0/vertical-tabs.png" alt="BrowserOS v0.42.0 vertical tabs toggle in settings" />
|
||||
</Frame>
|
||||
|
||||
---
|
||||
|
||||
## v0.41.0
|
||||
<sub>March 4, 2026</sub>
|
||||
|
||||
|
||||
@@ -23,17 +23,23 @@
|
||||
"group": "Core Features",
|
||||
"pages": [
|
||||
"features/bring-your-own-llm",
|
||||
"features/chatgpt-pro-oauth",
|
||||
"features/github-copilot-oauth",
|
||||
"features/qwen-code-oauth",
|
||||
"features/local-models",
|
||||
"features/workflows",
|
||||
"features/scheduled-tasks",
|
||||
"features/cowork",
|
||||
"features/connect-mcps",
|
||||
"features/skills",
|
||||
"features/smart-nudges",
|
||||
"features/use-with-claude-code",
|
||||
"features/soul",
|
||||
"features/memory",
|
||||
"features/sync-to-cloud",
|
||||
"features/llm-chat-hub",
|
||||
"features/ad-blocking"
|
||||
"features/ad-blocking",
|
||||
"features/vertical-tabs"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -13,6 +13,33 @@ See how to connect your own LLM in under a minute:
|
||||
src="https://pub-80f8a01e6e8b4239ae53a7652ef85877.r2.dev/resources/feature-videos/1-bring-your-own-LLM.mov"
|
||||
></video>
|
||||
|
||||
## Use Your Existing Subscription
|
||||
|
||||
Already paying for ChatGPT Pro, GitHub Copilot, or Qwen Code? Connect your existing account to BrowserOS with a single sign-in — no API keys, no extra cost.
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card href="/features/chatgpt-pro-oauth">
|
||||
<svg fill="currentColor" fillRule="evenodd" height="24" width="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"></path></svg>
|
||||
**ChatGPT Pro / Plus**
|
||||
|
||||
Sign in with your OpenAI account. Access GPT-5 Codex, GPT-5.4, and the full Codex lineup with up to 400K context.
|
||||
</Card>
|
||||
<Card href="/features/github-copilot-oauth">
|
||||
<svg fill="currentColor" fillRule="evenodd" height="24" width="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M19.245 5.364c1.322 1.36 1.877 3.216 2.11 5.817.622 0 1.2.135 1.592.654l.73.964c.21.278.323.61.323.955v2.62c0 .339-.173.669-.453.868C20.239 19.602 16.157 21.5 12 21.5c-4.6 0-9.205-2.583-11.547-4.258-.28-.2-.452-.53-.453-.868v-2.62c0-.345.113-.679.321-.956l.73-.963c.392-.517.974-.654 1.593-.654l.029-.297c.25-2.446.81-4.213 2.082-5.52 2.461-2.54 5.71-2.851 7.146-2.864h.198c1.436.013 4.685.323 7.146 2.864zm-7.244 4.328c-.284 0-.613.016-.962.05-.123.447-.305.85-.57 1.108-1.05 1.023-2.316 1.18-2.994 1.18-.638 0-1.306-.13-1.851-.464-.516.165-1.012.403-1.044.996a65.882 65.882 0 00-.063 2.884l-.002.48c-.002.563-.005 1.126-.013 1.69.002.326.204.63.51.765 2.482 1.102 4.83 1.657 6.99 1.657 2.156 0 4.504-.555 6.985-1.657a.854.854 0 00.51-.766c.03-1.682.006-3.372-.076-5.053-.031-.596-.528-.83-1.046-.996-.546.333-1.212.464-1.85.464-.677 0-1.942-.157-2.993-1.18-.266-.258-.447-.661-.57-1.108-.32-.032-.64-.049-.96-.05zm-2.525 4.013c.539 0 .976.426.976.95v1.753c0 .525-.437.95-.976.95a.964.964 0 01-.976-.95v-1.752c0-.525.437-.951.976-.951zm5 0c.539 0 .976.426.976.95v1.753c0 .525-.437.95-.976.95a.964.964 0 01-.976-.95v-1.752c0-.525.437-.951.976-.951zM7.635 5.087c-1.05.102-1.935.438-2.385.906-.975 1.037-.765 3.668-.21 4.224.405.394 1.17.657 1.995.657h.09c.649-.013 1.785-.176 2.73-1.11.435-.41.705-1.433.675-2.47-.03-.834-.27-1.52-.63-1.813-.39-.336-1.275-.482-2.265-.394zm6.465.394c-.36.292-.6.98-.63 1.813-.03 1.037.24 2.06.675 2.47.968.957 2.136 1.104 2.776 1.11h.044c.825 0 1.59-.263 1.995-.657.555-.556.765-3.187-.21-4.224-.45-.468-1.335-.804-2.385-.906-.99-.088-1.875.058-2.265.394zM12 7.615c-.24 0-.525.015-.84.044.03.16.045.336.06.526l-.001.159a2.94 2.94 0 01-.014.25c.225-.022.425-.027.612-.028h.366c.187 0 .387.006.612.028-.015-.146-.015-.277-.015-.409.015-.19.03-.365.06-.526a9.29 9.29 0 00-.84-.044z"></path></svg>
|
||||
**GitHub Copilot**
|
||||
|
||||
Sign in with your GitHub account. Access 19+ models including Claude, GPT-5, and Gemini through one subscription.
|
||||
</Card>
|
||||
<Card href="/features/qwen-code-oauth">
|
||||
<svg fill="currentColor" fillRule="evenodd" height="24" width="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12.604 1.34c.393.69.784 1.382 1.174 2.075a.18.18 0 00.157.091h5.552c.174 0 .322.11.446.327l1.454 2.57c.19.337.24.478.024.837-.26.43-.513.864-.76 1.3l-.367.658c-.106.196-.223.28-.04.512l2.652 4.637c.172.301.111.494-.043.77-.437.785-.882 1.564-1.335 2.34-.159.272-.352.375-.68.37-.777-.016-1.552-.01-2.327.016a.099.099 0 00-.081.05 575.097 575.097 0 01-2.705 4.74c-.169.293-.38.363-.725.364-.997.003-2.002.004-3.017.002a.537.537 0 01-.465-.271l-1.335-2.323a.09.09 0 00-.083-.049H4.982c-.285.03-.553-.001-.805-.092l-1.603-2.77a.543.543 0 01-.002-.54l1.207-2.12a.198.198 0 000-.197 550.951 550.951 0 01-1.875-3.272l-.79-1.395c-.16-.31-.173-.496.095-.965.465-.813.927-1.625 1.387-2.436.132-.234.304-.334.584-.335a338.3 338.3 0 012.589-.001.124.124 0 00.107-.063l2.806-4.895a.488.488 0 01.422-.246c.524-.001 1.053 0 1.583-.006L11.704 1c.341-.003.724.032.9.34zm-3.432.403a.06.06 0 00-.052.03L6.254 6.788a.157.157 0 01-.135.078H3.253c-.056 0-.07.025-.041.074l5.81 10.156c.025.042.013.062-.034.063l-2.795.015a.218.218 0 00-.2.116l-1.32 2.31c-.044.078-.021.118.068.118l5.716.008c.046 0 .08.02.104.061l1.403 2.454c.046.081.092.082.139 0l5.006-8.76.783-1.382a.055.055 0 01.096 0l1.424 2.53a.122.122 0 00.107.062l2.763-.02a.04.04 0 00.035-.02.041.041 0 000-.04l-2.9-5.086a.108.108 0 010-.113l.293-.507 1.12-1.977c.024-.041.012-.062-.035-.062H9.2c-.059 0-.073-.026-.043-.077l1.434-2.505a.107.107 0 000-.114L9.225 1.774a.06.06 0 00-.053-.031zm6.29 8.02c.046 0 .058.02.034.06l-.832 1.465-2.613 4.585a.056.056 0 01-.05.029.058.058 0 01-.05-.029L8.498 9.841c-.02-.034-.01-.052.028-.054l.216-.012 6.722-.012z"></path></svg>
|
||||
**Qwen Code**
|
||||
|
||||
Sign in with your Qwen account. Access Qwen 3 Coder with a 1 million token context window.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
---
|
||||
|
||||
## Which Model Should I Use?
|
||||
|
||||
| Mode | What works | Recommendation |
|
||||
|
||||
56
docs/features/chatgpt-pro-oauth.mdx
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
title: "ChatGPT Pro / Plus"
|
||||
description: "Use your ChatGPT subscription to power BrowserOS"
|
||||
---
|
||||
|
||||
Connect your ChatGPT Pro or Plus subscription to BrowserOS and access GPT-5 Codex, GPT-5.4, and the full lineup of OpenAI's most advanced models — with up to 400K context. No API keys needed.
|
||||
|
||||
## Setup
|
||||
|
||||
**1.** Open BrowserOS and go to **Settings** (`chrome://browseros/settings`). You'll see the AI Providers section.
|
||||
|
||||

|
||||
|
||||
**2.** Click **USE** on the **ChatGPT Plus/Pro** card. You'll be prompted to sign in with your OpenAI account.
|
||||
|
||||

|
||||
|
||||
**3.** Sign in with the OpenAI account that has your ChatGPT Pro or Plus subscription active, and accept the authorization.
|
||||
|
||||

|
||||
|
||||
**4.** Once authorized, ChatGPT will appear as a provider in your settings. Select a model and start using it.
|
||||
|
||||
## Available Models
|
||||
|
||||
| Model | Context Window |
|
||||
|-------|---------------|
|
||||
| `gpt-5.4` | 400K |
|
||||
| `gpt-5.3-codex` | 400K |
|
||||
| `gpt-5.2-codex` | 400K |
|
||||
| `gpt-5.2` | 200K |
|
||||
| `gpt-5.1-codex` | 400K |
|
||||
| `gpt-5.1-codex-max` | 400K |
|
||||
| `gpt-5.1-codex-mini` | 400K |
|
||||
| `gpt-5.1` | 200K |
|
||||
|
||||
<Info>
|
||||
ChatGPT Pro subscribers have access to the full model lineup. ChatGPT Plus subscribers can access a subset of models depending on their plan. The available models will be shown automatically after you connect.
|
||||
</Info>
|
||||
|
||||
<Tip>
|
||||
The Codex models (e.g., `gpt-5.3-codex`) are optimized for code and reasoning tasks — ideal for complex browser automation workflows that involve form filling, data extraction, and multi-step navigation.
|
||||
</Tip>
|
||||
|
||||
## Reasoning Settings
|
||||
|
||||
ChatGPT Pro includes additional settings for models that support reasoning:
|
||||
|
||||
- **Reasoning Effort** — Control how much the model "thinks" before responding. Options: none, low, medium, high.
|
||||
- **Reasoning Summary** — Choose how reasoning is displayed. Options: auto, concise, detailed.
|
||||
|
||||
These settings are available in the provider configuration after connecting.
|
||||
|
||||
## Disconnecting
|
||||
|
||||
To disconnect your OpenAI account, go to **Settings**, find the ChatGPT Plus/Pro provider, and click **Disconnect**. Your OAuth tokens will be immediately deleted from your machine.
|
||||
@@ -18,34 +18,37 @@ BrowserOS uses the [Model Context Protocol (MCP)](https://modelcontextprotocol.i
|
||||
|
||||
## Smart App Connection
|
||||
|
||||
When you ask the assistant to do something that needs an app you have not connected yet, it will detect this automatically and guide you through signing in, right in the conversation. No need to set things up in advance. You only sign in once per app, and it stays connected for future requests.
|
||||
When you ask the assistant to do something that needs an app you have not connected yet, it shows an interactive card right in the conversation. You can connect the app with one click or choose to skip it. No need to set things up in advance.
|
||||
|
||||
<Steps>
|
||||
<Step title="You make a request">
|
||||
Ask the assistant something like "What's on my calendar today?" or "Send an email to Sarah."
|
||||
</Step>
|
||||
<Step title="The assistant detects the app is not connected">
|
||||
If you have not signed into that app yet, the assistant opens a sign-in page in your browser.
|
||||
<Step title="A connection card appears">
|
||||
The assistant detects the app is not connected and shows a card explaining why connecting it would help. You get two choices: **Connect** or **Do it manually**.
|
||||
</Step>
|
||||
<Step title="You sign in once">
|
||||
Complete the OAuth sign-in. Your credentials are never stored in BrowserOS.
|
||||
<Step title="You connect or skip">
|
||||
- **Connect**: Opens a sign-in page. Authorize the app and the assistant continues with full integration access.
|
||||
- **Do it manually**: The assistant skips the integration and navigates to the app's website directly using browser automation.
|
||||
</Step>
|
||||
<Step title="The assistant continues where it left off">
|
||||
Once you confirm you are signed in, the assistant picks up right where it stopped and completes your request.
|
||||
<Step title="The assistant continues">
|
||||
Once connected, the app stays linked for all future conversations. If you chose to skip, the assistant remembers and will not ask again.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
{/* <Frame caption="The assistant detects an unconnected app and opens the sign-in page">
|
||||
{/* <Frame caption="The assistant detects an unconnected app and shows a connection card">
|
||||
<img src="/images/connect-apps-smart-connection.png" alt="Smart app connection prompt in chat" />
|
||||
</Frame> */}
|
||||
|
||||
You can also connect apps ahead of time from Settings if you prefer.
|
||||
See [Smart Nudges](/features/smart-nudges#app-connection) for more details on how connection suggestions work.
|
||||
|
||||
## Connect from Settings
|
||||
You can also connect apps ahead of time from the sidebar if you prefer.
|
||||
|
||||
## Connect from the Sidebar
|
||||
|
||||
<Steps>
|
||||
<Step title="Open Connected Apps">
|
||||
Go to **Settings > Connected Apps**
|
||||
<Step title="Open Connect Apps">
|
||||
Click **Connect Apps** in the sidebar.
|
||||
</Step>
|
||||
<Step title="Add an app">
|
||||
Click **Add built-in app** and select the app you want
|
||||
|
||||
60
docs/features/github-copilot-oauth.mdx
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: "GitHub Copilot"
|
||||
description: "Use your GitHub Copilot subscription to power BrowserOS"
|
||||
---
|
||||
|
||||
Connect your GitHub Copilot subscription to BrowserOS and access 19+ models — including Claude, GPT-5, and Gemini — through a single GitHub sign-in. No API keys needed.
|
||||
|
||||
<Info>
|
||||
**Free tier** includes GPT-5 Mini, Claude Haiku 4.5, GPT-4o, and GPT-4.1. **Copilot Pro** ($10/month) unlocks Claude Sonnet 4.6, Claude Opus 4.6, Gemini 3 Pro, GPT-5.4, and more.
|
||||
</Info>
|
||||
|
||||
## Setup
|
||||
|
||||
**1.** Open BrowserOS and go to **Settings** (`chrome://browseros/settings`). You'll see the AI Providers section.
|
||||
|
||||

|
||||
|
||||
**2.** Click **USE** on the **GitHub Copilot** card. A device code will appear — copy it, then click the link to open GitHub's device authorization page.
|
||||
|
||||

|
||||
|
||||
**3.** Select your GitHub account to authorize.
|
||||
|
||||

|
||||
|
||||
**4.** Paste the device code and authorize BrowserOS to access your Copilot subscription.
|
||||
|
||||

|
||||
|
||||
**5.** Once authorized, GitHub Copilot will appear as a provider in your settings. Select a model and start using it.
|
||||
|
||||
## Available Models
|
||||
|
||||
### Free Tier
|
||||
| Model | Context Window |
|
||||
|-------|---------------|
|
||||
| `gpt-5-mini` | 128K |
|
||||
| `claude-haiku-4.5` | 128K |
|
||||
| `gpt-4o` | 64K |
|
||||
| `gpt-4.1` | 64K |
|
||||
|
||||
### Copilot Pro / Pro+
|
||||
| Model | Context Window |
|
||||
|-------|---------------|
|
||||
| `claude-sonnet-4.6` | 200K |
|
||||
| `claude-opus-4.6` | 200K |
|
||||
| `gemini-2.5-pro` | 1M |
|
||||
| `gemini-3-pro-preview` | 1M |
|
||||
| `gpt-5.4` | 400K |
|
||||
| `gpt-5.3-codex` | 400K |
|
||||
| `gpt-5.2-codex` | 400K |
|
||||
| `grok-code-fast-1` | 128K |
|
||||
|
||||
<Tip>
|
||||
GitHub Copilot is the most versatile provider — one subscription gives you access to models from OpenAI, Anthropic, Google, and xAI. Great if you want to switch between models for different tasks.
|
||||
</Tip>
|
||||
|
||||
## Disconnecting
|
||||
|
||||
To disconnect your GitHub account, go to **Settings**, find the GitHub Copilot provider, and click **Disconnect**. Your OAuth tokens will be immediately deleted from your machine.
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: "Local Model Guide"
|
||||
title: "Bring Your Local Model"
|
||||
description: "Run AI models locally with Ollama or LM Studio for free, private, offline use"
|
||||
---
|
||||
|
||||
|
||||
39
docs/features/qwen-code-oauth.mdx
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: "Qwen Code"
|
||||
description: "Use your Qwen Code account to power BrowserOS"
|
||||
---
|
||||
|
||||
Connect your Qwen Code account to BrowserOS and access Alibaba's coding models with up to a **1 million token context window** — the largest of any provider we support. No API keys needed.
|
||||
|
||||
## Setup
|
||||
|
||||
**1.** Open BrowserOS and go to **Settings** (`chrome://browseros/settings`). You'll see the AI Providers section.
|
||||
|
||||

|
||||
|
||||
**2.** Click **USE** on the **Qwen Code** card. You'll be prompted to sign in with your Qwen account.
|
||||
|
||||

|
||||
|
||||
**3.** Sign in with your Alibaba Cloud / Qwen account to authorize BrowserOS.
|
||||
|
||||

|
||||
|
||||
**4.** Once authorized, Qwen Code will appear as a provider in your settings. Select a model and start using it.
|
||||
|
||||
## Available Models
|
||||
|
||||
| Model | Context Window |
|
||||
|-------|---------------|
|
||||
| `coder-model` | 1M |
|
||||
| `qwen3-coder-plus` | 1M |
|
||||
| `qwen3-coder-flash` | 1M |
|
||||
| `qwen3.5-plus` | 1M |
|
||||
|
||||
<Tip>
|
||||
Qwen Code's 1 million token context window is ideal for tasks that involve long documents, entire documentation sites, or working across many browser tabs simultaneously — the agent can hold everything in context at once.
|
||||
</Tip>
|
||||
|
||||
## Disconnecting
|
||||
|
||||
To disconnect your Qwen account, go to **Settings**, find the Qwen Code provider, and click **Disconnect**. Your OAuth tokens will be immediately deleted from your machine.
|
||||
@@ -15,9 +15,23 @@ Watch how to set up a scheduled task from scratch:
|
||||
|
||||
## Creating a Scheduled Task
|
||||
|
||||
There are two ways to create a scheduled task: from a conversation or from the settings page.
|
||||
|
||||
### From a conversation
|
||||
|
||||
After the agent completes a task that could run on a schedule, it will suggest scheduling it with an interactive card. You can also ask directly:
|
||||
|
||||
- "Schedule this to run every morning"
|
||||
- "Can this run daily at 8am?"
|
||||
- "Automate this task"
|
||||
|
||||
The agent fills in the task details for you. Just review and confirm. See [Smart Nudges](/features/smart-nudges#schedule-suggestion) for more details.
|
||||
|
||||
### From settings
|
||||
|
||||
<Steps>
|
||||
<Step title="Open Scheduled Tasks">
|
||||
Go to **Scheduled Tasks** in the sidebar, or find it under **Settings**.
|
||||
Click **Scheduled Tasks** in the sidebar.
|
||||
</Step>
|
||||
<Step title="Click New Task">
|
||||
Click the **New Task** button to open the creation dialog.
|
||||
|
||||
193
docs/features/skills.mdx
Normal file
@@ -0,0 +1,193 @@
|
||||
---
|
||||
title: "Skills"
|
||||
description: "Teach your BrowserOS agent new abilities with reusable, custom instructions"
|
||||
---
|
||||
|
||||
Skills let you teach the BrowserOS agent how to handle specific tasks. Each skill is a set of instructions written in plain Markdown that the agent loads when it recognizes a matching task. Think of skills as recipes: you write the steps once, and the agent follows them whenever that type of task comes up.
|
||||
|
||||
BrowserOS implements the open [Agent Skills specification](https://agentskills.io/specification), so skills you create are portable across any AI agent that supports the standard.
|
||||
|
||||
## How Skills Work
|
||||
|
||||
<Steps>
|
||||
<Step title="You create a skill">
|
||||
Give it a name, a short description of when to use it, and write the instructions in Markdown.
|
||||
</Step>
|
||||
<Step title="The agent sees the skill catalog">
|
||||
When a conversation starts, the agent loads a list of all your enabled skills with their names and descriptions.
|
||||
</Step>
|
||||
<Step title="The agent matches a task">
|
||||
When your request matches a skill's description, the agent loads that skill's full instructions and follows them.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Creating a Skill
|
||||
|
||||
<Steps>
|
||||
<Step title="Open Skills settings">
|
||||
Click **Skills** in the sidebar.
|
||||
</Step>
|
||||
<Step title="Click New Skill">
|
||||
Click the **New Skill** button to open the creation form.
|
||||
</Step>
|
||||
<Step title="Fill in the details">
|
||||
- **Name**: A short, descriptive name (e.g., "Morning Status Report")
|
||||
- **Description**: Tell the agent when to use this skill. Be specific. For example: "When the user wants to read status updates from work across Notion, Linear, and Slack"
|
||||
- **Content**: Write your instructions in Markdown. Include step-by-step directions, examples, and edge cases.
|
||||
</Step>
|
||||
<Step title="Save and enable">
|
||||
Click **Create**. The skill is enabled by default and will be available to the agent immediately.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Tip>
|
||||
Write your description like a trigger. The agent uses it to decide whether to activate the skill. A good description says both **what** the skill does and **when** to use it.
|
||||
</Tip>
|
||||
|
||||
## Example Skills
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Morning status report">
|
||||
**Description:** When the user wants to read status updates from work
|
||||
|
||||
**Instructions:**
|
||||
```markdown
|
||||
Always look for updates in 3 sources:
|
||||
1. **Notion** - Check the team updates page for any new entries from today
|
||||
2. **Linear** - Look at issues assigned to the user that were updated in the last 24 hours
|
||||
3. **Slack** - Check the #team-updates and #engineering channels for unread messages
|
||||
|
||||
Summarize everything in a single report grouped by source.
|
||||
If a source has no updates, say so.
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="PDF processing">
|
||||
**Description:** Extract text and tables from PDF files, fill PDF forms, and merge multiple PDFs. Use when the user mentions PDFs, forms, or document extraction.
|
||||
|
||||
**Instructions:**
|
||||
```markdown
|
||||
When extracting text from a PDF:
|
||||
1. Download or open the PDF in the browser
|
||||
2. Use the page content tool to extract visible text
|
||||
3. Preserve table structure using Markdown tables
|
||||
4. If the PDF has multiple pages, process each page
|
||||
|
||||
When filling a PDF form:
|
||||
- Ask the user for the values if not provided
|
||||
- Fill each field carefully and confirm before submitting
|
||||
|
||||
See references/FORMS.md for common form templates.
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Code review checklist">
|
||||
**Description:** When the user asks to review code, a pull request, or wants feedback on code quality
|
||||
|
||||
**Instructions:**
|
||||
```markdown
|
||||
Follow this checklist for every code review:
|
||||
1. Check for security issues (XSS, injection, hardcoded secrets)
|
||||
2. Look for performance problems (N+1 queries, unnecessary re-renders)
|
||||
3. Verify error handling is present and meaningful
|
||||
4. Check that naming is clear and consistent
|
||||
5. Look for missing tests for new logic
|
||||
|
||||
Format your review as a list of findings with severity: Critical, Warning, or Suggestion.
|
||||
Always start with what the code does well.
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Managing Skills
|
||||
|
||||
From the Skills page, you can:
|
||||
|
||||
- **Enable or disable** a skill using the toggle switch. Disabled skills are not loaded by the agent.
|
||||
- **Edit** a skill's name, description, or instructions by clicking the edit icon.
|
||||
- **Delete** a skill by clicking the trash icon. This removes the skill permanently.
|
||||
|
||||
## Skill File Format
|
||||
|
||||
Under the hood, each skill is stored as a `SKILL.md` file following the [Agent Skills specification](https://agentskills.io/specification):
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: morning-status-report
|
||||
description: When the user wants to read status updates from work
|
||||
metadata:
|
||||
display-name: Morning Status Report
|
||||
enabled: "true"
|
||||
---
|
||||
Always look for updates in 3 sources:
|
||||
1. Notion - Check the team updates page
|
||||
2. Linear - Look at assigned issues updated in the last 24 hours
|
||||
3. Slack - Check #team-updates and #engineering channels
|
||||
|
||||
Summarize everything in a single report grouped by source.
|
||||
```
|
||||
|
||||
The file uses YAML frontmatter for metadata and Markdown for the instructions.
|
||||
|
||||
### Frontmatter fields
|
||||
|
||||
| Field | Required | Description |
|
||||
|---|---|---|
|
||||
| `name` | Yes | Lowercase, hyphenated identifier (e.g., `morning-status-report`) |
|
||||
| `description` | Yes | When and how the agent should use this skill |
|
||||
| `license` | No | License for the skill |
|
||||
| `compatibility` | No | Environment requirements |
|
||||
| `metadata` | No | Extra fields like `display-name`, `enabled`, `version` |
|
||||
| `allowed-tools` | No | Restrict which tools the skill can use (experimental) |
|
||||
|
||||
### Supporting files
|
||||
|
||||
A skill can include additional directories alongside `SKILL.md`:
|
||||
|
||||
- **`scripts/`** for executable code the agent can run
|
||||
- **`references/`** for detailed documentation loaded on demand
|
||||
- **`assets/`** for templates, images, or data files
|
||||
|
||||
```
|
||||
morning-status-report/
|
||||
├── SKILL.md
|
||||
├── scripts/
|
||||
│ └── format-report.py
|
||||
└── references/
|
||||
└── REFERENCE.md
|
||||
```
|
||||
|
||||
The agent loads the main `SKILL.md` first. Supporting files are only loaded when the instructions reference them, keeping context usage efficient.
|
||||
|
||||
## Where Skills Live
|
||||
|
||||
Skills are stored as folders inside your BrowserOS configuration directory:
|
||||
|
||||
| OS | Path |
|
||||
|---|---|
|
||||
| macOS | `~/.browseros/skills/` |
|
||||
| Windows | `%USERPROFILE%\.browseros\skills\` |
|
||||
| Linux | `~/.browseros/skills/` |
|
||||
|
||||
Each skill gets its own folder named after the skill's `name` field.
|
||||
|
||||
## Tips for Writing Good Skills
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Be specific in descriptions" icon="crosshairs">
|
||||
Include keywords the agent can match against. "When the user asks about PDFs, forms, or document extraction" is better than "Helps with documents."
|
||||
</Card>
|
||||
<Card title="Keep instructions focused" icon="scissors">
|
||||
A skill should do one thing well. Split complex workflows into multiple skills rather than one large one.
|
||||
</Card>
|
||||
<Card title="Include examples" icon="lightbulb">
|
||||
Show the agent what good output looks like. Examples reduce ambiguity and improve results.
|
||||
</Card>
|
||||
<Card title="Use supporting files" icon="folder-tree">
|
||||
Move detailed references to separate files. The agent loads them only when needed, saving context space.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Note>
|
||||
Skills follow the open [Agent Skills specification](https://agentskills.io/specification). Skills you create in BrowserOS work with any agent that supports the standard.
|
||||
</Note>
|
||||
117
docs/features/smart-nudges.mdx
Normal file
@@ -0,0 +1,117 @@
|
||||
---
|
||||
title: "Smart Nudges"
|
||||
description: "BrowserOS suggests app connections and task scheduling at the right moment"
|
||||
---
|
||||
|
||||
Smart Nudges are context-aware suggestions that appear as interactive cards during a conversation. The agent detects opportunities to connect an app or schedule a task, and shows you a card at the right moment. You decide whether to act on it or skip it.
|
||||
|
||||
There are two types of nudges: **App Connection** and **Schedule Suggestion**.
|
||||
|
||||
## App Connection
|
||||
|
||||
When you ask the agent to do something that involves an external app (like sending an email or checking your calendar), it checks whether that app is connected. If it is not, the agent shows a connection card before starting the task.
|
||||
|
||||
<Steps>
|
||||
<Step title="You make a request">
|
||||
For example: "Send Sarah an email with the meeting notes."
|
||||
</Step>
|
||||
<Step title="The agent detects an unconnected app">
|
||||
Gmail is not connected yet, so the agent cannot send emails through the integration.
|
||||
</Step>
|
||||
<Step title="A connection card appears">
|
||||
The card explains why connecting the app would help and gives you two choices: **Connect** or **Do it manually**.
|
||||
</Step>
|
||||
<Step title="You choose">
|
||||
- **Connect**: Opens a sign-in page for the app. Once you authorize, the agent continues with full integration access.
|
||||
- **Do it manually**: The agent skips the integration and uses browser automation instead (navigates to the website directly).
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### What happens after you choose
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Connected" icon="circle-check">
|
||||
The app is added to your connected list. The agent uses the integration for this and all future conversations. You can manage connected apps in [Connect Apps](/features/connect-mcps).
|
||||
</Card>
|
||||
<Card title="Declined" icon="forward">
|
||||
The agent remembers your choice and will not ask about this app again. It uses browser automation to complete the task instead.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Tip>
|
||||
If you declined an app but change your mind later, you can connect it anytime from the [Connect Apps](/features/connect-mcps) settings page.
|
||||
</Tip>
|
||||
|
||||
### Supported apps
|
||||
|
||||
The agent can suggest connections for all 40+ built-in integrations, including Gmail, Google Calendar, Slack, Notion, GitHub, Linear, Jira, Figma, Salesforce, and many more. See [Connect Apps](/features/connect-mcps) for the full list.
|
||||
|
||||
## Schedule Suggestion
|
||||
|
||||
After the agent completes a task that could run on a recurring schedule, it shows a scheduling card. This helps you turn one-time tasks into automated routines without leaving the conversation.
|
||||
|
||||
<Steps>
|
||||
<Step title="The agent completes a task">
|
||||
For example: "Here are the top 5 tech headlines from today."
|
||||
</Step>
|
||||
<Step title="The agent recognizes a schedulable task">
|
||||
News gathering, price monitoring, report building, data tracking, and similar tasks that do not need your real-time input are good candidates.
|
||||
</Step>
|
||||
<Step title="A scheduling card appears">
|
||||
The card suggests a name and schedule. For example: "Run this automatically? 'Morning News Briefing' - daily at 09:00."
|
||||
</Step>
|
||||
<Step title="You choose">
|
||||
- **Schedule this task**: Opens the Scheduled Tasks page with the details pre-filled. Review and confirm to create the task.
|
||||
- **Maybe later**: Dismisses the card. You can always create the scheduled task manually later.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### You can also ask directly
|
||||
|
||||
You do not have to wait for the agent to suggest it. Just tell the agent you want to schedule the task:
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Example prompts" icon="message">
|
||||
- "Schedule this to run every morning"
|
||||
- "Can this run daily at 8am?"
|
||||
- "Automate this task"
|
||||
- "Run this every hour"
|
||||
|
||||
The agent will infer the task name, schedule type, and timing from your conversation and show the scheduling card immediately.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### What gets scheduled
|
||||
|
||||
The scheduling card pre-fills the [Scheduled Tasks](/features/scheduled-tasks) dialog with:
|
||||
|
||||
- **Task name**: A short description based on the conversation
|
||||
- **Prompt**: The original query you asked the agent
|
||||
- **Schedule type**: Daily or hourly, based on what makes sense for the task
|
||||
- **Time**: A suggested time (for daily tasks)
|
||||
|
||||
You can adjust any of these before confirming.
|
||||
|
||||
## When Nudges Appear
|
||||
|
||||
Nudges are designed to appear at the right moment without interrupting your workflow:
|
||||
|
||||
| Nudge | When it appears | How often |
|
||||
|---|---|---|
|
||||
| App Connection | Before the agent starts working, when it detects an unconnected app | Once per app per conversation |
|
||||
| Schedule Suggestion | After the agent finishes a task that could be automated | Once per conversation |
|
||||
|
||||
Nudges do not appear in:
|
||||
- **Scheduled tasks** running in the background
|
||||
- **Chat mode** (read-only, no browser automation)
|
||||
|
||||
## Privacy
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Nothing is sent without your approval" icon="shield-check">
|
||||
The agent only suggests a connection. No data is shared with the app until you explicitly authorize it.
|
||||
</Card>
|
||||
<Card title="Your choices are remembered locally" icon="hard-drive">
|
||||
Declined apps are stored on your device. The agent will not ask about them again unless you reconnect from settings.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -39,7 +39,7 @@ You do not need to write or edit SOUL.md yourself. The assistant handles it. But
|
||||
|
||||
## Viewing Your SOUL.md
|
||||
|
||||
Open **Settings > Agent Soul** to see what your assistant's personality file looks like right now. The page shows the current contents of SOUL.md in a read-only viewer.
|
||||
Open **Agent Soul** from the sidebar to see what your assistant's personality file looks like right now. The page shows the current contents of SOUL.md in a read-only viewer.
|
||||
|
||||
{/* <Frame caption="View your assistant's personality in Settings">
|
||||
<img src="/images/features/soul-settings.png" alt="Agent Soul settings page" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: "MCP Clients (Claude Code)"
|
||||
description: "Control your browser and 40+ apps from Claude Code, Gemini CLI, or any MCP client"
|
||||
title: "MCP Clients (Claude Code, OpenClaw)"
|
||||
description: "Control your browser and 40+ apps from Claude Code, OpenClaw, Gemini CLI, or any MCP client"
|
||||
---
|
||||
|
||||
BrowserOS is the best browser for AI coding agents. It comes with a built-in MCP server that gives your AI agent **full browser control** and **direct access to 40+ external services** — Gmail, Slack, GitHub, Google Calendar, Linear, Notion, and more — all through a single MCP connection.
|
||||
@@ -89,6 +89,20 @@ Wondering how BrowserOS MCP compares to Chrome DevTools MCP or other browser aut
|
||||
# Example: codex mcp add browseros http://127.0.0.1:9239/mcp --transport http
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="OpenClaw">
|
||||
Add BrowserOS to [OpenClaw](https://openclaw.ai/) by adding it to the `mcpServers` section in your `openclaw.json` config file:
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"browseros": {
|
||||
"url": "http://127.0.0.1:9239/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Replace the URL with your BrowserOS MCP URL from settings.
|
||||
</Tab>
|
||||
<Tab title="Claude Desktop">
|
||||
Open your Claude Desktop config file:
|
||||
```
|
||||
@@ -113,37 +127,37 @@ Wondering how BrowserOS MCP compares to Chrome DevTools MCP or other browser aut
|
||||
|
||||
## Example Prompts
|
||||
|
||||
Once connected, try these prompts in Claude Code:
|
||||
<Accordion title="Try these prompts once connected" icon="message">
|
||||
Extract structured data from any page you're logged into — no scraping setup needed.
|
||||
```
|
||||
Open my LinkedIn profile in BrowserOS and extract my work experience as JSON
|
||||
```
|
||||
|
||||
Extract structured data from any page you're logged into — no scraping setup needed.
|
||||
```
|
||||
Open my LinkedIn profile in BrowserOS and extract my work experience as JSON
|
||||
```
|
||||
Test your web app end-to-end without leaving the terminal — Claude navigates, interacts, and reports errors back.
|
||||
```
|
||||
In BrowserOS, go to localhost:3000, click the login button, and check for console errors
|
||||
```
|
||||
|
||||
Test your web app end-to-end without leaving the terminal — Claude navigates, interacts, and reports errors back.
|
||||
```
|
||||
In BrowserOS, go to localhost:3000, click the login button, and check for console errors
|
||||
```
|
||||
Capture visual snapshots of any page for debugging, documentation, or design review.
|
||||
```
|
||||
Take a screenshot of the current page in BrowserOS and save it to screenshots/
|
||||
```
|
||||
|
||||
Capture visual snapshots of any page for debugging, documentation, or design review.
|
||||
```
|
||||
Take a screenshot of the current page in BrowserOS and save it to screenshots/
|
||||
```
|
||||
Search through your real browsing history to find pages you visited earlier.
|
||||
```
|
||||
Search my BrowserOS history for "invoice" and list the recent matches
|
||||
```
|
||||
|
||||
Search through your real browsing history to find pages you visited earlier.
|
||||
```
|
||||
Search my BrowserOS history for "invoice" and list the recent matches
|
||||
```
|
||||
Access your email directly from the agent — read, search, and summarize without switching windows.
|
||||
```
|
||||
Read my latest Gmail messages and summarize them
|
||||
```
|
||||
|
||||
Access your email directly from the agent — read, search, and summarize without switching windows.
|
||||
```
|
||||
Read my latest Gmail messages and summarize them
|
||||
```
|
||||
|
||||
Chain multiple services together in a single prompt — file issues, notify your team, and stay in flow.
|
||||
```
|
||||
Create a Linear issue for the bug I just found and post a summary to Slack
|
||||
```
|
||||
Chain multiple services together in a single prompt — file issues, notify your team, and stay in flow.
|
||||
```
|
||||
Create a Linear issue for the bug I just found and post a summary to Slack
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
---
|
||||
|
||||
|
||||
60
docs/features/vertical-tabs.mdx
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: "Vertical Tabs"
|
||||
description: "Move your tabs to the side for a cleaner, more organized browsing experience"
|
||||
---
|
||||
|
||||
BrowserOS supports vertical tabs — a side panel that lists all your open tabs along the left edge of the browser window. Instead of shrinking tab titles into a cramped horizontal strip, vertical tabs give each tab its own full-width row so you can read titles at a glance, even with dozens of tabs open.
|
||||
|
||||
## Why Vertical Tabs?
|
||||
|
||||
Modern screens are wide, not tall. A horizontal tab bar wastes vertical space you could use for content, and tabs quickly become unreadable as they shrink. Vertical tabs solve both problems:
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Read every tab title" icon="text">
|
||||
Tabs stack vertically with full-width labels, so you always know what is open — no squinting at favicons.
|
||||
</Card>
|
||||
<Card title="Handle many tabs" icon="layer-group">
|
||||
Open 30, 50, or 100 tabs without the strip becoming unusable. The side panel scrolls naturally.
|
||||
</Card>
|
||||
<Card title="Reclaim vertical space" icon="arrows-left-right">
|
||||
The horizontal tab bar disappears, giving web pages more room on widescreen monitors.
|
||||
</Card>
|
||||
<Card title="Stay organized" icon="folder-tree">
|
||||
Combine vertical tabs with tab groups to visually separate work, research, and personal browsing.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Enabling Vertical Tabs
|
||||
|
||||
Toggle vertical tabs on or off from the Customization settings page.
|
||||
|
||||
<Steps>
|
||||
<Step title="Open Settings">
|
||||
Go to `chrome://browseros/settings` in the address bar.
|
||||
</Step>
|
||||
<Step title="Go to Customization">
|
||||
In the left sidebar, select **Customization**.
|
||||
</Step>
|
||||
<Step title="Toggle Use Vertical Tabs">
|
||||
Flip the **Use Vertical Tabs** switch to on. The browser immediately moves your tabs to a side panel.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Frame caption="Enable vertical tabs in Settings > Customization">
|
||||
<img src="/images/features--vertical-tabs-setting.png" alt="Vertical tabs toggle in BrowserOS Customization settings" />
|
||||
</Frame>
|
||||
|
||||
To switch back, return to the same setting and turn the toggle off. Your tabs move back to the horizontal strip instantly.
|
||||
|
||||
## How It Works
|
||||
|
||||
When vertical tabs are enabled, the tab strip relocates from the top of the window to a collapsible side panel on the left. Each tab is displayed as a row showing the page favicon and full title.
|
||||
|
||||
- **Click** a tab row to switch to it.
|
||||
- **Right-click** a tab for the standard context menu (pin, mute, close, move to group).
|
||||
- **Drag** tabs up or down to reorder them, or drag them into and out of tab groups.
|
||||
- The panel can be **collapsed** to show only favicons, freeing up even more horizontal space.
|
||||
|
||||
## Vertical Tabs + Tab Groups
|
||||
|
||||
Vertical tabs pair naturally with [tab groups](/features/workflows). Groups appear as collapsible sections in the side panel, making it easy to keep projects separate and fold away tabs you are not actively using.
|
||||
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 302 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 843 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 892 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 4.5 MiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 4.3 MiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 4.5 MiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 4.8 MiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 4.6 MiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 4.8 MiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 4.5 MiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 6.4 MiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 496 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 525 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 562 KiB |
BIN
docs/images/changelog/0.42.0/soul-memory.png
Normal file
|
After Width: | Height: | Size: 702 KiB |
BIN
docs/images/changelog/0.42.0/vertical-tabs.png
Normal file
|
After Width: | Height: | Size: 360 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 456 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 191 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 604 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 416 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 852 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 4.2 MiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 4.9 MiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 4.0 MiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 3.7 MiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 2.5 MiB |
BIN
docs/images/features--vertical-tabs-setting.png
Normal file
|
After Width: | Height: | Size: 235 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 183 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 226 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 221 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 257 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 188 KiB |
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 102 KiB |
1
docs/images/icons/githubcopilot.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>GithubCopilot</title><path d="M19.245 5.364c1.322 1.36 1.877 3.216 2.11 5.817.622 0 1.2.135 1.592.654l.73.964c.21.278.323.61.323.955v2.62c0 .339-.173.669-.453.868C20.239 19.602 16.157 21.5 12 21.5c-4.6 0-9.205-2.583-11.547-4.258-.28-.2-.452-.53-.453-.868v-2.62c0-.345.113-.679.321-.956l.73-.963c.392-.517.974-.654 1.593-.654l.029-.297c.25-2.446.81-4.213 2.082-5.52 2.461-2.54 5.71-2.851 7.146-2.864h.198c1.436.013 4.685.323 7.146 2.864zm-7.244 4.328c-.284 0-.613.016-.962.05-.123.447-.305.85-.57 1.108-1.05 1.023-2.316 1.18-2.994 1.18-.638 0-1.306-.13-1.851-.464-.516.165-1.012.403-1.044.996a65.882 65.882 0 00-.063 2.884l-.002.48c-.002.563-.005 1.126-.013 1.69.002.326.204.63.51.765 2.482 1.102 4.83 1.657 6.99 1.657 2.156 0 4.504-.555 6.985-1.657a.854.854 0 00.51-.766c.03-1.682.006-3.372-.076-5.053-.031-.596-.528-.83-1.046-.996-.546.333-1.212.464-1.85.464-.677 0-1.942-.157-2.993-1.18-.266-.258-.447-.661-.57-1.108-.32-.032-.64-.049-.96-.05zm-2.525 4.013c.539 0 .976.426.976.95v1.753c0 .525-.437.95-.976.95a.964.964 0 01-.976-.95v-1.752c0-.525.437-.951.976-.951zm5 0c.539 0 .976.426.976.95v1.753c0 .525-.437.95-.976.95a.964.964 0 01-.976-.95v-1.752c0-.525.437-.951.976-.951zM7.635 5.087c-1.05.102-1.935.438-2.385.906-.975 1.037-.765 3.668-.21 4.224.405.394 1.17.657 1.995.657h.09c.649-.013 1.785-.176 2.73-1.11.435-.41.705-1.433.675-2.47-.03-.834-.27-1.52-.63-1.813-.39-.336-1.275-.482-2.265-.394zm6.465.394c-.36.292-.6.98-.63 1.813-.03 1.037.24 2.06.675 2.47.968.957 2.136 1.104 2.776 1.11h.044c.825 0 1.59-.263 1.995-.657.555-.556.765-3.187-.21-4.224-.45-.468-1.335-.804-2.385-.906-.99-.088-1.875.058-2.265.394zM12 7.615c-.24 0-.525.015-.84.044.03.16.045.336.06.526l-.001.159a2.94 2.94 0 01-.014.25c.225-.022.425-.027.612-.028h.366c.187 0 .387.006.612.028-.015-.146-.015-.277-.015-.409.015-.19.03-.365.06-.526a9.29 9.29 0 00-.84-.044z"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
1
docs/images/icons/openai.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>OpenAI</title><path d="M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
1
docs/images/icons/qwen.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Qwen</title><path d="M12.604 1.34c.393.69.784 1.382 1.174 2.075a.18.18 0 00.157.091h5.552c.174 0 .322.11.446.327l1.454 2.57c.19.337.24.478.024.837-.26.43-.513.864-.76 1.3l-.367.658c-.106.196-.223.28-.04.512l2.652 4.637c.172.301.111.494-.043.77-.437.785-.882 1.564-1.335 2.34-.159.272-.352.375-.68.37-.777-.016-1.552-.01-2.327.016a.099.099 0 00-.081.05 575.097 575.097 0 01-2.705 4.74c-.169.293-.38.363-.725.364-.997.003-2.002.004-3.017.002a.537.537 0 01-.465-.271l-1.335-2.323a.09.09 0 00-.083-.049H4.982c-.285.03-.553-.001-.805-.092l-1.603-2.77a.543.543 0 01-.002-.54l1.207-2.12a.198.198 0 000-.197 550.951 550.951 0 01-1.875-3.272l-.79-1.395c-.16-.31-.173-.496.095-.965.465-.813.927-1.625 1.387-2.436.132-.234.304-.334.584-.335a338.3 338.3 0 012.589-.001.124.124 0 00.107-.063l2.806-4.895a.488.488 0 01.422-.246c.524-.001 1.053 0 1.583-.006L11.704 1c.341-.003.724.032.9.34zm-3.432.403a.06.06 0 00-.052.03L6.254 6.788a.157.157 0 01-.135.078H3.253c-.056 0-.07.025-.041.074l5.81 10.156c.025.042.013.062-.034.063l-2.795.015a.218.218 0 00-.2.116l-1.32 2.31c-.044.078-.021.118.068.118l5.716.008c.046 0 .08.02.104.061l1.403 2.454c.046.081.092.082.139 0l5.006-8.76.783-1.382a.055.055 0 01.096 0l1.424 2.53a.122.122 0 00.107.062l2.763-.02a.04.04 0 00.035-.02.041.041 0 000-.04l-2.9-5.086a.108.108 0 010-.113l.293-.507 1.12-1.977c.024-.041.012-.062-.035-.062H9.2c-.059 0-.073-.026-.043-.077l1.434-2.505a.107.107 0 000-.114L9.225 1.774a.06.06 0 00-.053-.031zm6.29 8.02c.046 0 .058.02.034.06l-.832 1.465-2.613 4.585a.056.056 0 01-.05.029.058.058 0 01-.05-.029L8.498 9.841c-.02-.034-.01-.052.028-.054l.216-.012 6.722-.012z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 130 B After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 314 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 270 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 289 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 247 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 566 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 217 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 244 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 342 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 556 KiB |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 490 KiB |
BIN
docs/images/setting-up-chatgpt/accept-screen.png
Normal file
|
After Width: | Height: | Size: 717 KiB |
BIN
docs/images/setting-up-chatgpt/llm-screen.png
Normal file
|
After Width: | Height: | Size: 815 KiB |
BIN
docs/images/setting-up-chatgpt/login-screen.png
Normal file
|
After Width: | Height: | Size: 637 KiB |
BIN
docs/images/setting-up-copilot/authorize-device.png
Normal file
|
After Width: | Height: | Size: 687 KiB |
BIN
docs/images/setting-up-copilot/device-code.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
docs/images/setting-up-copilot/llm-screen.png
Normal file
|
After Width: | Height: | Size: 825 KiB |
BIN
docs/images/setting-up-copilot/select-account.png
Normal file
|
After Width: | Height: | Size: 634 KiB |