Token导航 LogoToken导航TokenDH.com
前端设计敏感数据github未标认证来源可访问许可证需确认审计异常

magic-etl魔法等

Agent Skill

用于辅助数据整理、表格处理、CSV/Excel 分析、指标计算和图表准备。它适合让 Agent 清洗字段、汇总数据、发现异常、生成统计口径或把分析结果转成可读说明。使用时需要确认数据来源、字段含义和时间范围,避免把样本数据当全量事实;涉及敏感数据、导出文件或批量写回时,应先确认权限和脱敏边界。

总安装

915

周安装

37

GitHub Stars

15

下载量

287
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:magic-etl(魔法等)
来源仓库:https://github.com/stahura/domo-ai-vibe-rules
仓库路径:skills/magic-etl
安装命令:
npx skills add https://github.com/stahura/domo-ai-vibe-rules --skill magic-etl
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/stahura/domo-ai-vibe-rules --skill magic-etl

简介

magic-etl 用于辅助数据整理、表格处理和指标计算。

  • 适合让 Agent 清洗字段、汇总数据、发现异常或生成统计口径说明。
  • 通过 npx skills add 命令从指定 GitHub 仓库安装,需结合原始 README 核验具体用法。
  • 使用时需要确认数据来源和时间范围,避免把样本数据当全量事实;涉及敏感数据时应先确认脱敏边界。
  • 该技能适用于 CSV/Excel 数据分析与可视化准备场景。

SKILL.md

Creating Magic ETL Dataflows Programmatically in Domo

Overview

Magic ETL dataflows in Domo can be created, updated, and executed entirely through the API. The dataflow is defined as a JSON document describing a directed acyclic graph (DAG) of actions — input nodes, transforms, and output nodes.

CLI-First: Use the Java CLI for read/run operations, fall back to REST API for creation.

OperationUse CLI?Use REST API?
List dataflowslist-dataflow -dt MAGIC
Export dataflow definitionlist-dataflow -i <ID> -d -f <FILE>
Run a dataflowdataflow-run-now -i <ID>POST.../executions (more reliable for new dataflows)
Check execution statuslist-dataflow -i <ID> -e -l 1GET.../executions?limit=1
Create a dataflowPOST /api/dataprocessing/v1/dataflows (dev token works, executes immediately)
Update a dataflowset-dataflow-properties -i <id> -d <file>PUT /api/dataprocessing/v1/dataflows/<ID>
Rename/enableset-dataflow-properties -i <id> -n/-e/-sPUT /api/dataprocessing/v1/dataflows/<ID>/patch

Important: Creating dataflows via API (POST) works with developer tokens (confirmed April 2026). The created dataflow can be executed immediately — no UI save required. The domo (ryuu) CLI is for Custom App publishing only; use the Java CLI (domoutil.jar) for dataflow operations.

CLI Commands for Dataflows

List All Magic ETL Dataflows

list-dataflow -dt MAGIC

Get a Dataflow Definition (Export to JSON)

list-dataflow -i <DATAFLOW_ID> -d -f <OUTPUT_FILE>

This exports the full JSON definition including all actions, inputs, outputs, and GUI positions. This is the best way to understand the JSON structure — export an existing dataflow and study it.

Run a Dataflow

dataflow-run-now -i <DATAFLOW_ID>

List Dataflow Executions

list-dataflow -i <DATAFLOW_ID> -e -l <LIMIT>

Check Execution Status via API

curl -s "https://<instance>.domo.com/api/dataprocessing/v1/dataflows/<ID>/executions?limit=1&offset=0" \
  -H "x-domo-developer-token: <TOKEN>"

Returns execution state (SUCCESS, FAILED_DATA_FLOW, CREATED, RUNNING), row counts, errors, etc.

Creating a Dataflow via the API

Endpoint

POST https://<instance>.domo.com/api/dataprocessing/v1/dataflows

Auth (March 2026): This endpoint requires SID-based auth, not developer tokens. Developer tokens get 403 Forbidden. Use the SID exchange: refresh token → oauth2/token → access token → oauth2/sid → SID.

Headers:

Content-Type: application/json
X-Domo-Authentication: <SID>

The body must include "databaseType": "MAGIC". The created dataflow can be executed immediately — see Gotcha #7 and #11 for details.

Note: x-domo-developer-token works for all dataflow operations including POST (create), GET, PUT, and execution (confirmed April 2026).

Updating an Existing Dataflow

PUT https://<instance>.domo.com/api/dataprocessing/v1/dataflows/<DATAFLOW_ID>

Same headers and body format as POST. Include the full definition.

Dataflow JSON Structure

Top-Level Fields

{
  "name": "My Magic ETL",
  "databaseType": "MAGIC",
  "responsibleUserId": 149955692,
  "draft": false,
  "enabled": true,
  "runState": "ENABLED",
  "engineProperties": {
    "kettle.mode": "STRICT"
  },
  "inputs": [ ... ],
  "outputs": [ ... ],
  "actions": [ ... ]
}
FieldDescription
nameDisplay name of the dataflow
databaseTypeMust be "MAGIC" for Magic ETL
responsibleUserIdNumeric user ID of the owner
draftfalse for a published dataflow
enabledtrue to allow execution
runState"ENABLED" to allow scheduled runs
engineProperties{"kettle.mode": "STRICT"} is standard
inputsArray of input dataset references
outputsArray of output dataset references
actionsArray of action nodes (the DAG)

Top-Level gui Field (Canvas Layout & Sections)

The gui field controls the visual canvas layout, including colored Section zones that group related tiles. When useGraphUI: true, the canvas elements array controls tile positioning (overriding action-level gui.x/gui.y).

{
  "gui": {
    "version": "1.0",
    "canvases": {
      "default": {
        "canvasSettings": {
          "coarserGrid": false,
          "hideCoarserGridPopUp": false,
          "backgroundVariant": "None"
        },
        "elements": [
          { "type": "Section", ... },
          { "type": "Tile", ... }
        ],
        "disabledActions": []
      }
    },
    "useGraphUI": true
  }
}

Section Elements (Colored Zone Backgrounds)

Sections are colored rectangular zones that visually group related tiles on the canvas:

