Import, export, and predefined queries
When you copy a skill or app to another workspace, how predefined queries travel with it.
Source docs/en/site/skill-import-export.md
In user language: This article is for workspace admins. It explains what happens to predefined queries when you copy a skill or app to another workspace, how import can fill them in one step, and what to watch when the target database schema differs. Everyday members only need to use the skill or app; they do not need to know file names inside the zip. Implementation notes are at the end.
Date: 2026-07-19 Status: Implemented Related help: Workspace apps · Data connections and predefined queries · How to write a good workspace skill Mechanism notes: Workspace apps
Takeaway (read this first)
| Question | Answer |
|---|---|
| Does exporting a skill/app take the database account with it? | No |
| Does it take the predefined query SQL? | It tries to (written into a dependency list in the pack; no connection secrets) |
| What if queries are missing at import? | The skill/app can still import; data fetches fail until you fill in the queries |
| Can an admin fill them in one step? | Yes: at import you can write them onto a data connection in this workspace |
| Target tables have different names? | Write them first, then use smart check and fix or test and edit the SQL |
In one sentence: UI and logic travel in the skill/app pack; how to fetch data lives in predefined queries on a data connection; on migrate, take the query definitions as dependencies and optionally merge them on import.
1. Why a move used to “import but not work”
Skills and apps do not store a business-database connection. They call workspace data connections by query id, for example:
- The skill body says “call predefined query
staff_by_dept” - An employee-portrait
pipelinehard-codesemployee_by_name - A report-app script has
platform.query_run("dept_rank_emp", …)
The export pack used to mainly take:
- Skill: write-up, scripts, reference materials
- App: UI description and logic (not registered business data)
Predefined queries hang on Data integration → Data connections, not inside the pack. If the target workspace has no query of the same name (or no matching data connection), import itself often succeeds, but the first fetch reports “query definition not found”, or the conversation guesses another id on the spot and uses table preview as if it were a real result.
2. What we do now: a dependency list travels with the pack
2.1 Collect automatically on export
When you export a skill pack or app pack, the system:
- Scans materials in the pack for query ids (pipeline, scripts, body text, and so on)
- Resolves matching definitions in this workspace’s data connections (name, description, SQL, parameters)
- Writes a dependency file into the pack (no host, account, or password)
If the source workspace itself does not have complete definitions for those queries, the pack cannot carry the SQL — configure the usual queries on the source side before you export.
2.2 Gap check on import + optional write
Import preview compares against the target workspace and shows roughly:
| Status | Meaning |
|---|---|
| Ready | A data connection already has a same-name query with matching content |
| Missing | The pack has a definition; the target does not |
| Conflict | Same name exists, but SQL/parameters differ from the pack |
After you confirm import, if anything is missing (or conflicting), the workspace admin is asked:
- Whether to write onto a data connection in this workspace
- On same-name conflict: keep what is already there, or overwrite with the pack definition
You can also choose “import only, do not write” — the skill/app still lands; you fill queries later by hand under Data integration.
Non-admins can import a pack but cannot write queries onto a data connection; the UI asks them to involve an admin.
3. Steps (admin)
3.1 Export from the source workspace
| Type | How |
|---|---|
| App | Open the app → Export app pack → get a zip |
| Skill | Open the skill in Skill center → export (standard or full; both modes try to attach dependent queries) |
The export still does not include business-table data already registered in the source workspace, and does not include database connection secrets.
3.2 Prepare a data connection in the target workspace
Before writing predefined queries, the target workspace needs:
- Data integration enabled, with a working MySQL (or similar) data connection
- Business tables in the database (or at least room to edit SQL later to match)
- The person importing is a workspace admin (if they want to write queries in one step)
3.3 Import and write missing queries
- Import the skill or app pack; handle “identifier already exists” (overwrite / copy) as prompted
- If predefined-query dependencies are flagged: pick the data connection to write to, confirm “write and continue import”
- Open Data integration → that data connection and check the query list
- Run a real scenario once (type / to pick the skill in conversation, or tap the app button)
3.4 Same-name conflict
| Choice | When |
|---|---|
| Keep existing (default) | Target queries already work; you do not want the source environment to overwrite them |
| Overwrite same name | You want the source pack’s definitions — unify SQL and parameter names |
4. When the target database differs from the source
The dependency list answers “is there a same-name query”. It does not guarantee the SQL will run on the target database. Common gaps:
- Different table or column names (e.g.
empIdvsemp_id) - Allowed table scope is narrower; write-time validation fails
- Parameter names do not match what scripts/skills call
Suggested path:
- Finish import and write missing queries
- Run smart check and fix on the important connections (see Checking predefined queries)
- Execute each query id once with fixed sample parameters
- For employee-portrait fixed pipelines, also see Employee portrait and data connections
5. How this relates to “generate a skill / write queries from chat”
| Situation | What to do |
|---|---|
| New connection in this workspace | After saving the data connection you can generate a skill; or an admin writes queries in conversation |
| Copy a skill/app across workspaces | Use this article’s export dependencies + import merge |
| Portrait pipeline missing canonical ids | You can still write template queries from chat in one step (see the portrait alignment guide) |
The three complement each other: day-to-day setup uses forms/conversation; whole-pack moves use import/export dependency merge.
6. What members see
- Import succeeded, queries written: use the skill or app as before
- Pack imported, queries not written: tapping report/portrait fetch may fail; conversation may say the query was not found — ask an admin to fill them in
- No data connection: queries cannot be written; configure a connection first and import again (or paste query definitions by hand)
7. Checklist (before you migrate)
- [ ] Source workspace: queries the skill/app depends on are configured on a data connection and can run
- [ ] You have a zip (app or skill)
- [ ] Target workspace: data connection works, table structure is roughly usable
- [ ] An admin imports and chooses to write missing items
- [ ] Conflicts were keep-or-overwrite according to the intended definitions
- [ ] Spot-check conversation fetch or an app button
- [ ] If schemas differ, smart check or hand-edit SQL is done
Implementation map (for developers / troubleshooting)
| Capability | Where |
|---|---|
| Collect query ids, pack/parse dependencies | backend/internal/querydepbundle/ |
| App export inject / import merge | backend/internal/api/handlers/workspace_apps_import.go |
| Skill export inject / import merge | backend/internal/api/handlers/skills_import.go |
| Merge into a data connection | store.MergeImportQueryDefs (skip / replace) |
| In-pack dependency file | references/query-defs.json (format mindlink-query-deps) |
| Import form fields | merge_query_defs, data_source_slug, on_query_conflict |
| Web confirm flow | client/web/src/importQueryDeps.ts; called from app/skill import pages |
Preview response query_deps includes ready/missing/conflict counts and a suggested connection; if merge fails the app/skill may still be imported, and the response can include query_deps_merge_error for UI.