Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .smithery/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
This test is trying to use the default command executor instead of a mock.
Fix: Pass createMockExecutor() as the commandExecutor parameter in your test.
Example: await plugin.handler(args, createMockExecutor({success: true}), mockFileSystem)
See docs/TESTING.md for proper testing patterns.`);return mJe}function Ir(){if(process.env.VITEST==="true")throw new Error(`\u{1F6A8} REAL FILESYSTEM EXECUTOR DETECTED IN TEST! \u{1F6A8}
See docs/dev/TESTING.md for proper testing patterns.`);return mJe}function Ir(){if(process.env.VITEST==="true")throw new Error(`\u{1F6A8} REAL FILESYSTEM EXECUTOR DETECTED IN TEST! \u{1F6A8}
This test is trying to use the default filesystem executor instead of a mock.
Fix: Pass createMockFileSystemExecutor() as the fileSystemExecutor parameter in your test.
Example: await plugin.handler(args, mockCmd, createMockFileSystemExecutor())
See docs/TESTING.md for proper testing patterns.`);return hJe}var hre,gre,_re,hJe,hs=O(()=>{"use strict";hre=require("child_process"),gre=require("fs"),_re=require("os");Go();hJe={async mkdir(t,e){await(await import("fs/promises")).mkdir(t,e)},async readFile(t,e="utf8"){return await(await import("fs/promises")).readFile(t,e)},async writeFile(t,e,r="utf8"){await(await import("fs/promises")).writeFile(t,e,r)},async cp(t,e,r){await(await import("fs/promises")).cp(t,e,r)},async readdir(t,e){return await(await import("fs/promises")).readdir(t,e)},async rm(t,e){await(await import("fs/promises")).rm(t,e)},existsSync(t){return(0,gre.existsSync)(t)},async stat(t){return await(await import("fs/promises")).stat(t)},async mkdtemp(t){return await(await import("fs/promises")).mkdtemp(t)},tmpdir(){return(0,_re.tmpdir)()}}});var ze=O(()=>{"use strict";hs()});function Lt(t){return{type:"text",text:t}}function g2(t,e){return{type:"image",data:t,mimeType:e}}var Dn=O(()=>{"use strict"});function Sre(){return gJe}function MI(){let t=process.env.XCODEBUILDMCP_DISABLE_SESSION_DEFAULTS;if(!t)return!1;let e=t.trim().toLowerCase();return["1","true","yes","on"].includes(e)}function Jh(t){let e={};for(let[r,n]of Object.entries(t??{})){if(n==null)continue;let o=r.startsWith("TEST_RUNNER_")?r:`TEST_RUNNER_${r}`;e[o]=n}return e}var vre,_2,gJe,Xh=O(()=>{"use strict";vre=require("child_process");Go();_2=class{isRunningUnderClaudeCode(){if(process.env.VITEST==="true")return!1;if(process.env.CLAUDECODE==="1"||process.env.CLAUDE_CODE_ENTRYPOINT==="cli")return!0;try{let e=process.ppid;if(e&&(0,vre.execSync)(`ps -o command= -p ${e}`,{encoding:"utf8",timeout:1e3}).trim().includes("claude"))return!0}catch(e){A("debug",`Failed to detect parent process: ${e}`)}return!1}},gJe=new _2});function le(t,e=!1){return{content:[{type:"text",text:t}],isError:e}}function DI(t,e){return(e?e.existsSync(t):yre.existsSync(t))?{isValid:!0}:{isValid:!1,errorResponse:le(`File not found: '${t}'. Please check the path and try again.`,!0)}}function Sp(t){if(!Sre().isRunningUnderClaudeCode()||!t.content||t.content.length<=1)return t;let r=[];if(t.content.forEach((o,i)=>{o.type==="text"&&(i>0&&r.length>0&&r.push(`
See docs/dev/TESTING.md for proper testing patterns.`);return hJe}var hre,gre,_re,hJe,hs=O(()=>{"use strict";hre=require("child_process"),gre=require("fs"),_re=require("os");Go();hJe={async mkdir(t,e){await(await import("fs/promises")).mkdir(t,e)},async readFile(t,e="utf8"){return await(await import("fs/promises")).readFile(t,e)},async writeFile(t,e,r="utf8"){await(await import("fs/promises")).writeFile(t,e,r)},async cp(t,e,r){await(await import("fs/promises")).cp(t,e,r)},async readdir(t,e){return await(await import("fs/promises")).readdir(t,e)},async rm(t,e){await(await import("fs/promises")).rm(t,e)},existsSync(t){return(0,gre.existsSync)(t)},async stat(t){return await(await import("fs/promises")).stat(t)},async mkdtemp(t){return await(await import("fs/promises")).mkdtemp(t)},tmpdir(){return(0,_re.tmpdir)()}}});var ze=O(()=>{"use strict";hs()});function Lt(t){return{type:"text",text:t}}function g2(t,e){return{type:"image",data:t,mimeType:e}}var Dn=O(()=>{"use strict"});function Sre(){return gJe}function MI(){let t=process.env.XCODEBUILDMCP_DISABLE_SESSION_DEFAULTS;if(!t)return!1;let e=t.trim().toLowerCase();return["1","true","yes","on"].includes(e)}function Jh(t){let e={};for(let[r,n]of Object.entries(t??{})){if(n==null)continue;let o=r.startsWith("TEST_RUNNER_")?r:`TEST_RUNNER_${r}`;e[o]=n}return e}var vre,_2,gJe,Xh=O(()=>{"use strict";vre=require("child_process");Go();_2=class{isRunningUnderClaudeCode(){if(process.env.VITEST==="true")return!1;if(process.env.CLAUDECODE==="1"||process.env.CLAUDE_CODE_ENTRYPOINT==="cli")return!0;try{let e=process.ppid;if(e&&(0,vre.execSync)(`ps -o command= -p ${e}`,{encoding:"utf8",timeout:1e3}).trim().includes("claude"))return!0}catch(e){A("debug",`Failed to detect parent process: ${e}`)}return!1}},gJe=new _2});function le(t,e=!1){return{content:[{type:"text",text:t}],isError:e}}function DI(t,e){return(e?e.existsSync(t):yre.existsSync(t))?{isValid:!0}:{isValid:!1,errorResponse:le(`File not found: '${t}'. Please check the path and try again.`,!0)}}function Sp(t){if(!Sre().isRunningUnderClaudeCode()||!t.content||t.content.length<=1)return t;let r=[];if(t.content.forEach((o,i)=>{o.type==="text"&&(i>0&&r.length>0&&r.push(`
---
`),r.push(o.text))}),r.length===0)return t;let n=r.join("");return{...t,content:[{type:"text",text:n}]}}var yre,Qh=O(()=>{"use strict";yre=W(require("fs"),1);Go();Dn();Xh()});function ge(t,e){let r=e?`
Details: ${e}`:"";return{content:[{type:"text",text:`Error: ${t}${r}`}],isError:!0}}var eg,Ka,at,v2,gt,sr,yp=O(()=>{"use strict";eg=class t extends Error{constructor(e){super(e),this.name="XcodeBuildMCPError",Object.setPrototypeOf(this,t.prototype)}},Ka=class t extends eg{constructor(r,n){super(r);this.paramName=n;this.name="ValidationError",Object.setPrototypeOf(this,t.prototype)}},at=class t extends eg{constructor(r,n){super(r);this.originalError=n;this.name="SystemError",Object.setPrototypeOf(this,t.prototype)}},v2=class t extends eg{constructor(e){super(e),this.name="ConfigurationError",Object.setPrototypeOf(this,t.prototype)}},gt=class t extends eg{constructor(r,n,o,i){super(r);this.command=n;this.axeOutput=o;this.simulatorId=i;this.name="AxeError",Object.setPrototypeOf(this,t.prototype)}};sr=class t extends v2{constructor(r,n){super(r);this.details=n;this.name="DependencyError",Object.setPrototypeOf(this,t.prototype)}}});var hr=O(()=>{"use strict";Qh();yp()});var S2,gs,tg=O(()=>{"use strict";Go();S2=class{defaults={};setDefaults(e){this.defaults={...this.defaults,...e},A("info",`[Session] Defaults updated: ${Object.keys(e).join(", ")}`)}clear(e){if(e==null){this.defaults={},A("info","[Session] All defaults cleared");return}if(e.length===0){A("info","[Session] No keys provided to clear; no changes made");return}for(let r of e)delete this.defaults[r];A("info",`[Session] Defaults cleared: ${e.join(", ")}`)}get(e){return this.defaults[e]}getAll(){return{...this.defaults}}},gs=new S2});function Ht(t,e,r){return async n=>{try{let o=t.parse(n);return await e(o,r())}catch(o){if(o instanceof DP){let i=`Invalid parameters:
Expand Down
12 changes: 6 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ npx reloaderoo proxy --log-level debug -- node build/index.js
- ✅ **8 Inspect Commands**: Complete MCP protocol testing capabilities
- ✅ **Universal Compatibility**: Works on any system via npx

