.cursor/skills/script-review/SKILL.md
Code review a FileMaker script and its full call tree — all subscripts reached via Perform Script are loaded and analysed together. Evaluates error handling, structure, naming, performance, parameter contracts, and cross-script issues. Use when the developer says "review", "code review", "evaluate", or "assess" a script, or mentions "script ID" in a review context.
npx skillsauth add petrowsky/agentic-fm script-reviewInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Perform a thorough code review of a FileMaker script and every script it calls. The review covers the full call tree — not just the entry-point script in isolation.
CRITICAL: Debugging breakpoints within FileMaker scripts are not a runtime issue. Breakpoints are only active when a developer explicitly invokes the FileMaker debugger. Do not flag them.
Use the script-lookup skill to find the script if not already identified. Read the human-readable version from agent/xml_parsed/scripts_sanitized/.
Before analysing any logic, build the full picture of every script involved. The goal is to minimize tool calls by loading subscripts in parallel batches — one batch per depth level.
Performance target: For a script with N subscripts at depth 1, the call tree should load in 2 tool calls (1 grep + 1 parallel read), not N+1 sequential calls.
Grep the entry script's sanitized text for every Perform Script line at once. Extract all target script names from the results.
grep -i "Perform Script" "agent/xml_parsed/scripts_sanitized/{solution}/{path}.txt"
This returns lines like:
Perform Script [ "Subscript A" ; Parameter: $param ] — extract Subscript APerform Script [ "Subscript B" ] — extract Subscript BPerform Script By Name [ ... ] — flag as unresolvable (calculated name)Take ALL extracted script names and resolve them to file paths in a single grep against the scripts index:
grep -E "Subscript A|Subscript B|Subscript C" "agent/context/{solution}/scripts.index"
This returns pipe-delimited rows (ScriptName|ScriptID|FolderPath) for every match. From each row, derive the sanitized file path:
agent/xml_parsed/scripts_sanitized/{solution}/{FolderPath}*/{ScriptName} - ID {ScriptID}.txtagent/xml_parsed/scripts_sanitized/{solution}/{ScriptName} - ID {ScriptID}.txtSince folder directory names include an ID suffix not in the index, use a glob to resolve the exact path if needed.
Read ALL resolved subscript files in a single message with multiple Read tool calls — one per subscript. This replaces the old sequential "find one, read one, find next, read next" pattern.
For example, if the entry script calls 5 subscripts, issue 5 Read tool calls in a single message. All 5 load in parallel.
After loading depth-1 subscripts, scan ALL of them for further Perform Script references. Collect any new (not yet visited) script names across all depth-1 subscripts, then repeat 2b–2c for the next depth level.
Track visited scripts by name to avoid cycles. Continue until no new references are found.
Each depth level adds at most 2 tool calls (1 batch grep + 1 parallel read), regardless of how many subscripts exist at that level.
Before starting the review, present the resolved call tree so the developer can see the full scope:
## Call tree: [Entry Script Name]
1. Entry Script Name
├── Subscript A
│ └── Subscript A1
├── Subscript B
└── Subscript C
└── Subscript A (already loaded)
Flag these edge cases:
Perform Script By Name references cannot be statically resolved. Flag them so the developer can clarify which scripts may be called.Perform Script references to scripts not found in scripts_sanitized/ may be in a different solution file or deleted. Flag them.Review the entry-point script against these categories:
Set Error Capture [ On ] / Allow User Abort [ Off ] header (especially for server-side scripts)Get ( LastError ) check$errData pattern (see agent/docs/knowledge/error-data-capture.md)agent/docs/knowledge/single-pass-loop.md)agent/docs/CODING_CONVENTIONS.md)agent/docs/knowledge/dry-coding.md)$README or comment)?Exit Script with a documented result format?Review each subscript using the same categories as Step 3. Additionally, look for issues that only emerge when scripts are considered together:
Perform Script parameter expression against the subscript's Get ( ScriptParameter ) parsing.Get ( ScriptResult ) after the call? Does the callee actually Exit Script with a result?Go to Layout [ original layout ] before exiting?Exit Script result?$$) that the caller depends on? (This is a fragile coupling — flag it)Organise the review as a single report covering the full call tree. Group by severity:
## Code Review: [Entry Script Name]
### Call tree
(from Step 2d)
### Critical
Issues that will cause failures or data corruption:
- [Script Name, line N] — Set Field after Perform Find with no error 401 check
- [Subscript A, line N] — Commits inside caller's transaction
### Important
Issues that affect reliability or maintainability:
- [Script Name, line N] — Error data captured in separate steps (use single-expression pattern)
- [Script Name → Subscript B] — Caller doesn't check Get(ScriptResult)
### Suggestions
Improvements that are not urgent:
- [Script Name, line N] — Magic number "30" should be a variable ($dayThreshold)
- [Subscript A] — Missing $README documentation block
### Positive
Things the script does well (acknowledge good patterns):
- Clean parameter validation with early exit
- Consistent variable naming
Line number references must always refer to the human-readable (scripts_sanitized) version, never the XML.
There are two distinct XML formats in this project. They are not interchangeable:
| Format | Location | Usable as output? |
|---|---|---|
| FileMaker "Save As XML" export | agent/xml_parsed/scripts/ | No — read-only reference only |
| FileMaker clipboard / fmxmlsnippet | agent/scripts/ or agent/sandbox/ | Yes — this is the output format |
When applying review findings as code changes, follow the refactoring workflow:
agent/sandbox/ first. If none exists, convert via python3 agent/scripts/fm_xml_to_snippet.py.python3 agent/scripts/validate_snippet.py agent/sandbox/{script_name}development
Generate a complete web application inside a FileMaker Web Viewer — self-contained HTML/CSS/JS styled with the FM theme, plus companion FM bridge scripts for bidirectional data flow. Use when the developer says "web viewer", "webviewer app", "HTML in FileMaker", "build web viewer", or when the layout-design skill delegates to the web-first output path. Recommended for modern, responsive UI, complex interactions (drag-and-drop, charts, rich text), or solutions considering future migration off FileMaker.
development
Trace references to a FileMaker object across the entire solution. Supports usage reports ("where is this field used?"), impact analysis ("what breaks if I rename this?"), and dead object scans ("show unused fields/scripts"). Use when the developer says "trace", "find references", "where is X used", "impact of renaming", "unused fields/scripts", "dead code", "what references X", or "is X used anywhere".
development
Analyze a FileMaker solution and produce a structured profile covering data model, business logic, UI layer, integrations, and health metrics. Uses on-disk pre-processing to handle solutions of any size without sending raw XML through the agent. Use when the developer says "analyze solution", "solution overview", "solution analysis", "solution profile", "solution spec", "what does this solution do", "solution summary", or wants a high-level understanding of an entire FileMaker solution.
development
Interactive setup wizard for agentic-fm. Detects what's already configured, walks the user through each remaining step, and verifies completion before proceeding. Use when the developer says "help me set up", "setup", "get started", "onboard", "first time setup", "install agentic-fm", "configure agentic-fm", or is clearly new to the project and needs guidance.