.cursor/skills/script-refactor/SKILL.md
Analyse an existing FileMaker script and produce an improved version — better error handling, cleaner variable naming, consolidation of repeated logic — while preserving observable behaviour. At Tier 1 the refactored script is placed on the clipboard for manual paste. At Tier 3 the agent can autonomously deploy the replacement into Script Workspace. Triggers on phrases like "refactor", "improve this script", "clean up script", "modernise script", or "optimize script".
npx skillsauth add petrowsky/agentic-fm script-refactorInstall 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.
Analyse an existing script, identify improvements, and produce a refactored version as fmxmlsnippet — preserving observable behaviour while improving structure, error handling, and conventions.
Read agent/config/automation.json and check project_tier (preferred) or default_tier:
If the developer has not already identified the script, use the script-lookup skill to find it.
Once identified, read the human-readable version from agent/xml_parsed/scripts_sanitized/ to understand the current logic. Also check if an fmxmlsnippet version already exists in agent/sandbox/.
If neither exists, convert the SaXML version to fmxmlsnippet:
python3 agent/scripts/fm_xml_to_snippet.py "agent/xml_parsed/scripts/{solution}/{path}.xml" "agent/sandbox/{ScriptName}.xml"
Read agent/CONTEXT.json or index files for any field/layout/script references needed.
Before analysing 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 3b–3c 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.
Show the developer the full scope before starting analysis:
Call tree: [Script Name]
├── Subscript A
│ └── Subscript A1
├── Subscript B
└── Subscript C
Flag these edge cases:
Perform Script By Name references cannot be statically resolved. Ask the developer to clarify.scripts_sanitized/ may be in a different solution file or deleted. Flag them.Read through the target script and its call tree. Identify issues in these categories:
Set Error Capture [ On ] / Allow User Abort [ Off ] headerGet ( LastError ) check$errData pattern (see agent/docs/knowledge/error-data-capture.md)agent/docs/CODING_CONVENTIONS.md)Review the interactions between the target script and its subscripts:
Get ( ScriptResult )?Exit Script result?Flag issues in subscripts but do not refactor them — only the target script is modified unless the developer asks otherwise.
Use the implementation-plan skill internally to reason about the approach. When called internally, produce the plan inline without waiting for developer confirmation.
Present a summary of proposed changes to the developer:
## Proposed refactoring: [Script Name]
### Changes
1. Add error handling header (Set Error Capture + Allow User Abort)
2. Wrap main logic in single-pass loop with error exits
3. Replace inline find with Go to Related Record
4. Hoist repeated client name lookup to $clientName variable
5. Fix error capture pattern (separate steps → single expression)
### Preserved behaviour
- Same parameter format and exit result
- Same layout navigation sequence
- Same field modifications
### Risk
- None — structural changes only, no logic changes
Wait for developer confirmation before generating code.
Work from the fmxmlsnippet base in agent/sandbox/. Apply only the targeted changes — unchanged steps remain verbatim.
Follow all output rules from CLAUDE.md:
<fmxmlsnippet type="FMObjectList"> — no <Script> wrapperRun the validator:
python3 agent/scripts/validate_snippet.py agent/sandbox/{ScriptName}.xml
Fix any errors before proceeding.
Show the developer what changed. Present a before/after comparison of the human-readable script — not the raw XML.
Use snippet_to_hr.py to convert the refactored fmxmlsnippet to HR:
python3 agent/scripts/snippet_to_hr.py agent/sandbox/{ScriptName}.xml --raw
The original HR is already available in agent/xml_parsed/scripts_sanitized/.
Present a concise summary in the terminal listing each change with the relevant line numbers (from the human-readable version).
Check if the companion server is reachable:
curl -s --max-time 2 -o /dev/null -w "%{http_code}" {companion_url}/status
If reachable (HTTP 200 or 404), append this note after the terminal summary:
The webviewer is available — ask to "show the diff in the webviewer" for a side-by-side visual comparison.
Do not push the diff automatically. Only push when the developer explicitly asks. To push:
scripts_sanitized/snippet_to_hr.py --rawpython3 -c "
import json, sys
before = open(sys.argv[1]).read()
after = open(sys.argv[2]).read()
payload = json.dumps({
'type': 'diff',
'before': before,
'content': after,
'repo_path': '{repo_path}'
})
sys.stdout.write(payload)
" "{original_hr_path}" "{refactored_hr_path}" \
| curl -s -X POST -H 'Content-Type: application/json' -d @- {companion_url}/webviewer/push
After developer approval:
POST {companion_url}/clipboarddeploy.py or direct companion calls:
POST {companion_url}/trigger with raw AppleScript to open the script tab and pastePresent paste instructions:
The refactored script is on your clipboard. To install it:
- Open Script Name in Script Workspace
- Cmd+A — select all existing steps and delete
- Cmd+V — paste
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.