{
  "id": "a-unique-uuid",
  "type": "Section",
  "x": 56,
  "y": 72,
  "width": 1320,
  "height": 288,
  "name": "Work Orders Denormalization",
  "backgroundColor": "var(--colorChartBlue6)"
}
FieldDescription
idUnique UUID for the section
typeMust be "Section"
x, yAbsolute position on the canvas (top-left corner)
width, heightSize of the colored zone in pixels
nameLabel displayed in the section header
backgroundColorCSS variable for the zone color (see table below)

Available Section Background Colors

CSS VariableColorSuggested Use
var(--colorChartBlue6)Light blueInput/staging pipelines
var(--colorChartGreen6)Light greenQuality/validation pipelines
var(--colorChartPurple6)Light purpleOutput/publishing pipelines
var(--colorChartOrange6)Light orangeTransform/enrichment pipelines
var(--colorChartRed6)Light redFilter/exclusion pipelines
var(--colorChartYellow6)Light yellowShared/dimension tables

The 6 suffix indicates the lightest shade — ideal for section backgrounds so tile labels remain readable.

Tile Elements (Action Positions)

Each action node has a corresponding Tile element in the canvas. Tiles can be parented inside a Section, in which case their x/y are relative to the Section's position:

{
  "id": "LoadFromVault-work_orders",
  "type": "Tile",
  "x": 72,
  "y": 56,
  "parentId": "section-uuid-here",
  "color": null,
  "colorSource": null
}
FieldDescription
idMust match the action's id field
typeMust be "Tile"
x, yPosition — absolute if no parentId, relative to parent Section if parentId is set
parentIdUUID of the parent Section element (omit for unparented tiles)
colorOptional integer color code for the tile icon

Reparenting formula: When moving a tile into a section, convert absolute to relative coordinates:

  • relativeX = absoluteX - section.x
  • relativeY = absoluteY - section.y

Tiles without parentId render at absolute canvas coordinates and float outside any section.

ALWAYS Add Sections When Creating Dataflows

