diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index decb11d..12abd6e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,9 @@ jobs: - name: Install dependencies run: cd frontend && npm ci + - name: Lint & format check + run: cd frontend && npm run lint + - name: Run tests run: cd frontend && npm test diff --git a/frontend/.prettierignore b/frontend/.prettierignore new file mode 100644 index 0000000..1eae0cf --- /dev/null +++ b/frontend/.prettierignore @@ -0,0 +1,2 @@ +dist/ +node_modules/ diff --git a/frontend/.prettierrc b/frontend/.prettierrc new file mode 100644 index 0000000..05dafbf --- /dev/null +++ b/frontend/.prettierrc @@ -0,0 +1,11 @@ +{ + "plugins": ["prettier-plugin-svelte"], + "overrides": [ + { + "files": "*.svelte", + "options": { + "parser": "svelte" + } + } + ] +} diff --git a/frontend/eslint.config.js b/frontend/eslint.config.js new file mode 100644 index 0000000..7db6916 --- /dev/null +++ b/frontend/eslint.config.js @@ -0,0 +1,30 @@ +import js from "@eslint/js"; +import ts from "typescript-eslint"; +import svelte from "eslint-plugin-svelte"; +import prettier from "eslint-config-prettier"; + +export default ts.config( + { ignores: ["dist/", "node_modules/"] }, + + js.configs.recommended, + ...ts.configs.recommended, + ...svelte.configs["flat/recommended"], + + { + files: ["**/*.svelte"], + languageOptions: { + parserOptions: { + parser: ts.parser, + }, + }, + rules: { + // TypeScript handles undefined-variable checking; no-undef doesn't + // understand TS globals (DOM types, setTimeout, etc.) + "no-undef": "off", + }, + }, + + // Disable rules that conflict with Prettier (must be last) + prettier, + ...svelte.configs["flat/prettier"], +); diff --git a/frontend/index.html b/frontend/index.html index a35f54e..cd8b3c5 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -4,8 +4,14 @@
Select a tool from the sidebar to verify its schema and execute it.
++ Select a tool from the sidebar to verify its schema and + execute it. +
{JSON.stringify(block, null, 2)}
+ class="overflow-x-auto whitespace-pre-wrap break-words text-xs font-mono text-muted-foreground">{JSON.stringify(
+ block,
+ null,
+ 2,
+ )}
This tool takes no parameters.
{JSON.stringify(entry.input_params, null, 2)}
+ {JSON.stringify(
+ entry.input_params,
+ null,
+ 2,
+ )}
{entry.error_message}
+ {entry.error_message}
{JSON.stringify(entry.output, null, 2)}
+ {JSON.stringify(
+ entry.output,
+ null,
+ 2,
+ )}
- Results will appear here after execution -
+Results will appear here after execution
Press {isMac ? "\u2318" : "Ctrl"}+Enter to execute
diff --git a/frontend/src/components/ToolList.svelte b/frontend/src/components/ToolList.svelte index b9393ea..2e0f051 100644 --- a/frontend/src/components/ToolList.svelte +++ b/frontend/src/components/ToolList.svelte @@ -71,19 +71,25 @@{tools.length === 0 ? "No tools available" : "No matching tools"} @@ -116,7 +124,9 @@
This tool takes no parameters.
This tool takes no parameters.
'+(r?i:Et(i,!0))+`
-`:""+(r?i:Et(i,!0))+`
+`+o.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=l.text):r.push(o);continue}if(e){const l="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(l);break}else throw new Error(l)}}return this.state.top=!0,r}inline(e,r=[]){return this.inlineQueue.push({src:e,tokens:r}),r}inlineTokens(e,r=[]){var o,u,l;let n=e,i=null;if(this.tokens.links){const f=Object.keys(this.tokens.links);if(f.length>0)for(;(i=this.tokenizer.rules.inline.reflinkSearch.exec(n))!=null;)f.includes(i[0].slice(i[0].lastIndexOf("[")+1,-1))&&(n=n.slice(0,i.index)+"["+"a".repeat(i[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(i=this.tokenizer.rules.inline.anyPunctuation.exec(n))!=null;)n=n.slice(0,i.index)+"++"+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);for(;(i=this.tokenizer.rules.inline.blockSkip.exec(n))!=null;)n=n.slice(0,i.index)+"["+"a".repeat(i[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);let a=!1,s="";for(;e;){a||(s=""),a=!1;let f;if((u=(o=this.options.extensions)==null?void 0:o.inline)!=null&&u.some(d=>(f=d.call({lexer:this},e,r))?(e=e.substring(f.raw.length),r.push(f),!0):!1))continue;if(f=this.tokenizer.escape(e)){e=e.substring(f.raw.length),r.push(f);continue}if(f=this.tokenizer.tag(e)){e=e.substring(f.raw.length),r.push(f);continue}if(f=this.tokenizer.link(e)){e=e.substring(f.raw.length),r.push(f);continue}if(f=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(f.raw.length);const d=r.at(-1);f.type==="text"&&(d==null?void 0:d.type)==="text"?(d.raw+=f.raw,d.text+=f.text):r.push(f);continue}if(f=this.tokenizer.emStrong(e,n,s)){e=e.substring(f.raw.length),r.push(f);continue}if(f=this.tokenizer.codespan(e)){e=e.substring(f.raw.length),r.push(f);continue}if(f=this.tokenizer.br(e)){e=e.substring(f.raw.length),r.push(f);continue}if(f=this.tokenizer.del(e)){e=e.substring(f.raw.length),r.push(f);continue}if(f=this.tokenizer.autolink(e)){e=e.substring(f.raw.length),r.push(f);continue}if(!this.state.inLink&&(f=this.tokenizer.url(e))){e=e.substring(f.raw.length),r.push(f);continue}let p=e;if((l=this.options.extensions)!=null&&l.startInline){let d=1/0;const w=e.slice(1);let m;this.options.extensions.startInline.forEach(_=>{m=_.call({lexer:this},w),typeof m=="number"&&m>=0&&(d=Math.min(d,m))}),d<1/0&&d>=0&&(p=e.substring(0,d+1))}if(f=this.tokenizer.inlineText(p)){e=e.substring(f.raw.length),f.raw.slice(-1)!=="_"&&(s=f.raw.slice(-1)),a=!0;const d=r.at(-1);(d==null?void 0:d.type)==="text"?(d.raw+=f.raw,d.text+=f.text):r.push(f);continue}if(e){const d="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(d);break}else throw new Error(d)}}return r}},Mn=class{constructor(t){fe(this,"options");fe(this,"parser");this.options=t||$r}space(t){return""}code({text:t,lang:e,escaped:r}){var a;const n=(a=(e||"").match(Je.notSpaceStart))==null?void 0:a[0],i=t.replace(Je.endingNewline,"")+`
+`;return n?''+(r?i:Tt(i,!0))+`
+`:""+(r?i:Tt(i,!0))+`
`}blockquote({tokens:t}){return`${this.parser.parse(t)}`}html({text:t}){return t}heading({tokens:t,depth:e}){return`
${this.parser.parseInline(t)}
`}table(t){let e="",r="";for(let i=0;i