[Feature]: Add local (--dev) installation for custom workflow step types
還沒有人認領這個 Issue。
評估
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 新手友好度
- 55/100
- Issue 類型
- 功能
- 描述清晰度
- 基本清楚
- 活躍度
- 活躍
- 技術堆疊
- python
研究方向
Start with src/specify_cli/workflows/step/command_add.py and compare its behavior with install_from_directory in src/specify_cli/presets/init.py and the existing extension/workflow --dev handling. Then trace load_custom_steps in src/specify_cli/workflows/init.py and step delegation in bundler/services/primitives.py. Done means local and URL step installs are validated, registered, loadable, removable, and covered in docs and tests, with bundle behavior resolved or documented.
由索引模型根據 Issue 內容生成。
描述
Problem Statement
Custom workflow step types are the only first-class Spec-Kit component that cannot be installed from a local path. Every other artifact supports local development, but steps are catalog/HTTPS-only:
| Component | Local/dev install | Custom URL |
|---|---|---|
| Extension | specify extension add --dev <dir> |
--from <url> |
| Preset | specify preset add --dev <dir> |
--from <url> |
| Workflow | specify workflow add <path> --dev |
--from <url> |
| Bundle | specify bundle install <path> |
— |
| Step | none | none |
specify workflow step add accepts only a catalog step id and fetches step.yml/__init__.py (and optional extra_files) over HTTPS (src/specify_cli/workflows/step/command_add.py, _safe_fetch rejects non-HTTPS). There is no --dev or --from.
This makes custom steps impossible to iterate on or test from a checkout:
- A developer must publish the step package to an HTTPS catalog (or run a localhost catalog server) before they can run it once.
- CI cannot install a step from the repository under test without a network round-trip to a hosted catalog.
- Bundles that declare
provides.stepscannot be developed or validated offline —bundle installdelegates step installs toworkflow_step_add(component.id)(bundler/services/primitives.py), which always resolves through the step catalog. - Manually copying files into
.specify/workflows/steps/<id>/works at runtime (load_custom_stepsscans the directory) but is undocumented, unvalidated, and leaves the registry out of sync.
Net effect: the step type is second-class relative to extensions, presets, and workflows, and the only way to develop one is a throwaway localhost HTTPS/HTTP catalog.
Proposed Solution
Bring specify workflow step add to feature parity with the other components:
- Add
--dev <dir>to install a custom step from a local package directory containingstep.yml,__init__.py, and anyextra_files. It copies the package into.specify/workflows/steps/<id>/and records it in the step registry withsource: local, mirroringpreset add --dev/extension add --dev. - Add
--from <url>to install a single step package directly from a URL, mirroring the other components'--from. - Apply the same safety guards the catalog path already uses: validate
step.type_key, reject ids that collide with built-in step types, reject duplicate installs (with a consistent--force/reinstall semantic), and keep the symlink/..path-escape guards on the destination. - Optionally support
bundle install <local dir>resolvingprovides.stepsfrom the local bundle directory instead of the catalog stack, so step-bearing bundles work offline.
Alternatives Considered
- Manual copy into
.specify/workflows/steps/<id>/— works becauseload_custom_stepsscans the directory, but it's undocumented, skips validation, and doesn't register provenance, soworkflow step list/remove/bundle tracking miss it. - Localhost step catalog —
_validate_catalog_urlalready permitshttp://localhost, so a developer can run a local server and register it as a catalog. This is the current workaround, but it is heavy, undocumented, and not usable in CI without extra plumbing. - Ship the step inside a preset/extension archive — not possible: the engine only loads custom steps from
.specify/workflows/steps/.
Component
Specify CLI (initialization, commands)
AI Agent (if applicable)
Not applicable
Use Cases
- Iterating on a custom step type while developing a bundle that uses it, without publishing to a catalog on every change.
- Running a bundle's integration tests in CI against a local checkout of the step package.
- Authoring a step locally, then publishing it to a catalog only once it is stable.
- Offline development of step-bearing bundles.
Acceptance Criteria
-
specify workflow step add --dev <dir>installs a local step package into.specify/workflows/steps/<id>/. - The installed step is loaded by
workflow run,workflow resume, andworkflow add, and appears inworkflow step list. -
--devvalidatesstep.yml/__init__.py, rejects collisions with built-in step types, and rejects duplicate installs with the same semantics as the catalog path. - Destination path/symlink safety guards match the catalog install path.
- Registry provenance records a local source (consistent with presets/extensions), so
workflow step removecleans up correctly. -
--from <url>installs a single step package from a URL. -
bundle install <local dir>resolves and installsprovides.stepsfrom the local bundle source (or the limitation is explicitly documented). - Docs (
docs/reference/workflows.mdstep-type section) and tests cover the new paths.
Additional Context
- Command surface:
src/specify_cli/workflows/step/command_add.py(workflow_step_add(step_id),_safe_fetchHTTPS-only). - Catalog/URL validation:
src/specify_cli/workflows/step/catalog/_domain.py(_validate_catalog_url). - Loader:
src/specify_cli/workflows/__init__.py(load_custom_steps) — confirms local directory loading already works at runtime; only installation tooling is missing. - Bundle delegation:
bundler/services/primitives.py(steps→workflow_step_add). - Parity references:
install_from_directoryinsrc/specify_cli/presets/__init__.py, and--devhandling for extensions and workflows. - Motivating use case: a bundle that ships a custom step to consolidate run setup currently has to choose between a network-only component and a localhost catalog workaround.
AI Disclosure
Drafted with opencode (model deepseek-v4.1-flash), human-supervised and reviewed before submission.
- 主要語言
- Python
- 星號
- 138k
- 分支
- 12.4k
- 平均合併
- 3 天 2 小時
- 30 天內合併 PR
- 169
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
github/spec-kit 的其他 Issue
-
enhancement needs-triage triage-can-wait
難度 2/5 1-3 小時 新手友好度 65/100
-
preset-submission triage-must-have validation-passed
難度 2/5 1-3 小時 新手友好度 75/100
-
extension-submission triage-must-have validation-passed
難度 2/5 1-3 小時 新手友好度 70/100
-
extension-submission triage-can-wait validation-passed
難度 2/5 1-3 小時 新手友好度 76/100
-
enhancement needs-triage triage-can-wait
難度 2/5 1-3 小時 新手友好度 65/100
相似的 Issue
-
bug
難度 2/5 1-3 小時 新手友好度 75/100
stephrobert/dsoxlab#238 ·
-
難度 2/5 1-3 小時 新手友好度 75/100
-
難度 2/5 1-3 小時 新手友好度 75/100
sublimehq/package_control#1780 ·
-
難度 2/5 1-3 小時 新手友好度 65/100
-
難度 2/5 1-3 小時 新手友好度 70/100
nwg-piotr/nwg-displays#145 ·