For complete documentation, examples, and troubleshooting, see @docs/RELOADEROO.md
For complete documentation, examples, and troubleshooting, see @docs/dev/RELOADEROO.md

## Architecture Overview

Expand All @@ -116,13 +116,13 @@ XcodeBuildMCP uses the concept of configuration by convention for MCP exposing a

Tools are the core of the MCP server and are the primary way to interact with the server. They are organized into directories by their functionality and are automatically loaded and exposed to MCP clients.

For more information see @docs/PLUGIN_DEVELOPMENT.md
For more information see @docs/dev/PLUGIN_DEVELOPMENT.md

#### Resources

Resources are the secondary way to interact with the server. They are used to provide data to tools and are organized into directories by their functionality and are automatically loaded and exposed to MCP clients.

For more information see @docs/PLUGIN_DEVELOPMENT.md
For more information see @docs/dev/PLUGIN_DEVELOPMENT.md

### Tool Registration

Expand All @@ -141,7 +141,7 @@ XcodeBuildMCP loads tools at startup. To limit the toolset, set `XCODEBUILDMCP_E
5. **Shared Utilities**: Command execution, build management, validation
6. **Types**: Shared interfaces and Zod schemas

For more information see @docs/ARCHITECTURE.md
For more information see @docs/dev/ARCHITECTURE.md

## Testing

Expand All @@ -155,7 +155,7 @@ The project enforces a strict **Dependency Injection (DI)** testing philosophy.

This approach ensures that tests are robust, easy to maintain, and verify the actual integration between components without being tightly coupled to implementation details.

For complete guidelines, refer to @docs/TESTING.md.
For complete guidelines, refer to @docs/dev/TESTING.md.

## TypeScript Import Standards

Expand Down Expand Up @@ -189,7 +189,7 @@ This ensures all new code follows the `.ts` import pattern and maintains compati

Follow standardized development workflow with feature branches, structured pull requests, and linear commit history. **Never push to main directly or force push without permission.**

For complete guidelines, refer to @docs/RELEASE_PROCESS.md
For complete guidelines, refer to @docs/dev/RELEASE_PROCESS.md

## Useful external resources

Expand Down
Loading
Loading