[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M699G6XY1WTG7ESA1Y7YYCKT":3,"skill-same:01M699G6XY1WTG7ESA1Y7YYCKT":64},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":36,"linkOnly":37,"markdownContent":38,"markdownBody":39,"frontMatter":40,"refName":41,"commitSha":42,"skillDirectory":43,"forksCount":44,"repositoryHtmlUrl":45,"repositoryHomepageUrl":6,"ownerHtmlUrl":46,"ownerBlogUrl":47,"ownerDescription":48,"updatedAt":49,"install":50,"resources":63},"01M699G6XY1WTG7ESA1Y7YYCKT","query-builder-dax",null,"Guide for the DAX query shape produced by the Query Builder in the DAX test widget. Use this when modifying how the Query Builder generates DAX, or when generating an EVALUATE query from columns, measures, filters and sorting.","microsoft\u002Fsemantic-link-labs","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M699FKMT63C17BFNH8WHZN2K",599,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fsemantic-link-labs\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fquery-builder-dax\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],"dax","query builder dax","query builder","builder","query","when","test","evaluate","for","sorting","columns","widget","filters","shape","use","guide","how","2026-11-10 10:12:30",false,"---\nname: query-builder-dax\ndescription: Guide for the DAX query shape produced by the Query Builder in the DAX test widget. Use this when modifying how the Query Builder generates DAX, or when generating an EVALUATE query from columns, measures, filters and sorting.\n---\n\n# SKILL.md — Query Builder DAX Generation\n\n## Purpose\n\nDocument the canonical DAX query structure produced by the Query Builder in\nthe DAX performance test widget (`_build_summarize_dax` in\n`src\u002Fsempy_labs\u002Fsemantic_model\u002F_test_dax.py`).\n\nThe pattern follows the well-known \"Using DAX as a Query Language\" approach\n(Michael Kovalsky, Elegant BI:\n\u003Chttps:\u002F\u002Fwww.elegantbi.com\u002Fpost\u002Fdaxquerylanguage>), built on\n`SUMMARIZECOLUMNS`.\n\nUse this skill when changing how Query Builder state (columns, measures,\nfilters, sorting) is converted to DAX, so the generated query stays valid and\nconsistent.\n\n---\n\n## The canonical query shape\n\n```dax\nEVALUATE\nSUMMARIZECOLUMNS(\n    'Geography'[Area],\n    'Geography'[Country],\n    'Product'[Product],\n    FILTER(KEEPFILTERS(VALUES('Product'[Product Category])), 'Product'[Product Category] = \"Bicycles\"),\n    \"Revenue\", [Revenue]\n)\nORDER BY 'Geography'[Area], 'Geography'[Country]\n```\n\n`SUMMARIZECOLUMNS` implies the aggregation (the SQL `GROUP BY` is not needed)\nand the model relationships handle the joins.\n\n---\n\n## Element order (STRICT — wrong order errors out)\n\nInside `SUMMARIZECOLUMNS(...)` the elements MUST appear in this order:\n\n| # | Element | Where it goes | Syntax |\n|---|---------|---------------|--------|\n| 1 | **Attributes (columns)** | First | `'Table'[Column]` — one per group-by column, left to right |\n| 2 | **Filters (on columns)** | After all attributes | `FILTER(KEEPFILTERS(VALUES('Table'[Column])), \u003Cpredicate>)` — one per filter, any order |\n| 3 | **Measures** | After all filters | `\"Display Name\", [Measure]` — display name in quotes, measure in brackets |\n\nThen, OUTSIDE `SUMMARIZECOLUMNS`:\n\n| Element | Where it goes | Syntax |\n|---------|---------------|--------|\n| **Sorting** | Final clause, after the table expression | `ORDER BY 'Table'[Column] [ASC\\|DESC], ...` (defaults to ascending) |\n\n---\n\n## Columns (attributes)\n\n- Each group-by column from the builder's *Columns & Measures* pane becomes an\n  attribute, in pane order (top to bottom = left to right in the result).\n- Always fully qualify: `'Table'[Column]`. Escape `'` → `''` in the table name\n  and `]` → `]]` in the column name.\n\n## Measures\n\n- Each measure from the *Columns & Measures* pane becomes a measure element.\n- Syntax is `\"Display Name\", [Measure]`. The display name only renames the\n  output column; it does not rename the model measure.\n- Custom\u002Ftest measures can be added with a `DEFINE MEASURE ... ` block placed\n  **before** `EVALUATE`, then referenced in the measures section. (The Query\n  Builder currently only references existing model measures.)\n\n## Filters\n\nFilters come from the builder's *Filters* pane. Split by object kind:\n\n- **Column filters** go **inside** `SUMMARIZECOLUMNS`, after the attributes,\n  each as:\n  ```dax\n  FILTER(KEEPFILTERS(VALUES('Table'[Column])), \u003Cpredicate>)\n  ```\n  `KEEPFILTERS(VALUES(...))` preserves any existing filter context on that\n  column while applying the new condition.\n\n- **Measure filters** cannot live inside `SUMMARIZECOLUMNS` (measures are not\n  yet projected at that point). Wrap the whole table instead:\n  ```dax\n  FILTER(\n      SUMMARIZECOLUMNS( ... ),\n      [Measure] > 100\n  )\n  ```\n  Multiple measure predicates are combined with `&&`.\n\n### Predicate operators\n\n`_qb_build_predicate` maps a filter item (`ref`, `kind`, `data_type`, `op`,\n`value`, `value2`) to a boolean predicate:\n\n| Filter family | Operators → DAX |\n|---------------|-----------------|\n| text | `eq` `=`, `ne` `\u003C>`, `contains` `CONTAINSSTRING(ref, \"v\")`, `startswith` `LEFT(ref, n) = \"v\"` |\n| numeric \u002F datetime \u002F measure | `eq` `=`, `ne` `\u003C>`, `gt` `>`, `ge` `>=`, `lt` `\u003C`, `le` `\u003C=`, `between` `ref >= lo && ref \u003C= hi` |\n| boolean | `istrue` `ref = TRUE()`, `isfalse` `ref = FALSE()` |\n| any | `blank` `ISBLANK(ref)`, `notblank` `NOT ISBLANK(ref)` |\n\nValue literals:\n- numeric → bare number (quoted string if not numeric),\n- datetime → `DATE(y, m, d)` when the value matches `YYYY-MM-DD`, else a quoted\n  string,\n- text → quoted string (`\"` escaped as `\"\"`).\n\n## Sorting (ORDER BY)\n\n- The `ORDER BY` clause is the final part of the query, placed **after** the\n  (possibly `FILTER`-wrapped) `SUMMARIZECOLUMNS` table expression.\n- It is driven by the builder's *Order By* pane, which mirrors the\n  columns\u002Fmeasures from the *Columns & Measures* pane. Each Order By item has:\n  - a **toggle** (on\u002Foff, default **off**) — only enabled items appear in\n    `ORDER BY`;\n  - a **direction** icon — A-Z = ascending (`ASC`), Z-A = descending (`DESC`);\n  - independent **reorder** support (the pane order = clause order).\n- The serialized state carries an `order_by` list of items\n  (`ref`, `kind`, `name`, `table`, `enabled`, `dir`). `_build_summarize_dax`\n  emits `ORDER BY \u003Cref> ASC|DESC, ...` for the enabled items, in pane order.\n- Measures can be used in `ORDER BY` because each measure is projected as a\n  column in the result.\n- If the `order_by` key is **absent** (legacy state), the builder falls back to\n  ordering by all attribute columns ascending. If present but no item is\n  enabled, no `ORDER BY` is emitted.\n\n---\n\n## Edge cases\n\n- **Measures only (no columns):** emit `SUMMARIZECOLUMNS(\"Name\", [Measure], ...)`\n  with no attributes and no `ORDER BY`. Column filters still apply inside;\n  measure filters still wrap the outside.\n- **Nothing usable:** return an empty string (no columns and no measures).\n- **TOPN:** to cap rows, wrap the table in `TOPN(n, \u003Ctable>)` (respects the\n  `ORDER BY`). Not currently emitted by the Query Builder.\n\n---\n\n## Keep in sync\n\nThe JS front-end (`onBuildClick`) serializes builder state to JSON with\nsnake_case keys; the Python helpers read them. When adding operators or field\nmetadata, update BOTH:\n\n- JS `QB_OPS` \u002F chip serialization in `_test_dax.py` (widget_js),\n- Python `_qb_build_predicate` \u002F `_classify_filter_type` \u002F `_build_summarize_dax`.\n\nField objects use keys: `kind`, `table`, `name`, `data_type`, `ref`.\nFilter objects additionally: `op`, `value`, `value2`.\nOrder By objects additionally: `enabled` (bool), `dir` (`\"asc\"`\u002F`\"desc\"`).\n","# SKILL.md — Query Builder DAX Generation\n\n## Purpose\n\nDocument the canonical DAX query structure produced by the Query Builder in\nthe DAX performance test widget (`_build_summarize_dax` in\n`src\u002Fsempy_labs\u002Fsemantic_model\u002F_test_dax.py`).\n\nThe pattern follows the well-known \"Using DAX as a Query Language\" approach\n(Michael Kovalsky, Elegant BI:\n\u003Chttps:\u002F\u002Fwww.elegantbi.com\u002Fpost\u002Fdaxquerylanguage>), built on\n`SUMMARIZECOLUMNS`.\n\nUse this skill when changing how Query Builder state (columns, measures,\nfilters, sorting) is converted to DAX, so the generated query stays valid and\nconsistent.\n\n---\n\n## The canonical query shape\n\n```dax\nEVALUATE\nSUMMARIZECOLUMNS(\n    'Geography'[Area],\n    'Geography'[Country],\n    'Product'[Product],\n    FILTER(KEEPFILTERS(VALUES('Product'[Product Category])), 'Product'[Product Category] = \"Bicycles\"),\n    \"Revenue\", [Revenue]\n)\nORDER BY 'Geography'[Area], 'Geography'[Country]\n```\n\n`SUMMARIZECOLUMNS` implies the aggregation (the SQL `GROUP BY` is not needed)\nand the model relationships handle the joins.\n\n---\n\n## Element order (STRICT — wrong order errors out)\n\nInside `SUMMARIZECOLUMNS(...)` the elements MUST appear in this order:\n\n| # | Element | Where it goes | Syntax |\n|---|---------|---------------|--------|\n| 1 | **Attributes (columns)** | First | `'Table'[Column]` — one per group-by column, left to right |\n| 2 | **Filters (on columns)** | After all attributes | `FILTER(KEEPFILTERS(VALUES('Table'[Column])), \u003Cpredicate>)` — one per filter, any order |\n| 3 | **Measures** | After all filters | `\"Display Name\", [Measure]` — display name in quotes, measure in brackets |\n\nThen, OUTSIDE `SUMMARIZECOLUMNS`:\n\n| Element | Where it goes | Syntax |\n|---------|---------------|--------|\n| **Sorting** | Final clause, after the table expression | `ORDER BY 'Table'[Column] [ASC\\|DESC], ...` (defaults to ascending) |\n\n---\n\n## Columns (attributes)\n\n- Each group-by column from the builder's *Columns & Measures* pane becomes an\n  attribute, in pane order (top to bottom = left to right in the result).\n- Always fully qualify: `'Table'[Column]`. Escape `'` → `''` in the table name\n  and `]` → `]]` in the column name.\n\n## Measures\n\n- Each measure from the *Columns & Measures* pane becomes a measure element.\n- Syntax is `\"Display Name\", [Measure]`. The display name only renames the\n  output column; it does not rename the model measure.\n- Custom\u002Ftest measures can be added with a `DEFINE MEASURE ... ` block placed\n  **before** `EVALUATE`, then referenced in the measures section. (The Query\n  Builder currently only references existing model measures.)\n\n## Filters\n\nFilters come from the builder's *Filters* pane. Split by object kind:\n\n- **Column filters** go **inside** `SUMMARIZECOLUMNS`, after the attributes,\n  each as:\n  ```dax\n  FILTER(KEEPFILTERS(VALUES('Table'[Column])), \u003Cpredicate>)\n  ```\n  `KEEPFILTERS(VALUES(...))` preserves any existing filter context on that\n  column while applying the new condition.\n\n- **Measure filters** cannot live inside `SUMMARIZECOLUMNS` (measures are not\n  yet projected at that point). Wrap the whole table instead:\n  ```dax\n  FILTER(\n      SUMMARIZECOLUMNS( ... ),\n      [Measure] > 100\n  )\n  ```\n  Multiple measure predicates are combined with `&&`.\n\n### Predicate operators\n\n`_qb_build_predicate` maps a filter item (`ref`, `kind`, `data_type`, `op`,\n`value`, `value2`) to a boolean predicate:\n\n| Filter family | Operators → DAX |\n|---------------|-----------------|\n| text | `eq` `=`, `ne` `\u003C>`, `contains` `CONTAINSSTRING(ref, \"v\")`, `startswith` `LEFT(ref, n) = \"v\"` |\n| numeric \u002F datetime \u002F measure | `eq` `=`, `ne` `\u003C>`, `gt` `>`, `ge` `>=`, `lt` `\u003C`, `le` `\u003C=`, `between` `ref >= lo && ref \u003C= hi` |\n| boolean | `istrue` `ref = TRUE()`, `isfalse` `ref = FALSE()` |\n| any | `blank` `ISBLANK(ref)`, `notblank` `NOT ISBLANK(ref)` |\n\nValue literals:\n- numeric → bare number (quoted string if not numeric),\n- datetime → `DATE(y, m, d)` when the value matches `YYYY-MM-DD`, else a quoted\n  string,\n- text → quoted string (`\"` escaped as `\"\"`).\n\n## Sorting (ORDER BY)\n\n- The `ORDER BY` clause is the final part of the query, placed **after** the\n  (possibly `FILTER`-wrapped) `SUMMARIZECOLUMNS` table expression.\n- It is driven by the builder's *Order By* pane, which mirrors the\n  columns\u002Fmeasures from the *Columns & Measures* pane. Each Order By item has:\n  - a **toggle** (on\u002Foff, default **off**) — only enabled items appear in\n    `ORDER BY`;\n  - a **direction** icon — A-Z = ascending (`ASC`), Z-A = descending (`DESC`);\n  - independent **reorder** support (the pane order = clause order).\n- The serialized state carries an `order_by` list of items\n  (`ref`, `kind`, `name`, `table`, `enabled`, `dir`). `_build_summarize_dax`\n  emits `ORDER BY \u003Cref> ASC|DESC, ...` for the enabled items, in pane order.\n- Measures can be used in `ORDER BY` because each measure is projected as a\n  column in the result.\n- If the `order_by` key is **absent** (legacy state), the builder falls back to\n  ordering by all attribute columns ascending. If present but no item is\n  enabled, no `ORDER BY` is emitted.\n\n---\n\n## Edge cases\n\n- **Measures only (no columns):** emit `SUMMARIZECOLUMNS(\"Name\", [Measure], ...)`\n  with no attributes and no `ORDER BY`. Column filters still apply inside;\n  measure filters still wrap the outside.\n- **Nothing usable:** return an empty string (no columns and no measures).\n- **TOPN:** to cap rows, wrap the table in `TOPN(n, \u003Ctable>)` (respects the\n  `ORDER BY`). Not currently emitted by the Query Builder.\n\n---\n\n## Keep in sync\n\nThe JS front-end (`onBuildClick`) serializes builder state to JSON with\nsnake_case keys; the Python helpers read them. When adding operators or field\nmetadata, update BOTH:\n\n- JS `QB_OPS` \u002F chip serialization in `_test_dax.py` (widget_js),\n- Python `_qb_build_predicate` \u002F `_classify_filter_type` \u002F `_build_summarize_dax`.\n\nField objects use keys: `kind`, `table`, `name`, `data_type`, `ref`.\nFilter objects additionally: `op`, `value`, `value2`.\nOrder By objects additionally: `enabled` (bool), `dir` (`\"asc\"`\u002F`\"desc\"`).\n",{"name":5,"description":7},"main","2ddf46109c1209ceffa88149f4631e7b2275f9a1",".claude\u002Fskills\u002Fquery-builder-dax",204,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fsemantic-link-labs","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-11-13 04:54:42",{"source":8,"skillName":5,"commands":51,"prompt":61,"zipAvailable":62},[52,55,58],{"tool":53,"command":54},"npx","npx skills add microsoft\u002Fsemantic-link-labs --skill query-builder-dax",{"tool":56,"command":57},"bunx","bunx skills add microsoft\u002Fsemantic-link-labs --skill query-builder-dax",{"tool":59,"command":60},"pnpm","pnpm dlx skills add microsoft\u002Fsemantic-link-labs --skill query-builder-dax","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fsemantic-link-labs\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fquery-builder-dax\u002FSKILL.md",true,[],[65,94,126,143,159,173],{"skillNo":66,"name":67,"nameZh":6,"description":68,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":69,"categories":70,"keywords":84,"publishedAt":36},"01M699GKE0WWT6YVHBS06KM8AH","write-tests","Guide for writing unit tests. Use this when creating tests to verify Python logic.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fsemantic-link-labs\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fwrite-tests\u002FSKILL.md",[71,76,79],{"categoryNo":72,"categoryName":73,"taxonomyType":74,"taxonomyTypeDesc":75},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":77,"categoryName":78,"taxonomyType":74,"taxonomyTypeDesc":75},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":80,"categoryName":81,"taxonomyType":82,"taxonomyTypeDesc":83},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[85,86,87,27,88,24,89,90,91,92,33,34,93],"write tests","write","tests","unit","logic","writing","python","unit tests","verify",{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":109,"publishedAt":36},"01M699GGVJHWCJNW68P08VWCMA","ui-styling","Guide for the visual style, structure, and shared building blocks used by Semantic Link Labs interactive UI tools (HTML widgets and anywidget-based widgets). Use this when adding a new interactive UI, modifying an existing one, or adding shared visual components.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fsemantic-link-labs\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fui-styling\u002FSKILL.md",[100,103,106],{"categoryNo":101,"categoryName":102,"taxonomyType":74,"taxonomyTypeDesc":75},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":104,"categoryName":105,"taxonomyType":74,"taxonomyTypeDesc":75},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":107,"categoryName":108,"taxonomyType":82,"taxonomyTypeDesc":83},"01JBSEEDCAT000000000000032","设计师",[110,111,112,33,113,114,115,34,116,117,118,119,120,121,122,123,124,27,125,24],"ui styling","ui","styling","visual","structure","html","interactive","Building Blocks","Tools","components","shared","widgets","style","visual style","blocks","Existing",{"skillNo":127,"name":128,"nameZh":6,"description":129,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":130,"categories":131,"keywords":132,"publishedAt":36},"01M699GEZ3YRK8PCPVZF4NEEWF","tom-operations","Guide for working with the TOM (Tabular Object Model) wrapper. Use this when modifying semantic models programmatically.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fsemantic-link-labs\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ftom-operations\u002FSKILL.md",[],[133,134,34,135,27,136,137,138,139,140,33,24,141,142],"operations","tom operations","tabular","object","with","semantic","models","Wrapper","model","semantic models",{"skillNo":144,"name":145,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":147,"categories":148,"keywords":155,"publishedAt":36},"01M699GCWWBZM2XFNW5PTGRFJP","sql_to_dax","Guide for translating SQL aggregation expressions into DAX measures.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fsemantic-link-labs\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fsql_to_dax\u002FSKILL.md",[149,152],{"categoryNo":150,"categoryName":151,"taxonomyType":74,"taxonomyTypeDesc":75},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":153,"categoryName":154,"taxonomyType":82,"taxonomyTypeDesc":83},"01JBSEEDCAT000000000000033","数据分析师",[156,157,19,27,34,158],"sql","sql to dax","aggregation",{"skillNo":160,"name":161,"nameZh":6,"description":162,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":165,"publishedAt":36},"01M699GAY10VVK66E4QGT94A93","run-tests","Guide for running pytest tests locally. Use this when running tests to verify code changes.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fsemantic-link-labs\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Frun-tests\u002FSKILL.md",[],[87,166,167,27,168,33,34,93,169,170,171,172,24],"run","run tests","pytest","running tests","code","changes","running",{"skillNo":174,"name":175,"nameZh":6,"description":176,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":177,"categories":178,"keywords":183,"publishedAt":36},"01M699G8V718EXYE8BR7NX734G","rest-api-patterns","Guide for implementing REST API wrapper functions. Use this when adding new API wrappers or troubleshooting API calls.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fsemantic-link-labs\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Frest-api-patterns\u002FSKILL.md",[179,180],{"categoryNo":150,"categoryName":151,"taxonomyType":74,"taxonomyTypeDesc":75},{"categoryNo":181,"categoryName":182,"taxonomyType":82,"taxonomyTypeDesc":83},"01JBSEEDCAT000000000000030","开发工程师",[184,185,186,187,188,189,27,24,190,191,192,140,33,34,193],"REST","api patterns","rest api","rest api patterns","api","patterns","implementing","calls","functions","troubleshooting"]