@minus-ai/create-skill 0.1.0-beta.12 → 0.1.0-beta.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.mjs CHANGED
@@ -520,7 +520,11 @@ async function main() {
520
520
  const vars = { skillId: skillResult.id, folder, className, displayName, description, namespace, port, nodeVersion, nodeMajor: String(NODE_MAJOR_FLOOR) }
521
521
 
522
522
  // Backend files (pipeline.py from input-type subdir)
523
- writeOut(join(targetDir, 'pipeline.py'), render(readTemplate('pipeline.py.tpl', inputType), vars))
523
+ // 末尾统一追加 SDK 参考速查(纯注释单源模板),各场景模板不各自复制
524
+ writeOut(
525
+ join(targetDir, 'pipeline.py'),
526
+ render(readTemplate('pipeline.py.tpl', inputType), vars) + readTemplate('pipeline-reference.py.tpl')
527
+ )
524
528
  writeOut(join(targetDir, 'server.py'), render(readTemplate('server.py.tpl'), vars))
525
529
  writeOut(join(targetDir, 'pyproject.toml'), render(readTemplate('pyproject.toml.tpl'), vars))
526
530
  writeOut(join(targetDir, '.env.example'), render(readTemplate('env.example.tpl'), vars))
@@ -624,9 +628,10 @@ ${templateDocs[inputType] || templateDocs.custom}
624
628
  // README.md
625
629
  writeOut(join(targetDir, 'README.md'), render(readTemplate('README.md.tpl'), vars))
626
630
 
627
- // frontend/assets/ 和 tests/ 目录
631
+ // frontend/assets/ 和 tests/ 目录(pytest 骨架:新 skill 天生带测试)
628
632
  writeOut(join(targetDir, 'frontend', 'assets', '.gitkeep'), '')
629
- writeOut(join(targetDir, 'tests', '.gitkeep'), '')
633
+ writeOut(join(targetDir, 'tests', 'conftest.py'), render(readTemplate('conftest.py.tpl'), vars))
634
+ writeOut(join(targetDir, 'tests', 'test_pipeline.py'), render(readTemplate('test_pipeline.py.tpl'), vars))
630
635
 
631
636
  const rootPkgContent = render(readTemplate('root-package.json.tpl'), vars)
632
637
  const fePkgContent = render(readTemplate('frontend-package.json.tpl'), vars)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minus-ai/create-skill",
3
- "version": "0.1.0-beta.12",
3
+ "version": "0.1.0-beta.14",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "create-skill": "index.mjs"
@@ -45,7 +45,7 @@ pnpm install
45
45
  ```bash
46
46
  uv venv .venv
47
47
  source .venv/bin/activate # Windows: .venv\Scripts\activate
48
- uv pip install -e .
48
+ uv pip install -e . --reinstall-package minus-ai-sdk-python
49
49
  ```
50
50
 
51
51
  ## 配置
@@ -0,0 +1,5 @@
1
+ import sys
2
+ from pathlib import Path
3
+
4
+ # 项目根加进 sys.path,使 `import pipeline` 与运行时(server.py 同目录启动)一致
5
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
@@ -11,7 +11,7 @@
11
11
  "sonner": "^2.0.7"
12
12
  },
