CtrlK
BlogDocsLog inGet started
Tessl Logo

finkel/tasker-xml-authoring

Author and edit Android Tasker XML (tasks, profiles, projects, scenes) for import into the Tasker app — node skeleton, action codes, and per-arg encoding.

97

1.31x
Quality

97%

Does it follow best practices?

Impact

97%

1.31x

Average score across 4 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

SKILL.mdskills/tasker-xml-authoring/

name:
tasker-xml-authoring
description:
Use when hand-writing, generating, or editing Android Tasker XML files (.tsk.xml, .prf.xml, .prj.xml, .scn.xml, or a full backup .xml) to define tasks, profiles, projects, or scenes for import into the Tasker app — covers the TaskerData node skeleton, numeric action codes, and the per-argument Str/Int/App encoding.

Writing Tasker XML

Overview

Tasker (Android automation app) imports tasks/profiles/projects/scenes as XML. The hard part: an action's kind is a numeric <code>, and the layout of its arguments (how many, which are Str vs Int, in what order) is NOT publicly documented per code. Argument order is the single biggest source of broken imports and silent misbehavior.

Core principle: never invent an action's argument layout from memory. Build the action once inside the Tasker app, export it, and copy that XML — swapping only the values. Use this skill for the file skeleton and the encoding rules; use a real export for any action's exact arg slots.

When to Use

  • Writing or generating a .tsk.xml / .prf.xml / .prj.xml / .scn.xml / backup .xml
  • Editing an exported Tasker file (changing values, adding actions)
  • Mapping a numeric <code> to an action / event / state, or vice versa

When NOT: configuring Tasker through its GUI (no XML involved), or TaskerNet sharing (that wraps the same XML).

Export Types & Required Suffix

The suffix is mandatory — wrong suffix and Tasker won't list the file for import.

ExportSuffixTop-level node(s)
Task.tsk.xmlone Task
Profile.prf.xmlone Profile + its Tasks
Scene.scn.xmlone Scene + anonymous Tasks
Project.prj.xmlone Project (<name>Base) + its members
Data Backup.xmleverything

Import fails if a named task/profile/scene with the same name already exists.

File Skeleton

<TaskerData sr="" dvi="1" tv="6.3.13">
	<Profile sr="prof1" ve="2">
		<id>1</id>           <!-- required, unique -->
		<mid0>10</mid0>      <!-- entry task id; mid1 = exit task id -->
		<nme>My Profile</nme>
		<Time sr="con0" ve="2">...</Time>   <!-- ≥1 context: App/Day/Event/Loc/State/Time -->
	</Profile>
	<Task sr="task10">
		<id>10</id>          <!-- required, unique -->
		<nme>My Task</nme>   <!-- omit nme = anonymous task (referenced only by id) -->
		<Action sr="act0" ve="7">...</Action>   <!-- ≥1 Action -->
	</Task>
	<Project sr="proj0" ve="2">   <!-- first/only project MUST be proj0 -->
		<cdate>1700000000000</cdate>   <!-- epoch millis; projects need it to import -->
		<name>My Project</name>   <!-- required -->
		<pids>1</pids>            <!-- profile ids -->
		<tids>10</tids>           <!-- task ids -->
		<scenes>Scene 1</scenes>  <!-- scene names -->
	</Project>
</TaskerData>

Linking rules:

  • sr ids are positional and the importer keys off them. The first/only Project must be sr="proj0", profiles prof0/prof1/…, tasks task<id>. A project at sr="proj1" imports as "no project found" — the scanner looks for proj0. Same for the other node types.
  • A Project needs a <cdate> (epoch millis) or it may not import.
  • Profile runs tasks by id via <mid0> (entry) / <mid1> (exit), not by name.
  • Project lists members by id (<pids>, <tids>) and scenes by name (<scenes>).
  • ids must be unique within the file. Tasker reassigns them on import, but they must be internally consistent (a <mid0>10</mid0> needs a <Task> with <id>10).
  • <dmetric>W.0,H.0</dmetric> (display metrics) is only needed when the file contains a Scene.

Per-node required/optional tags (entry/exit ids, collision handling <rty>, <stayawake>, etc.) and the full Scene element list: see references/tasker-xml-codes.md for codes and the upstream repo https://github.com/Taskomater/Tasker-XML-Info for node tags.

Action Encoding — the part nothing else documents

<Action sr="act0" ve="7">
	<code>547</code>                          <!-- 547 = Variable Set -->
	<Str sr="arg0" ve="3">%greeting</Str>     <!-- text/var arg, value sits directly inside -->
	<Str sr="arg1" ve="3">Good morning</Str>
	<Int sr="arg2" val="0"/>                  <!-- numeric/boolean arg, literal in val= -->
	<Int sr="arg3" val="0"/>
	<label>set the greeting</label>           <!-- optional, the action's label text -->
	<on>false</on>                            <!-- optional, present+false = action disabled -->
