spec-to-ui 0.1.0 → 0.2.0
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/LICENSE +2 -0
- package/README.ko.md +129 -0
- package/README.md +96 -29
- package/RELEASE.md +26 -0
- package/THIRD-PARTY.md +14 -0
- package/bin/cli.mjs +70 -91
- package/bundle-manifest.json +140 -0
- package/package.json +40 -8
- package/plugin.json +16 -0
- package/skills/design-taste-frontend/LICENSE +21 -0
- package/skills/design-taste-frontend/README.md +81 -0
- package/skills/design-taste-frontend/SKILL.md +546 -0
- package/skills/design-taste-frontend/assets/app.css +216 -0
- package/skills/design-taste-frontend/assets/base.css +105 -0
- package/skills/design-taste-frontend/assets/base.js +37 -0
- package/skills/design-taste-frontend/assets/charts.js +619 -0
- package/skills/design-taste-frontend/assets/scenes/stage.css +28 -0
- package/skills/design-taste-frontend/assets/scenes/stage.js +134 -0
- package/skills/design-taste-frontend/evals/evals.json +76 -0
- package/skills/design-taste-frontend/library/app.json +1327 -0
- package/skills/design-taste-frontend/library/directions.json +1078 -0
- package/skills/design-taste-frontend/library/heroes.json +1086 -0
- package/skills/design-taste-frontend/library/motions.json +92 -0
- package/skills/design-taste-frontend/library/palettes.json +1485 -0
- package/skills/design-taste-frontend/library/photos.json +7240 -0
- package/skills/design-taste-frontend/library/sections.json +4429 -0
- package/skills/design-taste-frontend/library/sites.json +8350 -0
- package/skills/design-taste-frontend/library/type.json +2024 -0
- package/skills/design-taste-frontend/references/app-screens.md +1199 -0
- package/skills/design-taste-frontend/references/colour.md +141 -0
- package/skills/design-taste-frontend/references/copy.md +177 -0
- package/skills/design-taste-frontend/references/critique.md +182 -0
- package/skills/design-taste-frontend/references/imagery.md +791 -0
- package/skills/design-taste-frontend/references/layout.md +292 -0
- package/skills/design-taste-frontend/references/motion.md +980 -0
- package/skills/design-taste-frontend/references/research.md +356 -0
- package/skills/design-taste-frontend/references/scenes.md +174 -0
- package/skills/design-taste-frontend/references/tells.md +115 -0
- package/skills/design-taste-frontend/references/type.md +170 -0
- package/skills/design-taste-frontend/scripts/assets.mjs +865 -0
- package/skills/design-taste-frontend/scripts/draw.mjs +584 -0
- package/skills/design-taste-frontend/scripts/inspect.mjs +308 -0
- package/skills/design-taste-frontend/scripts/lib/app-draw.mjs +203 -0
- package/skills/design-taste-frontend/scripts/lib/cdp.mjs +248 -0
- package/skills/design-taste-frontend/scripts/lib/inspection-files.mjs +9 -0
- package/skills/design-taste-frontend/scripts/lib/probe.mjs +929 -0
- package/skills/design-taste-frontend/scripts/lib/rules.mjs +243 -0
- package/skills/design-taste-frontend/scripts/lint.mjs +119 -0
- package/skills/design-taste-frontend/scripts/scenes.mjs +124 -0
- package/skills/spec-to-ui/SKILL.md +61 -0
- package/{skill → skills/spec-to-ui}/references/composition-and-validation.md +6 -0
- package/{skill → skills/spec-to-ui}/references/drafts-and-feedback.md +10 -0
- package/skills/spec-to-ui/references/requirements-supplement.md +21 -0
- package/{skill → skills/spec-to-ui}/references/review-and-handoff.md +9 -0
- package/skills/spec-to-ui/references/skill-composition.md +21 -0
- package/{skill → skills/spec-to-ui}/references/structure-and-decisions.md +4 -0
- package/skills/specframe/NOTICE.md +7 -0
- package/skills/specframe/SKILL.md +58 -0
- package/skills/specframe/agents/openai.yaml +3 -0
- package/skills/specframe/references/operating-contract.md +137 -0
- package/skills/specframe/references/visual.md +3 -0
- package/skills/specframe/references/web.md +15 -0
- package/skills/specframe/scripts/state.py +182 -0
- package/skills/ui-ux-pro-max/LICENSE +21 -0
- package/skills/ui-ux-pro-max/SKILL.md +218 -0
- package/skills/ui-ux-pro-max/data/app-interface.csv +33 -0
- package/skills/ui-ux-pro-max/data/catalog-summary.json +78 -0
- package/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills/ui-ux-pro-max/data/colors.csv +193 -0
- package/skills/ui-ux-pro-max/data/data-provenance.json +1348 -0
- package/skills/ui-ux-pro-max/data/google-font-licenses.json +20185 -0
- package/skills/ui-ux-pro-max/data/google-fonts.csv +1935 -0
- package/skills/ui-ux-pro-max/data/icons.csv +106 -0
- package/skills/ui-ux-pro-max/data/landing.csv +35 -0
- package/skills/ui-ux-pro-max/data/motion.csv +18 -0
- package/skills/ui-ux-pro-max/data/phosphor-icons-upstream.json +32582 -0
- package/skills/ui-ux-pro-max/data/products.csv +193 -0
- package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills/ui-ux-pro-max/data/stacks/angular.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/avalonia.csv +57 -0
- package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +60 -0
- package/skills/ui-ux-pro-max/data/stacks/javafx.csv +76 -0
- package/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/laravel.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +62 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +84 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +68 -0
- package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills/ui-ux-pro-max/data/stacks/react.csv +67 -0
- package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +69 -0
- package/skills/ui-ux-pro-max/data/stacks/svelte.csv +56 -0
- package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/threejs.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/uno.csv +60 -0
- package/skills/ui-ux-pro-max/data/stacks/uwp.csv +56 -0
- package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills/ui-ux-pro-max/data/stacks/winui.csv +60 -0
- package/skills/ui-ux-pro-max/data/stacks/wpf.csv +57 -0
- package/skills/ui-ux-pro-max/data/styles.csv +89 -0
- package/skills/ui-ux-pro-max/data/typography.csv +75 -0
- package/skills/ui-ux-pro-max/data/ui-reasoning.csv +193 -0
- package/skills/ui-ux-pro-max/data/ux-guidelines.csv +120 -0
- package/skills/ui-ux-pro-max/references/pro-rules.md +117 -0
- package/skills/ui-ux-pro-max/references/quick-reference.md +256 -0
- package/skills/ui-ux-pro-max/scripts/core.py +993 -0
- package/skills/ui-ux-pro-max/scripts/design_system.py +1668 -0
- package/skills/ui-ux-pro-max/scripts/reasoning_contract.py +123 -0
- package/skills/ui-ux-pro-max/scripts/search.py +184 -0
- package/skills/ui-ux-pro-max/scripts/tests/fixtures/catalogs/google-api.json +36 -0
- package/skills/ui-ux-pro-max/scripts/tests/fixtures/catalogs/google-catalog.json +33 -0
- package/skills/ui-ux-pro-max/scripts/tests/fixtures/catalogs/google-existing.csv +3 -0
- package/skills/ui-ux-pro-max/scripts/tests/fixtures/catalogs/google-metadata.json +17 -0
- package/skills/ui-ux-pro-max/scripts/tests/fixtures/catalogs/google-overrides.json +7 -0
- package/skills/ui-ux-pro-max/scripts/tests/fixtures/catalogs/icons-curated.csv +4 -0
- package/skills/ui-ux-pro-max/scripts/tests/fixtures/catalogs/phosphor-core.json +23 -0
- package/skills/ui-ux-pro-max/scripts/tests/fixtures/catalogs/phosphor-package.json +13 -0
- package/skills/ui-ux-pro-max/scripts/tests/fixtures/catalogs/phosphor-react-exports.json +4 -0
- package/skills/ui-ux-pro-max/scripts/tests/fixtures/catalogs/phosphor-react-package.json +5 -0
- package/skills/ui-ux-pro-max/scripts/tests/fixtures/relevance-baseline.json +3366 -0
- package/skills/ui-ux-pro-max/scripts/tests/fixtures/relevance-cases.json +111 -0
- package/skills/ui-ux-pro-max/scripts/tests/fixtures/relevance-thresholds.json +100 -0
- package/skills/ui-ux-pro-max/scripts/tests/test_catalog_refresh.py +354 -0
- package/skills/ui-ux-pro-max/scripts/tests/test_catalog_summary_line_endings.py +78 -0
- package/skills/ui-ux-pro-max/scripts/tests/test_core.py +343 -0
- package/skills/ui-ux-pro-max/scripts/tests/test_core_data_quality.py +198 -0
- package/skills/ui-ux-pro-max/scripts/tests/test_data_contracts.py +421 -0
- package/skills/ui-ux-pro-max/scripts/tests/test_design_system_mode.py +233 -0
- package/skills/ui-ux-pro-max/scripts/tests/test_design_system_stack.py +61 -0
- package/skills/ui-ux-pro-max/scripts/tests/test_native_desktop_stack_freshness.py +179 -0
- package/skills/ui-ux-pro-max/scripts/tests/test_relevance_evaluator.py +182 -0
- package/skills/ui-ux-pro-max/scripts/tests/test_skill_script_paths.py +82 -0
- package/skills/ui-ux-pro-max/scripts/tests/test_style_taxonomy.py +175 -0
- package/skills/ui-ux-pro-max/scripts/tests/test_text_layout_resilience.py +120 -0
- package/skills/ui-ux-pro-max/scripts/tests/test_web_stack_freshness.py +191 -0
- package/skills/ui-ux-pro-max/scripts/validate_data.py +1095 -0
- package/sources.json +58 -0
- package/skill/SKILL.md +0 -68
- package/skill-manifest.json +0 -10
- /package/{skill → skills/spec-to-ui}/LICENSE +0 -0
- /package/{skill → skills/spec-to-ui}/agents/openai.yaml +0 -0
- /package/{skill → skills/spec-to-ui}/references/reference-selection.md +0 -0
package/LICENSE
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
The MIT license below applies to original spec-to-ui instructions and installer code. Third-party components retain their respective terms; see THIRD-PARTY.md and the LICENSE files within skills/. SpecFrame is included by redistribution permission, not relicensed under MIT.
|
|
2
|
+
|
|
1
3
|
MIT License
|
|
2
4
|
|
|
3
5
|
Copyright (c) 2026 spec-to-ui contributors
|
package/README.ko.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# spec-to-ui
|
|
2
|
+
|
|
3
|
+
요구사항 명세서를 화면 구조와 실제로 볼 수 있는 UI 초안으로 발전시키는 Codex 플러그인입니다. 디자인이나 CSS를 몰라도 예시와 미리보기를 보며 방향을 고를 수 있도록 돕습니다.
|
|
4
|
+
|
|
5
|
+
## 주요 기능
|
|
6
|
+
|
|
7
|
+
- 요구사항을 페이지, 정보 우선순위, 핵심 행동과 필요한 상태로 옮깁니다.
|
|
8
|
+
- 실제 참고 자료와 대표 화면으로 디자인을 비교하고 선택한 방향을 확장합니다.
|
|
9
|
+
- 명세서의 중요한 누락은 SpecFrame으로 보충하고, 승인된 범위에서 UI 작업으로 돌아옵니다.
|
|
10
|
+
- 정렬, 단어 단위 줄바꿈, 입력 요소와 열린 달력, 반응형, 초점, 모션을 함께 검토합니다.
|
|
11
|
+
- 채택한 디자인 규칙은 프로젝트의 `DESIGN.md`에 기록합니다.
|
|
12
|
+
|
|
13
|
+
## 포함된 스킬
|
|
14
|
+
|
|
15
|
+
| 구성 | 사용하는 시점 |
|
|
16
|
+
|---|---|
|
|
17
|
+
| spec-to-ui | 전체 UI 설계를 진행하고 필요한 보조 역할을 연결합니다. |
|
|
18
|
+
| SpecFrame | 기능·권한·업무 규칙의 누락이나 충돌이 화면 설계를 막을 때 사용합니다. |
|
|
19
|
+
| design-taste-frontend | 시각 방향, 이미지, 타이포그래피, 구성과 모션을 보강합니다. |
|
|
20
|
+
| ui-ux-pro-max | 폼, 반응형, 접근성, 탐색과 상호작용의 구체적인 문제를 검토합니다. |
|
|
21
|
+
|
|
22
|
+
`spec-to-ui`가 필요한 보조 스킬의 지침을 같은 묶음에서 읽도록 구성했습니다. 매번 네 스킬을 모두 실행하지는 않습니다. `DESIGN.md`는 프로젝트 문서이며, Refero Styles 등은 실제 참고 자료를 찾는 외부 서비스입니다. 별도 스킬이나 서비스 이용권이 포함된 것은 아닙니다.
|
|
23
|
+
|
|
24
|
+
## 필수 프로그램
|
|
25
|
+
|
|
26
|
+
- 플러그인을 지원하는 Codex와 `codex` 명령
|
|
27
|
+
- Node.js 22 이상과 npm
|
|
28
|
+
- 보조 검색 도구를 사용하는 경우 Python 3
|
|
29
|
+
|
|
30
|
+
브라우저, 이미지 제작, 외부 디자인 자료의 열람은 사용 중인 환경의 도구와 권한에 따릅니다. 필요한 도구를 사용할 수 없으면 가능한 대안과 미검증 범위를 안내하도록 되어 있습니다.
|
|
31
|
+
|
|
32
|
+
## 설치
|
|
33
|
+
|
|
34
|
+
다음 명령은 GitHub의 마켓플레이스를 등록한 뒤 npm의 `0.2.0` 패키지를 Codex 플러그인으로 설치합니다.
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
npx --yes spec-to-ui@0.2.0 install
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
실행할 설치 명령만 확인하려면 다음을 사용합니다.
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
npx --yes spec-to-ui@0.2.0 install --dry-run
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
npm 설치 도우미 없이 Codex에서 직접 설치할 수도 있습니다.
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
codex plugin marketplace add suminkim8203/spec-to-ui
|
|
50
|
+
codex plugin add spec-to-ui@spec-to-ui
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
설치 후 새 Codex 세션에서 호출합니다. 앱을 계속 열어 두었다면 새 채팅에서도 목록이 갱신되었는지 확인해 주십시오.
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
$spec-to-ui:spec-to-ui
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
플러그인 이름과 표시명은 모두 `spec-to-ui`입니다.
|
|
60
|
+
|
|
61
|
+
## 사용법
|
|
62
|
+
|
|
63
|
+
### 명세서로 시작하기
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
$spec-to-ui:spec-to-ui
|
|
67
|
+
요구사항은 ./REQUIREMENTS.md에 있습니다.
|
|
68
|
+
신규 사이트를 설계해 주세요. 참고 방향을 미리보기로 추천하고,
|
|
69
|
+
대표 화면을 확인한 뒤 전체 화면으로 확장하겠습니다.
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
이미 승인한 명세서는 재사용합니다. UI 구조에 영향을 주는 누락이 있으면 보충할 항목을 짚고 SpecFrame으로 연결합니다. 요구사항 보충에는 전체 명세서 확인과 사용자 승인이 필요합니다.
|
|
73
|
+
|
|
74
|
+
### 기존 설계를 이어가기
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
$spec-to-ui:spec-to-ui
|
|
78
|
+
현재 프로젝트의 REQUIREMENTS.md와 DESIGN.md를 읽고 이어서 진행해 주세요.
|
|
79
|
+
목록 구성은 유지하고 상세 화면과 신청 흐름을 확장해 주세요.
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
기존 결정과 승인 범위를 유지하며 필요한 부분부터 작업합니다. 목적·기능·권한·주요 흐름을 바꾸는 선택과 별도 설치·유료 연결·배포는 승인 범위를 확인합니다.
|
|
83
|
+
|
|
84
|
+
## 작동 구조
|
|
85
|
+
|
|
86
|
+
명세서와 기존 결정을 읽고 화면 구조를 정리합니다. 실제 참고 자료와 표현 방법을 제안한 뒤, 핵심 작업을 보여 주는 대표 화면을 만듭니다. 사용자 선택이나 위임 범위에 따라 확장하고 실제 브라우저에서 해당 흐름을 검증합니다.
|
|
87
|
+
|
|
88
|
+
디자인 제안에는 쉬운 설명과 볼 수 있는 예시를 함께 제시하도록 했습니다. 모션이 선택의 핵심이라면 재생하거나 조작할 수 있는 미리보기를 사용합니다. 참고 화면을 열어 보지 못했거나 실제 조작을 하지 못한 경우에는 확인했다고 보고하지 않습니다.
|
|
89
|
+
|
|
90
|
+
## 결정과 작업 기록
|
|
91
|
+
|
|
92
|
+
프로젝트의 `DESIGN.md`에 채택한 배치, 글꼴, 색, 간격, 컴포넌트와 상태 규칙을 기록합니다. AI 제안, 사용자 선택, 위임에 따른 결정, 미정 사항을 구분합니다. 요구사항은 기존 명세서에서 관리하며 두 개의 최신 명세서를 만들지 않습니다.
|
|
93
|
+
|
|
94
|
+
검증 결과에는 실제 확인한 화면·상태·조작과 미검증 사항을 남깁니다. 개발 설명이나 예시 데이터 안내를 제품 화면의 문구로 자동 삽입하지 않습니다.
|
|
95
|
+
|
|
96
|
+
## 0.1.0에서 바뀐 점
|
|
97
|
+
|
|
98
|
+
`0.1.0`은 단일 스킬을 복사하는 설치 도구입니다. `0.2.0`은 네 스킬을 묶은 플러그인으로, 호출명은 `$spec-to-ui:spec-to-ui`입니다. 이전 설치용 `--target`, `--project`, `--replace` 옵션은 지원하지 않습니다.
|
|
99
|
+
|
|
100
|
+
설치 도우미는 기존 단일 스킬과 개발용 플러그인을 자동으로 삭제하거나 교체하지 않습니다. 이전 단일 스킬의 `$spec-to-ui` 호출도 별도로 남을 수 있습니다. 개발용 플러그인과 공개 플러그인은 이름이 같으므로, 공개본으로 전환할 때는 Codex의 플러그인 관리 화면에서 사용할 쪽을 활성화해 주십시오.
|
|
101
|
+
|
|
102
|
+
## 고급 사용과 문제 해결
|
|
103
|
+
|
|
104
|
+
다른 위치에 있는 Codex 실행 파일을 사용하려면 경로를 지정합니다.
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
npx --yes spec-to-ui@0.2.0 install --codex /absolute/path/to/codex
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
설치 상태와 패키지 파일 검사는 각각 다음과 같습니다.
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
npx --yes spec-to-ui@0.2.0 status
|
|
114
|
+
npx --yes spec-to-ui@0.2.0 check
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`codex`를 찾지 못하면 Codex CLI의 설치와 경로를 확인해 주십시오. 플러그인 명령 자체가 없으면 사용 중인 Codex가 플러그인을 지원하는지 확인해야 합니다. 이 도구는 Codex나 Node.js를 자동으로 설치·업데이트하지 않습니다.
|
|
118
|
+
|
|
119
|
+
명령어 지원과 마켓플레이스 구조는 [공식 플러그인 문서](https://developers.openai.com/plugins/build/plugins)를 참고해 주십시오.
|
|
120
|
+
|
|
121
|
+
## 개발 및 검증
|
|
122
|
+
|
|
123
|
+
배포 구성과 확인 범위는 [RELEASE.md](RELEASE.md)에 기록했습니다. 설치·검색 검증과 예제 UI 검증은 서로 구분합니다. 특정 사례의 성공이 모든 프로젝트의 디자인 품질이나 실제 서비스 연동을 보장하지는 않습니다.
|
|
124
|
+
|
|
125
|
+
## 라이선스와 출처
|
|
126
|
+
|
|
127
|
+
직접 작성한 spec-to-ui 지침과 설치 도구에는 MIT 라이선스가 적용됩니다. 동봉한 외부 구성 요소의 조건과 수정 범위는 [THIRD-PARTY.md](THIRD-PARTY.md), 고정 원본은 [sources.json](sources.json)에 기록했습니다. 각 폴더의 LICENSE도 확인해 주십시오.
|
|
128
|
+
|
|
129
|
+
SpecFrame은 제작자의 재배포 허가에 따라 포함했으며 MIT로 재허가하지 않았습니다.
|
package/README.md
CHANGED
|
@@ -1,62 +1,129 @@
|
|
|
1
1
|
# spec-to-ui
|
|
2
2
|
|
|
3
|
-
요구사항 명세서를
|
|
3
|
+
요구사항 명세서를 화면 구조와 실제로 볼 수 있는 UI 초안으로 발전시키는 Codex 플러그인입니다. 디자인이나 CSS를 몰라도 예시와 미리보기를 보며 방향을 고를 수 있도록 돕습니다.
|
|
4
|
+
|
|
5
|
+
## 주요 기능
|
|
6
|
+
|
|
7
|
+
- 요구사항을 페이지, 정보 우선순위, 핵심 행동과 필요한 상태로 옮깁니다.
|
|
8
|
+
- 실제 참고 자료와 대표 화면으로 디자인을 비교하고 선택한 방향을 확장합니다.
|
|
9
|
+
- 명세서의 중요한 누락은 SpecFrame으로 보충하고, 승인된 범위에서 UI 작업으로 돌아옵니다.
|
|
10
|
+
- 정렬, 단어 단위 줄바꿈, 입력 요소와 열린 달력, 반응형, 초점, 모션을 함께 검토합니다.
|
|
11
|
+
- 채택한 디자인 규칙은 프로젝트의 `DESIGN.md`에 기록합니다.
|
|
12
|
+
|
|
13
|
+
## 포함된 스킬
|
|
14
|
+
|
|
15
|
+
| 구성 | 사용하는 시점 |
|
|
16
|
+
|---|---|
|
|
17
|
+
| spec-to-ui | 전체 UI 설계를 진행하고 필요한 보조 역할을 연결합니다. |
|
|
18
|
+
| SpecFrame | 기능·권한·업무 규칙의 누락이나 충돌이 화면 설계를 막을 때 사용합니다. |
|
|
19
|
+
| design-taste-frontend | 시각 방향, 이미지, 타이포그래피, 구성과 모션을 보강합니다. |
|
|
20
|
+
| ui-ux-pro-max | 폼, 반응형, 접근성, 탐색과 상호작용의 구체적인 문제를 검토합니다. |
|
|
21
|
+
|
|
22
|
+
`spec-to-ui`가 필요한 보조 스킬의 지침을 같은 묶음에서 읽도록 구성했습니다. 매번 네 스킬을 모두 실행하지는 않습니다. `DESIGN.md`는 프로젝트 문서이며, Refero Styles 등은 실제 참고 자료를 찾는 외부 서비스입니다. 별도 스킬이나 서비스 이용권이 포함된 것은 아닙니다.
|
|
23
|
+
|
|
24
|
+
## 필수 프로그램
|
|
25
|
+
|
|
26
|
+
- 플러그인을 지원하는 Codex와 `codex` 명령
|
|
27
|
+
- Node.js 22 이상과 npm
|
|
28
|
+
- 보조 검색 도구를 사용하는 경우 Python 3
|
|
29
|
+
|
|
30
|
+
브라우저, 이미지 제작, 외부 디자인 자료의 열람은 사용 중인 환경의 도구와 권한에 따릅니다. 필요한 도구를 사용할 수 없으면 가능한 대안과 미검증 범위를 안내하도록 되어 있습니다.
|
|
4
31
|
|
|
5
32
|
## 설치
|
|
6
33
|
|
|
7
|
-
|
|
34
|
+
다음 명령은 GitHub의 마켓플레이스를 등록한 뒤 npm의 `0.2.0` 패키지를 Codex 플러그인으로 설치합니다.
|
|
8
35
|
|
|
9
36
|
```sh
|
|
10
|
-
npx spec-to-ui install
|
|
37
|
+
npx --yes spec-to-ui@0.2.0 install
|
|
11
38
|
```
|
|
12
39
|
|
|
13
|
-
|
|
40
|
+
실행할 설치 명령만 확인하려면 다음을 사용합니다.
|
|
14
41
|
|
|
15
|
-
|
|
42
|
+
```sh
|
|
43
|
+
npx --yes spec-to-ui@0.2.0 install --dry-run
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
npm 설치 도우미 없이 Codex에서 직접 설치할 수도 있습니다.
|
|
16
47
|
|
|
17
48
|
```sh
|
|
18
|
-
|
|
49
|
+
codex plugin marketplace add suminkim8203/spec-to-ui
|
|
50
|
+
codex plugin add spec-to-ui@spec-to-ui
|
|
19
51
|
```
|
|
20
52
|
|
|
21
|
-
설치 후 Codex
|
|
53
|
+
설치 후 새 Codex 세션에서 호출합니다. 앱을 계속 열어 두었다면 새 채팅에서도 목록이 갱신되었는지 확인해 주십시오.
|
|
22
54
|
|
|
23
55
|
```text
|
|
24
|
-
$spec-to-ui
|
|
56
|
+
$spec-to-ui:spec-to-ui
|
|
25
57
|
```
|
|
26
58
|
|
|
27
|
-
|
|
59
|
+
플러그인 이름과 표시명은 모두 `spec-to-ui`입니다.
|
|
28
60
|
|
|
29
|
-
##
|
|
61
|
+
## 사용법
|
|
30
62
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
63
|
+
### 명세서로 시작하기
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
$spec-to-ui:spec-to-ui
|
|
67
|
+
요구사항은 ./REQUIREMENTS.md에 있습니다.
|
|
68
|
+
신규 사이트를 설계해 주세요. 참고 방향을 미리보기로 추천하고,
|
|
69
|
+
대표 화면을 확인한 뒤 전체 화면으로 확장하겠습니다.
|
|
34
70
|
```
|
|
35
71
|
|
|
36
|
-
|
|
72
|
+
이미 승인한 명세서는 재사용합니다. UI 구조에 영향을 주는 누락이 있으면 보충할 항목을 짚고 SpecFrame으로 연결합니다. 요구사항 보충에는 전체 명세서 확인과 사용자 승인이 필요합니다.
|
|
73
|
+
|
|
74
|
+
### 기존 설계를 이어가기
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
$spec-to-ui:spec-to-ui
|
|
78
|
+
현재 프로젝트의 REQUIREMENTS.md와 DESIGN.md를 읽고 이어서 진행해 주세요.
|
|
79
|
+
목록 구성은 유지하고 상세 화면과 신청 흐름을 확장해 주세요.
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
기존 결정과 승인 범위를 유지하며 필요한 부분부터 작업합니다. 목적·기능·권한·주요 흐름을 바꾸는 선택과 별도 설치·유료 연결·배포는 승인 범위를 확인합니다.
|
|
83
|
+
|
|
84
|
+
## 작동 구조
|
|
85
|
+
|
|
86
|
+
명세서와 기존 결정을 읽고 화면 구조를 정리합니다. 실제 참고 자료와 표현 방법을 제안한 뒤, 핵심 작업을 보여 주는 대표 화면을 만듭니다. 사용자 선택이나 위임 범위에 따라 확장하고 실제 브라우저에서 해당 흐름을 검증합니다.
|
|
87
|
+
|
|
88
|
+
디자인 제안에는 쉬운 설명과 볼 수 있는 예시를 함께 제시하도록 했습니다. 모션이 선택의 핵심이라면 재생하거나 조작할 수 있는 미리보기를 사용합니다. 참고 화면을 열어 보지 못했거나 실제 조작을 하지 못한 경우에는 확인했다고 보고하지 않습니다.
|
|
89
|
+
|
|
90
|
+
## 결정과 작업 기록
|
|
91
|
+
|
|
92
|
+
프로젝트의 `DESIGN.md`에 채택한 배치, 글꼴, 색, 간격, 컴포넌트와 상태 규칙을 기록합니다. AI 제안, 사용자 선택, 위임에 따른 결정, 미정 사항을 구분합니다. 요구사항은 기존 명세서에서 관리하며 두 개의 최신 명세서를 만들지 않습니다.
|
|
93
|
+
|
|
94
|
+
검증 결과에는 실제 확인한 화면·상태·조작과 미검증 사항을 남깁니다. 개발 설명이나 예시 데이터 안내를 제품 화면의 문구로 자동 삽입하지 않습니다.
|
|
95
|
+
|
|
96
|
+
## 0.1.0에서 바뀐 점
|
|
97
|
+
|
|
98
|
+
`0.1.0`은 단일 스킬을 복사하는 설치 도구입니다. `0.2.0`은 네 스킬을 묶은 플러그인으로, 호출명은 `$spec-to-ui:spec-to-ui`입니다. 이전 설치용 `--target`, `--project`, `--replace` 옵션은 지원하지 않습니다.
|
|
99
|
+
|
|
100
|
+
설치 도우미는 기존 단일 스킬과 개발용 플러그인을 자동으로 삭제하거나 교체하지 않습니다. 이전 단일 스킬의 `$spec-to-ui` 호출도 별도로 남을 수 있습니다. 개발용 플러그인과 공개 플러그인은 이름이 같으므로, 공개본으로 전환할 때는 Codex의 플러그인 관리 화면에서 사용할 쪽을 활성화해 주십시오.
|
|
101
|
+
|
|
102
|
+
## 고급 사용과 문제 해결
|
|
103
|
+
|
|
104
|
+
다른 위치에 있는 Codex 실행 파일을 사용하려면 경로를 지정합니다.
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
npx --yes spec-to-ui@0.2.0 install --codex /absolute/path/to/codex
|
|
108
|
+
```
|
|
37
109
|
|
|
38
|
-
|
|
110
|
+
설치 상태와 패키지 파일 검사는 각각 다음과 같습니다.
|
|
39
111
|
|
|
40
112
|
```sh
|
|
41
|
-
npx
|
|
113
|
+
npx --yes spec-to-ui@0.2.0 status
|
|
114
|
+
npx --yes spec-to-ui@0.2.0 check
|
|
42
115
|
```
|
|
43
116
|
|
|
44
|
-
|
|
117
|
+
`codex`를 찾지 못하면 Codex CLI의 설치와 경로를 확인해 주십시오. 플러그인 명령 자체가 없으면 사용 중인 Codex가 플러그인을 지원하는지 확인해야 합니다. 이 도구는 Codex나 Node.js를 자동으로 설치·업데이트하지 않습니다.
|
|
45
118
|
|
|
46
|
-
|
|
119
|
+
명령어 지원과 마켓플레이스 구조는 [공식 플러그인 문서](https://developers.openai.com/plugins/build/plugins)를 참고해 주십시오.
|
|
47
120
|
|
|
48
|
-
|
|
121
|
+
## 개발 및 검증
|
|
49
122
|
|
|
50
|
-
|
|
51
|
-
- 목록과 상세 사이의 이동, 선택과 초점, 원래 위치로의 복귀
|
|
52
|
-
- 작은 상호작용의 반응과 애니메이션, 동작 감소 환경
|
|
53
|
-
- 입력 필드와 버튼뿐 아니라 펼친 달력과 선택 목록의 디자인
|
|
54
|
-
- 기존 입력 방식과 선택 범위의 보존
|
|
55
|
-
- 불필요한 정보 반복과 개발 설명 문구
|
|
56
|
-
- 모호한 요구의 해석과 실제 사용에서 예상되는 불편
|
|
123
|
+
배포 구성과 확인 범위는 [RELEASE.md](RELEASE.md)에 기록했습니다. 설치·검색 검증과 예제 UI 검증은 서로 구분합니다. 특정 사례의 성공이 모든 프로젝트의 디자인 품질이나 실제 서비스 연동을 보장하지는 않습니다.
|
|
57
124
|
|
|
58
|
-
|
|
125
|
+
## 라이선스와 출처
|
|
59
126
|
|
|
60
|
-
|
|
127
|
+
직접 작성한 spec-to-ui 지침과 설치 도구에는 MIT 라이선스가 적용됩니다. 동봉한 외부 구성 요소의 조건과 수정 범위는 [THIRD-PARTY.md](THIRD-PARTY.md), 고정 원본은 [sources.json](sources.json)에 기록했습니다. 각 폴더의 LICENSE도 확인해 주십시오.
|
|
61
128
|
|
|
62
|
-
MIT
|
|
129
|
+
SpecFrame은 제작자의 재배포 허가에 따라 포함했으며 MIT로 재허가하지 않았습니다.
|
package/RELEASE.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# spec-to-ui 0.2.0
|
|
2
|
+
|
|
3
|
+
네 스킬을 포함하는 Codex 플러그인으로 배포합니다. 기존 0.1.0의 단일 스킬 복사 방식에서 공식 마켓플레이스 등록과 플러그인 설치 방식으로 바뀌었습니다.
|
|
4
|
+
|
|
5
|
+
## 배포 구성
|
|
6
|
+
|
|
7
|
+
- spec-to-ui: 명세서에서 UI 구조·참고·대표 화면·피드백으로 이어지는 설계
|
|
8
|
+
- SpecFrame: 구조에 영향을 주는 요구 누락·충돌의 보충과 승인 후 복귀
|
|
9
|
+
- design-taste-frontend: 채택한 구조를 보존하는 시각 표현 보강
|
|
10
|
+
- ui-ux-pro-max: 구체적인 폼·접근성·반응형·상호작용 지침 검색
|
|
11
|
+
|
|
12
|
+
기존 개발본의 지침과 보조 자료를 사용합니다. 설치 도구와 공개용 문서·메타데이터를 추가했으며 외부 서비스 이용권, 검증용 사이트, 사용자 대화와 제출 자료는 포함하지 않습니다.
|
|
13
|
+
|
|
14
|
+
## 검증 범위
|
|
15
|
+
|
|
16
|
+
- 검증한 개발본과 배포본의 스킬 파일 131개가 일치합니다.
|
|
17
|
+
- 실제 npm 압축 파일을 풀어 별도 Codex 설정 폴더에서 설치했습니다. 플러그인 버전 0.2.0과 네 스킬의 활성화·이름·설치 경로를 확인했습니다.
|
|
18
|
+
- 설치 도구의 12개 검사를 실행했습니다. 정상 검사, 설치 예정 명령 표시, 잘못된 옵션 거부, 공백을 포함한 인수 전달, 설치 오류 시 중단, 파일 변조 감지와 복원 후 검사를 포함합니다.
|
|
19
|
+
- 설치된 사본에서 SpecFrame 상태 도구, ui-ux-pro-max의 키보드·초점 검색, taste의 두 방향 제안을 실행했습니다.
|
|
20
|
+
- 기존 단일 스킬, 개발용 플러그인 설치본과 개발 원본은 변경하지 않았습니다.
|
|
21
|
+
|
|
22
|
+
설치 검증에는 Codex CLI 0.166.0-alpha.5.1, Node.js 22 이상을 지원하는 로컬 실행 환경을 사용했습니다. 공개 레지스트리의 다운로드와 GitHub 경유 설치는 게시 후 별도로 확인합니다.
|
|
23
|
+
|
|
24
|
+
첫 로컬 설치 시 마켓플레이스 폴더 밖을 가리킨 시험 경로가 거부되었습니다. 패키지를 포함한 마켓플레이스 안의 상대 경로로 수정해 통과했습니다. taste 도구는 `--help` 옵션을 지원하지 않아, 문서의 `--sector`와 `--options` 방식으로 다시 실행했습니다. 원본 도구를 수정하지 않았습니다.
|
|
25
|
+
|
|
26
|
+
개발 플러그인에서 확인한 실제 호출과 문화공간·회의실 예약 예제의 UI 검증은 같은 지침 파일에 대한 이전 근거입니다. 이번 배포 검사는 새로운 주제의 UI 제작, 모든 운영체제·실기기·화면 읽기 도구 시험이나 모든 프로젝트의 품질 보장을 뜻하지 않습니다. npm·GitHub 배포는 OpenAI 공개 플러그인 디렉터리의 등록·승인과도 별개입니다.
|
package/THIRD-PARTY.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# 원본과 조정 범위
|
|
2
|
+
|
|
3
|
+
spec-to-ui 0.2.0은 아래 네 스킬을 포함하는 공개 플러그인입니다. `skills/spec-to-ui/SKILL.md`가 진입점이며 형제 폴더의 보조 스킬을 연결합니다.
|
|
4
|
+
|
|
5
|
+
| 구성 | 고정 원본 | 고지와 조정 |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| spec-to-ui | 기존 0.1.0 배포 소스 | 기존 MIT 고지를 보존합니다. 조합·보충·추천 미리보기·DESIGN.md·완료 기준을 반영했습니다. |
|
|
8
|
+
| SpecFrame | ProjectFrame-skills/SpecFrame `0a9c555672384f27713184d55724155798af252e` | 제작자 재배포 허가를 사용자에게 확인받았습니다. MIT로 재허가하지 않습니다. 이 사본에서 승인 후 복귀 대상을 spec-to-ui로 변경했으며 요구 검토·승인·상태 소유 규칙을 유지합니다. |
|
|
9
|
+
| design-taste-frontend | Leonxlnx/taste-skill `12af471f627f866411b4bd785b19646d3672784c`, `skills/taste-skill` | 원본 LICENSE를 보존합니다. 조합의 승인된 구조와 디자인, 보조 범위·검증 도구 제약을 진입 지침에 명시했습니다. |
|
|
10
|
+
| ui-ux-pro-max | nextlevelbuilder/ui-ux-pro-max-skill `3a13158ff1f32156cbe144108de48eda2ecaed9a`, 2.15.0 | 원본 LICENSE를 보존합니다. Codex에서 실제 스킬 경로를 쓰도록 실행 예시를 조정하고 기존 DESIGN.md와 충돌하는 디자인 시스템 재생성을 제한했습니다. |
|
|
11
|
+
|
|
12
|
+
외부 참고 사이트의 사진·영상·글꼴·브랜드 자료는 포함하지 않았습니다. 원본 위치와 조회한 파일은 sources.json에 기록했습니다. 개인 대화나 허가 확인 전문은 배포 대상이 아닙니다.
|
|
13
|
+
|
|
14
|
+
SpecFrame은 제작자에게 확인받은 재배포 허가에 따라 포함했습니다. 해당 허가를 MIT 라이선스나 모든 이용자에게 적용되는 별도 재허가로 확대 해석하지 않습니다. SpecFrame을 별도로 재배포하거나 이용 범위를 확인하려면 원 제작자의 조건을 확인해 주십시오. 다른 구성 요소는 각각의 LICENSE와 고지를 따릅니다.
|
package/bin/cli.mjs
CHANGED
|
@@ -1,110 +1,89 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { createHash
|
|
4
|
-
import {
|
|
5
|
-
import { dirname, join, resolve, isAbsolute } from 'node:path';
|
|
2
|
+
import { readFileSync, readdirSync, lstatSync } from 'node:fs';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { dirname, join, relative, isAbsolute } from 'node:path';
|
|
6
5
|
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { spawnSync } from 'node:child_process';
|
|
7
7
|
|
|
8
|
-
const root = fileURLToPath(
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const digest = bytes => createHash('sha256').update(bytes).digest('hex');
|
|
8
|
+
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
9
|
+
const version = '0.2.0';
|
|
10
|
+
const defaultMarketplace = 'suminkim8203/spec-to-ui';
|
|
11
|
+
const installId = 'spec-to-ui@spec-to-ui';
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
try { return await lstat(path); }
|
|
16
|
-
catch (error) { if (error.code === 'ENOENT') return null; throw error; }
|
|
17
|
-
}
|
|
18
|
-
async function files(path, prefix = '') {
|
|
13
|
+
function files(folder) {
|
|
19
14
|
const result = [];
|
|
20
|
-
for (const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
else
|
|
15
|
+
for (const name of readdirSync(folder).sort()) {
|
|
16
|
+
const path = join(folder, name);
|
|
17
|
+
const stat = lstatSync(path);
|
|
18
|
+
if (stat.isSymbolicLink()) throw new Error('Symbolic link is not permitted: ' + relative(root, path));
|
|
19
|
+
if (stat.isDirectory()) result.push(...files(path));
|
|
20
|
+
else if (stat.isFile()) result.push(relative(root, path).split('\\').join('/'));
|
|
21
|
+
else throw new Error('Unexpected file type: ' + relative(root, path));
|
|
26
22
|
}
|
|
27
23
|
return result.sort();
|
|
28
24
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
async function validatePackage() {
|
|
36
|
-
for (const name of Object.keys(manifest)) {
|
|
37
|
-
if (isAbsolute(name) || name.split(/[\\/]/).includes('..')) throw new Error('잘못된 스킬 파일 경로입니다.');
|
|
25
|
+
|
|
26
|
+
function checkBundle() {
|
|
27
|
+
const manifest = JSON.parse(readFileSync(join(root, 'bundle-manifest.json'), 'utf8'));
|
|
28
|
+
if (manifest.version !== version || !manifest.sha256 || typeof manifest.sha256 !== 'object') {
|
|
29
|
+
throw new Error('Invalid bundle manifest');
|
|
38
30
|
}
|
|
39
|
-
|
|
31
|
+
for (const [path, expected] of Object.entries(manifest.sha256)) {
|
|
32
|
+
if (!path || isAbsolute(path) || path.includes('\\') || path.split('/').some(p => p === '..' || p === '.')) {
|
|
33
|
+
throw new Error('Invalid manifest path');
|
|
34
|
+
}
|
|
35
|
+
const full = join(root, path);
|
|
36
|
+
if (!lstatSync(full).isFile() || lstatSync(full).isSymbolicLink()) throw new Error('Invalid bundle file: ' + path);
|
|
37
|
+
const actual = createHash('sha256').update(readFileSync(full)).digest('hex');
|
|
38
|
+
if (actual !== expected) throw new Error('Bundle file differs: ' + path);
|
|
39
|
+
}
|
|
40
|
+
const listed = Object.keys(manifest.sha256).filter(p => p.startsWith('skills/')).sort();
|
|
41
|
+
const actual = files(join(root, 'skills'));
|
|
42
|
+
if (JSON.stringify(listed) !== JSON.stringify(actual)) throw new Error('Skill file list differs');
|
|
43
|
+
const plugin = JSON.parse(readFileSync(join(root, 'plugin.json'), 'utf8'));
|
|
44
|
+
if (plugin.name !== 'spec-to-ui' || plugin.version !== version) throw new Error('Plugin identity differs');
|
|
45
|
+
return { version, skillFiles: listed.length, skills: readdirSync(join(root, 'skills')).sort() };
|
|
40
46
|
}
|
|
41
|
-
function help() {
|
|
42
|
-
console.log(`spec-to-ui ${pkg.version}
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
npx spec-to-ui install --project 현재 프로젝트에 설치
|
|
47
|
-
npx spec-to-ui status 설치 상태 확인
|
|
48
|
-
npx spec-to-ui install --replace 기존 설치를 백업하고 교체
|
|
49
|
-
|
|
50
|
-
옵션:
|
|
51
|
-
--project 현재 폴더의 .agents/skills/spec-to-ui 사용
|
|
52
|
-
--target <directory> 지정한 스킬 폴더 사용
|
|
53
|
-
--replace 기존 폴더를 백업한 뒤 교체
|
|
54
|
-
--help 도움말
|
|
55
|
-
--version 버전
|
|
56
|
-
|
|
57
|
-
설치 후 Codex에서 $spec-to-ui를 호출합니다.
|
|
58
|
-
스킬이 목록에 나타나지 않으면 Codex를 다시 시작해 주세요.`);
|
|
48
|
+
function help() {
|
|
49
|
+
process.stdout.write(`spec-to-ui ${version}\n\nUsage:\n spec-to-ui install [--codex <binary>] [--marketplace <source>] [--dry-run]\n spec-to-ui status [--codex <binary>] [--dry-run]\n spec-to-ui check\n spec-to-ui --version\n\nInstall registers the marketplace and installs the spec-to-ui plugin through Codex.\nThe existing standalone skill and development plugin are not replaced.\nDefault marketplace: ${defaultMarketplace}\nRequires Node.js 22+ and a Codex version with plugin support.\nPython 3 is needed for companion search tools.\nOld --target, --project and --replace options are not supported by the plugin installer.\n`);
|
|
59
50
|
}
|
|
60
|
-
|
|
51
|
+
|
|
52
|
+
function main() {
|
|
61
53
|
const args = process.argv.slice(2);
|
|
62
|
-
if (args.length ===
|
|
63
|
-
if (args.length === 1 &&
|
|
54
|
+
if (!args.length || (args.length === 1 && ['--help', '-h', 'help'].includes(args[0]))) return help();
|
|
55
|
+
if (args.length === 1 && ['--version', '-v'].includes(args[0])) return process.stdout.write(version + '\n');
|
|
64
56
|
const command = args.shift();
|
|
65
|
-
if (!['install', 'status'].includes(command)) throw new Error('
|
|
66
|
-
|
|
57
|
+
if (!['install', 'status', 'check'].includes(command)) throw new Error('Unknown command: ' + command);
|
|
58
|
+
const options = { codex: 'codex', marketplace: defaultMarketplace, dryRun: false };
|
|
59
|
+
const seen = new Set();
|
|
67
60
|
while (args.length) {
|
|
68
61
|
const flag = args.shift();
|
|
69
|
-
if (flag
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
62
|
+
if (seen.has(flag)) throw new Error('Duplicate option: ' + flag);
|
|
63
|
+
seen.add(flag);
|
|
64
|
+
if (flag === '--dry-run' && command !== 'check') options.dryRun = true;
|
|
65
|
+
else if (flag === '--codex' && command !== 'check') {
|
|
66
|
+
const value = args.shift();
|
|
67
|
+
if (!value || value.startsWith('--')) throw new Error('Missing value: ' + flag);
|
|
68
|
+
options.codex = value;
|
|
69
|
+
} else if (flag === '--marketplace' && command === 'install') {
|
|
70
|
+
const value = args.shift();
|
|
71
|
+
if (!value || value.startsWith('--')) throw new Error('Missing value: ' + flag);
|
|
72
|
+
options.marketplace = value;
|
|
73
|
+
} else throw new Error('Unsupported option for ' + command + ': ' + flag);
|
|
75
74
|
}
|
|
76
|
-
|
|
77
|
-
if (command === '
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
75
|
+
const bundle = checkBundle();
|
|
76
|
+
if (command === 'check') return process.stdout.write(JSON.stringify({ ok: true, ...bundle }, null, 2) + '\n');
|
|
77
|
+
const commands = command === 'install'
|
|
78
|
+
? [['plugin', 'marketplace', 'add', options.marketplace, '--json'], ['plugin', 'add', installId, '--json']]
|
|
79
|
+
: [['plugin', 'list', '--json']];
|
|
80
|
+
if (options.dryRun) return process.stdout.write(JSON.stringify({ dryRun: true, commands: commands.map(args => ({ executable: options.codex, args })) }, null, 2) + '\n');
|
|
81
|
+
for (const args of commands) {
|
|
82
|
+
const result = spawnSync(options.codex, args, { stdio: 'inherit', shell: false });
|
|
83
|
+
if (result.error) throw new Error('Could not start Codex: ' + result.error.message + '. Use --codex <binary> to select your CLI.');
|
|
84
|
+
if (result.status !== 0) throw new Error('Codex command failed' + (result.signal ? ' (' + result.signal + ')' : ' with exit code ' + result.status));
|
|
86
85
|
}
|
|
87
|
-
if (
|
|
88
|
-
if (current && !replace) throw new Error(`기존 스킬을 유지했습니다: ${target}\n백업 후 교체하려면 --replace를 사용해 주세요.`);
|
|
89
|
-
await mkdir(dirname(target), { recursive: true });
|
|
90
|
-
const stage = await mkdtemp(join(dirname(target), '.spec-to-ui-install-'));
|
|
91
|
-
let backup = null;
|
|
92
|
-
try {
|
|
93
|
-
await cp(source, stage, { recursive: true, force: false });
|
|
94
|
-
if (!await matches(stage)) throw new Error('복사한 파일의 검증에 실패했습니다.');
|
|
95
|
-
if (current) {
|
|
96
|
-
// Backups stay outside the skills directory to avoid duplicate discovery.
|
|
97
|
-
const backupRoot = join(dirname(dirname(target)), 'skill-backups', 'spec-to-ui');
|
|
98
|
-
await mkdir(backupRoot, { recursive: true });
|
|
99
|
-
backup = join(backupRoot, `${new Date().toISOString().replace(/[:.]/g, '-')}-${randomUUID()}`);
|
|
100
|
-
await rename(target, backup);
|
|
101
|
-
} else if (await exists(target)) throw new Error('설치 대상이 작업 중 생성되어 설치를 중단했습니다.');
|
|
102
|
-
try { await rename(stage, target); }
|
|
103
|
-
catch (error) { if (backup) await rename(backup, target); throw error; }
|
|
104
|
-
} finally { await rm(stage, { recursive: true, force: true }); }
|
|
105
|
-
console.log(`spec-to-ui ${pkg.version} 설치 완료: ${target}`);
|
|
106
|
-
if (backup) console.log(`이전 스킬 백업: ${backup}`);
|
|
107
|
-
console.log('Codex에서 $spec-to-ui를 호출해 주세요.');
|
|
86
|
+
if (command === 'install') process.stdout.write('Installed via Codex. Start a new session and call $spec-to-ui:spec-to-ui.\n');
|
|
108
87
|
}
|
|
109
|
-
|
|
110
|
-
catch (error) {
|
|
88
|
+
|
|
89
|
+
try { main(); } catch (error) { process.stderr.write('spec-to-ui: ' + error.message + '\n'); process.exitCode = 1; }
|