13
13
  "devDependencies": {
14
- "@minus-ai/dev-vite-plugin": "^0.1.0-beta.12",
14
+ "@minus-ai/dev-vite-plugin": "^0.1.0-beta.14",
15
15
  "@types/node": "^{{nodeMajor}}.0.0",
16
16
  "@types/react": "^18.3.3",
17
17
  "@types/react-dom": "^18.3.0",
@@ -0,0 +1,14 @@
1
+
2
+
3
+ # ──────────────────────────────────────────────────────────────────────────────
4
+ # SDK 参考(纯注释,读懂后可整段删除)
5
+ #
6
+ # StepOutcome 三态与 ctx 能力(entry_params / previous_outputs / last_user_input /
7
+ # sif / llm / upload_file)的权威定义和用法,读已安装 SDK 的模块头注释与 docstring:
8
+ # .venv/**/minus_ai_sdk/pipeline/context.py
9
+ # .venv/**/minus_ai_sdk/pipeline/outcome.py
10
+ # 不要凭记忆写签名——以上述源码为准(SDK 会原地更新,文档随包发布永不过期)。
11
+ #
12
+ # 唯一容易写反的语义:StepOutcome.input_required 暂停后,用户提交的内容
13
+ # 挂在「下一步」的 ctx.last_user_input,而不是重跑本步。
14
+ # ──────────────────────────────────────────────────────────────────────────────
@@ -9,5 +9,16 @@ dependencies = [
9
9
  "uvicorn[standard]",
10
10
  ]
11
11
 
12
+ [project.optional-dependencies]
13
+ dev = ["pytest", "pytest-asyncio"]
14
+
12
15
  [tool.setuptools]
13
16
  py-modules = ["pipeline", "server"]
17
+
18
+ [tool.uv]
19
+ # SDK wheel 可能在同一版本号下更新过,安装时绕过本地缓存强制重新下载
20
+ reinstall-package = ["minus-ai-sdk-python"]
21
+
22
+ [tool.pytest.ini_options]
23
+ asyncio_mode = "auto"
24
+ testpaths = ["tests"]
@@ -16,10 +16,11 @@
16
16
  "dev:backend": "minus-dev-cleanup && mkdir -p .minus && echo $$ > .minus/backend.pid && .venv/bin/uvicorn server:app --port {{port}} --reload --reload-include '*.py' --reload-include '.env.local' --env-file .env.local",
17
17
  "dev:win": "minus-dev --port {{port}}",
18
18
  "dev:win:backend": "minus-dev --port {{port}} --backend-only",
19
- "build": "cd frontend && pnpm run build"
19
+ "build": "cd frontend && pnpm run build",
20
+ "test": ".venv/bin/pytest tests"
20
21
  },
21
22
  "devDependencies": {
22
- "@minus-ai/dev-vite-plugin": "^0.1.0-beta.12",
23
+ "@minus-ai/dev-vite-plugin": "^0.1.0-beta.14",
23
24
  "concurrently": "^9.1.2"
24
25
  }
25
26
  }
@@ -0,0 +1,35 @@
1
+ """pipeline step 函数的 payload 结构测试骨架。
2
+
3
+ 约定(与平台测试体系一致):
4
+ - 直接调用 step 函数,不起 HTTP/SSE;外部 API 用 monkeypatch mock。
5
+ - 断言 payload 的关键字段 + 类型,不断言会漂移的具体数据值。
6
+ 运行:.venv/bin/pytest(需先 .venv/bin/pip install pytest pytest-asyncio)
7
+ """
8
+ from types import SimpleNamespace
9
+
10
+ import pipeline as pl
11
+ from minus_ai_sdk import StepOutcome
12
+
13
+
14
+ class FakeContext:
15
+ """鸭子类型 PipelineContext:step 函数常用的成员。"""
16
+
17
+ def __init__(self, entry_params=None, last_user_input=None, previous_outputs=None):
18
+ self.entry_params = entry_params or {}
19
+ self.last_user_input = last_user_input or {}
20
+ self.previous_outputs = previous_outputs or {}
21
+ self.sif = SimpleNamespace() # 外部 API 客户端按需 monkeypatch
22
+ self.emitted = []
23
+
24
+ async def emit(self, message_type, payload=None):
25
+ self.emitted.append((message_type, payload))
26
+
27
+
28
+ async def test_step_1_returns_valid_outcome():
29
+ ctx = FakeContext(entry_params={})
30
+ outcome = await pl.{{className}}.step_1(SimpleNamespace(), ctx)
31
+ assert isinstance(outcome, StepOutcome)
32
+ assert isinstance(outcome.payload, dict)
33
+ # TODO: 按你的 step payload 契约补充关键字段断言,例如:
34
+ # assert outcome.kind.value == "input_required"
35
+ # assert isinstance(outcome.payload["rows"], list)