When building a dataflow with multiple logical branches or processing stages, always add Section elements to organize the visual layout. This is a best practice that makes dataflows immediately understandable. Group tiles by:

  • Pipeline branch (e.g., each fact table's join chain gets its own section)
  • Processing stage (e.g., "Input/Staging", "Transforms", "Output")
  • Shared resources (e.g., dimension tables used across branches)

Assign a distinct color to each section for visual differentiation.

Inputs Array

Each input references a Domo dataset that feeds into the dataflow:

"inputs": [
  {
    "dataSourceId": "422efbf4-6c96-4576-907b-eacae8379d5d",
    "executeFlowWhenUpdated": false,
    "dataSourceName": "RAW | SFDC | Accounts",
    "onlyLoadNewVersions": false,
    "recentVersionCutoffMs": 0
  }
]
FieldDescription
dataSourceIdUUID of the input dataset
dataSourceNameDisplay name (for readability)
executeFlowWhenUpdatedtrue to auto-trigger the dataflow when this input updates
onlyLoadNewVersionstrue to only process new data versions

Outputs Array

For a new dataflow where the output dataset doesn't exist yet:

"outputs": [
  {
    "dataSourceId": null,
    "dataSourceName": "SFDC | Account Summary",
    "versionChainType": "REPLACE"
  }
]

Setting dataSourceId to null tells Domo to create a new dataset on first run. After the first successful run, Domo assigns a UUID.

For an existing output dataset:

"outputs": [
  {
    "dataSourceId": "8fe448eb-231d-4ff5-95f1-86db64336e96",
    "dataSourceName": "SFDC | Account Opportunity Summary",
    "versionChainType": "REPLACE"
  }
]

versionChainType: "REPLACE" replaces all data each run. Other options include "APPEND".

Action Types

Actions are the nodes in the DAG. Each action has a unique id, a type, and references its upstream dependencies via dependsOn.

Common Action Fields

Every action has these fields:

{
  "type": "ActionType",
  "id": "unique-action-id",
  "name": "Human-readable name",
  "dependsOn": ["upstream-action-id-1", "upstream-action-id-2"],
  "settings": {
    "preferredDatabaseEntityType": "TEMP_VIEW"
  },
  "gui": {
    "x": 128,
    "y": 128,
    "color": null,
    "colorSource": null,
    "sampleJson": null
  },
  "tables": [{}]
}
FieldDescription
idUnique identifier for this action node. Can be any string, but convention is TypeName-uuid
dependsOnArray of action IDs that must complete before this one runs
gui.x / gui.yPosition in the visual canvas. When useGraphUI: true, the top-level gui.canvases.default.elements array takes precedence — set both to stay consistent
settings.preferredDatabaseEntityTypeAlways "TEMP_VIEW"
tablesAlways [{}]

LoadFromVault (Input Node)

Loads data from a Domo dataset into the dataflow.

{
  "type": "LoadFromVault",
  "id": "LoadFromVault-accounts",
  "name": "RAW | SFDC | Accounts",
  "settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
  "gui": {"x": 128, "y": 128, "color": null, "colorSource": null, "sampleJson": null},
  "previewRowLimit": 10000,
  "propagateAi": false,
  "filterPolicy": "LEGACY",
  "dataSourceId": "422efbf4-6c96-4576-907b-eacae8379d5d",
  "sourceType": "AUTO",
  "executeFlowWhenUpdated": false,
  "pseudoDataSource": false,
  "truncateTextColumns": false,
  "truncateRows": false,
  "onlyLoadNewVersions": false,
  "recentVersionCutoffMs": 0,
  "tables": [{}]
}

Key fields:

  • dataSourceId: UUID of the dataset to load
  • name: Should match the dataset name for clarity
  • No dependsOn — this is a root node

MergeJoin (Join)

Joins two upstream actions on specified keys.

{
  "type": "MergeJoin",
  "id": "MergeJoin-accounts-opps",
  "name": "Join Accounts & Opp Summary",
  "dependsOn": ["LoadFromVault-accounts", "GroupBy-opp-summary"],
  "disabled": false,
  "removeByDefault": false,
  "notes": [],
  "settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
  "gui": {"x": 576, "y": 320, "color": null, "colorSource": null, "sampleJson": null},
  "previewRowLimit": null,
  "joinType": "LEFT OUTER",
  "relationshipType": "MTM",
  "step1": "LoadFromVault-accounts",
  "step2": "GroupBy-opp-summary",
  "keys1": ["Id"],
  "keys2": ["AccountId"],
  "on": null,
  "schemaModification1": [],
  "schemaModification2": [
    {"name": "AccountId", "rename": "Opp_AccountId", "remove": true}
  ]
}
FieldDescription
joinType"LEFT OUTER", "INNER", "RIGHT OUTER", "FULL OUTER"
relationshipType"MTM" — use this abbreviation, NOT "MANY_TO_MANY" (causes validation errors)
step1Action ID for the left side of the join
step2Action ID for the right side of the join
keys1Array of column names from step1 to join on
keys2Array of column names from step2 to join on (matched positionally with keys1)
schemaModification1Rename or remove columns from step1 (left side)
schemaModification2Rename or remove columns from step2 (right side) to avoid name collisions
dependsOnMust include both step1 and step2 action IDs

Note: Keys can be asymmetric — keys1: ["fldWorkCodeID"] / keys2: ["ID"]. Domo matches by array position, not by column name.

schemaModification1 / schemaModification2

When two datasets share column names (e.g., both have Id, Name, Description), use schemaModification2 to rename or remove the conflicting columns from the right-side (step2) dataset:

"schemaModification2": [
  {"name": "Description", "rename": "Opportunities.Description", "remove": false},
  {"name": "Id", "rename": "Opportunities.Id", "remove": false},
  {"name": "Name", "rename": "Opportunities.Name", "remove": false},
  {"name": "AccountId", "rename": "Opp_AccountId", "remove": true}
]
  • remove: true — drops the column entirely from the output
  • remove: false — keeps the column but renames it to the rename value

GroupBy (Aggregation)

Aggregates data by grouping columns and applying aggregation functions.

{
  "type": "GroupBy",
  "id": "GroupBy-opp-summary",
  "name": "Summarize Opportunities per Account",
  "dependsOn": ["LoadFromVault-opportunities"],
  "settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
  "gui": {"x": 352, "y": 512, "color": null, "colorSource": null, "sampleJson": null},
  "input": "LoadFromVault-opportunities",
  "addLineNumber": false,
  "giveBackRow": false,
  "allRows": false,
  "groups": [
    {"name": "AccountId"}
  ],
  "fields": [
    {"name": "Opportunity Count", "source": "Id", "type": "COUNT_ALL", "valuefield": null, "expression": null, "settings": null},
    {"name": "Total Amount", "source": "Amount", "type": "SUM", "valuefield": null, "expression": null, "settings": null},
    {"name": "Avg Amount", "source": "Amount", "type": "AVERAGE", "valuefield": null, "expression": null, "settings": null},
    {"name": "Total Expected Revenue", "source": "ExpectedRevenue", "type": "SUM", "valuefield": null, "expression": null, "settings": null},
    {"name": "Avg Probability", "source": "Probability", "type": "AVERAGE", "valuefield": null, "expression": null, "settings": null}
  ],
  "tables": [{}]
}
FieldDescription
inputAction ID of the upstream data
groupsArray of columns to group by. Each entry: {"name": "ColumnName"}
fieldsArray of aggregation definitions

Aggregation Field Definition

{
  "name": "Total Amount",
  "source": "Amount",
  "type": "SUM",
  "valuefield": null,
  "expression": null,
  "settings": null
}
FieldDescription
nameOutput column name for the aggregated value
sourceSource column name to aggregate
typeAggregation function (see below)

Aggregation Types

TypeDescriptionConfirmed
SUMSum of valuesYes
AVERAGEMean of valuesYes
COUNT_ALLCount of all rows (including nulls)Yes
COUNT_DISTINCTCount of distinct values
MINMinimum valueYes
MAXMaximum value
FIRSTFirst value in group
LASTLast value in group
CONCAT_COMMAConcatenate values with comma separator

Important: The API uses MIN and MAX, not MINIMUM or MAXIMUM. Using MINIMUM returns a validation error: "The value is invalid for expected type... AggregateType". This was discovered through testing.

Expression-Based Aggregations (Advanced)

Instead of using source + type, you can use full SQL aggregation expressions. Set source, type, and valuefield to null and put the full expression in expression:

{
  "name": "Total Hours",
  "source": null,
  "type": null,
  "valuefield": null,
  "expression": "SUM(IFNULL(`Hours`,0))",
  "settings": null
}

CRITICAL: The expression must be a full SQL aggregation expression — NOT just the function name.

  • "expression": "SUM(IFNULL(\Hours,0))"with"source": null — CORRECT
  • "expression": "SUM" with "valuefield": "Hours" — WRONG (treats "SUM" as a column name)

This allows embedding complex logic like CASE WHEN directly in the GroupBy without needing a pre-GroupBy ExpressionEvaluator:

{
  "name": "LTM_Revenue",
  "source": null, "type": null, "valuefield": null,
  "expression": "SUM(CASE WHEN `Date` >= DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 12 MONTH) THEN IFNULL(`Revenue`,0) ELSE 0 END)",
  "settings": null
}

WindowAction (Rank & Window)

Applies window functions — ranking, row numbering, lag/lead offsets — partitioned by group columns and ordered by sort columns. This is the programmatic equivalent of the "Rank & Window" tile in the Magic ETL UI.

{
  "type": "WindowAction",
  "id": "WindowAction-first-order",
  "name": "First Order Date per Customer",
  "dependsOn": ["LoadFromVault-finance"],
  "settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
  "gui": {"x": 352, "y": 128, "color": null, "colorSource": null, "sampleJson": null},
  "input": "LoadFromVault-finance",
  "groupRules": [
    {"column": "customer", "caseSensitive": false}
  ],
  "orderRules": [
    {"column": "date_ymd", "caseSensitive": false, "ascending": true}
  ],
  "additions": [
    {
      "name": "Customer Order Rank",
      "operation": {
        "type": "RANKING",
        "operationType": "ROW_NUMBER",
        "column": null,
        "defaultValue": null,
        "amount": null
      }
    }
  ],
  "tables": [{}]
}
FieldDescription
inputAction ID of the upstream data
groupRulesPartition columns — the window function is applied within each group
orderRulesSort order within each partition
additionsArray of window function definitions to add as new columns

groupRules

Defines the PARTITION BY columns:

"groupRules": [
  {"column": "customer", "caseSensitive": false},
  {"column": "region", "caseSensitive": false}
]

Each entry partitions the data by that column. Multiple entries create a composite partition key.

orderRules

Defines the ORDER BY within each partition:

"orderRules": [
  {"column": "date_ymd", "caseSensitive": false, "ascending": true}
]
FieldDescription
columnColumn to sort by
caseSensitiveWhether string sorting is case-sensitive
ascendingtrue for ASC, false for DESC

Multiple orderRules create a composite sort key.

additions (Window Function Definitions)

Each addition creates a new column with the result of a window function:

{
  "name": "Output Column Name",
  "operation": {
    "type": "RANKING",
    "operationType": "ROW_NUMBER",
    "column": null,
    "defaultValue": null,
    "amount": null
  }
}

Window Operation Types

Ranking operations (type: "RANKING"):

operationTypeDescriptioncolumnamount
ROW_NUMBERSequential number within partition (1, 2, 3...)nullnull
RANKRank with gaps for ties (1, 2, 2, 4...)nullnull
DENSE_RANKRank without gaps for ties (1, 2, 2, 3...)nullnull

Offset operations (type: "OFFSET"):

operationTypeDescriptioncolumnamount
LAGValue from N rows before in the partitionSource column nameNumber of rows to look back
LEADValue from N rows ahead in the partitionSource column nameNumber of rows to look ahead

Example — LAG to get previous day's revenue:

{
  "name": "Previous Day Revenue",
  "operation": {
    "type": "OFFSET",
    "operationType": "LAG",
    "column": "revenue",
    "defaultValue": null,
    "amount": 1
  }
}

Example — ROW_NUMBER to rank orders per customer:

{
  "name": "Customer Order Rank",
  "operation": {
    "type": "RANKING",
    "operationType": "ROW_NUMBER",
    "column": null,
    "defaultValue": null,
    "amount": null
  }
}

Combining WindowAction with GroupBy

A common pattern is to use WindowAction for row-level ranking, then GroupBy for aggregation. For example, to find the first order date per customer:

  1. WindowAction: Partition by customer, order by date_ymd ASC, add ROW_NUMBER
  2. GroupBy: Group by customer, use MIN on date_ymd to get the first order date, plus SUM/AVERAGE on numeric columns

The WindowAction passes through all original columns plus the new additions, so downstream actions have access to everything.

Filter (Row Filtering)

Filters rows based on column conditions. This is the programmatic equivalent of the "Filter Rows" tile in the Magic ETL UI.

{
  "type": "Filter",
  "id": "Filter-exclude-florida",
  "name": "Exclude Florida",
  "dependsOn": ["LoadFromVault-sales"],
  "settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
  "gui": {"x": 352, "y": 256, "color": null, "colorSource": null, "sampleJson": null},
  "input": "LoadFromVault-sales",
  "filterList": [
    {
      "leftField": "state",
      "rightField": null,
      "rightValue": {"value": "Florida", "type": "STRING"},
      "rightExpr": "'Florida'",
      "operator": "NE",
      "expression": null,
      "andFilterList": []
    }
  ],
  "tables": [{}]
}
FieldDescription
inputAction ID of the upstream data
filterListArray of filter conditions (combined with OR logic)
andFilterListNested array within a filter for AND logic

Filter Condition Fields

FieldDescription
leftFieldColumn name to filter on
operatorComparison operator (see table below)
rightValueTyped value object: {"value": "Florida", "type": "STRING"}
rightExprString expression of the value, wrapped in single quotes for strings: "'Florida'"
rightFieldColumn name to compare against (for column-to-column comparisons, otherwise null)

Important: For string comparisons, rightValue must be a typed object with value and type fields, and rightExpr must wrap the value in single quotes. Using a plain string for rightValue returns a VALIDATION-DE error.

Expression-Based Filters (Alternative)

Instead of using leftField/operator/rightValue, you can use a raw SQL expression for complex conditions:

{
  "leftField": null,
  "rightField": null,
  "rightValue": null,
  "rightExpr": null,
  "operator": null,
  "expression": "IFNULL(TRIM(`column_name`),'') <> ''",
  "andFilterList": []
}

This is useful for multi-condition filters or filters with function calls. The expression is a SQL WHERE clause fragment.

Filter Operators

OperatorDescriptionConfirmed
NENot equalYes
EQEqual
LTLess than
GTGreater than
LELess than or equal
GEGreater than or equal
NNIs not nullYes (from existing dataflow)
NLIs null
NINNot in list
INIn list

rightValue Type Values

TypeUse For
STRINGText comparisons
NUMERICNumber comparisons
DATEDate comparisons

ExpressionEvaluator (Add Formula)

Adds calculated columns using Domo's expression language. This is the programmatic equivalent of the "Add Formula" tile in the Magic ETL UI.

{
  "type": "ExpressionEvaluator",
  "id": "ExpressionEvaluator-month-trunc",
  "name": "Add Month Column",
  "dependsOn": ["Filter-exclude-florida"],
  "settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
  "gui": {"x": 480, "y": 256, "color": null, "colorSource": null, "sampleJson": null},
  "input": "Filter-exclude-florida",
  "expressions": [
    {
      "expression": "concat(year(`date_ymd`),MONTHNAME(`date_ymd`))",
      "fieldName": "Year_Month",
      "settings": {}
    }
  ],
  "tables": [{}]
}
FieldDescription
inputAction ID of the upstream data
expressionsArray of formula definitions

Expression Definition

{
  "expression": "concat(year(`date_ymd`),MONTHNAME(`date_ymd`))",
  "fieldName": "Year_Month",
  "settings": {}
}
FieldDescription
expressionDomo formula expression. Column names must be wrapped in backticks.
fieldNameName of the new output column
settingsEmpty object {}

Known Working Functions

FunctionDescriptionExample
year()Extract year from dateyear(\date_ymd)
MONTH()Extract month number (1-12)MONTH(\date_ymd)
MONTHNAME()Extract month name from dateMONTHNAME(\date_ymd)
concat()Concatenate stringsconcat(year(\date_ymd), MONTHNAME(date_ymd))
DATE()Convert to date typeDATE(\date_ymd)
DATE_FORMAT()Format date as stringDATE_FORMAT(\date_ymd, 'yyyy-MM-dd')
LEFT()Left substringLEFT(\Date, 7) for year-month from "2025-01-15"
LPAD()Left-pad stringLPAD(MONTH(\date), 2, '0')
IFNULL()Null replacement (2 args only)IFNULL(\col, 0)
COALESCE()Null replacement (multi-arg)COALESCE(\a, b, 'default')
TRIM()Remove whitespaceTRIM(\col)
CAST()Type castingCAST(NULL AS DATETIME)
LAST_DAY()Last day of monthLAST_DAY(\date)
DATE_SUB()Subtract intervalDATE_SUB(\date, INTERVAL 12 MONTH)
CONVERT_TZ()Timezone conversionCONVERT_TZ(CURRENT_TIMESTAMP(),'UTC','US/Eastern')
CURRENT_TIMESTAMP()Current datetimeCURRENT_TIMESTAMP()

Important: TRUNC_MONTH() is NOT a valid function and returns "Unknown function: TRUNC_MONTH". To truncate dates to month level, use concat(year(...), MONTHNAME(...)) or similar string-based approaches.

Expression Behavior Rules

  • Expressions are processed in order — later expressions CAN reference fields computed by earlier ones in the same tile
  • Adding an expression with the same fieldName as an existing column replaces that column's value (useful for type casting or reformatting)
  • IFNULL() takes exactly 2 args; use COALESCE(a, b, c) for multi-arg null handling
  • CAST(NULL AS DATETIME) works for creating null typed columns

Multiple expressions can be added in a single ExpressionEvaluator action — each creates a new column (or replaces an existing one). All original columns are passed through.

Unique (Deduplicate)

Removes duplicate rows based on specified key columns. This is the programmatic equivalent of the "Remove Duplicates" tile.

{
  "type": "Unique",
  "id": "Unique-dedup",
  "name": "Deduplicate",
  "dependsOn": ["SelectValues-final"],
  "settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
  "gui": {"x": 800, "y": 256, "color": null, "colorSource": null, "sampleJson": null},
  "input": "SelectValues-final",
  "countRows": false,
  "fields": [
    {"name": "ColA", "caseInsensitive": false},
    {"name": "ColB", "caseInsensitive": false}
  ],
  "tables": [{}]
}
FieldDescription
inputAction ID of the upstream data
countRowstrue to add a count column showing how many duplicates were found
fieldsArray of columns that define uniqueness. Rows with identical values across all listed columns are deduplicated
fields[].caseInsensitivetrue for case-insensitive string matching

Tip: Add a Unique tile after joins that might fan out rows (e.g., many-to-many joins).

SelectValues (Column Selection / Rename)

Selects specific columns and optionally renames them.

{
  "type": "SelectValues",
  "id": "SelectValues-final",
  "name": "Select Final Columns",
  "dependsOn": ["MergeJoin-final"],
  "settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
  "gui": {"x": 1024, "y": 320, "color": null, "colorSource": null, "sampleJson": null},
  "input": "MergeJoin-final",
  "select": [
    {"name": "Id", "rename": "Account ID"},
    {"name": "Name", "rename": "Account Name"},
    {"name": "Industry"},
    {"name": "Contact Count"},
    {"name": "Total Amount"}
  ],
  "tables": [{}]
}
  • Only columns listed in select are passed through; all others are dropped
  • Omit rename to keep the original column name

Alternative format — uses fields instead of select. Only list columns you want to KEEP (with optional rename). Unlisted columns are dropped. Do NOT add remove: true entries — they cause DP-0003 validation errors.

Only list columns you want to KEEP (with optional rename). Unlisted columns are dropped. Do NOT add remove: true entries — they cause DP-0003 validation errors.

"fields": [
  {"name": "ID", "rename": "Dataflow ID"},
  {"name": "Display Name", "rename": "Dataflow Name"},
  {"name": "Link", "rename": "Dataflow Link"}
]

The minimal field entry is just {"name": "...", "rename": "..."}. Do NOT include type, dateFormat, settings, or remove — these cause DP-0003 Action is improperly configured errors on the fields format.

PublishToVault (Output Node)

Writes the final data to a Domo dataset.

{
  "type": "PublishToVault",
  "id": "PublishToVault-output",
  "name": "SFDC | Account Summary",
  "dependsOn": ["MergeJoin-final"],
  "disabled": false,
  "removeByDefault": false,
  "notes": [],
  "settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
  "gui": {"x": 1248, "y": 320, "color": null, "colorSource": null, "sampleJson": null},
  "previewRowLimit": null,
  "dataSource": {
    "type": "DataFlow",
    "name": "SFDC | Account Summary",
    "cloudId": "domo"
  },
  "versionChainType": "REPLACE",
  "partitionIdColumns": [],
  "upsertColumns": [],
  "retainPartitionExpression": ""
}
FieldDescription
dependsOnArray with a single action ID — the final transform step
dataSource.type"DataFlow"
dataSource.nameName for the output dataset
dataSource.guidUUID of existing output dataset — omit entirely for new datasets
dataSource.cloudId"domo"
versionChainType"REPLACE" (full replace) or "APPEND"
partitionIdColumns[] — always empty unless using partitioning
upsertColumns[] — always empty unless doing upserts
retainPartitionExpression"" — always empty string

CRITICAL: Do NOT include inputs, schemaSource, partitioned, or tables in PublishToVault. These fields cause DP-DSCF commit failures where the ETL processes all rows successfully but then fails to write to the output dataset. This was confirmed through extensive testing (April 2026).

For new dataflows, omit guid entirely. Domo assigns a real output dataset UUID on the first successful run.

Complete Example: Account Summary ETL

This example creates a dataflow that:

  1. Loads 3 Salesforce datasets (Accounts, Contacts, Opportunities)
  2. Aggregates contacts per account (count)
  3. Aggregates opportunities per account (count, total amount, avg amount, expected revenue, avg probability)
  4. Left joins both aggregations to the accounts table
  5. Outputs one row per account with all summary metrics

Pipeline Diagram

LoadFromVault(Accounts) ─────────────────────┐
                                              ├─ MergeJoin(LEFT) ──┐
LoadFromVault(Opportunities)                  │   on Id=AccountId   │
  └─ GroupBy(AccountId) ─────────────────────┘                     │
       COUNT(Id) → Opportunity Count                               ├─ MergeJoin(LEFT) ─── PublishToVault
       SUM(Amount) → Total Amount                                  │   on Id=AccountId
       AVG(Amount) → Avg Amount                                    │
       SUM(ExpectedRevenue) → Total Expected Revenue               │
       AVG(Probability) → Avg Probability                          │
                                                                   │
LoadFromVault(Contacts)                                            │
  └─ GroupBy(AccountId) ──────────────────────────────────────────┘
       COUNT(Id) → Contact Count

Creation Command

curl -s -X POST "https://<instance>.domo.com/api/dataprocessing/v1/dataflows" \
  -H "Content-Type: application/json" \
  -H "x-domo-developer-token: <TOKEN>" \
  -d @sfdc_account_summary_etl.json

Execution

# Via CLI
echo -e "connect -server <instance>.domo.com -token <TOKEN>\ndataflow-run-now -i <DATAFLOW_ID>\nquit" \
  | java -jar domoutil.jar

# Via API
curl -s -X POST "https://<instance>.domo.com/api/dataprocessing/v1/dataflows/<ID>/executions" \
  -H "x-domo-developer-token: <TOKEN>"

Complete Example: Customer Summary with Rank & Window

This example creates a dataflow that:

  1. Loads a finance dataset (329,460 rows with customer, date, sales, revenue, cogs)
  2. Uses a WindowAction to rank orders per customer by date (ROW_NUMBER)
  3. Aggregates per customer: first order date (MIN), SUM and AVERAGE for sales/revenue/cogs, order count

Pipeline Diagram

LoadFromVault(Mododata | Finance)  329,460 rows
  └── WindowAction: ROW_NUMBER partitioned by customer, ordered by date_ymd ASC
       └── GroupBy(customer):
            MIN(date_ymd)  → First Order Date
            SUM(sales)     → Total Sales
            AVG(sales)     → Avg Sales
            SUM(revenue)   → Total Revenue
            AVG(revenue)   → Avg Revenue
            SUM(cogs)      → Total COGS
            AVG(cogs)      → Avg COGS
            COUNT(date_ymd)→ Order Count
              └── PublishToVault  →  104 customer rows

Key JSON Snippets

WindowAction (Rank & Window tile):

{
  "type": "WindowAction",
  "id": "WindowAction-first-order",
  "name": "First Order Date per Customer",
  "dependsOn": ["LoadFromVault-finance"],
  "input": "LoadFromVault-finance",
  "groupRules": [
    {"column": "customer", "caseSensitive": false}
  ],
  "orderRules": [
    {"column": "date_ymd", "caseSensitive": false, "ascending": true}
  ],
  "additions": [
    {
      "name": "Customer Order Rank",
      "operation": {
        "type": "RANKING",
        "operationType": "ROW_NUMBER",
        "column": null,
        "defaultValue": null,
        "amount": null
      }
    }
  ]
}

GroupBy with MIN for first order date:

{
  "type": "GroupBy",
  "id": "GroupBy-customer-summary",
  "name": "Customer Aggregations",
  "dependsOn": ["WindowAction-first-order"],
  "input": "WindowAction-first-order",
  "groups": [{"name": "customer"}],
  "fields": [
    {"name": "First Order Date", "source": "date_ymd", "type": "MIN"},
    {"name": "Total Sales", "source": "sales", "type": "SUM"},
    {"name": "Avg Sales", "source": "sales", "type": "AVERAGE"},
    {"name": "Total Revenue", "source": "revenue", "type": "SUM"},
    {"name": "Avg Revenue", "source": "revenue", "type": "AVERAGE"},
    {"name": "Total COGS", "source": "cogs", "type": "SUM"},
    {"name": "Avg COGS", "source": "cogs", "type": "AVERAGE"},
    {"name": "Order Count", "source": "date_ymd", "type": "COUNT_ALL"}
  ]
}

Result

Output dataset: 104 rows (one per customer) with columns: customer, First Order Date, Total Sales, Avg Sales, Total Revenue, Avg Revenue, Total COGS, Avg COGS, Order Count.

Complete Example: Monthly Dept Metrics with Filter & Formula

This example creates a dataflow that:

  1. Loads a sales dataset (481,643 rows)
  2. Filters out rows where state = 'Florida'
  3. Adds a Year_Month column using concat(year(), MONTHNAME())
  4. Aggregates by Year_Month + department + metric_name: SUM and AVERAGE for revenue, store_revenue, web_revenue, mobile_revenue, total_costs, visits

Pipeline Diagram

LoadFromVault(Mododata | Sales)  481,643 rows
  └── Filter: state != 'Florida'
       └── ExpressionEvaluator: Year_Month = concat(year(date_ymd), MONTHNAME(date_ymd))
            └── GroupBy(Year_Month, department, metric_name):
                 SUM/AVG for revenue, store_revenue, web_revenue,
                 mobile_revenue, total_costs, visits
                   └── PublishToVault  →  14,057 rows

Key JSON Snippets

Filter (exclude a specific value):

{
  "type": "Filter",
  "id": "Filter-exclude-florida",
  "name": "Exclude Florida",
  "dependsOn": ["LoadFromVault-sales"],
  "input": "LoadFromVault-sales",
  "filterList": [
    {
      "leftField": "state",
      "rightField": null,
      "rightValue": {"value": "Florida", "type": "STRING"},
      "rightExpr": "'Florida'",
      "operator": "NE",
      "expression": null,
      "andFilterList": []
    }
  ]
}

ExpressionEvaluator (date to year-month string):

{
  "type": "ExpressionEvaluator",
  "id": "ExpressionEvaluator-month-trunc",
  "name": "Add Month Column",
  "dependsOn": ["Filter-exclude-florida"],
  "input": "Filter-exclude-florida",
  "expressions": [
    {
      "expression": "concat(year(`date_ymd`),MONTHNAME(`date_ymd`))",
      "fieldName": "Year_Month",
      "settings": {}
    }
  ]
}

Result

Output: 14,057 rows (1 row per month x department x metric_name, excluding Florida). Granularity reduced from 481K daily rows to 14K monthly aggregated rows.

ETL Error Codes Reference

When a dataflow execution fails, the error object in lastExecution.errors[] contains a code field. Use this table to diagnose:

CodeCategoryMeaningTypical Fix
DP-DSNFMissing inputRequired dataset does not existRecreate dataset or remove the LoadFromVault tile
DP-61100Missing inputSame as DP-DSNF (alternate code)Same as above
DP-0001Schema mismatchColumn referenced but not foundUpstream schema changed — update column references
DP-0059Formula errorSyntax error in expressionFix formula (e.g., missing END on CASE statement)
DP-0118Code/model crashTransform job failureCheck Python script or AI model tile
DP-TGTFRData volumeBatch Text Generation needs >= 100 rowsEnsure input has enough rows
MYSQL-601072Join key missingKey column doesn't exist in tableUpdate join key column names
DP-0000UnknownNo API-level detailsInspect in Domo UI

Tracing Errors to Specific Tiles

Error objects contain a parameters map with _actionId (UUID of the failing tile). Match it against actions[].id in the dataflow:

errors = dataflow.get("lastExecution", {}).get("errors", [])
actions_by_id = {a["id"]: a for a in dataflow.get("actions", [])}
for e in errors:
    action_id = e.get("parameters", {}).get("_actionId", "")
    tile = actions_by_id.get(action_id, {})
    print(f'Error: [{e["code"]}] {e["localizedMessage"]}')
    print(f'Tile: "{tile.get("name", "?")}" (type: {tile.get("type", "?")})')
    print(f'Property: {e.get("parameters", {}).get("_propertyPath", "")}')
_actionId tile typeWhat to inspect
ExpressionEvaluatorexpressions[].expression — the formula text
LoadFromVaultdataSourceId — the input dataset UUID
MergeJoinkeys1 / keys2 — join key column names
SelectValuesfields[].name — column names being selected
FilterfilterList[].leftField — filter column
PublishToVaultdataSource.guid — output dataset UUID

Common Pitfalls

1. DP-DSCF Commit Failure — Wrong PublishToVault Structure

The error "Failed to commit data to data source <UUID>" (code DP-DSCF) is caused by incorrect PublishToVault fields. The ETL will process all rows successfully but then fail at the commit step.

Root cause (confirmed April 2026): Using inputs, schemaSource, partitioned, or tables in the PublishToVault action.

Fix: Use this exact structure — partitionIdColumns, upsertColumns, retainPartitionExpression — and omit inputs, schemaSource, partitioned, tables:

{
  "type": "PublishToVault",
  "dataSource": {"type": "DataFlow", "name": "Output Name", "cloudId": "domo"},
  "versionChainType": "REPLACE",
  "partitionIdColumns": [],
  "upsertColumns": [],
  "retainPartitionExpression": ""
}

2. SelectValues fields Format — Only List Columns to Keep

The fields format of SelectValues causes DP-0003 Action is improperly configured if you include entries with "remove": true or extra fields like type, dateFormat, settings. Only list columns you want to keep:

"fields": [
  {"name": "ID", "rename": "Dataset ID"},
  {"name": "Name", "rename": "Dataset Name"}
]

Columns not listed are automatically dropped. Do NOT add remove entries.

3. Column Name Conflicts in Joins

When joining two datasets that share column names (e.g., Id, Name, Description), you must use schemaModification2 on the MergeJoin to rename or remove conflicting columns from the right-side dataset. Failing to do this results in ambiguous column names downstream.

4. Action IDs Must Be Unique

Every action in the actions array needs a unique id string. Convention is TypeName-uuid (e.g., "LoadFromVault-b71d89d7-6c08-44ad-a503-ebed046377e0"), but any unique string works (e.g., "LoadFromVault-accounts").

5. dependsOn Must Match step1/step2/input

For MergeJoin, the dependsOn array must contain both step1 and step2 action IDs. For GroupBy, the dependsOn must contain the input action ID. Mismatches will cause the dataflow to fail.

6. GUI Positions Affect the Visual Canvas

The gui.x and gui.y values determine where nodes appear in the Domo Magic ETL visual editor. Space nodes approximately 224px apart horizontally and 192px vertically for a clean layout. Input nodes typically start at x: 128.

When useGraphUI: true is set (the modern canvas mode), tile positions are controlled by the gui.canvases.default.elements array at the top level — not by the action-level gui fields. Always set both to stay consistent. See the "Top-Level gui Field" section for the full Section and Tile element schema.

7. Dataflow Creation via API — Auth (Updated April 2026)

Auth: POST /api/dataprocessing/v1/dataflows works with developer tokens (DDCI...) on most instances (confirmed April 2026). The body must include "databaseType": "MAGIC". The created dataflow is NOT in DRAFT state and can be executed immediately via API — no UI save required.

Outputs: When POST includes "outputs": [{"dataSourceId": null, "dataSourceName": "...", "versionChainType": "REPLACE"}], Domo assigns a real output dataset UUID immediately. The first successful execution creates the actual dataset.

CLI: The domo (ryuu) CLI is for Custom App publishing only and has no dataflow commands. The Java CLI (domoutil.jar) has dataflow commands but requires separate setup.

8. Aggregation Type Names Are Not What You'd Expect

The GroupBy type field uses MIN and MAX, not MINIMUM or MAXIMUM. Using MINIMUM returns a validation error:

{"code":"VALIDATION-DIV","message":"The value is invalid for expected type.","path":"actions[2].fields[0].type","parameters":{"field":"type","type":"AggregateType","rejected":"MINIMUM"}}

Confirmed working types: SUM, AVERAGE, COUNT_ALL, MIN. Use these exact strings.

9. Filter rightValue Must Be a Typed Object

The Filter action's rightValue cannot be a plain string. It must be a typed object:

// WRONG — returns VALIDATION-DE error
"rightValue": "Florida"

// CORRECT
"rightValue": {"value": "Florida", "type": "STRING"}

Additionally, rightExpr must wrap string values in single quotes: "'Florida'". Both rightValue and rightExpr should be set together.

10. TRUNC_MONTH and Other Date Functions Don't Exist

The ExpressionEvaluator does not support TRUNC_MONTH(), DATE_TRUNC(), or similar date truncation functions. To get a year-month value, use string concatenation:

concat(year(`date_ymd`), MONTHNAME(`date_ymd`))

Known working functions: year(), MONTHNAME(), concat(), DATE().

11. Dataflows Created via POST Can Be Executed Immediately (Updated April 2026)

Contrary to earlier notes, dataflows created via POST /api/dataprocessing/v1/dataflows with a dev token are NOT in DRAFT state and can be executed immediately via POST.../executions. The outputs array IS populated on creation when dataSourceId: null is passed. No UI save required. Executions return a valid execution ID and run to completion.

12. CLI dataflow-run-now Can Fail on New Dataflows

The Java CLI dataflow-run-now command may return 500 errors for newly created dataflows. Always use the API for running (POST /api/dataprocessing/v1/dataflows/{id}/executions) — it's more reliable.

13. responsibleUserId Is Optional

No need to specify responsibleUserId in the POST body — it defaults to the authenticated user.

14. LoadFromVault Nodes Can Feed Multiple Branches

A single LoadFromVault node can feed multiple downstream branches — just reference its ID in multiple dependsOn arrays. This avoids loading the same dataset twice.

15. PublishToVault — Use dependsOn Only, NOT inputs

The PublishToVault action uses dependsOn to reference its upstream action. Do NOT include an inputs array — it is not part of the working format and contributes to DP-DSCF commit failures. If numOutputs = 0 after creation, the dataSource object is likely missing from the action — PUT the corrected definition to fix.

16. API Token Authentication

The REST API uses the same developer token as the CLI:

x-domo-developer-token: <TOKEN>

This is different from OAuth — no client ID/secret exchange is needed.

19. All Non-LoadFromVault Actions Require disabled, removeByDefault, notes

Every action except LoadFromVault must include these fields or the dataflow may behave unexpectedly in the UI:

"disabled": false,
"removeByDefault": false,
"notes": [],
"previewRowLimit": null

MergeJoin additionally requires "on": null and explicit "schemaModification1": [] and "schemaModification2": [] (even when empty).

LoadFromVault uses "previewRowLimit": 10000 (not null).

20. relationshipType Must Be "MTM" Not "MANY_TO_MANY"

The MergeJoin field relationshipType must be the abbreviated form "MTM". Using "MANY_TO_MANY" causes validation errors. Other valid values: "OTO", "OTM", "MTO".

21. Always Ask for a Master Dataset Anchor Before Building Lineage ETLs

Before building any dataset lineage ETL, ask: "Is there a master 'My Datasets' or similar list dataset that every output row should be tied back to?" This anchor dataset (typically containing Dataset ID, Name, Link, Owner, etc.) should be loaded as the LEFT side of the final join so all datasets appear in the output — even those with no card/ETL associations (standalone datasets). Missing this anchor means the output only covers datasets that happen to appear in other metadata tables, missing any standalone ones.

17. Do NOT Use ?hydrate=full When Fetching Dataflows

GET /api/dataprocessing/v1/dataflows/{id}?hydrate=full returns 400 Bad Request for some dataflows. The non-hydrated endpoint (GET /api/dataprocessing/v1/dataflows/{id}) already returns the full actions[] array with all tile details. Always use the non-hydrated version.

18. PUT Replaces the Entire Dataflow Definition

When updating a dataflow via PUT /api/dataprocessing/v1/dataflows/{id}:

  • Send the full dataflow object — PUT replaces the entire definition. Always start from a fresh GET.
  • PUT only saves — it does not run the dataflow. Trigger execution separately with POST.../executions.
  • Version tracking — each successful PUT increments onboardFlowVersion.versionNumber. The execution response includes dataFlowVersion to confirm which version ran.

Known Action Types

All action types discovered across existing dataflows in the instance:

Action TypeDescriptionConfirmed Working
LoadFromVaultInput node — loads a Domo datasetYes
PublishToVaultOutput node — writes to a Domo datasetYes
MergeJoinJoin two upstream actions on keysYes
GroupByAggregate with SUM, AVERAGE, MIN, COUNT_ALL, etc.Yes
WindowActionRank & Window — ROW_NUMBER, RANK, LAG, LEADYes
SelectValuesSelect and rename columnsYes (but can cause commit errors before PublishToVault)
FilterFilter rows based on conditions (NE, EQ, NN, etc.)Yes
ExpressionEvaluatorAdd calculated columns / formulas (concat, year, MONTHNAME, DATE)Yes
UniqueDeduplicate rows by key columnsDocumented (from patterns guide)
MetadataChange column types or metadataSeen in existing dataflows
SplitColumnActionSplit a column into multiple columnsSeen in existing dataflows
FixedInputHardcoded/constant input dataSeen in existing dataflows

Workflow: Creating a New Magic ETL

Pre-Flight Questions (ask before building)

  • What are all the input dataset IDs and their column schemas? (query each via /api/query/v1/execute/<UUID> with SELECT * FROM table LIMIT 2)
  • Is there a master/anchor dataset (e.g., "My Datasets") that every output row should tie back to? If yes, get its UUID — it becomes the LEFT side of the final join.
  • What are the exact desired output column names and which input fields map to each?

Build Steps

  1. Get input dataset schemasPOST /api/query/v1/execute/<UUID> with {"sql": "SELECT * FROM table LIMIT 2"} on each input dataset
  2. Build the JSON definition — use the confirmed working action structures from this skill doc
  3. Add colored Section zones — group related tiles into Section elements in gui.canvases.default.elements. Assign each logical branch or processing stage a distinct color. Reparent Tile elements into their sections using parentId and relative coordinates. This step is required for all dataflows with 2+ branches or stages.
  4. Create via APIPOST /api/dataprocessing/v1/dataflows with dev token — works immediately, no UI save needed
  5. ExecutePOST /api/dataprocessing/v1/dataflows/<ID>/executions
  6. Check statusGET /api/dataprocessing/v1/dataflows/<ID>/executions/<EXEC_ID> — poll until state is SUCCESS or FAILED_DATA_FLOW
  7. On failure — check errors[] array in execution response for actionId and localizedMessage, fix the specific action, PUT the updated definition, re-run
  8. Export for debuggingGET /api/dataprocessing/v1/dataflows/<ID> returns the full saved definition including any server-assigned GUIDs

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

34.59%
按下载量换算99

Claude

30.94%
按下载量换算89

Cursor

19.01%
按下载量换算55

Gemini CLI

8.09%
按下载量换算23

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

未通过

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills