frappe-live-code-extractor
frappe-live-code-extractor
Queries the live Frappe database (read-only) and writes each artifact's code into source files and meta.json under <app>/live/<doctype-slug>/. Makes all DB-resident code visible to grep, LSP, and AI assistants. Safe to run at any time.
All doctypes — built-in Frappe types and custom app types — are treated identically. Each doctype has a config.json at <app>/live/<doctype-slug>/config.json. The script resolves it via a 3-step fallback:
- App config —
<app>/live/<doctype-slug>/config.jsonif it exists - Skill asset — copies the bundled default from
assets/into the app tree, then uses it - Agent — interview the user / infer from context to create a config (see REFERENCE.md)
Quick start
--app is required. The agent must determine the app before calling the script.
Agent: inferring the app
If the user has not specified an app, determine it from context:
- From the workspace folder — use the workspace folder the user is currently in. The app that owns the DocType being extracted is irrelevant — always use the user's active workspace app.
- From the conversation — if the user has explicitly mentioned an app name, use it.
- From installed apps — as a last resort, query the DB and pick the first non-framework app:
cd /workspace/development/frappe-bench
./env/bin/python - <<'EOF'
import os; os.environ['FRAPPE_STREAM_LOGGING'] = '1'
import frappe
frappe.init(site='development.localhost', sites_path='sites'); frappe.connect()
FRAMEWORK = {'frappe', 'erpnext', 'payments', 'hrms'}
apps = [a for a in frappe.get_installed_apps() if a not in FRAMEWORK]
print(apps[0] if apps else '')
frappe.destroy()
EOF
Once the app is known, run:
cd /workspace/development/frappe-bench
./env/bin/python skills/.agents/skills/frappe-live-code-extractor/scripts/extract.py \
--app myapp --site development.localhost
To extract a single DocType (faster, useful after editing one doctype):
./env/bin/python skills/.agents/skills/frappe-live-code-extractor/scripts/extract.py \
--app myapp --doctype "Report"
--doctype accepts the exact DocType name (case-insensitive). Works for both standard Frappe DocTypes (Server Script, Report, …) and custom ones registered via config.json.
When
--doctypeis specified, config seeding from assets is limited to that DocType only — no otherconfig.jsonfiles are written.
Workflows
Refresh before a refactor
When the user says "refresh the live code snapshot":
- Run the extraction command above
- Grep across
apps/<app>/<app>/— thelive/subtree is included automatically - Proceed with the refactor
Add a new DocType for extraction
When the user asks to "mirror" or "extract" a DocType that has no config yet:
- Discover fields — query the schema for Code/Text/HTML fields:
cd /workspace/development/frappe-bench ./env/bin/python -c " import os; os.environ['FRAPPE_STREAM_LOGGING'] = '1' import frappe frappe.init(site='development.localhost', sites_path='sites'); frappe.connect() meta = frappe.get_meta('Your DocType Name') for f in meta.fields: if f.fieldtype in ['Code','Text','Long Text','Small Text','HTML','HTML Editor','Markdown Editor']: print(f.fieldname, f.fieldtype, f.label) frappe.destroy() " - Create
config.jsonat<app>/live/<doctype-slug>/config.json— see REFERENCE.md for schema and examples.⚠️ Never add configs to
skills/.agents/skills/frappe-live-code-extractor/assets/unless explicitly told to. That directory is reserved for configs bundled with the skill itself. User-defined configs always go into the app's ownlive/<doctype-slug>/config.json. - Run extraction — the file is auto-discovered and processed
- Commit
config.jsonand extracted files
Advanced features
See REFERENCE.md for:
- Supported artifact types table
- Output directory structure and
meta.jsonformat config.jsonschema (all fields, advanced options)- Config examples (dynamic extensions, mutual exclusion, per-group filtering)
- Integration with git, multi-app extraction, troubleshooting
More from kehwar/skills
vue-testing-best-practices
Use for Vue.js testing. Covers Vitest, Vue Test Utils, component testing, mocking, testing patterns, and Playwright for E2E testing.
3find-skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
2pinia
Pinia official Vue state management library, type-safe and extensible. Use when defining stores, working with state/getters/actions, or implementing store patterns in Vue apps.
2frappe-app-include-js
Expert guidance for writing always-loaded desk JavaScript in Frappe apps — utilities and controllers that are available across every desk page. Use when adding a reusable JS namespace, wrapping frappe.call in a utility function, registering app_include_js in hooks.py, or writing shared logic that multiple doctypes or pages need. NOT for per-doctype form/list JS (use frappe-doctype-form-view or frappe-doctype-list-view instead).
2frappe-dev-debugger
Query the live Frappe database, read private/public .json.gz snapshot files from disk, execute whitelisted Python methods, and run arbitrary scripts with full Frappe context via bench console. Use when debugging Frappe issues in development — checking document field values, inspecting stored report/snapshot files, running live queries, or calling whitelisted server methods from the terminal.
2frappe-doctype-form-view
Expert guidance for implementing Frappe DocType JavaScript form controllers (.js app files). Covers the complete lifecycle hook execution order (setup/onload/refresh) with explicit placement rules, frm object API (fields_dict, set_query, set_value, toggle_display/reqd/enable, add_custom_button, frm.trigger), frappe.call for server methods, frappe.prompt and frappe.ui.Dialog for user input dialogs, frappe.show_progress for progress feedback, child table APIs, and reusable helper code via frappe.ui.form.Controller subclasses (extend_cscript pattern) to avoid global scope pollution. Use when writing or debugging .js controller files, choosing which hook to use, adding custom buttons, building dialogs, running server methods, triggering events programmatically, sharing logic across event handlers, or fixing bugs caused by logic placed in the wrong hook.
2