302302 font-style : italic;
303303 }
304304
305+ # cli .runtime-tabs {
306+ background : var (--surface-inset );
307+ border-radius : 0.5rem ;
308+ overflow : hidden;
309+ margin-top : 1.5rem ;
310+ }
311+
312+ # cli .runtime-tabs .tab-buttons {
313+ display : flex;
314+ border-bottom : 1px solid var (--border );
315+ }
316+
317+ # cli .runtime-tabs .tab-button {
318+ flex : 1 ;
319+ padding : 0.75rem 1.5rem ;
320+ background : transparent;
321+ border : none;
322+ color : var (--text-secondary );
323+ font-family : var (--font-sans );
324+ font-size : 1rem ;
325+ cursor : pointer;
326+ transition : all 0.2s ease;
327+ border-bottom : 2px solid transparent;
328+ }
329+
330+ # cli .runtime-tabs .tab-button : hover {
331+ color : var (--text );
332+ background : var (--surface-inset-deep );
333+ }
334+
335+ # cli .runtime-tabs .tab-button .active {
336+ color : var (--text );
337+ border-bottom-color : var (--accent );
338+ background : var (--surface );
339+ }
340+
341+ # cli .runtime-tabs .tab-pane {
342+ display : none;
343+ padding : 1.5rem ;
344+ }
345+
346+ # cli .runtime-tabs .tab-pane .active {
347+ display : block;
348+ }
349+
350+ # cli .runtime-tabs .tab-pane p {
351+ margin : 0.75rem 0 ;
352+ }
353+
305354 @media (max-width : 768px ) {
306- # clients .tab-buttons {
355+ # clients .tab-buttons ,
356+ # cli .runtime-tabs .tab-buttons {
307357 flex-direction : column;
308358 }
309359
310- # clients .tab-button {
360+ # clients .tab-button ,
361+ # cli .runtime-tabs .tab-button {
311362 border-bottom : 1px solid var (--border );
312363 border-right : none;
313364 }
314365
315- # clients .tab-button .active {
366+ # clients .tab-button .active ,
367+ # cli .runtime-tabs .tab-button .active {
316368 border-bottom-color : var (--border );
317369 border-right : 2px solid var (--accent );
318370 }
342394 overflow-wrap : break-word;
343395 }
344396
397+ pre {
398+ background : var (--surface-inset );
399+ padding : 1.25rem ;
400+ border-radius : 0.5rem ;
401+ overflow-x : auto;
402+ }
403+
404+ pre code {
405+ background : none;
406+ padding : 0 ;
407+ word-break : normal;
408+ overflow-wrap : normal;
409+ }
410+
345411 main header {
346412 margin-bottom : 2rem ;
347413 }
514580 } ) ;
515581 } ) ;
516582
517- // Client tabs (Cursor, VSCode, etc.)
518- const clientTabButtons = document . querySelectorAll ( '.client-tabs .tab-button' ) ;
519- const clientTabPanes = document . querySelectorAll ( '.client-tabs .tab-pane' ) ;
520- clientTabButtons . forEach ( button => {
521- button . addEventListener ( 'click' , function ( ) {
522- const targetTab = this . getAttribute ( 'data-tab' ) ;
523-
524- // Remove active class from all client buttons and panes
525- clientTabButtons . forEach ( btn => btn . classList . remove ( 'active' ) ) ;
526- clientTabPanes . forEach ( pane => pane . classList . remove ( 'active' ) ) ;
527-
528- // Add active class to clicked button and corresponding pane
529- this . classList . add ( 'active' ) ;
530- document . getElementById ( targetTab + '-tab' ) . classList . add ( 'active' ) ;
583+ document . querySelectorAll ( '.client-tabs, .runtime-tabs' ) . forEach ( tabGroup => {
584+ const buttons = tabGroup . querySelectorAll ( '.tab-button' ) ;
585+ const panes = tabGroup . querySelectorAll ( '.tab-pane' ) ;
586+ buttons . forEach ( button => {
587+ button . addEventListener ( 'click' , function ( ) {
588+ const targetTab = this . getAttribute ( 'data-tab' ) ;
589+ buttons . forEach ( btn => btn . classList . remove ( 'active' ) ) ;
590+ panes . forEach ( pane => pane . classList . remove ( 'active' ) ) ;
591+ this . classList . add ( 'active' ) ;
592+ document . getElementById ( targetTab + '-tab' ) . classList . add ( 'active' ) ;
593+ } ) ;
531594 } ) ;
532595 } ) ;
533596 } ) ;
571634 < p >
572635 This service translates Apple Developer documentation, Human Interface Guidelines, WWDC sessions, and external Swift-DocC sites into AI-friendly Markdown.
573636 </ p >
637+ < p >
638+ Access it in your < a href ="#http "> browser</ a > , over < a href ="#mcp "> MCP</ a > , from the < a href ="#cli "> command line</ a > , or with an unofficial < a href ="https://chromewebstore.google.com/detail/donffakeimppgoehccpfhlchmbfdmfpj " rel ="noopener noreferrer "> Chrome extension</ a > .
639+ </ p >
574640 </ header >
575641
576642 < section id ="http ">
@@ -610,25 +676,6 @@ <h2>Examples</h2>
610676 </ section >
611677
612678
613- < section id ="bot ">
614- < header >
615- < h2 > Bot & Crawling Policy</ h2 >
616- < p >
617- Fetches are made with the user agent
618- < code class ="no-wrap "> sosumi-ai/1.0 (+https://sosumi.ai/#bot)</ code > .
619- </ p >
620- < p >
621- For external Swift-DocC hosts, sosumi honors
622- < code class ="no-wrap "> robots.txt</ code > rules and opt-out response directives such as
623- < code class ="no-wrap "> X-Robots-Tag: noai</ code > .
624- </ p >
625- < p >
626- Questions or issues: < a href ="mailto:info@sosumi.ai "> info@sosumi.ai</ a >
627- </ p >
628- </ header >
629- </ section >
630-
631-
632679 < section id ="mcp ">
633680 < header >
634681 < h2 > MCP Usage</ h2 >
@@ -807,21 +854,19 @@ <h3>Available Tools</h3>
807854 </ li >
808855 </ ul >
809856 </ div >
810- </ section >
811-
812857
813- < div class ="troubleshooting ">
814- < h3 > Troubleshooting</ h3 >
815- < p >
816- If you're experiencing connection timeouts or network issues with the MCP server,
817- you may need to configure a proxy.
818- This is particularly common in corporate environments
819- or regions with restricted internet access.
820- </ p >
821- < p >
822- Configure your MCP client to use a proxy by adding environment variables:
823- </ p >
824- < pre > < code class ="mcp-config "> < span class ="dimmed "> < span class ="punctuation "> {</ span > </ span >
858+ < div class ="troubleshooting ">
859+ < h3 > Troubleshooting</ h3 >
860+ < p >
861+ If you're experiencing connection timeouts or network issues with the MCP server,
862+ you may need to configure a proxy.
863+ This is particularly common in corporate environments
864+ or regions with restricted internet access.
865+ </ p >
866+ < p >
867+ Configure your MCP client to use a proxy by adding environment variables:
868+ </ p >
869+ < pre > < code class ="mcp-config "> < span class ="dimmed "> < span class ="punctuation "> {</ span > </ span >
825870< span class ="dimmed "> < span class ="key "> "mcpServers"</ span > < span class ="punctuation "> :</ span > < span class ="punctuation "> {</ span > </ span >
826871< span class ="sosumi-entry "> < span class ="key "> "sosumi"</ span > < span class ="punctuation "> :</ span > < span class ="punctuation "> {</ span >
827872 < span class ="key "> "command"</ span > < span class ="punctuation "> :</ span > < span class ="string "> "npx"</ span > < span class ="punctuation "> ,</ span >
@@ -836,12 +881,80 @@ <h3>Troubleshooting</h3>
836881 < span class ="punctuation "> }</ span >
837882 < span class ="punctuation "> }</ span > </ span > < span class ="dimmed "> < span class ="punctuation "> }</ span > </ span >
838883< span class ="dimmed "> < span class ="punctuation "> }</ span > </ span > </ code > </ pre >
884+ < p >
885+ Replace < code > proxy.example.com:8080</ code > with your actual proxy server details.
886+ For authenticated proxies, use the format:
887+ < code > http://username:password@proxy.example.com:8080</ code >
888+ </ p >
889+ </ div >
890+ </ section >
891+
892+
893+ < section id ="cli ">
894+ < header >
895+ < h2 > CLI Usage</ h2 >
896+ < p >
897+ Sosumi also provides a CLI that complements MCP.
898+ </ p >
899+ </ header >
900+
901+ < div class ="runtime-tabs ">
902+ < div class ="tab-buttons ">
903+ < button class ="tab-button active " data-tab ="rt-node "> Node.js</ button >
904+ < button class ="tab-button " data-tab ="rt-bun "> Bun</ button >
905+ < button class ="tab-button " data-tab ="rt-deno "> Deno</ button >
906+ </ div >
907+
908+ < div class ="tab-pane active " id ="rt-node-tab ">
909+ < p > Run directly with < a href ="https://docs.npmjs.com/cli/commands/npx " rel ="noopener noreferrer "> < code > npx</ code > </ a >
910+ (included with < a href ="https://nodejs.org/ " rel ="noopener noreferrer "> Node.js</ a > ):</ p >
911+ < pre > < code > npx @nshipster/sosumi fetch https://developer.apple.com/documentation/swift/array</ code > </ pre >
912+ < p > If you use it regularly, install it once:</ p >
913+ < pre > < code > npm i -g @nshipster/sosumi</ code > </ pre >
914+ </ div >
915+
916+ < div class ="tab-pane " id ="rt-bun-tab ">
917+ < p > Run directly with < a href ="https://bun.sh/docs/cli/bunx " rel ="noopener noreferrer "> < code > bunx</ code > </ a >
918+ (included with < a href ="https://bun.sh/ " rel ="noopener noreferrer "> Bun</ a > ):</ p >
919+ < pre > < code > bunx @nshipster/sosumi fetch https://developer.apple.com/documentation/swift/array</ code > </ pre >
920+ < p > If you use it regularly, install it once:</ p >
921+ < pre > < code > bun i -g @nshipster/sosumi</ code > </ pre >
922+ </ div >
923+
924+ < div class ="tab-pane " id ="rt-deno-tab ">
925+ < p > Run directly with < a href ="https://docs.deno.com/runtime/reference/cli/run/ " rel ="noopener noreferrer "> < code > deno run</ code > </ a > :</ p >
926+ < pre > < code > deno run -A npm:@nshipster/sosumi fetch https://developer.apple.com/documentation/swift/array</ code > </ pre >
927+ < p > If you use it regularly, install it once:</ p >
928+ < pre > < code > deno install -g -A npm:@nshipster/sosumi</ code > </ pre >
929+ </ div >
930+ </ div >
931+
932+ < h3 > Fetching Documentation</ h3 >
839933 < p >
840- Replace < code > proxy.example.com:8080</ code > with your actual proxy server details.
841- For authenticated proxies, use the format:
842- < code > http://username:password@proxy.example.com:8080</ code >
934+ Fetch any content type supported by the MCP tools —
935+ API docs, Human Interface Guidelines, WWDC sessions, and external Swift-DocC pages:
843936 </ p >
844- </ div >
937+ < pre > < code > sosumi fetch /documentation/swift/array
938+ sosumi fetch /design/human-interface-guidelines/color
939+ sosumi fetch /videos/play/wwdc2021/10133
940+ sosumi fetch https://apple.github.io/swift-argument-parser/documentation/argumentparser</ code > </ pre >
941+
942+ < h3 > Searching</ h3 >
943+ < p > Search Apple Developer documentation:</ p >
944+ < pre > < code > sosumi search "SwiftData"</ code > </ pre >
945+
946+ < h3 > JSON Output</ h3 >
947+ < p >
948+ By default, output is plain text / Markdown.
949+ Add < code > --json</ code > for scripts:
950+ </ p >
951+ < pre > < code > sosumi fetch /documentation/swift/array --json
952+ sosumi search "SwiftData" --json</ code > </ pre >
953+
954+ < h3 > Local Server</ h3 >
955+ < p > Run a local instance of the server from the published package:</ p >
956+ < pre > < code > sosumi serve
957+ sosumi serve --port 8787</ code > </ pre >
845958 </ section >
846959 </ main >
847960
@@ -876,6 +989,13 @@ <h3>Troubleshooting</h3>
876989 You are solely responsible for how you access and use Apple's content through this tool.
877990 Do not use this service to circumvent technical measures or for redistribution.
878991 </ p >
992+ < p id ="bot ">
993+ Fetches are made with the user agent
994+ < code class ="no-wrap "> sosumi-ai/1.0 (+https://sosumi.ai/#bot)</ code > .
995+ For external Swift-DocC hosts, sosumi honors
996+ < code class ="no-wrap "> robots.txt</ code > rules and opt-out response directives such as
997+ < code class ="no-wrap "> X-Robots-Tag: noai</ code > .
998+ </ p >
879999 < p >
8801000 < strong > Contact:</ strong > < a href ="mailto:info@sosumi.ai "> info@sosumi.ai</ a >
8811001 </ p >
0 commit comments