Sync third-party and MCP marketplace plugins

Constraint: Public skills are published only by explicit administrator action unless they are tracked third-party market sources.
Confidence: high
Scope-risk: narrow
Directive: Keep private/internal skills out of the public marketplace and preserve normal incremental market Git history.
Tested: Marketplace validation passed.
This commit is contained in:
KeyInfo Bot committed 2026-10-24 00:02:56 +08:00
1 parent ed52dd300b
commit e224150d81
15 files changed
+215 -43

No files matched your search

+13 -13
View File
@@ -105,8 +105,8 @@
"repo": "https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git", "repo": "https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git",
"ref": "main", "ref": "main",
"adapter": "claude-skill", "adapter": "claude-skill",
"commit": "623a9a9037d006ea727f8213f084d02a6b6f11b5", "commit": "d14efff8ed1faa4187f004f79926f428c8074ec7",
"syncedAt": "2026-10-22T16:00:00Z" "syncedAt": "2026-10-23T16:00:00Z"
}, },
{ {
"id": "caveman", "id": "caveman",
@@ -114,8 +114,8 @@
"repo": "https://github.com/JuliusBrussee/caveman.git", "repo": "https://github.com/JuliusBrussee/caveman.git",
"ref": "main", "ref": "main",
"adapter": "codex-plugin", "adapter": "codex-plugin",
"commit": "bad48a0e1df55e05e3f52249afa35ecc1909ee76", "commit": "b4531dfc05a3ef0ba93b57e8bfa5f48564a4b4d6",
"syncedAt": "2026-10-21T06:48:34Z" "syncedAt": "2026-10-23T16:00:00Z"
}, },
{ {
"id": "taste-skill", "id": "taste-skill",
@@ -132,8 +132,8 @@
"repo": "https://github.com/shadcn-ui/ui.git", "repo": "https://github.com/shadcn-ui/ui.git",
"ref": "main", "ref": "main",
"adapter": "claude-skill", "adapter": "claude-skill",
"commit": "25af02b1b467fcd53b63e0c6d6d324c57c16ef18", "commit": "3d98900e9b73c45f035f8109e9d41ba6a51685e7",
"syncedAt": "2026-10-22T16:00:00Z" "syncedAt": "2026-10-23T16:00:00Z"
}, },
{ {
"id": "frontend-slides", "id": "frontend-slides",
@@ -168,8 +168,8 @@
"repo": "https://github.com/hugohe3/ppt-master.git", "repo": "https://github.com/hugohe3/ppt-master.git",
"ref": "main", "ref": "main",
"adapter": "claude-skill", "adapter": "claude-skill",
"commit": "622bf0148bca4f697b0184322c7e2aa2a04520a2", "commit": "523e5bd972f94c3cac8742fec0d54d43824a17bb",
"syncedAt": "2026-10-22T16:00:00Z" "syncedAt": "2026-10-23T16:00:00Z"
}, },
{ {
"id": "grill-me", "id": "grill-me",
@@ -220,10 +220,10 @@
"id": "artemis-automation", "id": "artemis-automation",
"pluginName": "artemis-automation", "pluginName": "artemis-automation",
"repo": "https://git.playones.com/chenmingxuan/Artemis-Eapil.git", "repo": "https://git.playones.com/chenmingxuan/Artemis-Eapil.git",
"ref": "v2.0.1", "ref": "v2.1.0",
"adapter": "claude-skill", "adapter": "claude-skill",
"commit": "b584dae80aaae66607d6335bf1efa4b847f1955b", "commit": "83bcfd54d578a76aaea73e059a8547e3dc07ddbd",
"syncedAt": "2026-10-22T16:00:00Z" "syncedAt": "2026-10-23T16:00:00Z"
}, },
{ {
"id": "embedded-app-pc-debug", "id": "embedded-app-pc-debug",
@@ -258,8 +258,8 @@
"repo": "https://github.com/vercel/next.js.git", "repo": "https://github.com/vercel/next.js.git",
"ref": "canary", "ref": "canary",
"adapter": "skill-collection", "adapter": "skill-collection",
"commit": "443a9e7abf105be7b9e4bfe77200aebb2d46645f", "commit": "3dd7baa502a13a96836680fa4d84cb5020ae94fc",
"syncedAt": "2026-10-22T16:00:00Z" "syncedAt": "2026-10-23T16:00:00Z"
}, },
{ {
"id": "shuorenhua", "id": "shuorenhua",
@@ -1,6 +1,6 @@
{ {
"name": "artemis-automation", "name": "artemis-automation",
"version": "2.0.1", "version": "2.1.0",
"description": "使用 ARTEMIS MCP 完成 Android 自动化测试、批量执行、失败诊断、历史检索和报告交付。", "description": "使用 ARTEMIS MCP 完成 Android 自动化测试、批量执行、失败诊断、历史检索和报告交付。",
"author": { "author": {
"name": "chenmingxuan", "name": "chenmingxuan",
@@ -1,9 +1,9 @@
{ {
"sourceId": "artemis-automation", "sourceId": "artemis-automation",
"repo": "https://git.playones.com/chenmingxuan/Artemis-Eapil.git", "repo": "https://git.playones.com/chenmingxuan/Artemis-Eapil.git",
"ref": "v2.0.1", "ref": "v2.1.0",
"commit": "b584dae80aaae66607d6335bf1efa4b847f1955b", "commit": "83bcfd54d578a76aaea73e059a8547e3dc07ddbd",
"adapter": "claude-skill", "adapter": "claude-skill",
"sourcePath": "skills/artemis-use", "sourcePath": "skills/artemis-use",
"syncedAt": "2026-10-22T16:00:00Z" "syncedAt": "2026-10-23T16:00:00Z"
} }
@@ -22,7 +22,7 @@ ARTEMIS 自己编排手机和已授权插件,共用网页的任务队列、历
## 三种模式 ## 三种模式
- **Flash**:路径明确的快速执行,单个执行模型观察并操作;适合冒烟、稳定流程与探索后复跑。可以接受中途指导,也有结束验收。任务长不自动等于需要 Pro。 - **Flash**:路径明确的快速执行,单个执行模型观察并操作;适合冒烟、稳定流程与探索后复跑。可以接受中途指导;最终 AI 判定与分析默认关闭,可在全局功能配置开启。关闭时显示“未做 AI 判定”,不能当作验收通过。任务长不自动等于需要 Pro。
- **Pro**:需要持久计划、多个分支、检查点、ADB/日志诊断或详细报告;按计划执行并验证。`explorer_mode` 是 Pro 的视觉定位深度,不是探索任务模式。 - **Pro**:需要持久计划、多个分支、检查点、ADB/日志诊断或详细报告;按计划执行并验证。`explorer_mode` 是 Pro 的视觉定位深度,不是探索任务模式。
- **探索**:用户只有大概流程,需要与模型交流、纠正方向或人工示范;以 Pro 的执行能力推进,最终提炼一个可复用用例。超时保存并暂停,可继续。探索成功、生成用例和 Flash/Pro 复跑成功是三个不同结果。 - **探索**:用户只有大概流程,需要与模型交流、纠正方向或人工示范;以 Pro 的执行能力推进,最终提炼一个可复用用例。超时保存并暂停,可继续。探索成功、生成用例和 Flash/Pro 复跑成功是三个不同结果。
@@ -6,7 +6,7 @@
| --- | --- | --- | --- | | --- | --- | --- | --- |
| 适合 | 目标清楚、路径明确、低分支流程;冒烟和已提炼用例复跑 | 复杂分支、持久计划、检查点、长程监控、ADB/日志、详细记录 | 流程尚未定型,用户参与纠正或示范的一个复杂用例 | | 适合 | 目标清楚、路径明确、低分支流程;冒烟和已提炼用例复跑 | 复杂分支、持久计划、检查点、长程监控、ADB/日志、详细记录 | 流程尚未定型,用户参与纠正或示范的一个复杂用例 |
| 执行方式 | 单执行模型观察→动作;需要时使用定位等辅助工具 | Planner 制订计划;Operator 执行;Checker 验收;按需生成报告 | 复用 Pro 工具和计划,加持续对话、提问等待、示范分析和用例提炼 | | 执行方式 | 单执行模型观察→动作;需要时使用定位等辅助工具 | Planner 制订计划;Operator 执行;Checker 验收;按需生成报告 | 复用 Pro 工具和计划,加持续对话、提问等待、示范分析和用例提炼 |
| 验收 | 默认结束时只读验收 | 默认结束验收,可配置检查点/strict | 先处理用户指导,再验收探索目标;不把示范当独立复跑通过 | | 验收 | 最终 AI 判定与分析默认关闭,可在全局功能配置开启 | 默认结束验收,可配置检查点/strict | 先处理用户指导,再验收探索目标;不把示范当独立复跑通过 |
| 中途输入 | `inject_instruction` 指导当前任务 | 同 Flash,还能记录计划及诊断信息 | `message` 持续交流;结束后消息仅讨论,再操作需 `continue` | | 中途输入 | `inject_instruction` 指导当前任务 | 同 Flash,还能记录计划及诊断信息 | `message` 持续交流;结束后消息仅讨论,再操作需 `continue` |
| 入口 | `mobile_run_task(model="Flash")` | `mobile_run_task(model="Pro")` | `mobile_exploration(create/start/...)` | | 入口 | `mobile_run_task(model="Flash")` | `mobile_run_task(model="Pro")` | `mobile_exploration(create/start/...)` |
| 产物 | 步骤、证据、测试结果,按需导出报告 | 以上加计划、笔记和可选详细报告 | 对话、各轮执行和示范证据、一个用例的不可变版本 | | 产物 | 步骤、证据、测试结果,按需导出报告 | 以上加计划、笔记和可选详细报告 | 对话、各轮执行和示范证据、一个用例的不可变版本 |
@@ -2,8 +2,8 @@
"sourceId": "caveman", "sourceId": "caveman",
"repo": "https://github.com/JuliusBrussee/caveman.git", "repo": "https://github.com/JuliusBrussee/caveman.git",
"ref": "main", "ref": "main",
"commit": "bad48a0e1df55e05e3f52249afa35ecc1909ee76", "commit": "b4531dfc05a3ef0ba93b57e8bfa5f48564a4b4d6",
"adapter": "codex-plugin", "adapter": "codex-plugin",
"sourcePath": "plugins/caveman", "sourcePath": "plugins/caveman",
"syncedAt": "2026-10-21T06:48:34Z" "syncedAt": "2026-10-23T16:00:00Z"
} }
@@ -3,5 +3,5 @@
"name": "playwright浏览器自动化操作", "name": "playwright浏览器自动化操作",
"version": "20260605", "version": "20260605",
"keySource": "none", "keySource": "none",
"syncedAt": "2026-10-22T16:02:41Z" "syncedAt": "2026-10-23T16:02:55Z"
} }
@@ -2,8 +2,8 @@
"sourceId": "next-skills", "sourceId": "next-skills",
"repo": "https://github.com/vercel/next.js.git", "repo": "https://github.com/vercel/next.js.git",
"ref": "canary", "ref": "canary",
"commit": "443a9e7abf105be7b9e4bfe77200aebb2d46645f", "commit": "3dd7baa502a13a96836680fa4d84cb5020ae94fc",
"adapter": "skill-collection", "adapter": "skill-collection",
"sourcePath": "skills", "sourcePath": "skills",
"syncedAt": "2026-10-22T16:00:00Z" "syncedAt": "2026-10-23T16:00:00Z"
} }
@@ -2,8 +2,8 @@
"sourceId": "ppt-master", "sourceId": "ppt-master",
"repo": "https://github.com/hugohe3/ppt-master.git", "repo": "https://github.com/hugohe3/ppt-master.git",
"ref": "main", "ref": "main",
"commit": "622bf0148bca4f697b0184322c7e2aa2a04520a2", "commit": "523e5bd972f94c3cac8742fec0d54d43824a17bb",
"adapter": "claude-skill", "adapter": "claude-skill",
"sourcePath": "skills/ppt-master", "sourcePath": "skills/ppt-master",
"syncedAt": "2026-10-22T16:00:00Z" "syncedAt": "2026-10-23T16:00:00Z"
} }
@@ -421,7 +421,9 @@ eligible visual layer may be a direct full-canvas `<rect>` or one inside a
simple single-child group. Its fill must have a registered native mapping simple single-child group. Its fill must have a registered native mapping
(solid, linear/radial gradient, or preset pattern), and it must have no (solid, linear/radial gradient, or preset pattern), and it must have no
transform, filter, clip, rounding, or visible stroke. Export writes the fill as transform, filter, clip, rounding, or visible stroke. Export writes the fill as
Slide `p:bg`; image elements remain pictures. Structured routes use the Slide `p:bg`; image elements remain pictures. A rebuilt round-trip slide keeps
its source `p:bg`, so a new full-canvas `<rect>` there stays a shape at its SVG
paint position. Structured routes use the
narrower explicit solid-background ownership contract in narrower explicit solid-background ownership contract in
[`pptx-structure-interface.md`](../../references/pptx-structure-interface.md). [`pptx-structure-interface.md`](../../references/pptx-structure-interface.md).
@@ -1823,15 +1823,22 @@ def _apply_roundtrip_slide_overlay(
) )
else: else:
selected_by_id[shape_id] = (source_shapes[shape_id], False) selected_by_id[shape_id] = (source_shapes[shape_id], False)
extra_generated = [ # New objects keep their SVG paint position: each one follows the nearest
generated_shapes[shape_id] # preceding authored object, and leading ones precede the first slot.
for shape_id in generated_order extra_generated: dict[str | None, list[ET.Element]] = {}
if shape_id not in source_id_by_generated_top_id preceding_authored_id: str | None = None
] for shape_id in generated_order:
if shape_id in source_id_by_generated_top_id:
preceding_authored_id = source_id_by_generated_top_id[shape_id]
else:
extra_generated.setdefault(preceding_authored_id, []).append(
generated_shapes[shape_id]
)
authored_iterator = iter(authored_order) authored_iterator = iter(authored_order)
merged_children: list[tuple[ET.Element, bool]] = [] merged_children: list[tuple[ET.Element, bool]] = []
final_authored_slot = 0 final_authored_slot = 0
anchor_slots: dict[str | None, int] = {}
for child in list(source_tree): for child in list(source_tree):
shape_id = ( shape_id = (
source_key_by_element.get(id(child)) source_key_by_element.get(id(child))
@@ -1841,16 +1848,18 @@ def _apply_roundtrip_slide_overlay(
if shape_id not in authored_top_ids: if shape_id not in authored_top_ids:
merged_children.append((child, False)) merged_children.append((child, False))
continue continue
anchor_slots.setdefault(None, len(merged_children))
next_shape_id = next(authored_iterator, None) next_shape_id = next(authored_iterator, None)
if next_shape_id is not None: if next_shape_id is not None:
merged_children.append(selected_by_id[next_shape_id]) merged_children.append(selected_by_id[next_shape_id])
anchor_slots[next_shape_id] = len(merged_children)
final_authored_slot = len(merged_children) final_authored_slot = len(merged_children)
if next(authored_iterator, None) is not None: if next(authored_iterator, None) is not None:
raise TemplateStructureError( raise TemplateStructureError(
"Generated authored shape roster exceeds the source overlay slots" "Generated authored shape roster exceeds the source overlay slots"
) )
if not authored_top_ids: if not authored_top_ids:
final_authored_slot = next( anchor_slots[None] = next(
( (
index index
for index, (element, _generated) in enumerate(merged_children) for index, (element, _generated) in enumerate(merged_children)
@@ -1858,10 +1867,16 @@ def _apply_roundtrip_slide_overlay(
), ),
len(merged_children), len(merged_children),
) )
merged_children[final_authored_slot:final_authored_slot] = [ if authored_order:
(element, True) # Trailing additions stay after every source authored slot, so unlisted
for element in extra_generated # source shapes past the last filled slot keep painting below them.
] anchor_slots[authored_order[-1]] = final_authored_slot
# Anchors ascend in authored order; splice from the back to keep indexes valid.
for anchor, elements in reversed(list(extra_generated.items())):
insert_at = anchor_slots[anchor]
merged_children[insert_at:insert_at] = [
(element, True) for element in elements
]
generated_nodes = [ generated_nodes = [
element for element, generated in merged_children if generated element for element, generated in merged_children if generated
@@ -7706,7 +7721,12 @@ def create_pptx_with_native_svg(
theme_font_spec=active_theme_font_spec, theme_font_spec=active_theme_font_spec,
theme_color_spec=active_theme_color_spec, theme_color_spec=active_theme_color_spec,
primary_language=primary_language, primary_language=primary_language,
promote_background=pptx_structure != "structured", # A round-trip overlay keeps the source p:bg, so a
# new full-canvas rect must stay a shape to survive.
promote_background=(
pptx_structure != "structured"
and slide_patch is None
),
dangerous_nonconforming_export=( dangerous_nonconforming_export=(
dangerous_nonconforming_export dangerous_nonconforming_export
), ),
@@ -0,0 +1,148 @@
#!/usr/bin/env python3
"""Regress Edit Native paint order for new objects on rebuilt round-trip slides.
Usage: python3 -m unittest tests.test_edit_native_batch_d
Dependencies: python-pptx and the converter's normal dependencies.
"""
from __future__ import annotations
import io
import re
import sys
import tempfile
import unittest
import zipfile
from contextlib import redirect_stderr, redirect_stdout
from pathlib import Path
from xml.etree import ElementTree as ET
SCRIPTS_DIR = Path(__file__).resolve().parents[1]
if str(SCRIPTS_DIR) not in sys.path:
sys.path.insert(0, str(SCRIPTS_DIR))
from pptx import Presentation # noqa: E402
from pptx.enum.shapes import MSO_SHAPE # noqa: E402
from pptx.util import Inches # noqa: E402
from pptx_to_svg.converter import ConvertOptions, convert_pptx_to_svg # noqa: E402
from svg_to_pptx.pptx_package import cli # noqa: E402
NS = {
'p': 'http://schemas.openxmlformats.org/presentationml/2006/main',
'a': 'http://schemas.openxmlformats.org/drawingml/2006/main',
}
SOURCE_NAMES = ('base', 'tab', 'callout')
SOURCE_GROUP_IDS = {'base': 'shape-2', 'tab': 'shape-3', 'callout': 'shape-4'}
def _rect(name: str, *, full: bool = False) -> str:
frame = 'x="0" y="0" width="960" height="720"' if full else 'x="8" y="8" width="100" height="80"'
return f'<rect id="{name}" {frame} fill="#F12345" />'
class EditNativeBatchDTests(unittest.TestCase):
def setUp(self) -> None:
self.temporary = tempfile.TemporaryDirectory()
self.addCleanup(self.temporary.cleanup)
self.root = Path(self.temporary.name)
def _workspace(self, *, hidden: tuple[str, ...] = ()) -> Path:
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[6])
for index, name in enumerate(SOURCE_NAMES):
shape = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE, Inches(index + 0.5), Inches(1), Inches(2), Inches(2),
)
shape.name = name
if name in hidden:
shape._element.find('.//p:cNvPr', NS).set('hidden', '1')
source = self.root / 'source.pptx'
prs.save(source)
project = self.root / 'workspace'
with redirect_stdout(io.StringIO()), redirect_stderr(io.StringIO()):
convert_pptx_to_svg(source, project, ConvertOptions(inheritance_mode='both', roundtrip=True))
return project
def _groups(self, project: Path) -> tuple[Path, str, dict[str, str]]:
path = project / 'authoring-svg-flat' / 'slide_01.svg'
text = path.read_text(encoding='utf-8')
groups = {
name: re.search(rf'<g id="{group_id}".*?</g>', text, re.S).group(0)
for name, group_id in SOURCE_GROUP_IDS.items()
if f'<g id="{group_id}"' in text
}
return path, text, groups
def _author(self, project: Path, *order: str) -> None:
"""Rewrite slide 1 so its top-level objects follow ``order``.
Source names reuse their imported groups; any other name is a new rect,
and a ``full:`` prefix makes it full-canvas.
"""
path, text, groups = self._groups(project)
first = min(text.index(group) for group in groups.values())
last = max(text.index(group) + len(group) for group in groups.values())
body = []
for name in order:
if name in groups:
body.append(groups[name])
elif name.startswith('full:'):
body.append(_rect(name.removeprefix('full:'), full=True))
else:
body.append(_rect(name))
path.write_text(text[:first] + '\n'.join(body) + text[last:], encoding='utf-8')
def _export_roster(self, project: Path) -> tuple[list[str], ET.Element]:
output = project / 'result.pptx'
stdout, stderr = io.StringIO(), io.StringIO()
with redirect_stdout(stdout), redirect_stderr(stderr):
result = cli.main([str(project), '--roundtrip', '-o', str(output)])
self.assertEqual(result, 0, stdout.getvalue() + stderr.getvalue())
self.assertIn('rebuilt=1', stdout.getvalue())
with zipfile.ZipFile(output) as archive:
slide = ET.fromstring(archive.read('ppt/slides/slide1.xml'))
tree = slide.find('p:cSld/p:spTree', NS)
names = [
child.find('./*/p:cNvPr', NS).get('name')
for child in tree
if child.find('./*/p:cNvPr', NS) is not None
]
return names, slide
def test_replaced_first_object_stays_below_source_objects(self) -> None:
project = self._workspace()
self._author(project, 'hr-base-map', 'tab', 'callout')
names, _slide = self._export_roster(project)
self.assertEqual(names, ['hr-base-map', 'tab', 'callout'])
def test_new_objects_keep_leading_middle_and_trailing_positions(self) -> None:
project = self._workspace()
self._author(project, 'lead', 'base', 'mid-1', 'mid-2', 'tab', 'callout', 'tail')
names, _slide = self._export_roster(project)
self.assertEqual(names, ['lead', 'base', 'mid-1', 'mid-2', 'tab', 'callout', 'tail'])
def test_reused_slots_anchor_to_the_object_actually_placed(self) -> None:
project = self._workspace()
self._author(project, 'callout', 'new', 'tab')
names, _slide = self._export_roster(project)
self.assertEqual(names, ['callout', 'new', 'tab'])
def test_trailing_object_stays_above_unlisted_source_shape(self) -> None:
project = self._workspace(hidden=('tab',))
self._author(project, 'base', 'tail')
names, _slide = self._export_roster(project)
self.assertEqual(names, ['base', 'tab', 'tail'])
def test_middle_object_follows_its_authored_predecessor(self) -> None:
project = self._workspace(hidden=('tab',))
self._author(project, 'base', 'mid', 'callout')
names, _slide = self._export_roster(project)
self.assertEqual(names, ['base', 'mid', 'tab', 'callout'])
def test_new_full_canvas_rect_stays_a_shape_under_the_source_background(self) -> None:
project = self._workspace()
self._author(project, 'full:new-under', 'base', 'tab', 'callout')
names, slide = self._export_roster(project)
self.assertEqual(names, ['new-under', 'base', 'tab', 'callout'])
self.assertIsNone(slide.find('p:cSld/p:bg', NS))
@@ -2,8 +2,8 @@
"sourceId": "shadcn", "sourceId": "shadcn",
"repo": "https://github.com/shadcn-ui/ui.git", "repo": "https://github.com/shadcn-ui/ui.git",
"ref": "main", "ref": "main",
"commit": "25af02b1b467fcd53b63e0c6d6d324c57c16ef18", "commit": "3d98900e9b73c45f035f8109e9d41ba6a51685e7",
"adapter": "claude-skill", "adapter": "claude-skill",
"sourcePath": "skills/shadcn", "sourcePath": "skills/shadcn",
"syncedAt": "2026-10-22T16:00:00Z" "syncedAt": "2026-10-23T16:00:00Z"
} }
@@ -290,6 +290,7 @@ uipro init --ai warp # Warp
uipro init --ai augment # Augment uipro init --ai augment # Augment
uipro init --ai codewhale # CodeWhale uipro init --ai codewhale # CodeWhale
uipro init --ai zcode # ZCode uipro init --ai zcode # ZCode
uipro init --ai kimi # Kimi Code
uipro init --ai amazonq # Amazon Q Developer uipro init --ai amazonq # Amazon Q Developer
uipro init --ai openclaw # OpenClaw (.agents/skills/) uipro init --ai openclaw # OpenClaw (.agents/skills/)
uipro init --ai universal # Universal / Agent Standard (.agents/skills/) uipro init --ai universal # Universal / Agent Standard (.agents/skills/)
@@ -304,6 +305,7 @@ The npm package is `ui-ux-pro-max-cli`; it still installs the `uipro` command. O
uipro init --ai claude --global # Install to ~/.claude/skills/ uipro init --ai claude --global # Install to ~/.claude/skills/
uipro init --ai cursor --global # Install to ~/.cursor/skills/ uipro init --ai cursor --global # Install to ~/.cursor/skills/
uipro init --ai zcode --global # Install to ~/.zcode/skills/ uipro init --ai zcode --global # Install to ~/.zcode/skills/
uipro init --ai kimi --global # Install to ~/.kimi-code/skills/
uipro init --ai universal --global # Install to ~/.agents/skills/ uipro init --ai universal --global # Install to ~/.agents/skills/
``` ```
@@ -336,7 +338,7 @@ If it is missing, install it yourself from [python.org](https://www.python.org/d
### Skill Mode (Auto-activate) ### Skill Mode (Auto-activate)
**Supported:** Claude Code, Cursor, Windsurf, Antigravity, Codex CLI, Continue, Gemini CLI, OpenCode, Qoder, CodeBuddy, Droid (Factory), KiloCode, Warp, Augment, CodeWhale, ZCode, Amazon Q Developer, OpenClaw, GitHub Copilot **Supported:** Claude Code, Cursor, Windsurf, Antigravity, Codex CLI, Continue, Gemini CLI, OpenCode, Qoder, CodeBuddy, Droid (Factory), KiloCode, Warp, Augment, CodeWhale, ZCode, Kimi Code, Amazon Q Developer, OpenClaw, GitHub Copilot
The skill activates automatically when you request UI/UX work. Just chat naturally: The skill activates automatically when you request UI/UX work. Just chat naturally:
@@ -2,8 +2,8 @@
"sourceId": "ui-ux-pro-max", "sourceId": "ui-ux-pro-max",
"repo": "https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git", "repo": "https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git",
"ref": "main", "ref": "main",
"commit": "623a9a9037d006ea727f8213f084d02a6b6f11b5", "commit": "d14efff8ed1faa4187f004f79926f428c8074ec7",
"adapter": "claude-skill", "adapter": "claude-skill",
"sourcePath": ".claude/skills/ui-ux-pro-max", "sourcePath": ".claude/skills/ui-ux-pro-max",
"syncedAt": "2026-10-22T16:00:00Z" "syncedAt": "2026-10-23T16:00:00Z"
} }