</Action>

Argument tag types (the slot index is arg0, arg1, … in on-screen order):

TagHoldsForm
Strtext, including %variables<Str sr="arg0" ve="3">value</Str> — value directly inside; empty = <Str sr="arg0" ve="3"/>
Intnumber or boolean toggleliteral: <Int sr="arg1" val="0"/> · variable: <Int sr="arg1"><var>%n</var></Int>
Appan app picker arg<App sr="arg0"><appPkg>…</appPkg><appClass>…</appClass><label>…</label></App>
Bundleplugin config (code 1000)<Bundle sr="arg0"><Vals sr="val">…</Vals></Bundle>

Action-level condition (the "if" on a single action) is a ConditionList:

<ConditionList sr="if">
	<Condition sr="c0" ve="3">
		<lhs>%ssid</lhs>
		<op>13</op>      <!-- numeric comparison code, maps to the dropdown (~/=/matches/set/…) -->
		<rhs></rhs>
	</Condition>
</ConditionList>

<op> is a numeric comparison code whose mapping isn't enumerated upstream — export a real condition to read off the right number rather than guessing.

Argument Value Rules

  • Variable names keep their %. Variable Set arg0 is %greeting, NOT greeting. Tasker does NOT add the % for you. This applies everywhere a variable is named or referenced.
  • Str holds its value as the element's text content — not in an attribute, not in a child <t>.
  • Int literals go in val="…"; to drive an Int slot from a variable use a child <var>%x</var> and omit val.
  • Booleans/checkboxes are Int val="0"/val="1".

Reliable Workflow

  1. Find the action's <code> in references/tasker-xml-codes.md (Task Actions / Profile Events / Profile States lists).
  2. For the argument layout of that code: build the action once in the Tasker app with placeholder values, export the task, and copy the <Action> block. Swap in real values. Do not guess slot order/types from the action name. A handful of already-verified 6.7.5 layouts (Wait 30, Perform Task 130, HTTP Request 339, Widget v2 461 + its custom-layout JSON schema) are in references/confirmed-arg-layouts.md.
  3. Assemble into the file skeleton, keeping ids consistent.
  4. Name the file with the correct suffix and import to verify.

Common Mistakes

MistakeFix
Variable name without % (greeting)Store the full %greeting
Guessing an action's arg count/order from its nameExport the real action and copy its XML
Wrong/invented arg tags (e.g. an <Img>/<Long> slot that isn't there)Match the exported block's tags exactly
Wrong file suffix → not shown in import menuUse .tsk.xml/.prf.xml/.prj.xml/.scn.xml
Project at sr="proj1" → "no project found" on importFirst/only project must be sr="proj0"
Project missing <cdate> → fails to importAdd <cdate> (epoch millis)
Profile references a task nameProfiles link tasks by id (<mid0>/<mid1>)
Duplicate name already in configImport fails; rename first
Inconsistent ids (mid0 points to a missing task id)Keep all id/mid/tids references consistent
Putting Str value in an attributeValue goes inside the element as text
Expecting Variable Search Replace (598) "Store Matches" to return all occurrencesIt stores the capture groups of the first match only. To get every match, parse differently (e.g. have the source return a comma/newline list) — Tasker's List Dialog Items field auto-splits a variable on commas/newlines.
Widget v2 (461) Custom layout JSON put in arg3 → runs but errors "For custom Layouts you need to define a JSON structure"The Custom Layout JSON slot is arg13, not the arg3 next to the arg2="Custom" selector. See references/confirmed-arg-layouts.md.
Can't tell which argN a GUI field maps toType a unique marker (e.g. MARK123) into the field, export, grep the XML for it.

Grounded Example — Morning.tsk.xml

Set %greeting, then Flash it. (Flash code is 548; confirm its arg slots against a real export before trusting any arg beyond arg0.)

<TaskerData sr="" dvi="1" tv="6.3.13">
	<Task sr="task1">
		<id>1</id>
		<nme>Morning</nme>
		<Action sr="act0" ve="7">
			<code>547</code>
			<Str sr="arg0" ve="3">%greeting</Str>
			<Str sr="arg1" ve="3">Good morning</Str>
			<Int sr="arg2" val="0"/>
			<Int sr="arg3" val="0"/>
		</Action>
		<Action sr="act1" ve="7">
			<code>548</code>
			<Str sr="arg0" ve="3">%greeting</Str>
			<Int sr="arg1" val="0"/>
		</Action>
	</Task>
</TaskerData>

skills

tile.json