project-auto-wizard 0.6.0 → 0.8.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/README.md CHANGED
@@ -17,7 +17,7 @@ npx project-auto-wizard
17
17
  [![node](https://img.shields.io/badge/node-%3E%3D20.12-brightgreen)](package.json)
18
18
 
19
19
  <!-- AUTO-VERSION-SECTION: DO NOT EDIT MANUALLY -->
20
- ## 최신 버전 : v0.5.1 (2026-08-23)
20
+ ## 최신 버전 : v0.8.0 (2026-08-25)
21
21
 
22
22
  [전체 버전 기록 보기](CHANGELOG.md)
23
23
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-auto-wizard",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "One command DevOps: npx wizard that installs GitHub-native AI Release Automation into any project",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -30,6 +30,11 @@ DEPLOY_PORT:
30
30
  help: "호스트(서버)에서 컨테이너로 연결할 포트입니다. 다른 서비스와 겹치지 않게 정하세요."
31
31
  example: "8080"
32
32
 
33
+ ENABLE_VOLUME_MOUNT:
34
+ label: "볼륨 마운트 사용"
35
+ help: "켜면 아래 호스트/컨테이너 경로가 실제 배포에 반영되어 컨테이너에 볼륨이 마운트됩니다. 끄면(기본값) 경로를 입력해도 무시됩니다."
36
+ example: "true"
37
+
33
38
  VOLUME_HOST_PATH:
34
39
  label: "호스트(NAS) 볼륨 경로"
35
40
  help: "서버에 데이터를 영구 저장할 실제 디렉토리 경로입니다."
@@ -74,7 +74,7 @@ env:
74
74
  CONTAINER_NAME: ""
75
75
 
76
76
  # 🗂️ 볼륨 마운트 설정 (빈값이면 마운트 안함)
77
- ENABLE_VOLUME_MOUNT: "false"
77
+ ENABLE_VOLUME_MOUNT: "false" # @wizard ask:false
78
78
  VOLUME_HOST_PATH: "/volume1/projects/__PROJECT_NAME__" # @wizard ask:/volume1/projects/__PROJECT_NAME__
79
79
  VOLUME_CONTAINER_PATH: "/mnt/__PROJECT_NAME__" # @wizard ask:/mnt/__PROJECT_NAME__
80
80
 
@@ -74,7 +74,7 @@ env:
74
74
  CONTAINER_NAME: ""
75
75
 
76
76
  # 🗂️ 볼륨 마운트 설정 (빈값이면 마운트 안함)
77
- ENABLE_VOLUME_MOUNT: "false"
77
+ ENABLE_VOLUME_MOUNT: "false" # @wizard ask:false
78
78
  VOLUME_HOST_PATH: "/volume1/projects/__PROJECT_NAME__" # @wizard ask:/volume1/projects/__PROJECT_NAME__
79
79
  VOLUME_CONTAINER_PATH: "/mnt/__PROJECT_NAME__" # @wizard ask:/mnt/__PROJECT_NAME__
80
80
 
@@ -106,9 +106,9 @@ env:
106
106
  NGINX_BACKUP_KEEP: "10"
107
107
 
108
108
  # 📦 볼륨 마운트 설정
109
- ENABLE_VOLUME_MOUNT: "false"
109
+ ENABLE_VOLUME_MOUNT: "false" # @wizard ask:false
110
110
  VOLUME_HOST_PATH: "/volume1/projects/__PROJECT_NAME__" # @wizard ask:/volume1/projects/__PROJECT_NAME__
111
- VOLUME_CONTAINER_PATH: "/app"
111
+ VOLUME_CONTAINER_PATH: "/app" # @wizard ask:/app
112
112
 
113
113
  # 🔐 SSH 인증 방식: "password"(Synology·일반 서버) | "key"(AWS EC2·.pem)
114
114
  # password → SERVER_PASSWORD secret 사용
@@ -99,7 +99,7 @@ env:
99
99
  EXTRA_NETWORKS: ""
100
100
 
101
101
  # 📦 볼륨 마운트 설정
102
- ENABLE_VOLUME_MOUNT: "false"
102
+ ENABLE_VOLUME_MOUNT: "false" # @wizard ask:false
103
103
  VOLUME_HOST_PATH: "/volume1/projects/__PROJECT_NAME__" # @wizard ask:/volume1/projects/__PROJECT_NAME__
104
104
  VOLUME_CONTAINER_PATH: "/mnt/__PROJECT_NAME__" # @wizard ask:/mnt/__PROJECT_NAME__
105
105
 
@@ -98,7 +98,7 @@ env:
98
98
  # 📦 볼륨 마운트 설정
99
99
  # true: 볼륨 마운트 활성화 (디렉토리 없으면 자동 생성)
100
100
  # false: 볼륨 마운트 비활성화 (기본값)
101
- ENABLE_VOLUME_MOUNT: "false"
101
+ ENABLE_VOLUME_MOUNT: "false" # @wizard ask:false
102
102
  VOLUME_HOST_PATH: "/volume1/projects/__PROJECT_NAME__" # @wizard ask:/volume1/projects/__PROJECT_NAME__
103
103
  VOLUME_CONTAINER_PATH: "/mnt/__PROJECT_NAME__" # @wizard ask:/mnt/__PROJECT_NAME__
104
104
 
@@ -52,6 +52,14 @@ export function resolveToken(name, type, resolvers = {}) {
52
52
  return typeof fn === "function" ? (fn(type) ?? "") : "";
53
53
  }
54
54
 
55
+ // __PROJECT_NAME__/__APP_ARTIFACT_NAME__ 전역 토큰을 repoName으로 치환.
56
+ // substituteEnv()(설치 파일 본문)와 collectAsks()(마법사 화면 표시용 기본값) 양쪽에서
57
+ // 재사용한다 — 두 곳이 서로 다른 로직으로 갈라지면 issue #110과 같은 표시 불일치가 재발한다.
58
+ export function replaceProjectTokens(text, repoName) {
59
+ if (!text.includes("__PROJECT_NAME__") && !text.includes("__APP_ARTIFACT_NAME__")) return text;
60
+ return text.replaceAll("__PROJECT_NAME__", repoName).replaceAll("__APP_ARTIFACT_NAME__", repoName);
61
+ }
62
+
55
63
  // 파일 전체 치환 (configure_workflow_env 등가).
56
64
  // content: 원본 워크플로우 텍스트. 반환: 치환된 텍스트.
57
65
  // opts:
@@ -88,9 +96,7 @@ export function substituteEnv(content, opts = {}) {
88
96
  let out = lines.join(usesCRLF ? "\r\n" : "\n");
89
97
 
90
98
  // 잔여 전역 토큰 (.sh 3347~3351)
91
- if (out.includes("__PROJECT_NAME__") || out.includes("__APP_ARTIFACT_NAME__")) {
92
- out = out.replaceAll("__PROJECT_NAME__", repoName).replaceAll("__APP_ARTIFACT_NAME__", repoName);
93
- }
99
+ out = replaceProjectTokens(out, repoName);
94
100
 
95
101
  // paths-anchor (.sh 3353~3360): 경로가 '.'이 아니면 주석 라인 전체를 paths 라인으로 교체
96
102
  if (PATHS_ANCHOR_RE.test(out) && projectPath && projectPath !== ".") {
@@ -8,7 +8,7 @@ import { readFileSync } from "node:fs";
8
8
  import { stdin, stderr } from "node:process";
9
9
  import { PAYLOAD } from "../core/paths.js";
10
10
  import { exists, listYamlFiles } from "../core/fsutil.js";
11
- import { parseWizardLine, resolveToken } from "../core/wizard-env.js";
11
+ import { parseWizardLine, resolveToken, replaceProjectTokens } from "../core/wizard-env.js";
12
12
  import { loadWizardPrompts, wfField, workflowDisplayName } from "../core/wizard-labels.js";
13
13
  import { deployFilter } from "../core/deploy-style.js";
14
14
  import * as engine from "./readline-engine.js";
@@ -75,9 +75,13 @@ export function collectAsks(payloadRoot, types = [], opts = {}) {
75
75
  const p = parseWizardLine(line); // KEY 정규식 [A-Z_]+ (.sh와 동일)
76
76
  if (!p || p.action !== "ask") continue;
77
77
  // 타입별 기본값: @접두면 resolver 해석, 아니면 리터럴 (.sh _type_default 등가)
78
- const typeDefault = p.arg.startsWith("@")
78
+ const rawDefault = p.arg.startsWith("@")
79
79
  ? resolveToken(p.arg.slice(1), type, resolvers)
80
80
  : p.arg;
81
+ // 리터럴 기본값 안에 __PROJECT_NAME__ 등이 박혀 있으면(issue #110) 실제 repoName으로
82
+ // 풀어준다 — substituteEnv()가 설치 파일에 적용하는 것과 동일한 치환이라야 마법사
83
+ // 화면 표시와 실제 설치 결과가 어긋나지 않는다.
84
+ const typeDefault = replaceProjectTokens(rawDefault, resolveToken("repo", type, resolvers));
81
85
  typeDefaults.set(`${type}|${p.key}`, typeDefault);
82
86
  if (!defaults.has(p.key)) { keys.push(p.key); defaults.set(p.key, typeDefault); }
83
87
  const list = usages.get(p.key) || [];