projectops 3.0.195 → 4.0.1

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/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  > 이슈 등록부터 커밋, 보고서, 배포까지. 개발자는 코드만 작성하세요.
8
8
 
9
9
  <!-- AUTO-VERSION-SECTION: DO NOT EDIT MANUALLY -->
10
- ## 최신 버전 : v3.0.194 (2026-07-08)
10
+ ## 최신 버전 : v3.0.195 (2026-07-08)
11
11
 
12
12
  [전체 버전 기록 보기](CHANGELOG.md)
13
13
 
@@ -85,6 +85,17 @@ GitHub에서 **"Use this template"** 클릭 → 1분 내 자동 초기화 완료
85
85
 
86
86
  ### 기존 프로젝트에 통합
87
87
 
88
+ **권장 — npx (macOS · Linux · Windows 공통)**
89
+
90
+ ```bash
91
+ npx projectops
92
+ ```
93
+
94
+ > Node.js 18+ 만 있으면 별도 설치 없이 대화형 마법사가 실행됩니다. 비대화형: `npx projectops --mode full --type spring,react --force`
95
+
96
+ <details>
97
+ <summary>대안 — 스크립트 직접 실행 (Node 없이)</summary>
98
+
88
99
  ```bash
89
100
  # macOS / Linux
90
101
  bash <(curl -fsSL "https://raw.githubusercontent.com/Cassiiopeia/projectops/main/template_integrator.sh")
@@ -95,6 +106,8 @@ bash <(curl -fsSL "https://raw.githubusercontent.com/Cassiiopeia/projectops/main
95
106
  $wc=New-Object Net.WebClient;$wc.Encoding=[Text.Encoding]::UTF8;iex $wc.DownloadString("https://raw.githubusercontent.com/Cassiiopeia/projectops/main/template_integrator.ps1")
96
107
  ```
97
108
 
109
+ </details>
110
+
98
111
  ### Agent Skills만 설치
99
112
 
100
113
  ```bash
@@ -113,15 +126,24 @@ gemini extensions install https://github.com/Cassiiopeia/projectops
113
126
  codex plugin marketplace add Cassiiopeia/projectops
114
127
  ```
115
128
 
116
- `template_integrator --mode skills` 마법사는 Codex marketplace를 등록한 뒤 native skills fallback도 자동 준비합니다. `/plugins`는 설치 확인/관리용으로만 사용하면 됩니다.
129
+ `--mode skills` 마법사는 Codex marketplace를 등록한 뒤 native skills fallback도 자동 준비합니다. `/plugins`는 설치 확인/관리용으로만 사용하면 됩니다.
117
130
 
118
131
  Codex plugin marketplace를 사용할 수 없는 환경에서는 [Skills 가이드](docs/SKILLS.md)의 fallback 설치 방식을 사용하세요.
119
132
 
120
133
  ```bash
121
- # Cursor / 전체 Agent Skills 설치 메뉴
134
+ # Cursor / 전체 Agent Skills 설치 메뉴 (권장 — npx)
135
+ npx projectops --mode skills
136
+ ```
137
+
138
+ <details>
139
+ <summary>대안 — 스크립트 직접 실행 (Node 없이)</summary>
140
+
141
+ ```bash
122
142
  bash <(curl -fsSL "https://raw.githubusercontent.com/Cassiiopeia/projectops/main/template_integrator.sh") --mode skills
123
143
  ```
124
144
 
145
+ </details>
146
+
125
147
  > Claude Code는 `/cassiiopeia:` 자동완성, Gemini는 extension, Codex는 plugin marketplace를 우선 사용합니다. 자세한 설치 방식은 [Skills 가이드](docs/SKILLS.md)를 확인하세요.
126
148
 
127
149
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "projectops",
3
- "version": "3.0.195",
3
+ "version": "4.0.1",
4
4
  "description": "ProjectOps — 완전 자동화 GitHub 프로젝트 관리 템플릿 통합 CLI (구 SUH-DEVOPS-TEMPLATE 마법사)",
5
5
  "keywords": [
6
6
  "devops",
@@ -24,6 +24,9 @@
24
24
  "url": "https://github.com/Cassiiopeia/projectops/issues"
25
25
  },
26
26
  "type": "module",
27
+ "scripts": {
28
+ "test": "node --test"
29
+ },
27
30
  "bin": {
28
31
  "projectops": "bin/projectops.js"
29
32
  },
@@ -30,11 +30,17 @@ export function remove(p) {
30
30
  rmSync(p, { recursive: true, force: true });
31
31
  }
32
32
 
33
- // 디렉토리 직하위 .yaml/.yml 파일명 목록 (정렬). 하위 폴더 제외.
33
+ // 디렉토리 직하위 .yaml/.yml 파일명 목록. 하위 폴더 제외.
34
+ // 정렬 순서는 .sh의 glob `"$_dir"/*.yaml "$_dir"/*.yml` 와 일치시킨다:
35
+ // 확장자로 1차 그룹(.yaml 먼저 → .yml 나중), 각 그룹 안에서 알파벳순.
36
+ // (단순 .sort()는 확장자를 섞어 정렬해 .sh와 파일 순회 순서가 갈리고,
37
+ // 그 결과 version.yml deploy 블록의 키 순서까지 달라진다. 확장자 그룹핑으로 바이트 등가 확보.)
34
38
  export function listYamlFiles(dir) {
35
39
  if (!existsSync(dir)) return [];
36
- return readdirSync(dir, { withFileTypes: true })
40
+ const names = readdirSync(dir, { withFileTypes: true })
37
41
  .filter((e) => e.isFile() && /\.(ya?ml)$/.test(e.name))
38
- .map((e) => e.name)
39
- .sort();
42
+ .map((e) => e.name);
43
+ const yaml = names.filter((n) => n.endsWith(".yaml")).sort();
44
+ const yml = names.filter((n) => n.endsWith(".yml")).sort();
45
+ return [...yaml, ...yml];
40
46
  }